From: Nikita Popov Date: Thu, 29 Aug 2019 10:32:23 +0000 (+0200) Subject: Merge branch 'PHP-7.2' into PHP-7.3 X-Git-Tag: php-7.4.0RC1~24^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34edd4aa2aa100a39075d3c4b086165f8c372945;p=php Merge branch 'PHP-7.2' into PHP-7.3 --- 34edd4aa2aa100a39075d3c4b086165f8c372945 diff --cc Zend/zend_vm_def.h index 0bedf907a2,df0a3d9812..99b731b11a --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@@ -2442,10 -2415,9 +2447,9 @@@ ZEND_VM_HOT_HELPER(zend_leave_helper, A } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype); + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } - zend_vm_stack_free_extra_args_ex(call_info, execute_data); old_execute_data = execute_data; execute_data = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); diff --cc Zend/zend_vm_execute.h index 1c95ac57a0,28fc5dabe4..b29f5bddc6 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@@ -553,10 -485,9 +558,9 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE((zend_object*)execute_data->func->op_array.prototype); + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } - zend_vm_stack_free_extra_args_ex(call_info, execute_data); old_execute_data = execute_data; execute_data = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@@ -55335,125 -59744,7 +55339,129 @@@ ZEND_API void execute_ex(zend_execute_d #endif #endif #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) +zend_leave_helper_SPEC_LABEL: +{ + zend_execute_data *old_execute_data; + uint32_t call_info = EX_CALL_INFO(); + + if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { + i_free_compiled_variables(execute_data); + + EG(current_execute_data) = EX(prev_execute_data); + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + zend_object *object = Z_OBJ(execute_data->This); +#if 0 + if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { +#else + if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { +#endif + GC_DELREF(object); + zend_object_store_ctor_failed(object); + } + OBJ_RELEASE(object); + } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + EG(vm_stack_top) = (zval*)execute_data; + execute_data = EX(prev_execute_data); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { + i_free_compiled_variables(execute_data); + + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + EG(current_execute_data) = EX(prev_execute_data); ++ ++ /* Free extra args before releasing the closure, ++ * as that may free the op_array. */ ++ zend_vm_stack_free_extra_args_ex(call_info, execute_data); ++ + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + zend_object *object = Z_OBJ(execute_data->This); +#if 0 + if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { +#else + if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { +#endif + GC_DELREF(object); + zend_object_store_ctor_failed(object); + } + OBJ_RELEASE(object); + } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + - zend_vm_stack_free_extra_args_ex(call_info, execute_data); + old_execute_data = execute_data; + execute_data = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) { + zend_detach_symbol_table(execute_data); + destroy_op_array(&EX(func)->op_array); + efree_size(EX(func), sizeof(zend_op_array)); + old_execute_data = execute_data; + execute_data = EG(current_execute_data) = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + + zend_attach_symbol_table(execute_data); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else { + if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { + i_free_compiled_variables(execute_data); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + zend_vm_stack_free_extra_args_ex(call_info, execute_data); + } + EG(current_execute_data) = EX(prev_execute_data); + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + ZEND_VM_RETURN(); + } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ { + zend_array *symbol_table = EX(symbol_table); + + zend_detach_symbol_table(execute_data); + old_execute_data = EX(prev_execute_data); + while (old_execute_data) { + if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) { + if (old_execute_data->symbol_table == symbol_table) { + zend_attach_symbol_table(old_execute_data); + } + break; + } + old_execute_data = old_execute_data->prev_execute_data; + } + EG(current_execute_data) = EX(prev_execute_data); + ZEND_VM_RETURN(); + } + } +} + HYBRID_CASE(ZEND_JMP_SPEC): + VM_TRACE(ZEND_JMP_SPEC) ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_DO_ICALL_SPEC_RETVAL_UNUSED):