diff options
-rw-r--r-- | Zend/zend_compile.c | 114 | ||||
-rw-r--r-- | Zend/zend_execute.c | 90 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 2 | ||||
-rw-r--r-- | Zend/zend_types.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 437 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 3101 | ||||
-rw-r--r-- | Zend/zend_vm_gen.php | 4 | ||||
-rw-r--r-- | Zend/zend_vm_opcodes.c | 104 | ||||
-rw-r--r-- | Zend/zend_vm_opcodes.h | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/compact_literals.c | 565 | ||||
-rw-r--r-- | ext/opcache/Optimizer/dfa_pass.c | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/optimize_func_calls.c | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/sccp.c | 4 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_cfg.c | 4 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_dump.c | 2 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 117 | ||||
-rw-r--r-- | ext/opcache/zend_file_cache.c | 4 | ||||
-rw-r--r-- | ext/opcache/zend_persist.c | 2 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_opcode.c | 2 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_utils.c | 6 | ||||
-rw-r--r-- | sapi/phpdbg/tests/exceptions_003.phpt | 2 | ||||
-rw-r--r-- | sapi/phpdbg/tests/stepping_001.phpt | 2 |
23 files changed, 2752 insertions, 1822 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3d9b2e77c6..9127c110bd 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -64,18 +64,20 @@ typedef struct _zend_loop_var { } u; } zend_loop_var; -static inline void zend_alloc_cache_slot(uint32_t literal) { +static inline uint32_t zend_alloc_cache_slot(void) { zend_op_array *op_array = CG(active_op_array); - Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size; + uint32_t ret = op_array->cache_size; op_array->cache_size += sizeof(void*); + return ret; } #define POLYMORPHIC_CACHE_SLOT_SIZE 2 -static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) { +static inline uint32_t zend_alloc_polymorphic_cache_slot(void) { zend_op_array *op_array = CG(active_op_array); - Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size; + uint32_t ret = op_array->cache_size; op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*); + return ret; } ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); @@ -453,7 +455,6 @@ static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int li zval_make_interned_string(zv); } ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv); - Z_CACHE_SLOT(op_array->literals[literal_position]) = -1; } /* }}} */ @@ -531,8 +532,6 @@ static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *nam zend_string *lc_name = zend_string_tolower(name); zend_add_literal_string(op_array, &lc_name); - zend_alloc_cache_slot(ret); - return ret; } /* }}} */ @@ -2026,7 +2025,34 @@ static void zend_find_live_range(zend_op *opline, zend_uchar type, uint32_t var) } else if (def->opcode == ZEND_NEW) { /* Objects created via ZEND_NEW are only fully initialized * after the DO_FCALL (constructor call) */ - def = CG(active_op_array)->opcodes + def->op2.opline_num - 1; + int level = 0; + while (def + 1 != opline) { + def++; + if (def->opcode == ZEND_DO_FCALL) { + if (level == 0) { + break; + } + level--; + } else { + switch(def->opcode) { + case ZEND_INIT_FCALL: + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: + case ZEND_INIT_USER_CALL: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_STATIC_METHOD_CALL: + case ZEND_NEW: + level++; + break; + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: + level--; + break; + } + } + } if (def + 1 == opline) { break; } @@ -2507,6 +2533,7 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int th opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), zend_resolve_class_name(name, type)); + opline->extended_value = zend_alloc_cache_slot(); } else { zend_ensure_valid_class_fetch_type(fetch_type); } @@ -2742,7 +2769,7 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t opline = zend_delayed_emit_op(result, ZEND_FETCH_OBJ_R, &obj_node, &prop_node); if (opline->op2_type == IS_CONST) { convert_to_string(CT_CONSTANT(opline->op2)); - zend_alloc_polymorphic_cache_slot(opline->op2.constant); + opline->extended_value = zend_alloc_polymorphic_cache_slot(); } zend_adjust_for_fetch_type(opline, type); @@ -2777,12 +2804,15 @@ zend_op *zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, i } if (opline->op1_type == IS_CONST) { convert_to_string(CT_CONSTANT(opline->op1)); - zend_alloc_polymorphic_cache_slot(opline->op1.constant); + opline->extended_value = zend_alloc_polymorphic_cache_slot(); } if (class_node.op_type == IS_CONST) { opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal( CG(active_op_array), Z_STR(class_node.u.constant)); + if (opline->op1_type != IS_CONST) { + opline->extended_value = zend_alloc_polymorphic_cache_slot(); + } } else { SET_NODE(opline->op2, &class_node); } @@ -3148,7 +3178,7 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ znode var_node, expr_node; zend_op *opline; - uint32_t offset; + uint32_t offset, cache_slot; zend_ensure_writable_variable(var_ast); @@ -3178,10 +3208,12 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); opline = zend_delayed_compile_end(offset); + cache_slot = opline->extended_value; opline->opcode = opcode; opline->extended_value = ZEND_ASSIGN_OBJ; - zend_emit_op_data(&expr_node); + opline = zend_emit_op_data(&expr_node); + opline->extended_value = cache_slot; return; EMPTY_SWITCH_DEFAULT_CASE() } @@ -3385,7 +3417,7 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) / opline->op2_type = IS_CONST; opline->op2.constant = zend_add_ns_func_name_literal( CG(active_op_array), Z_STR(name_node->u.constant)); - zend_alloc_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); zend_compile_call_common(result, args_ast, NULL); } @@ -3406,7 +3438,8 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), class); opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), method); - zend_alloc_cache_slot(opline->op2.constant); + /* 2 slots, for class and method */ + opline->result.num = zend_alloc_polymorphic_cache_slot(); zval_ptr_dtor(&name_node->u.constant); } else { zend_op *opline = get_next_op(CG(active_op_array)); @@ -3415,7 +3448,7 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a SET_UNUSED(opline->op1); opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), str); - zend_alloc_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); } } else { zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node); @@ -3521,7 +3554,7 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */ opline = zend_emit_op_tmp(result, ZEND_DEFINED, NULL, NULL); opline->op1_type = IS_CONST; LITERAL_STR(opline->op1, name); - zend_alloc_cache_slot(opline->op1.constant); + opline->extended_value = zend_alloc_cache_slot(); /* Lowercase constant name in a separate literal */ { @@ -3595,7 +3628,7 @@ static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t opline->op1.num = zend_vm_calc_used_stack(num_args, fbc); opline->op2_type = IS_CONST; LITERAL_STR(opline->op2, lcname); - zend_alloc_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); return SUCCESS; } @@ -3715,7 +3748,7 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string * opline->op2.constant = zend_add_ns_func_name_literal( CG(active_op_array), name); } - zend_alloc_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); if (args->children == 1 && (args->child[0]->kind != ZEND_AST_ZVAL || @@ -4075,7 +4108,7 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ ZVAL_NEW_STR(&name_node.u.constant, lcname); opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node); - zend_alloc_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); zend_compile_call_common(result, args_ast, fbc); } @@ -4109,7 +4142,7 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{ opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), Z_STR(method_node.u.constant)); - zend_alloc_polymorphic_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_polymorphic_cache_slot(); } else { SET_NODE(opline->op2, &method_node); } @@ -4170,12 +4203,11 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), Z_STR(method_node.u.constant)); + opline->result.num = zend_alloc_polymorphic_cache_slot(); + } else { if (opline->op1_type == IS_CONST) { - zend_alloc_cache_slot(opline->op2.constant); - } else { - zend_alloc_polymorphic_cache_slot(opline->op2.constant); + opline->result.num = zend_alloc_cache_slot(); } - } else { SET_NODE(opline->op2, &method_node); } zend_check_live_ranges(opline); @@ -4238,17 +4270,13 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ opline->op1_type = IS_CONST; opline->op1.constant = zend_add_class_name_literal( CG(active_op_array), Z_STR(class_node.u.constant)); + opline->op2.num = zend_alloc_cache_slot(); } else { SET_NODE(opline->op1, &class_node); } zend_compile_call_common(&ctor_result, args_ast, NULL); zend_do_free(&ctor_result); - - /* We save the position of DO_FCALL for convenience in find_live_range(). - * This info is not preserved for runtime. */ - opline = &CG(active_op_array)->opcodes[opnum]; - opline->op2.opline_num = get_next_op_number(CG(active_op_array)); } /* }}} */ @@ -4279,7 +4307,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as global variable"); } else if (zend_try_compile_cv(&result, var_ast) == SUCCESS) { zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node); - zend_alloc_cache_slot(opline->op2.constant); + opline->extended_value = zend_alloc_cache_slot(); } else { /* name_ast should be evaluated only. FETCH_GLOBAL_LOCK instructs FETCH_W * to not free the name_node operand, so it can be reused in the following @@ -5209,6 +5237,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ opline->op1_type = IS_CONST; opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), zend_resolve_class_name_ast(class_ast)); + opline->extended_value = zend_alloc_cache_slot(); if (zend_string_equals_literal(var_name, "this")) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); @@ -5218,7 +5247,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ opline->result.var = lookup_cv(CG(active_op_array), var_name); if (is_last_catch && is_last_class) { - opline->extended_value = ZEND_LAST_CATCH; + opline->extended_value |= ZEND_LAST_CATCH; } if (!is_last_class) { @@ -5675,9 +5704,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ /* Allocate cache slot to speed-up run-time class resolution */ if (opline->opcode == ZEND_RECV_INIT) { if (ZEND_TYPE_IS_CLASS(arg_info->type)) { - zend_alloc_cache_slot(opline->op2.constant); - } else { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = -1; + opline->extended_value = zend_alloc_cache_slot(); } } else { if (ZEND_TYPE_IS_CLASS(arg_info->type)) { @@ -5688,9 +5715,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ } } } else { - if (opline->opcode == ZEND_RECV_INIT) { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = -1; - } else { + if (opline->opcode != ZEND_RECV_INIT) { opline->op2.num = -1; } } @@ -6272,6 +6297,7 @@ void zend_compile_use_trait(zend_ast *ast) /* {{{ */ opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), zend_resolve_class_name_ast(trait_ast)); + opline->extended_value = zend_alloc_cache_slot(); ce->num_traits++; } @@ -6314,6 +6340,7 @@ void zend_compile_implements(znode *class_node, zend_ast *ast) /* {{{ */ opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), zend_resolve_class_name_ast(class_ast)); + opline->extended_value = zend_alloc_cache_slot(); CG(active_class_entry)->num_interfaces++; } @@ -7515,6 +7542,7 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */ opline->op2_type = IS_CONST; opline->op2.constant = zend_add_class_name_literal( CG(active_op_array), Z_STR(class_node.u.constant)); + opline->extended_value = zend_alloc_cache_slot(); } else { SET_NODE(opline->op2, &class_node); } @@ -7586,7 +7614,9 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ } result->op_type = opline->result_type = IS_TMP_VAR; - opline->extended_value |= ast->kind == ZEND_AST_ISSET ? ZEND_ISSET : 0; + if (ast->kind == ZEND_AST_ISSET) { + opline->extended_value |= ZEND_ISSET; + } } /* }}} */ @@ -7749,7 +7779,7 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */ CG(active_op_array), resolved_name, 0); } } - zend_alloc_cache_slot(opline->op2.constant); + opline->extended_value = zend_alloc_cache_slot(); } /* }}} */ @@ -7801,11 +7831,7 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ zend_set_class_name_op1(opline, &class_node); - if (opline->op1_type == IS_CONST) { - zend_alloc_cache_slot(opline->op2.constant); - } else { - zend_alloc_polymorphic_cache_slot(opline->op2.constant); - } + opline->extended_value = zend_alloc_polymorphic_cache_slot(); } /* }}} */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9e4f0baf0a..60b7d8b211 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2000,96 +2000,6 @@ use_read_property: } } -static zend_always_inline zval* zend_fetch_static_property_address(zval *varname, zend_uchar varname_type, znode_op op2, zend_uchar op2_type, int type EXECUTE_DATA_DC OPLINE_DC) -{ - zval *retval; - zend_string *name, *tmp_name; - zend_class_entry *ce; - - if (varname_type == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (varname_type == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - - if (op2_type == IS_CONST) { - if (varname_type == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(varname))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(varname) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - if (type != BP_VAR_IS) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - } - return NULL; - } - - return retval; - } else { - zval *class_name = RT_CONSTANT(opline, op2); - - if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (varname_type != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - return NULL; - } - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - } - } else { - if (op2_type == IS_UNUSED) { - ce = zend_fetch_class(NULL, op2.num); - if (UNEXPECTED(ce == NULL)) { - if (varname_type != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - return NULL; - } - } else { - ce = Z_CE_P(EX_VAR(op2.var)); - } - if (varname_type == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(varname)) == ce)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(varname) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - if (type != BP_VAR_IS) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - } - return NULL; - } - - return retval; - } - } - - retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); - - if (varname_type != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (UNEXPECTED(retval == NULL)) { - return NULL; - } - - if (varname_type == IS_CONST) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(varname), ce, retval); - } - - return retval; -} - #if ZEND_INTENSIVE_DEBUGGING #define CHECK_SYMBOL_TABLES() \ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 41b40a2663..48f1e4785c 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -663,7 +663,7 @@ ZEND_API int pass_two(zend_op_array *op_array) opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2); } break; diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 4aa2fa0d1a..6b905a2183 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -192,7 +192,6 @@ struct _zval_struct { } u1; union { uint32_t next; /* hash collision chain */ - uint32_t cache_slot; /* literal cache slot */ uint32_t opline_num; /* opline number (for FAST_CALL) */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ @@ -411,9 +410,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_NEXT(zval) (zval).u2.next #define Z_NEXT_P(zval_p) Z_NEXT(*(zval_p)) -#define Z_CACHE_SLOT(zval) (zval).u2.cache_slot -#define Z_CACHE_SLOT_P(zval_p) Z_CACHE_SLOT(*(zval_p)) - #define Z_LINENO(zval) (zval).u2.lineno #define Z_LINENO_P(zval_p) Z_LINENO(*(zval_p)) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3f34100ba7..1a2f5c402d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -799,7 +799,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -813,7 +813,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } } else { - zend_assign_op_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -965,62 +965,62 @@ ZEND_VM_INLINE_HELPER(zend_binary_assign_op_helper, VAR|UNUSED|THIS|CV, CONST|TM #endif } -ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, add_function); } -ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, sub_function); } -ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mul_function); } -ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, div_function); } -ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mod_function); } -ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_left_function); } -ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_right_function); } -ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, concat_function); } -ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_or_function); } -ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_and_function); } -ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_xor_function); } -ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ, SPEC(DIM_OBJ)) +ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ|CACHE_SLOT, SPEC(DIM_OBJ)) { ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, pow_function); } @@ -1056,7 +1056,7 @@ ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -1082,7 +1082,7 @@ ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } } else { - zend_pre_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -1091,12 +1091,12 @@ ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 1); } -ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 0); } @@ -1131,7 +1131,7 @@ ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -1153,7 +1153,7 @@ ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } } else { - zend_post_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -1162,12 +1162,12 @@ ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 1); } -ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 0); } @@ -1512,15 +1512,87 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, zend_free_op free_op1; zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - retval = zend_fetch_static_property_address(varname, OP1_TYPE, opline->op2, OP2_TYPE, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (OP2_TYPE == IS_CONST) { + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + FREE_UNFETCHED_OP1(); + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + FREE_UNFETCHED_OP1(); + retval = NULL; + break; + } + if (OP1_TYPE != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (OP2_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + FREE_UNFETCHED_OP1(); + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (OP1_TYPE == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + FREE_UNFETCHED_OP1(); + break; + } + } + } + + varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (OP1_TYPE == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + FREE_OP1(); + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - FREE_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -1529,8 +1601,6 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, } } - FREE_OP1(); - if (type == BP_VAR_R || type == BP_VAR_IS) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { @@ -1539,22 +1609,22 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R); } -ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W); } -ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW); } -ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { USE_OPLINE @@ -1565,12 +1635,12 @@ ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CL } } -ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET); } -ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS); } @@ -1703,7 +1773,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1; @@ -1746,7 +1816,7 @@ ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST zval *retval; if (OP2_TYPE == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -1806,7 +1876,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1821,7 +1891,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) property = GET_OP2_ZVAL_PTR(BP_VAR_R); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -1829,7 +1899,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1843,7 +1913,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) } property = GET_OP2_ZVAL_PTR(BP_VAR_R); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -1851,7 +1921,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1; @@ -1888,7 +1958,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR zval *retval; if (OP2_TYPE == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -1946,7 +2016,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE @@ -1967,7 +2037,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST } } -ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1982,7 +2052,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) property = GET_OP2_ZVAL_PTR(BP_VAR_R); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -2028,7 +2098,7 @@ ZEND_VM_HANDLER(198, ZEND_FETCH_LIST_W, VAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV)) +ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV)) { USE_OPLINE zend_free_op free_op1, free_op2, free_op_data; @@ -2085,8 +2155,8 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC( } if (OP2_TYPE == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -2165,7 +2235,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -2913,28 +2983,29 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|CV, CACHE_SLOT) { + zend_free_op free_op2; + zval *class_name; USE_OPLINE SAVE_OPLINE(); if (OP2_TYPE == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_free_op free_op2; - zval *class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + } else if (OP2_TYPE == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, opline->op1.num); + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); ZEND_VM_C_LABEL(try_class_name): - if (OP2_TYPE == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); @@ -2950,13 +3021,13 @@ ZEND_VM_C_LABEL(try_class_name): } zend_throw_error(NULL, "Class name must be a valid object or a string"); } - - FREE_OP2(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + FREE_OP2(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM) +ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM|CACHE_SLOT) { USE_OPLINE zval *function_name; @@ -2976,7 +3047,9 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper); } - function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP2_TYPE != IS_CONST) { + function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + } if (OP2_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -3016,6 +3089,9 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, HANDLE_EXCEPTION(); } } + if (OP2_TYPE == IS_CONST) { + function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); FREE_OP2(); FREE_OP1(); @@ -3028,8 +3104,8 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, called_scope = obj->ce; if (OP2_TYPE == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -3040,6 +3116,10 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, HANDLE_EXCEPTION(); } + if (OP2_TYPE == IS_CONST) { + function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -3054,7 +3134,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -3085,7 +3165,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM) +ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT) { USE_OPLINE zval *function_name; @@ -3098,14 +3178,16 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (OP1_TYPE == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (OP2_TYPE != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (OP1_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -3120,12 +3202,12 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (OP1_TYPE != IS_CONST && OP2_TYPE == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (OP2_TYPE != IS_UNUSED) { zend_free_op free_op2; @@ -3166,11 +3248,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (OP2_TYPE == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (OP1_TYPE == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -3240,16 +3318,16 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM) +ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) { USE_OPLINE zend_function *fbc; zval *function_name, *func; zend_execute_data *call; - function_name = (zval*)RT_CONSTANT(opline, opline->op2); - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name)); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + function_name = (zval*)RT_CONSTANT(opline, opline->op2); func = zend_hash_find_ex(EG(function_table), Z_STR_P(function_name+1), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); @@ -3260,7 +3338,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM) if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); + CACHE_PTR(opline->result.num, fbc); } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL); @@ -3403,7 +3481,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) +ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) { USE_OPLINE zval *func_name; @@ -3411,9 +3489,9 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) zend_function *fbc; zend_execute_data *call; - func_name = RT_CONSTANT(opline, opline->op2) + 1; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + func_name = RT_CONSTANT(opline, opline->op2) + 1; func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (func == NULL) { func_name++; @@ -3425,7 +3503,7 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) } } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), fbc); + CACHE_PTR(opline->result.num, fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -3439,17 +3517,18 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM) +ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT) { USE_OPLINE zend_free_op free_op2; - zval *fname = GET_OP2_ZVAL_PTR(BP_VAR_R); + zval *fname; zval *func; zend_function *fbc; zend_execute_data *call; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname)); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + fname = GET_OP2_ZVAL_PTR(BP_VAR_R); func = zend_hash_find_ex(EG(function_table), Z_STR_P(fname), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); @@ -3457,7 +3536,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM) HANDLE_EXCEPTION(); } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc); + CACHE_PTR(opline->result.num, fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -3748,7 +3827,7 @@ ZEND_VM_C_LABEL(fcall_end): ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED) +ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED|CACHE_SLOT) { USE_OPLINE @@ -4085,7 +4164,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -4099,11 +4178,11 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH) ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); ZEND_VM_CONTINUE(); } - catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH); if (UNEXPECTED(catch_ce == NULL)) { catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce); + CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce); } ce = EG(exception)->ce; @@ -4115,7 +4194,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH) if (ce != catch_ce) { if (!catch_ce || !instanceof_function(ce, catch_ce)) { - if (opline->extended_value == ZEND_LAST_CATCH) { + if (opline->extended_value & ZEND_LAST_CATCH) { zend_rethrow_exception(execute_data); HANDLE_EXCEPTION(); } @@ -4725,7 +4804,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|VAR|CV, NUM) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(63, ZEND_RECV, NUM, ANY) +ZEND_VM_HANDLER(63, ZEND_RECV, NUM, UNUSED|CACHE_SLOT) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4746,7 +4825,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, NUM, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) +ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT) { USE_OPLINE uint32_t arg_num; @@ -4772,7 +4851,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(Z_CACHE_SLOT_P(default_value))) || EG(exception))) { + if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -4781,7 +4860,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY) +ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED|CACHE_SLOT) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4902,7 +4981,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, TMPVAR, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM) +ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, NUM) { USE_OPLINE zval *result; @@ -4912,7 +4991,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM) SAVE_OPLINE(); if (OP1_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->op2.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { @@ -4920,7 +4999,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM) ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + CACHE_PTR(opline->op2.num, ce); } } else if (OP1_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -5052,13 +5131,13 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST) +ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT) { USE_OPLINE zend_constant *c; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + c = CACHED_PTR(opline->extended_value); } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL) { SAVE_OPLINE(); @@ -5081,7 +5160,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST) HANDLE_EXCEPTION(); } } else { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); + CACHE_PTR(opline->extended_value, c); } ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); @@ -5089,7 +5168,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST) +ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST, CACHE_SLOT) { zend_class_entry *ce, *scope; zend_class_constant *c; @@ -5100,11 +5179,11 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO do { if (OP1_TYPE == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + } else if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); } else { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { @@ -5112,7 +5191,6 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (OP1_TYPE == IS_UNUSED) { @@ -5125,8 +5203,8 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; } } @@ -5148,11 +5226,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO HANDLE_EXCEPTION(); } } - if (OP1_TYPE == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); - } + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } else { zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -5487,7 +5561,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { USE_OPLINE zval *varname; @@ -5497,47 +5571,41 @@ ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH SAVE_OPLINE(); - varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - - if (OP1_TYPE == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - FREE_OP1(); + FREE_UNFETCHED_OP1(); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (OP2_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - FREE_OP1(); + FREE_UNFETCHED_OP1(); HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (OP1_TYPE != IS_CONST) { @@ -5639,7 +5707,7 @@ ZEND_VM_C_LABEL(num_index_dim): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -5665,7 +5733,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -6314,7 +6382,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH| ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET) +ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET|CACHE_SLOT) { USE_OPLINE zval *value; @@ -6325,16 +6393,9 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA zend_class_entry *ce; SAVE_OPLINE(); - varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); - if (OP1_TYPE == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (OP2_TYPE == IS_CONST) { - if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6342,24 +6403,23 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA } ZEND_VM_C_GOTO(is_static_prop_return); - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (OP1_TYPE != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (OP2_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - FREE_OP1(); + FREE_UNFETCHED_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } @@ -6367,9 +6427,9 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (OP1_TYPE == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6380,10 +6440,17 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA } } + varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (OP1_TYPE == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (OP1_TYPE != IS_CONST) { @@ -6536,7 +6603,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET) +ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET|CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -6571,7 +6638,7 @@ ZEND_VM_C_LABEL(isset_no_object): } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } FREE_OP2(); @@ -6923,7 +6990,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1; @@ -6938,11 +7005,11 @@ ZEND_VM_C_LABEL(try_instanceof): zend_class_entry *ce; if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (OP2_TYPE == IS_UNUSED) { @@ -6986,20 +7053,20 @@ ZEND_VM_HANDLER(0, ZEND_NOP, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST) +ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST, CACHE_SLOT) { USE_OPLINE zend_class_entry *ce = Z_CE_P(EX_VAR(opline->op1.var)); zend_class_entry *iface; SAVE_OPLINE(); - iface = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + iface = CACHED_PTR(opline->extended_value); if (UNEXPECTED(iface == NULL)) { iface = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); if (UNEXPECTED(iface == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), iface); + CACHE_PTR(opline->extended_value, iface); } if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) { @@ -7010,14 +7077,14 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) +ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY, CACHE_SLOT) { USE_OPLINE zend_class_entry *ce = Z_CE_P(EX_VAR(opline->op1.var)); zend_class_entry *trait; SAVE_OPLINE(); - trait = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + trait = CACHED_PTR(opline->extended_value); if (UNEXPECTED(trait == NULL)) { trait = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, @@ -7028,7 +7095,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), trait); + CACHE_PTR(opline->extended_value, trait); } zend_do_implement_trait(ce, trait); @@ -7584,7 +7651,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH) ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper, try_catch_offset, current_try_catch_offset, op_num, current_op_num); } -ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) +ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST, CACHE_SLOT) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -7599,7 +7666,7 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) varname = GET_OP2_ZVAL_PTR(BP_VAR_R); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - idx = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1; if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); @@ -7619,11 +7686,11 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval)); idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); } else { idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); ZEND_VM_C_LABEL(check_indirect): /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { @@ -7756,18 +7823,18 @@ ZEND_VM_C_LABEL(type_check_resource): } } -ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) +ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT) { USE_OPLINE zend_constant *c; int result; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { result = 1; } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) { result = 0; } else { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), c); + CACHE_PTR(opline->extended_value, c); result = 1; } ZEND_VM_SMART_BRANCH(result, 0); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cc67f61dff..8c7727003d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1466,67 +1466,6 @@ send_array: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - uint32_t arg_num = opline->op1.num; - - if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { - SAVE_OPLINE(); - zend_missing_arg_error(execute_data); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); - - SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { - HANDLE_EXCEPTION(); - } - } - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - uint32_t arg_num = opline->op1.num; - uint32_t arg_count = EX_NUM_ARGS(); - zval *params; - - SAVE_OPLINE(); - - params = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); - - if (arg_num <= arg_count) { - zval *param; - - array_init_size(params, arg_count - arg_num + 1); - zend_hash_real_init(Z_ARRVAL_P(params), 1); - ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { - param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - do { - zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); - if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); - ZEND_HASH_FILL_ADD(param); - param++; - } while (++arg_num <= arg_count); - } else { - do { - if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); - ZEND_HASH_FILL_ADD(param); - param++; - } while (++arg_num <= arg_count); - } - } ZEND_HASH_FILL_END(); - } else { - ZVAL_EMPTY_ARRAY(params); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -1674,7 +1613,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OP zend_class_entry *trait; SAVE_OPLINE(); - trait = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + trait = CACHED_PTR(opline->extended_value); if (UNEXPECTED(trait == NULL)) { trait = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, @@ -1685,7 +1624,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OP if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), trait); + CACHE_PTR(opline->extended_value, trait); } zend_do_implement_trait(ce, trait); @@ -2085,9 +2024,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME zval *function_name, *func; zend_execute_data *call; - function_name = (zval*)RT_CONSTANT(opline, opline->op2); - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name)); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + function_name = (zval*)RT_CONSTANT(opline, opline->op2); func = zend_hash_find_ex(EG(function_table), Z_STR_P(function_name+1), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); @@ -2098,7 +2037,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); + CACHE_PTR(opline->result.num, fbc); } call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL); @@ -2172,9 +2111,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CON zend_function *fbc; zend_execute_data *call; - func_name = RT_CONSTANT(opline, opline->op2) + 1; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + func_name = RT_CONSTANT(opline, opline->op2) + 1; func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (func == NULL) { func_name++; @@ -2186,7 +2125,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CON } } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), fbc); + CACHE_PTR(opline->result.num, fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -2204,13 +2143,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO { USE_OPLINE - zval *fname = RT_CONSTANT(opline, opline->op2); + zval *fname; zval *func; zend_function *fbc; zend_execute_data *call; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname)); + fbc = CACHED_PTR(opline->result.num); if (UNEXPECTED(fbc == NULL)) { + fname = RT_CONSTANT(opline, opline->op2); func = zend_hash_find_ex(EG(function_table), Z_STR_P(fname), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); @@ -2218,7 +2158,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO HANDLE_EXCEPTION(); } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc); + CACHE_PTR(opline->result.num, fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -2259,7 +2199,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(Z_CACHE_SLOT_P(default_value))) || EG(exception))) { + if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)) || EG(exception))) { HANDLE_EXCEPTION(); } } @@ -2275,13 +2215,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDL zend_class_entry *iface; SAVE_OPLINE(); - iface = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + iface = CACHED_PTR(opline->extended_value); if (UNEXPECTED(iface == NULL)) { iface = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); if (UNEXPECTED(iface == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), iface); + CACHE_PTR(opline->extended_value, iface); } if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) { @@ -2394,6 +2334,67 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + uint32_t arg_num = opline->op1.num; + + if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { + SAVE_OPLINE(); + zend_missing_arg_error(execute_data); + HANDLE_EXCEPTION(); + } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); + + SAVE_OPLINE(); + if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)) || EG(exception))) { + HANDLE_EXCEPTION(); + } + } + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + uint32_t arg_num = opline->op1.num; + uint32_t arg_count = EX_NUM_ARGS(); + zval *params; + + SAVE_OPLINE(); + + params = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); + + if (arg_num <= arg_count) { + zval *param; + + array_init_size(params, arg_count - arg_num + 1); + zend_hash_real_init(Z_ARRVAL_P(params), 1); + ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { + param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); + if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + do { + zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); + if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); + ZEND_HASH_FILL_ADD(param); + param++; + } while (++arg_num <= arg_count); + } else { + do { + if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); + ZEND_HASH_FILL_ADD(param); + param++; + } while (++arg_num <= arg_count); + } + } ZEND_HASH_FILL_END(); + } else { + ZVAL_EMPTY_ARRAY(params); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2916,11 +2917,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_ ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); ZEND_VM_CONTINUE(); } - catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH); if (UNEXPECTED(catch_ce == NULL)) { catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce); + CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce); } ce = EG(exception)->ce; @@ -2932,7 +2933,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_ if (ce != catch_ce) { if (!catch_ce || !instanceof_function(ce, catch_ce)) { - if (opline->extended_value == ZEND_LAST_CATCH) { + if (opline->extended_value & ZEND_LAST_CATCH) { zend_rethrow_exception(execute_data); HANDLE_EXCEPTION(); } @@ -3084,78 +3085,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; - - SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); - } - - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } - - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, - constructor, - opline->extended_value, - ce, - Z_OBJ_P(result)); - Z_ADDREF_P(result); - } - - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -3978,12 +3907,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN zend_constant *c; int result; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { result = 1; } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) { result = 0; } else { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), c); + CACHE_PTR(opline->extended_value, c); result = 1; } ZEND_VM_SMART_BRANCH(result, 0); @@ -4639,15 +4568,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CONST == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -4820,7 +4820,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -4916,7 +4916,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_ zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -5138,7 +5138,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -5178,6 +5180,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO HANDLE_EXCEPTION(); } } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -5190,8 +5195,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO called_scope = obj->ce; if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -5202,6 +5207,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO HANDLE_EXCEPTION(); } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -5216,7 +5225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -5258,14 +5267,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -5280,12 +5291,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { @@ -5326,11 +5337,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -5486,11 +5493,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS do { if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + } else if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); } else { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { @@ -5498,7 +5505,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (IS_CONST == IS_UNUSED) { @@ -5511,8 +5517,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; } } @@ -5534,11 +5540,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); - } + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } else { zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -5676,47 +5678,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_C SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CONST != IS_CONST) { @@ -5737,16 +5733,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - - if (IS_CONST == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5754,23 +5743,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -5779,9 +5767,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5792,10 +5780,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CONST != IS_CONST) { @@ -5982,7 +5977,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -7027,7 +7022,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_ zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -7124,7 +7119,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -7347,7 +7342,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -7387,6 +7384,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM HANDLE_EXCEPTION(); } } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op2); @@ -7399,8 +7399,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM called_scope = obj->ce; if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -7411,6 +7411,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM HANDLE_EXCEPTION(); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -7425,7 +7429,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -7468,14 +7472,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -7490,12 +7496,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { zend_free_op free_op2; @@ -7536,11 +7542,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -7968,7 +7970,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op2); @@ -8173,15 +8175,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_VAR == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CONST == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -8244,47 +8317,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_V SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CONST != IS_CONST) { @@ -8305,16 +8372,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -8322,23 +8382,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -8347,9 +8406,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -8360,10 +8419,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CONST != IS_CONST) { @@ -8692,15 +8758,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_UNUSED == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CONST == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -8793,14 +8930,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_UNUSED != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -8815,12 +8954,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -8861,11 +9000,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_UNUSED == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -8985,6 +9120,78 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; + + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->op2.num, ce); + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); + } + + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + constructor, + opline->extended_value, + ce, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9144,47 +9351,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_U SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CONST != IS_CONST) { @@ -9242,16 +9443,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -9259,23 +9453,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -9284,9 +9477,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -9297,10 +9490,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CONST != IS_CONST) { @@ -10166,7 +10366,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -10262,7 +10462,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HAN zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -10484,7 +10684,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -10524,6 +10726,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV HANDLE_EXCEPTION(); } } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -10536,8 +10741,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV called_scope = obj->ce; if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -10548,6 +10753,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV HANDLE_EXCEPTION(); } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -10562,7 +10771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -10604,14 +10813,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -10626,12 +10837,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -10672,11 +10883,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CV == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -11103,7 +11310,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -13749,15 +13956,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zend_free_op free_op1; zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_CONST == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -13766,8 +14045,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ } } - zval_ptr_dtor_nogc(free_op1); - if (type == BP_VAR_R || type == BP_VAR_IS) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { @@ -13905,7 +14182,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_ zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -14001,7 +14278,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -14189,7 +14466,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -14229,6 +14508,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C HANDLE_EXCEPTION(); } } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op1); @@ -14241,8 +14523,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C called_scope = obj->ce; if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -14253,6 +14535,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C HANDLE_EXCEPTION(); } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -14267,7 +14553,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -14363,47 +14649,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_ SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -14424,16 +14704,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_CONST == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -14441,24 +14714,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } @@ -14466,9 +14738,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -14479,10 +14751,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -14670,7 +14949,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op1); @@ -14694,11 +14973,11 @@ try_instanceof: zend_class_entry *ce; if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_CONST == IS_UNUSED) { @@ -15515,7 +15794,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -15612,7 +15891,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVA zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -15801,7 +16080,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -15841,6 +16122,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T HANDLE_EXCEPTION(); } } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); @@ -15853,8 +16137,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T called_scope = obj->ce; if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -15865,6 +16149,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T HANDLE_EXCEPTION(); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -15879,7 +16167,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -16133,7 +16421,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op2); @@ -16197,15 +16485,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zend_free_op free_op1; zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_VAR == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -16214,8 +16574,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ } } - zval_ptr_dtor_nogc(free_op1); - if (type == BP_VAR_R || type == BP_VAR_IS) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { @@ -16270,47 +16628,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_ SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -16331,16 +16683,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -16348,24 +16693,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } @@ -16373,9 +16717,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -16386,10 +16730,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -16425,11 +16776,11 @@ try_instanceof: zend_class_entry *ce; if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_VAR == IS_UNUSED) { @@ -16627,15 +16978,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zend_free_op free_op1; zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_UNUSED == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -16644,8 +17067,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ } } - zval_ptr_dtor_nogc(free_op1); - if (type == BP_VAR_R || type == BP_VAR_IS) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); } else { @@ -16734,47 +17155,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_ SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -16833,16 +17248,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -16850,24 +17258,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } @@ -16875,9 +17282,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -16888,10 +17295,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -16927,11 +17341,11 @@ try_instanceof: zend_class_entry *ce; if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_UNUSED == IS_UNUSED) { @@ -17442,7 +17856,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -17538,7 +17952,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -17726,7 +18140,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -17766,6 +18182,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C HANDLE_EXCEPTION(); } } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op1); @@ -17778,8 +18197,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C called_scope = obj->ce; if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -17790,6 +18209,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C HANDLE_EXCEPTION(); } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -17804,7 +18227,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -18057,7 +18480,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op1); @@ -21686,78 +22109,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; - - SAVE_OPLINE(); - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); - } - - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } - - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, - constructor, - opline->extended_value, - ce, - Z_OBJ_P(result)); - Z_ADDREF_P(result); - } - - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22839,7 +23190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -22853,7 +23204,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -23260,7 +23611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -23286,7 +23637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -23334,7 +23685,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -23356,7 +23707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -23467,7 +23818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -23489,7 +23840,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA } property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -23533,7 +23884,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -23622,8 +23973,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -23702,7 +24053,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -23772,8 +24123,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -23852,7 +24203,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -23922,8 +24273,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -24002,7 +24353,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -24072,8 +24423,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -24152,7 +24503,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -24600,14 +24951,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -24622,12 +24975,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { @@ -24668,11 +25021,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_CONST == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -24753,11 +25102,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ do { if (IS_VAR == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + } else if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); } else { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { @@ -24765,7 +25114,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (IS_VAR == IS_UNUSED) { @@ -24778,8 +25126,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; } } @@ -24801,11 +25149,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ HANDLE_EXCEPTION(); } } - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); - } + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } else { zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -25050,7 +25394,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -25276,7 +25620,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -25290,7 +25634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -25699,7 +26043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -25725,7 +26069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -25774,7 +26118,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -25796,7 +26140,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -25908,7 +26252,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -25930,7 +26274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_H } property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -25974,7 +26318,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -26064,8 +26408,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -26144,7 +26488,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -26214,8 +26558,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -26294,7 +26638,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -26364,8 +26708,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -26444,7 +26788,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -26514,8 +26858,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -26594,7 +26938,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -26986,14 +27330,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -27008,12 +27354,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { zend_free_op free_op2; @@ -27054,11 +27400,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -27361,7 +27703,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -28508,14 +28850,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_UNUSED != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -28530,12 +28874,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -28576,11 +28920,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_UNUSED == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -28700,6 +29040,78 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; + + SAVE_OPLINE(); + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->op2.num, ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); + } + + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + constructor, + opline->extended_value, + ce, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -29135,7 +29547,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -29149,7 +29561,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -29556,7 +29968,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -29582,7 +29994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -29630,7 +30042,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -29652,7 +30064,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -29763,7 +30175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLE property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -29785,7 +30197,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL } property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -29829,7 +30241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -29918,8 +30330,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -29998,7 +30410,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -30068,8 +30480,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -30148,7 +30560,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -30218,8 +30630,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -30298,7 +30710,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -30368,8 +30780,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -30448,7 +30860,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -30953,14 +31365,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -30975,12 +31389,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -31021,11 +31435,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_CV == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -31327,7 +31737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER( } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -31621,78 +32031,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPE ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; - - SAVE_OPLINE(); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); - } - - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } - - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, - constructor, - opline->extended_value, - ce, - Z_OBJ_P(result)); - Z_ADDREF_P(result); - } - - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -31878,7 +32216,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -31892,7 +32230,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -32017,7 +32355,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32043,7 +32381,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -32091,7 +32429,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -32113,7 +32451,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -32174,7 +32512,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_U zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -32248,7 +32586,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_ property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -32270,7 +32608,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST } property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -32315,7 +32653,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -32408,7 +32746,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -32473,8 +32811,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -32553,7 +32891,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -32623,8 +32961,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -32703,7 +33041,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -32773,8 +33111,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -32853,7 +33191,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -32923,8 +33261,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -33003,7 +33341,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -33054,26 +33392,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + + zval *class_name; USE_OPLINE SAVE_OPLINE(); if (IS_CONST == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - - zval *class_name = RT_CONSTANT(opline, opline->op2); + } else if (IS_CONST == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + class_name = RT_CONSTANT(opline, opline->op2); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, opline->op1.num); + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = RT_CONSTANT(opline, opline->op2); try_class_name: - if (IS_CONST == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); @@ -33089,9 +33428,9 @@ try_class_name: } zend_throw_error(NULL, "Class name must be a valid object or a string"); } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -33114,7 +33453,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -33154,6 +33495,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S HANDLE_EXCEPTION(); } } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -33166,8 +33510,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S called_scope = obj->ce; if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -33178,6 +33522,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S HANDLE_EXCEPTION(); } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -33192,7 +33540,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -33234,14 +33582,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -33256,12 +33606,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { @@ -33302,11 +33652,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_CONST == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -33381,8 +33727,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON USE_OPLINE zend_constant *c; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + c = CACHED_PTR(opline->extended_value); } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL) { SAVE_OPLINE(); @@ -33405,7 +33751,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON HANDLE_EXCEPTION(); } } else { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); + CACHE_PTR(opline->extended_value, c); } ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); @@ -33424,11 +33770,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS do { if (IS_UNUSED == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + } else if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); } else { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { @@ -33436,7 +33782,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (IS_UNUSED == IS_UNUSED) { @@ -33449,8 +33794,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); break; } } @@ -33472,11 +33817,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS HANDLE_EXCEPTION(); } } - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); - } + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } else { zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -33515,7 +33856,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -33560,7 +33901,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -33744,7 +34085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -33758,7 +34099,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -33883,7 +34224,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -33909,7 +34250,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -33958,7 +34299,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -33980,7 +34321,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -34042,7 +34383,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -34117,7 +34458,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -34139,7 +34480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA } property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -34184,7 +34525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -34278,7 +34619,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -34343,8 +34684,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -34423,7 +34764,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -34493,8 +34834,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -34573,7 +34914,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -34643,8 +34984,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -34723,7 +35064,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -34793,8 +35134,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -34873,7 +35214,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -34924,26 +35265,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_H static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_free_op free_op2; + zval *class_name; USE_OPLINE SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_free_op free_op2; - zval *class_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + class_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, opline->op1.num); + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); try_class_name: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); @@ -34959,10 +35301,10 @@ try_class_name: } zend_throw_error(NULL, "Class name must be a valid object or a string"); } - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -34985,7 +35327,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -35025,6 +35369,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T HANDLE_EXCEPTION(); } } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op2); @@ -35037,8 +35384,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T called_scope = obj->ce; if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -35049,6 +35396,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T HANDLE_EXCEPTION(); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -35063,7 +35414,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -35106,14 +35457,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -35128,12 +35481,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { zend_free_op free_op2; @@ -35174,11 +35527,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -35274,7 +35623,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -35320,7 +35669,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op2); @@ -35614,26 +35963,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER( static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + + zval *class_name; USE_OPLINE SAVE_OPLINE(); if (IS_UNUSED == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - - zval *class_name = NULL; + } else if (IS_UNUSED == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + class_name = NULL; + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, opline->op1.num); + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = NULL; try_class_name: - if (IS_UNUSED == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); @@ -35649,9 +35999,9 @@ try_class_name: } zend_throw_error(NULL, "Class name must be a valid object or a string"); } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -35667,14 +36017,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_UNUSED != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -35689,12 +36041,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -35735,11 +36087,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -35859,6 +36207,78 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; + + SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->op2.num, ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); + } + + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + constructor, + opline->extended_value, + ce, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -36191,7 +36611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -36205,7 +36625,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -36330,7 +36750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -36356,7 +36776,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -36404,7 +36824,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -36426,7 +36846,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -36487,7 +36907,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -36561,7 +36981,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HAN property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -36583,7 +37003,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA } property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -36628,7 +37048,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -36721,7 +37141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -36786,8 +37206,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -36866,7 +37286,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -36936,8 +37356,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -37016,7 +37436,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -37086,8 +37506,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -37166,7 +37586,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -37236,8 +37656,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -37316,7 +37736,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -37367,26 +37787,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + + zval *class_name; USE_OPLINE SAVE_OPLINE(); if (IS_CV == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - - zval *class_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } else if (IS_CV == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + class_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, opline->op1.num); + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); try_class_name: - if (IS_CV == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); @@ -37402,9 +37823,9 @@ try_class_name: } zend_throw_error(NULL, "Class name must be a valid object or a string"); } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -37427,7 +37848,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -37467,6 +37890,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C HANDLE_EXCEPTION(); } } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -37479,8 +37905,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C called_scope = obj->ce; if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -37491,6 +37917,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C HANDLE_EXCEPTION(); } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -37505,7 +37935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -37547,14 +37977,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + ce = CACHED_PTR(opline->result.num); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -37569,12 +38001,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -37615,11 +38047,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_CV == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -37715,7 +38143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -37760,7 +38188,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -40393,7 +40821,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -40407,7 +40835,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -40814,7 +41242,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -40840,7 +41268,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -40888,7 +41316,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -40910,7 +41338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -40934,15 +41362,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CV == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -41166,7 +41665,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_C zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -41240,7 +41739,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -41262,7 +41761,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN } property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -41307,7 +41806,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN zval *retval; if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -41400,7 +41899,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -41489,8 +41988,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -41569,7 +42068,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -41639,8 +42138,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -41719,7 +42218,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -41789,8 +42288,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -41869,7 +42368,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -41939,8 +42438,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } if (IS_CONST == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -42019,7 +42518,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -42585,7 +43084,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -42625,6 +43126,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S HANDLE_EXCEPTION(); } } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -42637,8 +43141,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S called_scope = obj->ce; if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -42649,6 +43153,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S HANDLE_EXCEPTION(); } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -42663,7 +43171,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -42817,47 +43325,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONS SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CV != IS_CONST) { @@ -42984,7 +43486,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -43005,16 +43507,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_CONST == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -43022,23 +43517,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -43047,9 +43541,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -43060,10 +43554,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CV != IS_CONST) { @@ -43250,7 +43751,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -43274,11 +43775,11 @@ try_instanceof: zend_class_entry *ce; if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_CONST == IS_UNUSED) { @@ -43464,7 +43965,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C varname = RT_CONSTANT(opline, opline->op2); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - idx = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1; if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); @@ -43484,11 +43985,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval)); idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); } else { idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); check_indirect: /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { @@ -44351,7 +44852,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -44365,7 +44866,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -44774,7 +45275,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -44800,7 +45301,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -44849,7 +45350,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -44871,7 +45372,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -45061,7 +45562,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -45136,7 +45637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -45158,7 +45659,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA } property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -45203,7 +45704,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA zval *retval; if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -45297,7 +45798,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -45387,8 +45888,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -45467,7 +45968,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -45537,8 +46038,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -45617,7 +46118,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -45687,8 +46188,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -45767,7 +46268,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -45837,8 +46338,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -45917,7 +46418,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -46427,7 +46928,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -46467,6 +46970,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA HANDLE_EXCEPTION(); } } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); zval_ptr_dtor_nogc(free_op2); @@ -46479,8 +46985,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA called_scope = obj->ce; if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -46491,6 +46997,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA HANDLE_EXCEPTION(); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -46505,7 +47015,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -46768,7 +47278,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -46946,7 +47456,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } zval_ptr_dtor_nogc(free_op2); @@ -47279,15 +47789,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_VAR == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CV == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -47463,47 +48044,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_ SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CV != IS_CONST) { @@ -47524,16 +48099,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_VAR == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -47541,23 +48109,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -47566,9 +48133,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -47579,10 +48146,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CV != IS_CONST) { @@ -47617,11 +48191,11 @@ try_instanceof: zend_class_entry *ce; if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_VAR == IS_UNUSED) { @@ -48130,15 +48704,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *varname; zval *retval; + zend_string *name, *tmp_name; + zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); + do { + if (IS_UNUSED == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value)) != NULL)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } else { + zval *class_name = RT_CONSTANT(opline, opline->op2); + + if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value)) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value, ce); + } + } + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + retval = NULL; + break; + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + retval = CACHED_PTR(opline->extended_value + sizeof(void*)); + + /* check if static properties were destoyed */ + if (EXPECTED(CE_STATIC_MEMBERS(ce) != NULL)) { + + break; + } + } + } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (IS_CV == IS_CONST && EXPECTED(retval)) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, retval); + } + + } while (0); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } else { @@ -48849,47 +49494,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUS SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + /*CACHE_PTR(opline->extended_value, ce);*/ } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + zend_std_unset_static_property(ce, name); if (IS_CV != IS_CONST) { @@ -48972,16 +49611,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zend_class_entry *ce; SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - if (IS_UNUSED == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) != NULL)) { + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -48989,23 +49621,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + } else if (UNEXPECTED((ce = CACHED_PTR(opline->extended_value & ~ZEND_ISSET)) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->extended_value & ~ZEND_ISSET, ce); + } } } else { if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); @@ -49014,9 +49645,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(opline->extended_value & ~ZEND_ISSET) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + value = CACHED_PTR((opline->extended_value & ~ZEND_ISSET) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -49027,10 +49658,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + value = zend_std_get_static_property(ce, name, 1); if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(opline->extended_value & ~ZEND_ISSET, ce, value); } if (IS_CV != IS_CONST) { @@ -49065,11 +49703,11 @@ try_instanceof: zend_class_entry *ce; if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + CACHE_PTR(opline->extended_value, ce); } } } else if (IS_UNUSED == IS_UNUSED) { @@ -50098,7 +50736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -50112,7 +50750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -50519,7 +51157,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -50545,7 +51183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); @@ -50593,7 +51231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -50615,7 +51253,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); @@ -50804,7 +51442,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -50878,7 +51516,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_W); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -50900,7 +51538,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE } property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -50945,7 +51583,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE zval *retval; if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -51038,7 +51676,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(free_op1, result); @@ -51127,8 +51765,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -51207,7 +51845,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -51277,8 +51915,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -51357,7 +51995,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -51427,8 +52065,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -51507,7 +52145,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -51577,8 +52215,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } if (IS_CV == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(opline->extended_value))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(opline->extended_value + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; @@ -51657,7 +52295,7 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -52279,7 +52917,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -52319,6 +52959,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA HANDLE_EXCEPTION(); } } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); @@ -52331,8 +52974,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA called_scope = obj->ce; if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; @@ -52343,6 +52986,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA HANDLE_EXCEPTION(); } + if (IS_CV == IS_CONST) { + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + } + /* First, locate the function. */ fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { @@ -52357,7 +53004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); @@ -52618,7 +53265,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } else { zend_wrong_property_unset(offset); } @@ -52795,7 +53442,7 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISSET) : NULL)); } @@ -54521,7 +55168,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_RETURN_SPEC_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_RETURN_SPEC_CV_LABEL, - (void*)&&ZEND_RECV_SPEC_LABEL, + (void*)&&ZEND_RECV_SPEC_UNUSED_LABEL, (void*)&&ZEND_RECV_INIT_SPEC_CONST_LABEL, (void*)&&ZEND_SEND_VAL_SPEC_CONST_LABEL, (void*)&&ZEND_SEND_VAL_SPEC_TMPVAR_LABEL, @@ -54543,10 +55190,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_SEND_REF_SPEC_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SEND_REF_SPEC_CV_LABEL, - (void*)&&ZEND_NEW_SPEC_CONST_LABEL, + (void*)&&ZEND_NEW_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NEW_SPEC_VAR_LABEL, - (void*)&&ZEND_NEW_SPEC_UNUSED_LABEL, + (void*)&&ZEND_NEW_SPEC_VAR_UNUSED_LABEL, + (void*)&&ZEND_NEW_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_LABEL, (void*)&&ZEND_FREE_SPEC_TMPVAR_LABEL, @@ -55656,7 +56303,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_GENERATOR_RETURN_SPEC_CV_LABEL, (void*)&&ZEND_FAST_CALL_SPEC_LABEL, (void*)&&ZEND_FAST_RET_SPEC_LABEL, - (void*)&&ZEND_RECV_VARIADIC_SPEC_LABEL, + (void*)&&ZEND_RECV_VARIADIC_SPEC_UNUSED_LABEL, (void*)&&ZEND_SEND_UNPACK_SPEC_LABEL, (void*)&&ZEND_POW_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_POW_SPEC_CONST_TMPVAR_LABEL, @@ -57025,12 +57672,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SEND_ARRAY_SPEC): ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_RECV_SPEC): - ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_RECV_VARIADIC_SPEC): - ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_BEGIN_SILENCE_SPEC): ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -57124,6 +57765,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_VAR): ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_RECV_SPEC_UNUSED): + ZEND_RECV_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_RECV_VARIADIC_SPEC_UNUSED): + ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_CV): ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -57181,9 +57828,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_BOOL_SPEC_CONST): ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_NEW_SPEC_CONST): - ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_CLONE_SPEC_CONST): ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -57577,6 +58221,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED): ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_NEW_SPEC_CONST_UNUSED): + ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED): ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -58567,9 +59214,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SEND_USER_SPEC_VAR): ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_NEW_SPEC_VAR): - ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_CAST_SPEC_VAR): ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -59098,6 +59742,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED): ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_NEW_SPEC_VAR_UNUSED): + ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED): ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -59332,9 +59979,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK): ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_NEW_SPEC_UNUSED): - ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_CLONE_SPEC_UNUSED): ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -59560,6 +60204,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED): ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_NEW_SPEC_UNUSED_UNUSED): + ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_UNUSED): ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -62418,7 +63065,7 @@ void zend_init_opcodes_handlers(void) ZEND_RETURN_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RECV_SPEC_HANDLER, + ZEND_RECV_SPEC_UNUSED_HANDLER, ZEND_RECV_INIT_SPEC_CONST_HANDLER, ZEND_SEND_VAL_SPEC_CONST_HANDLER, ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER, @@ -62440,10 +63087,10 @@ void zend_init_opcodes_handlers(void) ZEND_SEND_REF_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, + ZEND_NEW_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NEW_SPEC_VAR_UNUSED_HANDLER, + ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, ZEND_FREE_SPEC_TMPVAR_HANDLER, @@ -63553,7 +64200,7 @@ void zend_init_opcodes_handlers(void) ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, ZEND_FAST_CALL_SPEC_HANDLER, ZEND_FAST_RET_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER, ZEND_SEND_UNPACK_SPEC_HANDLER, ZEND_POW_SPEC_CONST_CONST_HANDLER, ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index d95a439c7e..c694c94287 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -70,9 +70,11 @@ $vm_op_flags = array( "ZEND_VM_OP_CLASS_FETCH" => 0x70, "ZEND_VM_OP_CONSTRUCTOR" => 0x80, "ZEND_VM_OP_CONST_FETCH" => 0x90, + "ZEND_VM_OP_CACHE_SLOT" => 0xa0, "ZEND_VM_EXT_VAR_FETCH" => 1<<16, "ZEND_VM_EXT_ISSET" => 1<<17, + "ZEND_VM_EXT_CACHE_SLOT" => 1<<18, "ZEND_VM_EXT_ARRAY_INIT" => 1<<19, "ZEND_VM_EXT_REF" => 1<<20, "ZEND_VM_EXT_MASK" => 0x0f000000, @@ -114,6 +116,7 @@ $vm_op_decode = array( "CLASS_FETCH" => ZEND_VM_OP_CLASS_FETCH, "CONSTRUCTOR" => ZEND_VM_OP_CONSTRUCTOR, "CONST_FETCH" => ZEND_VM_OP_CONST_FETCH, + "CACHE_SLOT" => ZEND_VM_OP_CACHE_SLOT, ); $vm_ext_decode = array( @@ -129,6 +132,7 @@ $vm_ext_decode = array( "ISSET" => ZEND_VM_EXT_ISSET, "REF" => ZEND_VM_EXT_REF, "SRC" => ZEND_VM_EXT_SRC, + "CACHE_SLOT" => ZEND_VM_EXT_CACHE_SLOT, ); $vm_kind_name = array( diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 7be1db0052..a40134936d 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -247,17 +247,17 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x00000707, 0x07000003, 0x00000003, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, - 0x04006751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, + 0x04046751, 0x00000001, 0x00000001, 0x00000001, @@ -283,47 +283,47 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x01000701, 0x00000000, 0x00000001, - 0x01000300, + 0x01040300, 0x00000000, - 0x01000310, + 0x01040310, 0x00000003, - 0x00000010, - 0x00000310, + 0x0000a110, + 0x00040310, 0x00001007, 0x00001001, 0x00001001, - 0x01000073, - 0x01000300, + 0x0100a173, + 0x01040300, 0x00004005, 0x00186703, 0x00106703, 0x08000007, 0x00010107, 0x00000701, - 0x00000751, + 0x00040751, 0x00002003, 0x03000001, 0x00000007, 0x00010107, 0x00000707, - 0x00000757, + 0x00040757, 0x00010107, 0x00006701, - 0x00000751, + 0x00040751, 0x00010107, 0x00006701, - 0x00000751, + 0x00040751, 0x00010107, 0x00000707, - 0x00000757, + 0x00040757, 0x00010107, 0x00006703, - 0x00000753, + 0x00040753, 0x00010107, 0x00000701, - 0x00000751, + 0x00040751, 0x0000070b, - 0x00000391, + 0x00040391, 0x00001001, 0x00000000, 0x00000000, @@ -331,13 +331,13 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x00000000, 0x01000000, 0x00001001, - 0x02002003, + 0x02042003, 0x00000003, - 0x00000771, + 0x00040771, 0x00000057, 0x0b000003, - 0x01000757, - 0x01008773, + 0x01040757, + 0x01048773, 0x00030107, 0x00020707, 0x00001003, @@ -346,9 +346,9 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x01000000, 0x00001003, 0x00000007, - 0x00000003, + 0x00040003, 0x09000003, - 0x00000103, + 0x0000a103, 0x00002003, 0x03000001, 0x00004005, @@ -356,29 +356,29 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x00000000, 0x00000000, 0x00000000, - 0x00000751, - 0x00000751, - 0x00000751, - 0x00000751, - 0x00000751, + 0x00040751, + 0x00040751, + 0x00040751, + 0x00040751, + 0x00040751, 0x00000000, - 0x00007305, + 0x00047305, 0x00000000, 0x00000100, 0x00000000, 0x00000003, 0x00000303, - 0x00000300, + 0x00040300, 0x00000100, 0x00000000, 0x00006701, - 0x00020757, + 0x00060757, 0x00000000, 0x00000000, 0x00002000, 0x00002003, 0x00000103, - 0x00000000, + 0x00040000, 0x00000000, 0x00000101, 0x00000071, @@ -388,24 +388,24 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x00000003, 0x00000020, 0x00003000, - 0x00000010, + 0x0000a110, 0x00000000, 0x00000707, - 0x04006751, - 0x00000301, + 0x04046751, + 0x00040301, 0x00002003, 0x00000707, 0x03000000, 0x03000100, - 0x00007307, - 0x00007307, - 0x00007307, - 0x00007307, - 0x00007307, - 0x00007307, - 0x00007307, - 0x00027307, - 0x00000373, + 0x00047307, + 0x00047307, + 0x00047307, + 0x00047307, + 0x00047307, + 0x00047307, + 0x00047307, + 0x00067307, + 0x00040373, 0x00100101, 0x00100301, 0x00000101, diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index d652c292ce..6f9b323bb0 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -48,8 +48,10 @@ #define ZEND_VM_OP_CLASS_FETCH 0x00000070 #define ZEND_VM_OP_CONSTRUCTOR 0x00000080 #define ZEND_VM_OP_CONST_FETCH 0x00000090 +#define ZEND_VM_OP_CACHE_SLOT 0x000000a0 #define ZEND_VM_EXT_VAR_FETCH 0x00010000 #define ZEND_VM_EXT_ISSET 0x00020000 +#define ZEND_VM_EXT_CACHE_SLOT 0x00040000 #define ZEND_VM_EXT_ARRAY_INIT 0x00080000 #define ZEND_VM_EXT_REF 0x00100000 #define ZEND_VM_EXT_MASK 0x0f000000 diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 65007a9455..9c0fd96471 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -965,7 +965,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start); } break; diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 63102beaac..b74df321f1 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -42,76 +42,77 @@ #define LITERAL_PROPERTY 0x0900 #define LITERAL_GLOBAL 0x0A00 -#define LITERAL_EX_CLASS 0x4000 -#define LITERAL_EX_OBJ 0x2000 -#define LITERAL_MAY_MERGE 0x1000 #define LITERAL_KIND_MASK 0x0f00 #define LITERAL_NUM_RELATED_MASK 0x000f -#define LITERAL_NUM_SLOTS_MASK 0x00f0 -#define LITERAL_NUM_SLOTS_SHIFT 4 #define LITERAL_NUM_RELATED(info) (info & LITERAL_NUM_RELATED_MASK) -#define LITERAL_NUM_SLOTS(info) ((info & LITERAL_NUM_SLOTS_MASK) >> LITERAL_NUM_SLOTS_SHIFT) typedef struct _literal_info { uint32_t flags; /* bitmask (see defines above) */ - union { - int num; /* variable number or class name literal number */ - } u; } literal_info; -#define LITERAL_FLAGS(kind, slots, related) \ - ((kind) | ((slots) << LITERAL_NUM_SLOTS_SHIFT) | (related)) - -#define LITERAL_INFO(n, kind, merge, slots, related) do { \ - info[n].flags = (((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ - } while (0) - -#define LITERAL_INFO_CLASS(n, kind, merge, slots, related, _num) do { \ - info[n].flags = (LITERAL_EX_CLASS | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ - info[n].u.num = (_num); \ +#define LITERAL_INFO(n, kind, related) do { \ + info[n].flags = ((kind) | (related)); \ } while (0) -#define LITERAL_INFO_OBJ(n, kind, merge, slots, related) do { \ - info[n].flags = (LITERAL_EX_OBJ | ((merge) ? LITERAL_MAY_MERGE : 0) | LITERAL_FLAGS(kind, slots, related)); \ - info[n].u.num = (uint32_t)-1; \ - } while (0) - -static void optimizer_literal_obj_info(literal_info *info, - zend_uchar op_type, - znode_op op, - int constant, - uint32_t kind, - uint32_t slots, - uint32_t related, - zend_op_array *op_array) +static zend_bool class_name_type_hint(const zend_op_array *op_array, uint32_t arg_num) { - /* For now we merge only $this object properties and methods. - * In general it's also possible to do it for any CV variable as well, - * but it would require complex dataflow and/or type analysis. - */ - if (Z_TYPE(op_array->literals[constant]) == IS_STRING && - op_type == IS_UNUSED) { - LITERAL_INFO_OBJ(constant, kind, 1, slots, related); + zend_arg_info *arg_info; + + if (arg_num > 0) { + if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + if (EXPECTED(arg_num <= op_array->num_args)) { + arg_info = &op_array->arg_info[arg_num-1]; + } else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) { + arg_info = &op_array->arg_info[op_array->num_args]; + } else { + return 0; + } + return ZEND_TYPE_IS_CLASS(arg_info->type); + } } else { - LITERAL_INFO(constant, kind, 0, slots, related); + arg_info = op_array->arg_info - 1; + return ZEND_TYPE_IS_CLASS(arg_info->type); } + return 0; } -static void optimizer_literal_class_info(literal_info *info, - zend_uchar op_type, - znode_op op, - int constant, - uint32_t kind, - uint32_t slots, - uint32_t related, - zend_op_array *op_array) +static uint32_t add_static_slot(HashTable *hash, + zend_op_array *op_array, + uint32_t op1, + uint32_t op2, + uint32_t kind, + int *cache_size) { - if (op_type == IS_CONST) { - LITERAL_INFO_CLASS(constant, kind, 1, slots, related, op.constant); + uint32_t ret; + zend_string *key; + size_t key_len; + zval *class_name = &op_array->literals[op1]; + zval *prop_name = &op_array->literals[op2]; + zval *pos, tmp; + + key_len = Z_STRLEN_P(class_name) + sizeof("::") - 1 + Z_STRLEN_P(prop_name); + key = zend_string_alloc(key_len, 0); + memcpy(ZSTR_VAL(key), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name)); + memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name), "::", sizeof("::") - 1); + memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name) + sizeof("::") - 1, + Z_STRVAL_P(prop_name), + Z_STRLEN_P(prop_name) + 1); + + ZSTR_H(key) = zend_hash_func(ZSTR_VAL(key), ZSTR_LEN(key)); + ZSTR_H(key) += kind; + + pos = zend_hash_find(hash, key); + if (pos) { + ret = Z_LVAL_P(pos); } else { - LITERAL_INFO(constant, kind, 0, slots, related); + ret = *cache_size; + *cache_size += 2 * sizeof(void *); + ZVAL_LONG(&tmp, ret); + zend_hash_add(hash, key, &tmp); } + zend_string_release(key); + return ret; } void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx) @@ -127,9 +128,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx HashTable hash; zend_string *key = NULL; void *checkpoint = zend_arena_checkpoint(ctx->arena); + int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot; if (op_array->last_literal) { - cache_size = 0; info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info)); /* Mark literals of specific types */ @@ -138,66 +139,48 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx while (opline < end) { switch (opline->opcode) { case ZEND_INIT_FCALL: - LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 1); + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1); break; case ZEND_INIT_FCALL_BY_NAME: - LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2); + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 2); break; case ZEND_INIT_NS_FCALL_BY_NAME: - LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3); + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 3); break; case ZEND_INIT_METHOD_CALL: if (opline->op1_type == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1); } if (opline->op2_type == IS_CONST) { - optimizer_literal_obj_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_METHOD, 2, 2, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_METHOD, 2); } break; case ZEND_INIT_STATIC_METHOD_CALL: if (opline->op1_type == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2); } if (opline->op2_type == IS_CONST) { - optimizer_literal_class_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_STATIC_METHOD, (opline->op1_type == IS_CONST) ? 1 : 2, 2, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_STATIC_METHOD, 2); } break; case ZEND_CATCH: - LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2); break; case ZEND_DEFINED: - LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1, 1, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 2); break; case ZEND_FETCH_CONSTANT: if ((opline->op1.num & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { - LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 5); + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 5); } else { - LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 3); + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 3); } break; case ZEND_FETCH_CLASS_CONSTANT: if (opline->op1_type == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2); } - optimizer_literal_class_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_CLASS_CONST, (opline->op1_type == IS_CONST) ? 1 : 2, 1, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS_CONST, 1); break; case ZEND_FETCH_STATIC_PROP_R: case ZEND_FETCH_STATIC_PROP_W: @@ -208,16 +191,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_UNSET_STATIC_PROP: case ZEND_ISSET_ISEMPTY_STATIC_PROP: if (opline->op2_type == IS_CONST) { - LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2); } if (opline->op1_type == IS_CONST) { - optimizer_literal_class_info( - info, - opline->op2_type, - opline->op2, - opline->op1.constant, - LITERAL_STATIC_PROPERTY, 2, 1, - op_array); + LITERAL_INFO(opline->op1.constant, LITERAL_STATIC_PROPERTY, 1); } break; case ZEND_FETCH_CLASS: @@ -225,12 +202,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: if (opline->op2_type == IS_CONST) { - LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2); } break; case ZEND_NEW: if (opline->op1_type == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 2); } break; case ZEND_ASSIGN_OBJ: @@ -247,13 +224,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_POST_DEC_OBJ: case ZEND_ISSET_ISEMPTY_PROP_OBJ: if (opline->op2_type == IS_CONST) { - optimizer_literal_obj_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_PROPERTY, 2, 1, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1); } break; case ZEND_ASSIGN_ADD: @@ -270,47 +241,30 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_ASSIGN_BW_XOR: if (opline->op2_type == IS_CONST) { if (opline->extended_value == ZEND_ASSIGN_OBJ) { - optimizer_literal_obj_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_PROPERTY, 2, 1, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1); } else { - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1); + LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1); } } break; case ZEND_BIND_GLOBAL: - LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 0, 1, 1); + LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 1); break; case ZEND_RECV_INIT: - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 0, 0, 1); - if (Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) != (uint32_t)-1) { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = cache_size; - cache_size += sizeof(void *); - } + LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1); break; case ZEND_DECLARE_FUNCTION: case ZEND_DECLARE_CLASS: case ZEND_DECLARE_INHERITED_CLASS: case ZEND_DECLARE_INHERITED_CLASS_DELAYED: - LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 0, 0, 2); + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 2); break; - case ZEND_RECV: - case ZEND_RECV_VARIADIC: - case ZEND_VERIFY_RETURN_TYPE: - if (opline->op2.num != (uint32_t)-1) { - opline->op2.num = cache_size; - cache_size += sizeof(void *); - } default: if (opline->op1_type == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1); } if (opline->op2_type == IS_CONST) { - LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1, 0, 1); + LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1); } break; } @@ -350,26 +304,15 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx } switch (Z_TYPE(op_array->literals[i])) { case IS_NULL: - /* Only checking MAY_MERGE for IS_NULL here - * is because only IS_NULL can be default value for class type hinting(RECV_INIT). */ - if ((info[i].flags & LITERAL_MAY_MERGE)) { - if (l_null < 0) { - l_null = j; - if (i != j) { - op_array->literals[j] = op_array->literals[i]; - info[j] = info[i]; - } - j++; - } - map[i] = l_null; - } else { - map[i] = j; + if (l_null < 0) { + l_null = j; if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; } j++; } + map[i] = l_null; break; case IS_FALSE: if (l_false < 0) { @@ -422,34 +365,20 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx } break; case IS_STRING: - if (info[i].flags & LITERAL_MAY_MERGE) { - if (info[i].flags & LITERAL_EX_OBJ) { - int key_len = sizeof("$this->") - 1 + Z_STRLEN(op_array->literals[i]); - key = zend_string_alloc(key_len, 0); - memcpy(ZSTR_VAL(key), "$this->", sizeof("$this->") - 1); - memcpy(ZSTR_VAL(key) + sizeof("$this->") - 1, Z_STRVAL(op_array->literals[i]), Z_STRLEN(op_array->literals[i]) + 1); - ZSTR_LEN(key) = key_len; - } else if (info[i].flags & LITERAL_EX_CLASS) { - int key_len; - zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num]; - key_len = Z_STRLEN_P(class_name) + sizeof("::") - 1 + Z_STRLEN(op_array->literals[i]); - key = zend_string_alloc(key_len, 0); - memcpy(ZSTR_VAL(key), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name)); - memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name), "::", sizeof("::") - 1); - memcpy(ZSTR_VAL(key) + Z_STRLEN_P(class_name) + sizeof("::") - 1, - Z_STRVAL(op_array->literals[i]), - Z_STRLEN(op_array->literals[i]) + 1); - } else { - key = zend_string_init(Z_STRVAL(op_array->literals[i]), Z_STRLEN(op_array->literals[i]), 0); - } - ZSTR_H(key) = zend_hash_func(ZSTR_VAL(key), ZSTR_LEN(key)); - ZSTR_H(key) += info[i].flags; + if (LITERAL_NUM_RELATED(info[i].flags) == 1) { + key = zend_string_copy(Z_STR(op_array->literals[i])); + } else { + key = zend_string_init(Z_STRVAL(op_array->literals[i]), Z_STRLEN(op_array->literals[i]), 0); + ZSTR_H(key) = ZSTR_HASH(Z_STR(op_array->literals[i])) + + LITERAL_NUM_RELATED(info[i].flags) - 1; } - if ((info[i].flags & LITERAL_MAY_MERGE) && - (pos = zend_hash_find(&hash, key)) != NULL && - Z_TYPE(op_array->literals[i]) == Z_TYPE(op_array->literals[Z_LVAL_P(pos)]) && - info[i].flags == info[Z_LVAL_P(pos)].flags) { - + pos = zend_hash_find(&hash, key); + if (pos != NULL && + Z_TYPE(op_array->literals[Z_LVAL_P(pos)]) == IS_STRING && + LITERAL_NUM_RELATED(info[i].flags) == LITERAL_NUM_RELATED(info[Z_LVAL_P(pos)].flags) && + (LITERAL_NUM_RELATED(info[i].flags) != 2 || + ((info[i].flags & LITERAL_KIND_MASK) != LITERAL_VALUE && + (info[Z_LVAL_P(pos)].flags & LITERAL_KIND_MASK) != LITERAL_VALUE))) { zend_string_release(key); map[i] = Z_LVAL_P(pos); zval_ptr_dtor_nogc(&op_array->literals[i]); @@ -461,19 +390,13 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx } } else { map[i] = j; - if (info[i].flags & LITERAL_MAY_MERGE) { - ZVAL_LONG(&zv, j); - zend_hash_add_new(&hash, key, &zv); - zend_string_release(key); - } + ZVAL_LONG(&zv, j); + zend_hash_add_new(&hash, key, &zv); + zend_string_release(key); if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; } - if (LITERAL_NUM_SLOTS(info[i].flags)) { - Z_CACHE_SLOT(op_array->literals[j]) = cache_size; - cache_size += LITERAL_NUM_SLOTS(info[i].flags) * sizeof(void*); - } j++; n = LITERAL_NUM_RELATED(info[i].flags); while (n > 1) { @@ -511,11 +434,19 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx break; } } - zend_hash_destroy(&hash); + zend_hash_clean(&hash); op_array->last_literal = j; - op_array->cache_size = cache_size; - /* Update opcodes to use new literals table */ + const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int)); + memset(const_slot, -1, j * 6 * sizeof(int)); + class_slot = const_slot + j; + func_slot = class_slot + j; + bind_var_slot = func_slot + j; + property_slot = bind_var_slot + j; + method_slot = property_slot + j; + + /* Update opcodes to use new literals table */ + cache_size = 0; opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { @@ -525,8 +456,288 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx if (opline->op2_type == IS_CONST) { opline->op2.constant = map[opline->op2.constant]; } + switch (opline->opcode) { + case ZEND_RECV_INIT: + if (class_name_type_hint(op_array, opline->op1.num)) { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + } + break; + case ZEND_RECV: + case ZEND_RECV_VARIADIC: + if (class_name_type_hint(op_array, opline->op1.num)) { + opline->op2.num = cache_size; + cache_size += sizeof(void *); + } + break; + case ZEND_VERIFY_RETURN_TYPE: + if (class_name_type_hint(op_array, 0)) { + opline->op2.num = cache_size; + cache_size += sizeof(void *); + } + break; + case ZEND_ASSIGN_ADD: + case ZEND_ASSIGN_SUB: + case ZEND_ASSIGN_MUL: + case ZEND_ASSIGN_DIV: + case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_MOD: + case ZEND_ASSIGN_SL: + case ZEND_ASSIGN_SR: + case ZEND_ASSIGN_CONCAT: + case ZEND_ASSIGN_BW_OR: + case ZEND_ASSIGN_BW_AND: + case ZEND_ASSIGN_BW_XOR: + if (opline->extended_value != ZEND_ASSIGN_OBJ) { + break; + } + if (opline->op2_type == IS_CONST) { + // op2 property + if (opline->op1_type == IS_UNUSED && + property_slot[opline->op2.constant] >= 0) { + (opline+1)->extended_value = property_slot[opline->op2.constant]; + } else { + (opline+1)->extended_value = cache_size; + cache_size += 2 * sizeof(void *); + if (opline->op1_type == IS_UNUSED) { + property_slot[opline->op2.constant] = (opline+1)->extended_value; + } + } + } + break; + case ZEND_ASSIGN_OBJ: + case ZEND_FETCH_OBJ_R: + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_IS: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_UNSET_OBJ: + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + if (opline->op2_type == IS_CONST) { + // op2 property + if (opline->op1_type == IS_UNUSED && + property_slot[opline->op2.constant] >= 0) { + opline->extended_value = property_slot[opline->op2.constant]; + } else { + opline->extended_value = cache_size; + cache_size += 2 * sizeof(void *); + if (opline->op1_type == IS_UNUSED) { + property_slot[opline->op2.constant] = opline->extended_value; + } + } + } + break; + case ZEND_ISSET_ISEMPTY_PROP_OBJ: + if (opline->op2_type == IS_CONST) { + // op2 property + if (opline->op1_type == IS_UNUSED && + property_slot[opline->op2.constant] >= 0) { + opline->extended_value = property_slot[opline->op2.constant] | (opline->extended_value & ZEND_ISSET); + } else { + opline->extended_value = cache_size | (opline->extended_value & ZEND_ISSET); + cache_size += 2 * sizeof(void *); + if (opline->op1_type == IS_UNUSED) { + property_slot[opline->op2.constant] = opline->extended_value & ~ZEND_ISSET; + } + } + } + break; + case ZEND_INIT_FCALL: + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + // op2 func + if (func_slot[opline->op2.constant] >= 0) { + opline->result.num = func_slot[opline->op2.constant]; + } else { + opline->result.num = cache_size; + cache_size += sizeof(void *); + func_slot[opline->op2.constant] = opline->result.num; + } + break; + case ZEND_INIT_METHOD_CALL: + if (opline->op2_type == IS_CONST) { + // op2 method + if (opline->op1_type == IS_UNUSED && + method_slot[opline->op2.constant] >= 0) { + opline->result.num = method_slot[opline->op2.constant]; + } else { + opline->result.num = cache_size; + cache_size += 2 * sizeof(void *); + if (opline->op1_type == IS_UNUSED) { + method_slot[opline->op2.constant] = opline->result.num; + } + } + } + break; + case ZEND_INIT_STATIC_METHOD_CALL: + if (opline->op2_type == IS_CONST) { + // op2 static method + if (opline->op1_type == IS_CONST) { + opline->result.num = add_static_slot(&hash, op_array, + opline->op1.constant, + opline->op2.constant, + LITERAL_STATIC_METHOD, + &cache_size); + } else { + opline->result.num = cache_size; + cache_size += 2 * sizeof(void *); + } + } else if (opline->op1_type == IS_CONST) { + // op1 class + if (class_slot[opline->op1.constant] >= 0) { + opline->result.num = class_slot[opline->op1.constant]; + } else { + opline->result.num = cache_size; + cache_size += sizeof(void *); + class_slot[opline->op1.constant] = opline->result.num; + } + } + break; + case ZEND_DEFINED: + // op1 const + if (const_slot[opline->op1.constant] >= 0) { + opline->extended_value = const_slot[opline->op1.constant]; + } else { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + const_slot[opline->op1.constant] = opline->extended_value; + } + break; + case ZEND_FETCH_CONSTANT: + // op2 const + if (const_slot[opline->op2.constant] >= 0) { + opline->extended_value = const_slot[opline->op2.constant]; + } else { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + const_slot[opline->op2.constant] = opline->extended_value; + } + break; + case ZEND_FETCH_CLASS_CONSTANT: + if (opline->op1_type == IS_CONST) { + // op1/op2 class_const + opline->extended_value = add_static_slot(&hash, op_array, + opline->op1.constant, + opline->op2.constant, + LITERAL_CLASS_CONST, + &cache_size); + } else { + opline->extended_value = cache_size; + cache_size += 2 * sizeof(void *); + } + break; + case ZEND_FETCH_STATIC_PROP_R: + case ZEND_FETCH_STATIC_PROP_W: + case ZEND_FETCH_STATIC_PROP_RW: + case ZEND_FETCH_STATIC_PROP_IS: + case ZEND_FETCH_STATIC_PROP_UNSET: + case ZEND_FETCH_STATIC_PROP_FUNC_ARG: + case ZEND_UNSET_STATIC_PROP: + if (opline->op1_type == IS_CONST) { + // op1 static property + if (opline->op2_type == IS_CONST) { + opline->extended_value = add_static_slot(&hash, op_array, + opline->op2.constant, + opline->op1.constant, + LITERAL_STATIC_PROPERTY, + &cache_size); + } else { + opline->extended_value = cache_size; + cache_size += 2 * sizeof(void *); + } + } else if (opline->op2_type == IS_CONST) { + // op2 class + if (class_slot[opline->op2.constant] >= 0) { + opline->extended_value = class_slot[opline->op2.constant]; + } else { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + class_slot[opline->op2.constant] = opline->extended_value; + } + } + break; + case ZEND_ISSET_ISEMPTY_STATIC_PROP: + if (opline->op1_type == IS_CONST) { + // op1 static property + if (opline->op2_type == IS_CONST) { + opline->extended_value = add_static_slot(&hash, op_array, + opline->op2.constant, + opline->op1.constant, + LITERAL_STATIC_PROPERTY, + &cache_size) | (opline->extended_value & ZEND_ISSET); + } else { + opline->extended_value = cache_size | (opline->extended_value & ZEND_ISSET); + cache_size += 2 * sizeof(void *); + } + } else if (opline->op2_type == IS_CONST) { + // op2 class + if (class_slot[opline->op2.constant] >= 0) { + opline->extended_value = class_slot[opline->op2.constant] | (opline->extended_value & ZEND_ISSET); + } else { + opline->extended_value = cache_size | (opline->extended_value & ZEND_ISSET); + cache_size += sizeof(void *); + class_slot[opline->op2.constant] = opline->extended_value & ~ZEND_ISSET; + } + } + break; + case ZEND_FETCH_CLASS: + case ZEND_ADD_INTERFACE: + case ZEND_ADD_TRAIT: + case ZEND_INSTANCEOF: + if (opline->op2_type == IS_CONST) { + // op2 class + if (class_slot[opline->op2.constant] >= 0) { + opline->extended_value = class_slot[opline->op2.constant]; + } else { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + class_slot[opline->op2.constant] = opline->extended_value; + } + } + break; + case ZEND_NEW: + if (opline->op1_type == IS_CONST) { + // op1 class + if (class_slot[opline->op1.constant] >= 0) { + opline->op2.num = class_slot[opline->op1.constant]; + } else { + opline->op2.num = cache_size; + cache_size += sizeof(void *); + class_slot[opline->op1.constant] = opline->op2.num; + } + } + break; + case ZEND_CATCH: + if (opline->op1_type == IS_CONST) { + // op1 class + if (class_slot[opline->op1.constant] >= 0) { + opline->extended_value = class_slot[opline->op1.constant] | (opline->extended_value & ZEND_LAST_CATCH); + } else { + opline->extended_value = cache_size | (opline->extended_value & ZEND_LAST_CATCH); + cache_size += sizeof(void *); + class_slot[opline->op1.constant] = opline->extended_value & ~ZEND_LAST_CATCH; + } + } + break; + case ZEND_BIND_GLOBAL: + // op2 bind var + if (bind_var_slot[opline->op2.constant] >= 0) { + opline->extended_value = bind_var_slot[opline->op2.constant]; + } else { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + bind_var_slot[opline->op2.constant] = opline->extended_value; + } + break; + } opline++; } + op_array->cache_size = cache_size; + zend_hash_destroy(&hash); zend_arena_release(&ctx->arena, checkpoint); #if DEBUG_COMPACT_LITERALS diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 13aec486f6..4a7ba6ba69 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -552,7 +552,7 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa } break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) { ZEND_SET_OP_JMP_ADDR(opline, opline->op2, op_array->opcodes + dst->start); } diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index 32de6ba35c..1642994765 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -193,14 +193,12 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) } else if (fcall->opcode == ZEND_INIT_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); - Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; opline->opcode = zend_get_call_op(fcall, call_stack[call].func); } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); - Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]); fcall->op2.constant = fcall->op2.constant + 1; diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 1b2623c307..ca5b2213f0 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -438,7 +438,7 @@ static inline int ct_eval_isset_dim(zval *result, uint32_t extended_value, zval // TODO return FAILURE; } else { - ZVAL_BOOL(result, extended_value != ZEND_ISSET); + ZVAL_BOOL(result, !(extended_value & ZEND_ISSET)); return SUCCESS; } } @@ -592,7 +592,7 @@ static inline int ct_eval_isset_obj(zval *result, uint32_t extended_value, zval } return SUCCESS; } else { - ZVAL_BOOL(result, extended_value != ZEND_ISSET); + ZVAL_BOOL(result, !(extended_value & ZEND_ISSET)); return SUCCESS; } } diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index a2d021516d..6c29b37c41 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -385,7 +385,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b BB_START(i + 1); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes); } BB_START(i + 1); @@ -546,7 +546,7 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b block->successors[1] = j + 1; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { block->successors_count = 2; block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes]; block->successors[1] = j + 1; diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index 22e149ae55..7fb55355fd 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -674,7 +674,7 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * } else { uint32_t op2_flags = ZEND_VM_OP2_FLAGS(flags); if (ZEND_VM_OP_JMP_ADDR == (op2_flags & ZEND_VM_OP_MASK)) { - if (opline->opcode != ZEND_CATCH || opline->extended_value != ZEND_LAST_CATCH) { + if (opline->opcode != ZEND_CATCH || !(opline->extended_value & ZEND_LAST_CATCH)) { if (b) { fprintf(stderr, " BB%d", b->successors[n++]); } else { diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index f9b21ff19e..07860f3998 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -206,7 +206,6 @@ int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv) op_array->last_literal++; op_array->literals = (zval*)erealloc(op_array->literals, op_array->last_literal * sizeof(zval)); ZVAL_COPY_VALUE(&op_array->literals[i], zv); - Z_CACHE_SLOT(op_array->literals[i]) = -1; return i; } @@ -232,13 +231,10 @@ static inline void drop_leading_backslash(zval *val) { } } -static inline void alloc_cache_slots_op1(zend_op_array *op_array, zend_op *opline, uint32_t num) { - Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size; - op_array->cache_size += num * sizeof(void *); -} -static inline void alloc_cache_slots_op2(zend_op_array *op_array, zend_op *opline, uint32_t num) { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; +static inline uint32_t alloc_cache_slots(zend_op_array *op_array, uint32_t num) { + uint32_t ret = op_array->cache_size; op_array->cache_size += num * sizeof(void *); + return ret; } #define REQUIRES_STRING(val) do { \ @@ -275,15 +271,43 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_RETURN_BY_REF: case ZEND_INSTANCEOF: return 0; - case ZEND_INIT_STATIC_METHOD_CALL: case ZEND_CATCH: - case ZEND_FETCH_CLASS_CONSTANT: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 1) | (opline->extended_value & ZEND_LAST_CATCH); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; case ZEND_DEFINED: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 1); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; case ZEND_NEW: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op1.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op1(op_array, opline, 1); + opline->op2.num = alloc_cache_slots(op_array, 1); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; + case ZEND_INIT_STATIC_METHOD_CALL: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type != IS_CONST) { + opline->result.num = alloc_cache_slots(op_array, 1); + } + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; + case ZEND_FETCH_CLASS_CONSTANT: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1); + } zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); break; case ZEND_FETCH_STATIC_PROP_R: @@ -292,9 +316,23 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_FETCH_STATIC_PROP_IS: case ZEND_FETCH_STATIC_PROP_UNSET: case ZEND_FETCH_STATIC_PROP_FUNC_ARG: + case ZEND_UNSET_STATIC_PROP: TO_STRING_NOWARN(val); opline->op1.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op1(op_array, opline, 2); + if (opline->op2_type == IS_CONST && opline->extended_value + sizeof(void*) == op_array->cache_size) { + op_array->cache_size += sizeof(void *); + } else { + opline->extended_value = alloc_cache_slots(op_array, 2); + } + break; + case ZEND_ISSET_ISEMPTY_STATIC_PROP: + TO_STRING_NOWARN(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type == IS_CONST && (opline->extended_value & ~ZEND_ISSET) + sizeof(void*) == op_array->cache_size) { + op_array->cache_size += sizeof(void *); + } else { + opline->extended_value = alloc_cache_slots(op_array, 2) | (opline->extended_value & ZEND_ISSET); + } break; case ZEND_SEND_VAR: opline->opcode = ZEND_SEND_VAL; @@ -351,11 +389,22 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, (opline + 1)->op2.var == opline->result.var) { return 0; } - case ZEND_INIT_FCALL_BY_NAME: - /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->extended_value = alloc_cache_slots(op_array, 1); + break; + case ZEND_INIT_FCALL_BY_NAME: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->result.num = alloc_cache_slots(op_array, 1); + break; case ZEND_FETCH_STATIC_PROP_R: case ZEND_FETCH_STATIC_PROP_W: case ZEND_FETCH_STATIC_PROP_RW: @@ -363,12 +412,22 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_FETCH_STATIC_PROP_UNSET: case ZEND_FETCH_STATIC_PROP_FUNC_ARG: case ZEND_UNSET_STATIC_PROP: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + if (opline->op1_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1); + } + break; case ZEND_ISSET_ISEMPTY_STATIC_PROP: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 1); + if (opline->op1_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1) | (opline->extended_value & ZEND_ISSET); + } break; case ZEND_INIT_FCALL: REQUIRES_STRING(val); @@ -380,7 +439,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, val = &tmp; } opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 1); + opline->result.num = alloc_cache_slots(op_array, 1); break; case ZEND_INIT_DYNAMIC_CALL: if (Z_TYPE_P(val) == IS_STRING) { @@ -398,19 +457,25 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 1); + opline->result.num = alloc_cache_slots(op_array, 1); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } break; case ZEND_INIT_METHOD_CALL: + REQUIRES_STRING(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->result.num = alloc_cache_slots(op_array, 2); + break; case ZEND_INIT_STATIC_METHOD_CALL: REQUIRES_STRING(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 2); + if (opline->op1_type != IS_CONST) { + opline->result.num = alloc_cache_slots(op_array, 2); + } break; - /*case ZEND_FETCH_CLASS_CONSTANT:*/ case ZEND_ASSIGN_OBJ: case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_W: @@ -423,10 +488,14 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: + TO_STRING_NOWARN(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 2); + break; case ZEND_ISSET_ISEMPTY_PROP_OBJ: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 2); + opline->extended_value = alloc_cache_slots(op_array, 2) | (opline->extended_value & ZEND_ISSET); break; case ZEND_ASSIGN_ADD: case ZEND_ASSIGN_SUB: @@ -443,7 +512,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, if (opline->extended_value == ZEND_ASSIGN_OBJ) { TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 2); + (opline+1)->extended_value = alloc_cache_slots(op_array, 2); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } @@ -766,7 +835,7 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline)); } break; @@ -806,7 +875,7 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_ ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]); } break; @@ -1174,7 +1243,7 @@ static void zend_redo_pass_two(zend_op_array *op_array) opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; } break; @@ -1260,7 +1329,7 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; } break; diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index db926a5172..de54949901 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -447,7 +447,7 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra SERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { SERIALIZE_PTR(opline->op2.jmp_addr); } break; @@ -1053,7 +1053,7 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr UNSERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { UNSERIALIZE_PTR(opline->op2.jmp_addr); } break; diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index a2549308ad..8c16538207 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -453,7 +453,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes]; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes]; } break; diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c index 4b3bf4c668..d066674b90 100644 --- a/sapi/phpdbg/phpdbg_opcode.c +++ b/sapi/phpdbg/phpdbg_opcode.c @@ -115,7 +115,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *opline) /*{{{ */ /* RESULT */ switch (opline->opcode) { case ZEND_CATCH: - if (opline->extended_value == ZEND_LAST_CATCH) { + if (opline->extended_value & ZEND_LAST_CATCH) { if (decode[2]) { efree(decode[2]); decode[2] = NULL; diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index cdee919f79..71194633ab 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -764,16 +764,16 @@ PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zen while (1) { zend_class_entry *ce; - if (!(ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(cur, cur->op1))))) { + if (!(ce = CACHED_PTR(cur->extended_value & ~ZEND_LAST_CATCH))) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(cur, cur->op1)), RT_CONSTANT(cur, cur->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(cur, cur->op1)), ce); + CACHE_PTR(cur->extended_value & ~ZEND_LAST_CATCH, ce); } if (ce == exception->ce || (ce && instanceof_function(exception->ce, ce))) { return 1; } - if (cur->extended_value == ZEND_LAST_CATCH) { + if (cur->extended_value & ZEND_LAST_CATCH) { return 0; } diff --git a/sapi/phpdbg/tests/exceptions_003.phpt b/sapi/phpdbg/tests/exceptions_003.phpt index e78ff1d489..16920870c3 100644 --- a/sapi/phpdbg/tests/exceptions_003.phpt +++ b/sapi/phpdbg/tests/exceptions_003.phpt @@ -26,7 +26,7 @@ prompt> [L7 %s ECHO<1> "ok\n" 00009: } catch (Error $e) { prompt> ok [L7 %s FAST_RET ~%d try-catch(0) %s] -[L9 %s CATCH<1> "Error" $e %s] +[L9 %s CATCH<%d> "Error" $e %s] >00005: x(); 00006: } finally { 00007: print "ok\n"; diff --git a/sapi/phpdbg/tests/stepping_001.phpt b/sapi/phpdbg/tests/stepping_001.phpt index a7ab9e59aa..90b2e5573a 100644 --- a/sapi/phpdbg/tests/stepping_001.phpt +++ b/sapi/phpdbg/tests/stepping_001.phpt @@ -25,7 +25,7 @@ prompt> [L0 %s HANDLE_EXCEPTION 00005: } 00006: prompt> [L0 %s HANDLE_EXCEPTION %s] -[L9 %s CATCH<1> "Exception" $e %s] +[L9 %s CATCH<%d> "Exception" $e %s] >00008: foo(); 00009: } catch (Exception $e) { 00010: echo "ok"; |