diff options
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_compile.c | 2 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 45 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 41 | ||||
-rw-r--r-- | Zend/zend_vm_opcodes.c | 4 |
4 files changed, 58 insertions, 34 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index d8180c9bee..59dea8664b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5851,6 +5851,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as if (op_array->fn_flags & ZEND_ACC_CLOSURE) { opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL); + opline->extended_value = zend_alloc_cache_slot(); opline->op1_type = IS_CONST; LITERAL_STR(opline->op1, key); } else { @@ -6470,6 +6471,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */ if (decl->flags & ZEND_ACC_ANON_CLASS) { opline->opcode = ZEND_DECLARE_ANON_CLASS; + opline->extended_value = zend_alloc_cache_slot(); opline->result_type = IS_VAR; opline->result.var = get_temporary_variable(); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0224e674e7..327e6c17e1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7264,24 +7264,28 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY) +ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT) { zval *zv; zend_class_entry *ce; USE_OPLINE - zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); - ZEND_ASSERT(zv != NULL); - ce = Z_CE_P(zv); - Z_CE_P(EX_VAR(opline->result.var)) = ce; - - if (ce->ce_flags & ZEND_ACC_LINKED) { - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); + if (!(ce->ce_flags & ZEND_ACC_LINKED)) { + SAVE_OPLINE(); + zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + CACHE_PTR(opline->extended_value, ce); } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY) @@ -7550,19 +7554,26 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) +ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED, CACHE_SLOT) { USE_OPLINE + zend_function *func; zval *zfunc; zval *object; zend_class_entry *called_scope; - zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); - ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); + func = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(func == NULL)) { + zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zfunc != NULL); + func = Z_FUNC_P(zfunc); + ZEND_ASSERT(func->type == ZEND_USER_FUNCTION); + CACHE_PTR(opline->extended_value, func); + } if (Z_TYPE(EX(This)) == IS_OBJECT) { called_scope = Z_OBJCE(EX(This)); - if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) || + if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { object = NULL; } else { @@ -7572,7 +7583,7 @@ ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) called_scope = Z_CE(EX(This)); object = NULL; } - zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), + zend_create_closure(EX_VAR(opline->result.var), func, EX(func)->op_array.scope, called_scope, object); ZEND_VM_NEXT_OPCODE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2c21ea0a04..b93a21a9fe 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2430,18 +2430,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE zend_class_entry *ce; USE_OPLINE - zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); - ZEND_ASSERT(zv != NULL); - ce = Z_CE_P(zv); - Z_CE_P(EX_VAR(opline->result.var)) = ce; - - if (ce->ce_flags & ZEND_ACC_LINKED) { - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); + if (!(ce->ce_flags & ZEND_ACC_LINKED)) { + SAVE_OPLINE(); + zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + CACHE_PTR(opline->extended_value, ce); } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9395,16 +9399,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_function *func; zval *zfunc; zval *object; zend_class_entry *called_scope; - zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); - ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); + func = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(func == NULL)) { + zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zfunc != NULL); + func = Z_FUNC_P(zfunc); + ZEND_ASSERT(func->type == ZEND_USER_FUNCTION); + CACHE_PTR(opline->extended_value, func); + } if (Z_TYPE(EX(This)) == IS_OBJECT) { called_scope = Z_OBJCE(EX(This)); - if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) || + if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { object = NULL; } else { @@ -9414,7 +9425,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C called_scope = Z_CE(EX(This)); object = NULL; } - zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), + zend_create_closure(EX_VAR(opline->result.var), func, EX(func)->op_array.scope, called_scope, object); ZEND_VM_NEXT_OPCODE(); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 6ef58e4d90..7ae64a3224 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -363,11 +363,11 @@ static uint32_t zend_vm_opcodes_flags[195] = { 0x00000000, 0x00000101, 0x00000000, - 0x00000103, + 0x00040103, 0x00000303, 0x00000003, 0x00000303, - 0x00000000, + 0x00040000, 0x00000000, 0x00060757, 0x00000000, |