diff --git a/phper-sys/php_wrapper.c b/phper-sys/php_wrapper.c index a12012d..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: // ================================================== @@ -198,6 +202,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); } @@ -348,6 +356,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); } @@ -447,11 +459,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); +} + 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; +} + +int phper_zend_result_failure() { + return FAILURE; +} + // ================================================== // memory apis: // ================================================== 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..690aed0 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}, @@ -177,17 +178,23 @@ 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() - } + 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() } + } + + /// Gets associated called scope if it exists + pub fn get_called_scope(&mut self) -> Option<&ClassEntry> { unsafe { - let val = ZVal::from_mut_ptr(phper_get_this(&mut self.inner)); - val.as_mut_z_obj() + let ptr = phper_get_called_scope(&mut self.inner); + if ptr.is_null() { + None + } else { + Some(ClassEntry::from_ptr(ptr)) + } } }