From: Dmitry Stogov Date: Thu, 16 Apr 2015 09:16:03 +0000 (+0300) Subject: Mark call frames to closures with ZEND_CALL_CLOSURE flag to avoid expensive check... X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~264 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a759967dd1c09f8553bd5dedc82673fec15acb80;p=php Mark call frames to closures with ZEND_CALL_CLOSURE flag to avoid expensive check at zend_leave_helper() --- diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 57b234a12a..980a06c199 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -429,19 +429,27 @@ struct _zend_execute_data { #define ZEND_CALL_FREE_EXTRA_ARGS (1 << 2) /* equal to IS_TYPE_REFCOUNTED */ #define ZEND_CALL_CTOR (1 << 3) #define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 4) +#define ZEND_CALL_CLOSURE (1 << 5) #define ZEND_CALL_INFO(call) \ (Z_TYPE_INFO((call)->This) >> 24) +#define ZEND_CALL_KIND_EX(call_info) \ + (call_info & (ZEND_CALL_CODE | ZEND_CALL_TOP)) + #define ZEND_CALL_KIND(call) \ - (ZEND_CALL_INFO(call) & (ZEND_CALL_CODE | ZEND_CALL_TOP)) + ZEND_CALL_KIND_EX(ZEND_CALL_INFO(call)) #define ZEND_SET_CALL_INFO(call, info) do { \ Z_TYPE_INFO((call)->This) = IS_OBJECT_EX | ((info) << 24); \ } while (0) -#define ZEND_ADD_CALL_FLAG(call, info) do { \ - Z_TYPE_INFO((call)->This) |= ((info) << 24); \ +#define ZEND_ADD_CALL_FLAG_EX(call_info, flag) do { \ + call_info |= ((flag) << 24); \ + } while (0) + +#define ZEND_ADD_CALL_FLAG(call, flag) do { \ + ZEND_ADD_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \ } while (0) #define ZEND_CALL_NUM_ARGS(call) \ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index add05f3139..f98faf9197 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -192,9 +192,9 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3 func, num_args, called_scope, object); } -static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call) +static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_info, zend_execute_data *call) { - if (ZEND_CALL_INFO(call) & ZEND_CALL_FREE_EXTRA_ARGS) { + if (call_info & ZEND_CALL_FREE_EXTRA_ARGS) { zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); zval *p = end + (ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args); do { @@ -204,6 +204,11 @@ static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data * } } +static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call) +{ + zend_vm_stack_free_extra_args_ex(ZEND_CALL_INFO(call), call); +} + static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call) { uint32_t num_args = ZEND_CALL_NUM_ARGS(call); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b710ae99c0..ac9f4b1c5c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -833,6 +833,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { ZEND_ASSERT(GC_TYPE(func->op_array.prototype) == IS_OBJECT); GC_REFCOUNT(func->op_array.prototype)++; + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE); } if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_init_execute_data(call, &func->op_array, fci->retval); diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 98603200bf..7d2472a145 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -103,7 +103,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished if (generator->execute_data) { zend_execute_data *execute_data = generator->execute_data; - zend_op_array *op_array = &execute_data->func->op_array; if (!execute_data->symbol_table) { zend_free_compiled_variables(execute_data); @@ -131,8 +130,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished } /* Free closure object */ - if (op_array->fn_flags & ZEND_ACC_CLOSURE) { - OBJ_RELEASE((zend_object *) op_array->prototype); + if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { + OBJ_RELEASE((zend_object *) EX(func)->common.prototype); } efree(generator->stack); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0dea57aced..28bde464a7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2352,9 +2352,9 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) { zend_execute_data *old_execute_data; - zend_call_kind call_kind = EX_CALL_KIND(); + uint32_t call_info = EX_CALL_INFO(); - if (call_kind == ZEND_CALL_NESTED_FUNCTION) { + if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_FUNCTION) { zend_object *object; i_free_compiled_variables(execute_data); @@ -2364,7 +2364,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) zend_vm_stack_free_extra_args(execute_data); old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); - if (UNEXPECTED(old_execute_data->func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE((zend_object*)old_execute_data->func->op_array.prototype); } object = Z_OBJ(old_execute_data->This); @@ -2395,7 +2395,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) LOAD_OPLINE(); ZEND_VM_INC_OPCODE(); ZEND_VM_LEAVE(); - } else if (call_kind == ZEND_CALL_NESTED_CODE) { + } else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) { zend_detach_symbol_table(execute_data); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); @@ -2413,14 +2413,14 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) ZEND_VM_INC_OPCODE(); ZEND_VM_LEAVE(); } else { - if (call_kind == ZEND_CALL_TOP_FUNCTION) { + if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_TOP_FUNCTION) { i_free_compiled_variables(execute_data); if (UNEXPECTED(EX(symbol_table) != NULL)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } zend_vm_stack_free_extra_args(execute_data); EG(current_execute_data) = EX(prev_execute_data); - if (EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) { + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype); } } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ { @@ -3112,6 +3112,7 @@ ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV) zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); @@ -3147,6 +3148,7 @@ ZEND_VM_C_LABEL(try_function_name): /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE(fbc->common.prototype) == IS_OBJECT); GC_REFCOUNT(fbc->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } FREE_OP2(); } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && @@ -3241,7 +3243,7 @@ ZEND_VM_C_LABEL(try_function_name): FREE_OP2(); HANDLE_EXCEPTION(); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -3261,6 +3263,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); @@ -3276,6 +3279,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) } ZEND_ASSERT(GC_TYPE(func->common.prototype) == IS_OBJECT); GC_REFCOUNT(func->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } called_scope = fcc.called_scope; object = fcc.object; @@ -3304,7 +3308,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) object = NULL; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, func, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -4434,7 +4438,7 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY) } } zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args))); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { @@ -4481,7 +4485,7 @@ ZEND_VM_C_LABEL(send_array): EX(call)->func->common.scope ? "::" : "", EX(call)->func->common.function_name->val); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { @@ -4539,7 +4543,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) EX(call)->func->common.scope ? "::" : "", EX(call)->func->common.function_name->val); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 6d4ee188d9..c969a302cf 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -437,9 +437,9 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value) static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { zend_execute_data *old_execute_data; - zend_call_kind call_kind = EX_CALL_KIND(); + uint32_t call_info = EX_CALL_INFO(); - if (call_kind == ZEND_CALL_NESTED_FUNCTION) { + if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_FUNCTION) { zend_object *object; i_free_compiled_variables(execute_data); @@ -449,7 +449,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ zend_vm_stack_free_extra_args(execute_data); old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); - if (UNEXPECTED(old_execute_data->func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE((zend_object*)old_execute_data->func->op_array.prototype); } object = Z_OBJ(old_execute_data->This); @@ -480,7 +480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ LOAD_OPLINE(); ZEND_VM_INC_OPCODE(); ZEND_VM_LEAVE(); - } else if (call_kind == ZEND_CALL_NESTED_CODE) { + } else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) { zend_detach_symbol_table(execute_data); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); @@ -498,14 +498,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ ZEND_VM_INC_OPCODE(); ZEND_VM_LEAVE(); } else { - if (call_kind == ZEND_CALL_TOP_FUNCTION) { + if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_TOP_FUNCTION) { i_free_compiled_variables(execute_data); if (UNEXPECTED(EX(symbol_table) != NULL)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } zend_vm_stack_free_extra_args(execute_data); EG(current_execute_data) = EX(prev_execute_data); - if (EX(func)->op_array.fn_flags & ZEND_ACC_CLOSURE) { + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE((zend_object*)EX(func)->op_array.prototype); } } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ { @@ -1102,7 +1102,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O } } zend_internal_type_error(EX_USES_STRICT_TYPES(), "call_user_func_array() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(args))); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { @@ -1149,7 +1149,7 @@ send_array: EX(call)->func->common.scope ? "::" : "", EX(call)->func->common.function_name->val); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { @@ -1988,6 +1988,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_H zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = EX_CONSTANT(opline->op2); @@ -2022,6 +2023,7 @@ try_function_name: /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE(fbc->common.prototype) == IS_OBJECT); GC_REFCOUNT(fbc->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && @@ -2116,7 +2118,7 @@ try_function_name: HANDLE_EXCEPTION(); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -2392,6 +2394,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HAND zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -2426,6 +2429,7 @@ try_function_name: /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE(fbc->common.prototype) == IS_OBJECT); GC_REFCOUNT(fbc->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && @@ -2520,7 +2524,7 @@ try_function_name: HANDLE_EXCEPTION(); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -2583,6 +2587,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_ zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -2618,6 +2623,7 @@ try_function_name: /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE(fbc->common.prototype) == IS_OBJECT); GC_REFCOUNT(fbc->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } zval_ptr_dtor_nogc(free_op2); } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && @@ -2712,7 +2718,7 @@ try_function_name: zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, fbc, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -5428,6 +5434,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = EX_CONSTANT(opline->op2); @@ -5443,6 +5450,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS } ZEND_ASSERT(GC_TYPE(func->common.prototype) == IS_OBJECT); GC_REFCOUNT(func->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } called_scope = fcc.called_scope; object = fcc.object; @@ -5471,7 +5479,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS object = NULL; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, func, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -8890,6 +8898,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -8905,6 +8914,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H } ZEND_ASSERT(GC_TYPE(func->common.prototype) == IS_OBJECT); GC_REFCOUNT(func->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } called_scope = fcc.called_scope; object = fcc.object; @@ -8933,7 +8943,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H object = NULL; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, func, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -10484,6 +10494,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV zend_class_entry *called_scope; zend_object *object; zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION; SAVE_OPLINE(); function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -10499,6 +10510,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV } ZEND_ASSERT(GC_TYPE(func->common.prototype) == IS_OBJECT); GC_REFCOUNT(func->common.prototype)++; + call_info |= ZEND_CALL_CLOSURE; } called_scope = fcc.called_scope; object = fcc.object; @@ -10527,7 +10539,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV object = NULL; } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = zend_vm_stack_push_call_frame(call_info, func, opline->extended_value, called_scope, object); call->prev_execute_data = EX(call); EX(call) = call; @@ -14431,7 +14443,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEN EX(call)->func->common.scope ? "::" : "", EX(call)->func->common.function_name->val); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) { @@ -28169,7 +28181,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND EX(call)->func->common.scope ? "::" : "", EX(call)->func->common.function_name->val); - if (EX(call)->func->common.fn_flags & ZEND_ACC_CLOSURE) { + if (ZEND_CALL_INFO(EX(call)) & ZEND_CALL_CLOSURE) { OBJ_RELEASE((zend_object*)EX(call)->func->common.prototype); } if (Z_OBJ(EX(call)->This)) {