From b15f4d83a760013142c5275a2b29244a5ef62d90 Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Thu, 26 May 2016 12:10:15 +0100 Subject: [PATCH] fixes for 7.1, add leave helper function --- src/class.c | 55 +++++++++++++++++++++++++++++++++---------------------- src/handlers.c | 33 +++++++++++++++++++++++---------- uopz.h | 2 +- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/class.c b/src/class.c index 15100d9..db9fe6c 100644 --- a/src/class.c +++ b/src/class.c @@ -27,6 +27,14 @@ ZEND_EXTERN_MODULE_GLOBALS(uopz); +#if PHP_VERSION_ID >= 70100 +# define uopz_get_scope(e) ((e) ? zend_get_executed_scope() : EG(fake_scope)) +# define uopz_set_scope(s) EG(fake_scope) = (s) +#else +# define uopz_get_scope(e) EG(scope) +# define uopz_set_scope(s) EG(scope) = (s) +#endif + void uopz_set_mock(zend_string *clazz, zval *mock) { /* {{{ */ zend_string *key = zend_string_tolower(clazz); @@ -131,12 +139,12 @@ zend_bool uopz_implement(zend_class_entry *clazz, zend_class_entry *interface) { } /* }}} */ void uopz_set_property(zval *object, zval *member, zval *value) { /* {{{ */ - zend_class_entry *scope = EG(scope); + zend_class_entry *scope = uopz_get_scope(1); zend_class_entry *ce = Z_OBJCE_P(object); zend_property_info *info; do { - EG(scope) = ce; + uopz_set_scope(ce); info = zend_get_property_info(ce, Z_STR_P(member), 1); @@ -148,25 +156,25 @@ void uopz_set_property(zval *object, zval *member, zval *value) { /* {{{ */ } while (ce); if (info && info != ZEND_WRONG_PROPERTY_INFO) { - EG(scope) = info->ce; + uopz_set_scope(info->ce); } else { - EG(scope) = Z_OBJCE_P(object); + uopz_set_scope(Z_OBJCE_P(object)); } Z_OBJ_HT_P(object) ->write_property(object, member, value, NULL); - EG(scope) = scope; + uopz_set_scope(scope); } /* }}} */ void uopz_get_property(zval *object, zval *member, zval *value) { /* {{{ */ - zend_class_entry *scope = EG(scope); + zend_class_entry *scope = uopz_get_scope(1); zend_class_entry *ce = Z_OBJCE_P(object); zend_property_info *info; zval *prop, rv; do { - EG(scope) = ce; + uopz_set_scope(ce); info = zend_get_property_info(ce, Z_STR_P(member), 1); @@ -178,14 +186,15 @@ void uopz_get_property(zval *object, zval *member, zval *value) { /* {{{ */ } while (ce); if (info && info != ZEND_WRONG_PROPERTY_INFO) { - EG(scope) = info->ce; + uopz_set_scope(info->ce); } else { - EG(scope) = Z_OBJCE_P(object); + uopz_set_scope(Z_OBJCE_P(object)); } prop = Z_OBJ_HT_P(object) ->read_property(object, member, BP_VAR_R, NULL, &rv); - EG(scope) = scope; + + uopz_set_scope(scope); if (!prop) { return; @@ -195,13 +204,13 @@ void uopz_get_property(zval *object, zval *member, zval *value) { /* {{{ */ } /* }}} */ void uopz_set_static_property(zend_class_entry *ce, zend_string *property, zval *value) { /* {{{ */ - zend_class_entry *scope = EG(scope); + zend_class_entry *scope = uopz_get_scope(1); zend_class_entry *seek = ce; zend_property_info *info; zval *prop; do { - EG(scope) = seek; + uopz_set_scope(seek); info = zend_get_property_info(seek, property, 1); @@ -213,13 +222,14 @@ void uopz_set_static_property(zend_class_entry *ce, zend_string *property, zval } while (seek); if (info && info != ZEND_WRONG_PROPERTY_INFO) { - EG(scope) = info->ce; + uopz_set_scope(info->ce); } else { - EG(scope) = ce; + uopz_set_scope(ce); } - prop = zend_std_get_static_property(EG(scope), property, 1); - EG(scope) = scope; + prop = zend_std_get_static_property(uopz_get_scope(0), property, 1); + + uopz_set_scope(scope); if (!prop) { return; @@ -230,13 +240,13 @@ void uopz_set_static_property(zend_class_entry *ce, zend_string *property, zval } /* }}} */ void uopz_get_static_property(zend_class_entry *ce, zend_string *property, zval *value) { /* {{{ */ - zend_class_entry *scope = EG(scope); + zend_class_entry *scope = uopz_get_scope(1); zend_class_entry *seek = ce; zend_property_info *info; zval *prop; do { - EG(scope) = seek; + uopz_set_scope(seek); info = zend_get_property_info(seek, property, 1); @@ -248,13 +258,14 @@ void uopz_get_static_property(zend_class_entry *ce, zend_string *property, zval } while (seek); if (info && info != ZEND_WRONG_PROPERTY_INFO) { - EG(scope) = info->ce; + uopz_set_scope(info->ce); } else { - EG(scope) = ce; + uopz_set_scope(ce); } - prop = zend_std_get_static_property(EG(scope), property, 1); - EG(scope) = scope; + prop = zend_std_get_static_property(uopz_get_scope(0), property, 1); + + uopz_set_scope(scope); if (!prop) { return; diff --git a/src/handlers.c b/src/handlers.c index 11b7f5f..98e9c37 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -344,6 +344,27 @@ static inline void uopz_run_hook(zend_function *function, zend_execute_data *exe } } /* }}} */ +/* {{{ */ +static inline int php_uopz_leave_helper(zend_execute_data *execute_data) { + zend_execute_data *call = EX(call); + uint32_t info = ZEND_CALL_INFO(call); + + if (info & ZEND_CALL_RELEASE_THIS) { + OBJ_RELEASE(Z_OBJ(call->This)); + } else if (info & ZEND_CALL_CLOSURE) { + OBJ_RELEASE((zend_object*)call->func->op_array.prototype); + } + + EX(call) = call->prev_execute_data; + + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + EX(opline) = EX(opline) + 1; + + return ZEND_USER_OPCODE_LEAVE; +} /* }}} */ + int uopz_return_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ zend_execute_data *call = EX(call); @@ -366,26 +387,18 @@ int uopz_return_handler(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */ uopz_execute_return(ureturn, call, return_value); - EX(call) = call->prev_execute_data; - zend_vm_stack_free_call_frame(call); - EX(opline) = opline + 1; - if (!RETURN_VALUE_USED(opline)) { zval_ptr_dtor(&rv); } - return ZEND_USER_OPCODE_CONTINUE; + return php_uopz_leave_helper(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU); } if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(return_value, &ureturn->value); } - EX(call) = call->prev_execute_data; - zend_vm_stack_free_call_frame(call); - EX(opline) = opline + 1; - - return ZEND_USER_OPCODE_CONTINUE; + return php_uopz_leave_helper(UOPZ_OPCODE_HANDLER_ARGS_PASSTHRU); } }