From 29afca20ef250057edc7c4495964d134d33022d5 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Mon, 1 Sep 2025 22:19:28 +1000 Subject: [PATCH 01/10] adding methods on function and execute data --- phper/src/functions.rs | 5 +++++ phper/src/values.rs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/phper/src/functions.rs b/phper/src/functions.rs index 498568b..7bd873e 100644 --- a/phper/src/functions.rs +++ b/phper/src/functions.rs @@ -629,6 +629,11 @@ impl ZFunc { } } + /// Detects if the function is static. + pub fn is_static(&self) -> bool { + unsafe { (self.inner.op_array.fn_flags & ZEND_ACC_STATIC) != 0 } + } + /// Get the type of the function (sys::ZEND_USER_FUNCTION, /// sys::ZEND_INTERNAL_FUNCTION, or sys::ZEND_EVAL_CODE). pub fn get_type(&self) -> u32 { diff --git a/phper/src/values.rs b/phper/src/values.rs index cb39819..4941484 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -191,6 +191,14 @@ impl ExecuteData { } } + /// Gets associated called scope if it exists + pub fn get_called_scope(&mut self) -> Option<&ZStr> { + unsafe { + let val = ZVal::from_ptr(phper_get_called_scope(&mut self.inner)); + val.as_z_str() + } + } + pub(crate) unsafe fn get_parameters_array(&mut self) -> Vec> { unsafe { let num_args = self.num_args(); From 24fe9e8f84330626d64ef8973f16d66624678df5 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Mon, 1 Sep 2025 22:27:40 +1000 Subject: [PATCH 02/10] retrieve ClassEntry for called scope --- phper-sys/php_wrapper.c | 4 ++++ phper/src/values.rs | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/phper-sys/php_wrapper.c b/phper-sys/php_wrapper.c index a12012d..07aad65 100644 --- a/phper-sys/php_wrapper.c +++ b/phper-sys/php_wrapper.c @@ -348,6 +348,10 @@ zval *phper_get_this(zend_execute_data *execute_data) { return getThis(); } +zend_class_entry *phper_get_called_scope(zend_execute_data *execute_data) { + return zend_get_called_scope(execute_data); +} + size_t phper_zend_object_properties_size(zend_class_entry *ce) { return zend_object_properties_size(ce); } diff --git a/phper/src/values.rs b/phper/src/values.rs index 4941484..22e2d33 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -12,6 +12,7 @@ use crate::{ arrays::{ZArr, ZArray}, + classes::ClassEntry, errors::ExpectTypeError, functions::{ZFunc, call_internal}, objects::{StateObject, ZObj, ZObject}, @@ -192,10 +193,14 @@ impl ExecuteData { } /// Gets associated called scope if it exists - pub fn get_called_scope(&mut self) -> Option<&ZStr> { + pub fn get_called_scope(&mut self) -> Option<&ClassEntry> { unsafe { - let val = ZVal::from_ptr(phper_get_called_scope(&mut self.inner)); - val.as_z_str() + let ptr = phper_get_called_scope(&mut self.inner); + if ptr.is_null() { + None + } else { + Some(ClassEntry::from_ptr(ptr)) + } } } From 1cb3a668c69c23ab879af0979558580a8a58f8bd Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Mon, 1 Sep 2025 22:47:54 +1000 Subject: [PATCH 03/10] get this may return a null pointer --- phper/src/values.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/phper/src/values.rs b/phper/src/values.rs index 22e2d33..c99c79e 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -187,8 +187,13 @@ impl ExecuteData { /// Gets associated mutable `$this` object if exists. pub fn get_this_mut(&mut self) -> Option<&mut ZObj> { unsafe { - let val = ZVal::from_mut_ptr(phper_get_this(&mut self.inner)); - val.as_mut_z_obj() + let ptr = phper_get_this(&mut self.inner); + if ptr.is_null() { + None + } else { + let val = ZVal::from_mut_ptr(ptr); + val.as_mut_z_obj() + } } } From 14fb44e3f732c54b62ce0930b70dbc07e3caa53c Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Mon, 1 Sep 2025 23:08:03 +1000 Subject: [PATCH 04/10] public get_parameters_array --- phper/src/values.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phper/src/values.rs b/phper/src/values.rs index c99c79e..ab724dc 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -209,7 +209,7 @@ impl ExecuteData { } } - pub(crate) unsafe fn get_parameters_array(&mut self) -> Vec> { + pub unsafe fn get_parameters_array(&mut self) -> Vec> { unsafe { let num_args = self.num_args(); let mut arguments = vec![zeroed::(); num_args]; From 6399c31c67b4d8c877d220f7c9454bc644a51b99 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Wed, 3 Sep 2025 13:30:15 +1000 Subject: [PATCH 05/10] ensure param slot exists --- phper/src/values.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/phper/src/values.rs b/phper/src/values.rs index ab724dc..48da3f0 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -209,7 +209,7 @@ impl ExecuteData { } } - pub unsafe fn get_parameters_array(&mut self) -> Vec> { + pub(crate) unsafe fn get_parameters_array(&mut self) -> Vec> { unsafe { let num_args = self.num_args(); let mut arguments = vec![zeroed::(); num_args]; @@ -238,6 +238,18 @@ impl ExecuteData { ZVal::from_mut_ptr(val) } } + + /// Ensure parameter slot exists, if not, create it and set to null. + pub fn ensure_parameter_slot(&mut self, index: usize) { + let num_args = self.num_args(); + if index >= num_args { + unsafe { + let params_ptr = phper_zend_call_var_num(self.as_mut_ptr(), index as i32); + phper_zval_null(params_ptr); + (*self.inner.func).common.num_args = (index + 1) as u32; + } + } + } } /// Wrapper of [zval]. From ab294eb6721d069c8b2f753f176653cca19d99b3 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Mon, 15 Sep 2025 16:56:47 +1000 Subject: [PATCH 06/10] Revert "ensure param slot exists" This reverts commit 6399c31c67b4d8c877d220f7c9454bc644a51b99. --- phper/src/values.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/phper/src/values.rs b/phper/src/values.rs index 48da3f0..ab724dc 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -209,7 +209,7 @@ impl ExecuteData { } } - pub(crate) unsafe fn get_parameters_array(&mut self) -> Vec> { + pub unsafe fn get_parameters_array(&mut self) -> Vec> { unsafe { let num_args = self.num_args(); let mut arguments = vec![zeroed::(); num_args]; @@ -238,18 +238,6 @@ impl ExecuteData { ZVal::from_mut_ptr(val) } } - - /// Ensure parameter slot exists, if not, create it and set to null. - pub fn ensure_parameter_slot(&mut self, index: usize) { - let num_args = self.num_args(); - if index >= num_args { - unsafe { - let params_ptr = phper_zend_call_var_num(self.as_mut_ptr(), index as i32); - phper_zval_null(params_ptr); - (*self.inner.func).common.num_args = (index + 1) as u32; - } - } - } } /// Wrapper of [zval]. From 3555a340ebc8d42c771cc69e4e903e8582783293 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Thu, 18 Sep 2025 16:11:03 +1000 Subject: [PATCH 07/10] more function-based methods --- phper-sys/php_wrapper.c | 32 ++++++++++++++++++++++++++++++++ phper/src/values.rs | 13 +++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/phper-sys/php_wrapper.c b/phper-sys/php_wrapper.c index 07aad65..80c4ae8 100644 --- a/phper-sys/php_wrapper.c +++ b/phper-sys/php_wrapper.c @@ -198,6 +198,10 @@ void phper_zval_str(zval *zv, zend_string *s) { ZVAL_STR(zv, s); } +void phper_zval_undef(zval *zv) { + ZVAL_UNDEF(zv); +} + void phper_convert_to_long(zval *op) { convert_to_long(op); } @@ -451,11 +455,39 @@ uint32_t phper_zend_num_args(const zend_execute_data *execute_data) { return ZEND_NUM_ARGS(); } +uint32_t phper_zend_call_num_args(const zend_execute_data *execute_data) { + return ZEND_CALL_NUM_ARGS(execute_data); +} + +void phper_zend_set_call_num_args(zend_execute_data *execute_data, uint32_t num) { + ZEND_CALL_NUM_ARGS(execute_data) = num; +} + +uint32_t phper_zend_call_info(zend_execute_data *execute_data) { + return ZEND_CALL_INFO(execute_data); +} + +void phper_zend_add_call_flag(zend_execute_data *execute_data, uint32_t flag) { + ZEND_ADD_CALL_FLAG(execute_data, flag); +} + +uint32_t phper_zend_call_may_have_undef() { + return ZEND_CALL_MAY_HAVE_UNDEF; +} + bool phper_zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array) { return zend_get_parameters_array_ex(param_count, argument_array) != 0; } +int phper_zend_result_success() { + return SUCCESS; +} + +int phper_zend_result_failure() { + return FAILURE; +} + // ================================================== // memory apis: // ================================================== diff --git a/phper/src/values.rs b/phper/src/values.rs index ab724dc..e3e3dc1 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -179,21 +179,14 @@ impl ExecuteData { /// Gets associated `$this` object if exists. pub fn get_this(&mut self) -> Option<&ZObj> { unsafe { - let val = ZVal::from_ptr(phper_get_this(&mut self.inner)); - val.as_z_obj() + ZVal::try_from_ptr(phper_get_this(&mut self.inner))?.as_z_obj() } } /// Gets associated mutable `$this` object if exists. pub fn get_this_mut(&mut self) -> Option<&mut ZObj> { unsafe { - let ptr = phper_get_this(&mut self.inner); - if ptr.is_null() { - None - } else { - let val = ZVal::from_mut_ptr(ptr); - val.as_mut_z_obj() - } + ZVal::try_from_mut_ptr(phper_get_this(&mut self.inner))?.as_mut_z_obj() } } @@ -209,7 +202,7 @@ impl ExecuteData { } } - pub unsafe fn get_parameters_array(&mut self) -> Vec> { + pub(crate) unsafe fn get_parameters_array(&mut self) -> Vec> { unsafe { let num_args = self.num_args(); let mut arguments = vec![zeroed::(); num_args]; From 97bf7d9920161a15d624453a03bd43ffd09257e3 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Thu, 18 Sep 2025 16:21:49 +1000 Subject: [PATCH 08/10] move const accessor --- phper-sys/php_wrapper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phper-sys/php_wrapper.c b/phper-sys/php_wrapper.c index 80c4ae8..e4393e0 100644 --- a/phper-sys/php_wrapper.c +++ b/phper-sys/php_wrapper.c @@ -471,15 +471,15 @@ void phper_zend_add_call_flag(zend_execute_data *execute_data, uint32_t flag) { ZEND_ADD_CALL_FLAG(execute_data, flag); } -uint32_t phper_zend_call_may_have_undef() { - return ZEND_CALL_MAY_HAVE_UNDEF; -} - bool phper_zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array) { return zend_get_parameters_array_ex(param_count, argument_array) != 0; } +uint32_t phper_zend_call_may_have_undef() { + return ZEND_CALL_MAY_HAVE_UNDEF; +} + int phper_zend_result_success() { return SUCCESS; } From 8f2076e60bb51a7b937c86d6b3c280ba12559984 Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Thu, 18 Sep 2025 16:34:25 +1000 Subject: [PATCH 09/10] fmt --- phper/src/values.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/phper/src/values.rs b/phper/src/values.rs index e3e3dc1..690aed0 100644 --- a/phper/src/values.rs +++ b/phper/src/values.rs @@ -178,16 +178,12 @@ impl ExecuteData { /// Gets associated `$this` object if exists. pub fn get_this(&mut self) -> Option<&ZObj> { - unsafe { - ZVal::try_from_ptr(phper_get_this(&mut self.inner))?.as_z_obj() - } + unsafe { ZVal::try_from_ptr(phper_get_this(&mut self.inner))?.as_z_obj() } } /// Gets associated mutable `$this` object if exists. pub fn get_this_mut(&mut self) -> Option<&mut ZObj> { - unsafe { - ZVal::try_from_mut_ptr(phper_get_this(&mut self.inner))?.as_mut_z_obj() - } + unsafe { ZVal::try_from_mut_ptr(phper_get_this(&mut self.inner))?.as_mut_z_obj() } } /// Gets associated called scope if it exists From 3b2c62bc4a0876958c7fba642df3af6ba3ad652e Mon Sep 17 00:00:00 2001 From: Brett McBride Date: Fri, 19 Sep 2025 10:09:35 +1000 Subject: [PATCH 10/10] define ZEND_CALL_MAY_HAVE_UNDEF --- phper-sys/php_wrapper.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phper-sys/php_wrapper.c b/phper-sys/php_wrapper.c index e4393e0..72a0489 100644 --- a/phper-sys/php_wrapper.c +++ b/phper-sys/php_wrapper.c @@ -50,6 +50,10 @@ phper_init_class_entry_handler(zend_class_entry *class_ce, void *argument); #define IS_VOID 0x1D #endif +#ifndef ZEND_CALL_MAY_HAVE_UNDEF +#define ZEND_CALL_MAY_HAVE_UNDEF (1 << 26) +#endif + // ================================================== // zval apis: // ==================================================