diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 134 |
1 files changed, 79 insertions, 55 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c0ff942e20..1ec6d97343 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -414,11 +414,15 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC); } } - zval_ptr_dtor(&EG(This)); + if (!Z_DELREF(EG(This))) { + _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC); + } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) { + gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC); + } } - Z_OBJ(EG(This)) = EX(current_this); - EG(scope) = EX(current_scope); - EG(called_scope) = EX(current_called_scope); + Z_OBJ(EG(This)) = EX(object); + EG(scope) = EX(scope); + EG(called_scope) = EX(called_scope); EX(call)--; @@ -487,12 +491,12 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_bool should_change_scope = 0; zend_function *fbc = EX(function_state).function; + zend_object *object; zend_uint num_args; SAVE_OPLINE(); - EX(object) = EX(call)->object; + object = EX(call)->object; if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) { if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) { zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name->val, fbc->common.function_name->val); @@ -509,7 +513,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } if (fbc->common.scope && !(fbc->common.fn_flags & ZEND_ACC_STATIC) && - !EX(object)) { + !object) { if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { /* FIXME: output identifiers properly */ @@ -524,17 +528,6 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } } - if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) { - should_change_scope = 1; - EX(current_this) = Z_OBJ(EG(This)); - EX(current_scope) = EG(scope); - EX(current_called_scope) = EG(called_scope); - Z_OBJ(EG(This)) = EX(object); -//??? EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL; - EG(scope) = fbc->common.scope; - EG(called_scope) = EX(call)->called_scope; - } - if (UNEXPECTED(EX(call)->num_additional_args != 0)) { num_args = opline->extended_value + EX(call)->num_additional_args; EX(function_state).arguments = zend_vm_stack_push_args(num_args TSRMLS_CC); @@ -549,6 +542,17 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { + int should_change_scope = 0; + zval *ret; + + if (fbc->common.scope) { + should_change_scope = 1; + Z_OBJ(EG(This)) = object; +//??? EG(scope) = (object) ? NULL : fbc->common.scope; + EG(scope) = fbc->common.scope; + EG(called_scope) = EX(call)->called_scope; + } + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { zend_uint i; zval *p = EX(function_state).arguments - num_args; @@ -556,30 +560,44 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR for (i = 0; i < num_args; ++i, ++p) { zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC); } + if (UNEXPECTED(EG(exception) != NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(should_change_scope)) { + goto fcall_end_change_scope; + } else { + goto fcall_end; + } + } } - if (EXPECTED(EG(exception) == NULL)) { - zval *ret = EX_VAR(opline->result.var); + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; - ZVAL_NULL(ret); - Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(num_args, ret TSRMLS_CC); + } else { + zend_execute_internal(execute_data, NULL TSRMLS_CC); + } - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(num_args, ret TSRMLS_CC); - } else { - zend_execute_internal(execute_data, NULL TSRMLS_CC); - } + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(ret); + } - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(ret); - } - } else if (RETURN_VALUE_USED(opline)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (UNEXPECTED(should_change_scope)) { + goto fcall_end_change_scope; + } else { + goto fcall_end; } } else if (fbc->type == ZEND_USER_FUNCTION) { zval *return_value = NULL; + Z_OBJ(EG(This)) = object; + EG(scope) = fbc->common.scope; + EG(called_scope) = EX(call)->called_scope; EG(active_symbol_table) = NULL; EG(active_op_array) = &fbc->op_array; if (RETURN_VALUE_USED(opline)) { @@ -609,11 +627,16 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } EG(active_symbol_table) = EX(symbol_table); } else { /* ZEND_OVERLOADED_FUNCTION */ + Z_OBJ(EG(This)) = object; +//??? EG(scope) = NULL; + EG(scope) = fbc->common.scope; + EG(called_scope) = EX(call)->called_scope; + ZVAL_NULL(EX_VAR(opline->result.var)); /* Not sure what should be done here if it's a static method */ - if (EXPECTED(EX(object) != NULL)) { - EX(object)->handlers->call_method(fbc->common.function_name, EX(object), num_args, EX_VAR(opline->result.var) TSRMLS_CC); + if (EXPECTED(object != NULL)) { + object->handlers->call_method(fbc->common.function_name, object, num_args, EX_VAR(opline->result.var) TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -632,26 +655,31 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR } } - EX(function_state).function = (zend_function *) EX(op_array); - EX(function_state).arguments = NULL; - - if (should_change_scope) { - if (Z_OBJ(EG(This))) { - if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { - if (EX(call)->is_ctor_result_used) { - Z_DELREF(EG(This)); - } - if (Z_REFCOUNT(EG(This)) == 1) { - zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC); - } +fcall_end_change_scope: + if (Z_OBJ(EG(This))) { + if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) { + if (EX(call)->is_ctor_result_used) { + Z_DELREF(EG(This)); + } + if (Z_REFCOUNT(EG(This)) == 1) { + zend_object_store_ctor_failed(Z_OBJ(EG(This)) TSRMLS_CC); } - zval_ptr_dtor(&EG(This)); } - Z_OBJ(EG(This)) = EX(current_this); - EG(scope) = EX(current_scope); - EG(called_scope) = EX(current_called_scope); + if (!Z_DELREF(EG(This))) { + EX(function_state).function = (zend_function *) EX(op_array); + EX(function_state).arguments = NULL; + _zval_dtor_func_for_ptr(Z_COUNTED(EG(This)) ZEND_FILE_LINE_CC); + } else if (UNEXPECTED(!Z_GC_INFO(EG(This)))) { + gc_possible_root(Z_COUNTED(EG(This)) TSRMLS_CC); + } } + Z_OBJ(EG(This)) = EX(object); + EG(scope) = EX(scope); + EG(called_scope) = EX(called_scope); +fcall_end: + EX(function_state).function = (zend_function *) EX(op_array); + EX(function_state).arguments = NULL; EX(call)--; zend_vm_stack_clear_multiple(1 TSRMLS_CC); @@ -2916,7 +2944,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA } EX(function_state).function = (zend_function *) new_op_array; - EX(object) = NULL; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); @@ -7953,7 +7980,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND } EX(function_state).function = (zend_function *) new_op_array; - EX(object) = NULL; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); @@ -13058,7 +13084,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND } EX(function_state).function = (zend_function *) new_op_array; - EX(object) = NULL; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); @@ -29866,7 +29891,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL } EX(function_state).function = (zend_function *) new_op_array; - EX(object) = NULL; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); |