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 {
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();
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)
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 {
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();
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)
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 {
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();
0x00000000,
0x00000101,
0x00000000,
- 0x00000103,
+ 0x00040103,
0x00000303,
0x00000003,
0x00000303,
- 0x00000000,
+ 0x00040000,
0x00000000,
0x00060757,
0x00000000,
bind_var_slot[opline->op2.constant] = opline->extended_value;
}
break;
+ case ZEND_DECLARE_LAMBDA_FUNCTION:
+ case ZEND_DECLARE_ANON_CLASS:
+ opline->extended_value = cache_size;
+ cache_size += sizeof(void *);
+ break;
}
opline++;
}