From: Dmitry Stogov Date: Tue, 27 Oct 2015 12:47:58 +0000 (+0300) Subject: Speed up fetching of class entries for self:: parent:: and static:: X-Git-Tag: php-7.1.0alpha2~40^2~36^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb7be5379d9b6e20f4d086bd688103fe75f46977;p=php Speed up fetching of class entries for self:: parent:: and static:: This is generalized solution for Bob's idea of speed up self::method() calls without ZEND_FETCH_CLASS. At first, it adds few new opcodes to separate class related behaviour: FETCH_STATIC_PROP_R FETCH_STATIC_PROP_W FETCH_STATIC_PROP_RW FETCH_STATIC_PROP_FUNC_ARG FETCH_STATIC_PROP_UNSET FETCH_STATIC_PROP_IS UNSET_STATIC_PROP ISSET_ISEMPTY_STATIC_PROP FETCH_CLASS_CONSTANT At seconds, it enables IS_UNUSED operand to fetch (self, parent or static without separate FETCH_CLASS) for new opcodes and the following ones: INIT_STATIC_METHOD_CALL NEW END_INSTANCEOF Finaly, opcache optimizer had to be fixed to support new opcodes. --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index d3a361dac9..0f31182beb 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -627,7 +627,8 @@ void zend_do_free(znode *op1) /* {{{ */ && opline->result.var == op1->u.op.var) { if (opline->opcode == ZEND_FETCH_R || opline->opcode == ZEND_FETCH_DIM_R || - opline->opcode == ZEND_FETCH_OBJ_R) { + opline->opcode == ZEND_FETCH_OBJ_R || + opline->opcode == ZEND_FETCH_STATIC_PROP_R) { /* It's very rare and useless case. It's better to use additional FREE opcode and simplify the FETCH handlers their selves */ @@ -1807,25 +1808,27 @@ ZEND_API size_t zend_dirname(char *path, size_t len) static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */ { + zend_uchar factor = (opline->opcode == ZEND_FETCH_STATIC_PROP_R) ? 1 : 3; + switch (type & BP_VAR_MASK) { case BP_VAR_R: return; case BP_VAR_W: case BP_VAR_REF: - opline->opcode += 3; + opline->opcode += 1 * factor; return; case BP_VAR_RW: - opline->opcode += 6; + opline->opcode += 2 * factor; return; case BP_VAR_IS: - opline->opcode += 9; + opline->opcode += 3 * factor; return; case BP_VAR_FUNC_ARG: - opline->opcode += 12; + opline->opcode += 4 * factor; opline->extended_value |= type >> BP_VAR_SHIFT; return; case BP_VAR_UNSET: - opline->opcode += 15; + opline->opcode += 5 * factor; return; EMPTY_SWITCH_DEFAULT_CASE() } @@ -2158,6 +2161,62 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int th } /* }}} */ +static void zend_compile_class_ref_ex(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */ +{ + uint32_t fetch_type; + + if (name_ast->kind != ZEND_AST_ZVAL) { + znode name_node; + + zend_compile_expr(&name_node, name_ast); + + if (name_node.op_type == IS_CONST) { + zend_string *name; + + if (Z_TYPE(name_node.u.constant) != IS_STRING) { + zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name"); + } + + name = Z_STR(name_node.u.constant); + fetch_type = zend_get_class_fetch_type(name); + + if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name(name, ZEND_NAME_FQ)); + } else { + zend_ensure_valid_class_fetch_type(fetch_type); + result->op_type = IS_UNUSED; + result->u.op.num = fetch_type | fetch_flags; + } + + zend_string_release(name); + } else { + zend_op *opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node); + opline->extended_value = ZEND_FETCH_CLASS_DEFAULT | fetch_flags; + } + return; + } + + /* Fully qualified names are always default refs */ + if (name_ast->attr == ZEND_NAME_FQ) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast)); + return; + } + + fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast)); + if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast)); + } else { + zend_ensure_valid_class_fetch_type(fetch_type); + result->op_type = IS_UNUSED; + result->u.op.num = fetch_type | fetch_flags; + return 0; + } +} +/* }}} */ + static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; @@ -2364,19 +2423,14 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t znode class_node, prop_node; zend_op *opline; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - zend_compile_class_ref(&class_node, class_ast, 1); - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&prop_node, prop_ast); if (delayed) { - opline = zend_delayed_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + opline = zend_delayed_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL); } else { - opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + opline = zend_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL); } if (opline->op1_type == IS_CONST) { zend_alloc_polymorphic_cache_slot(opline->op1.constant); @@ -3296,15 +3350,8 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ znode class_node, method_node; zend_op *opline; - zend_ulong extended_value = 0; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - opline = zend_compile_class_ref(&class_node, class_ast, 1); - extended_value = opline->extended_value; - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&method_node, method_ast); if (method_node.op_type == IS_CONST) { @@ -3320,7 +3367,6 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ opline = get_next_op(CG(active_op_array)); opline->opcode = ZEND_INIT_STATIC_METHOD_CALL; - opline->extended_value = extended_value; zend_set_class_name_op1(opline, &class_node); @@ -3352,10 +3398,7 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ zend_op *opline; uint32_t opnum; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else if (class_ast->kind == ZEND_AST_CLASS) { + if (class_ast->kind == ZEND_AST_CLASS) { uint32_t dcl_opnum = get_next_op_number(CG(active_op_array)); zend_compile_class_decl(class_ast); /* jump over anon class declaration */ @@ -3367,7 +3410,7 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ class_node.u.op.var = opline->result.var; opline->op1.opline_num = get_next_op_number(CG(active_op_array)); } else { - zend_compile_class_ref(&class_node, class_ast, 1); + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); } opnum = get_next_op_number(CG(active_op_array)); @@ -3507,7 +3550,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */ return; case ZEND_AST_STATIC_PROP: opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET, 0); - opline->opcode = ZEND_UNSET_VAR; + opline->opcode = ZEND_UNSET_STATIC_PROP; return; EMPTY_SWITCH_DEFAULT_CASE() } @@ -6301,13 +6344,7 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */ "instanceof expects an object instance, constant given"); } - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - opline = zend_compile_class_ref(&class_node, class_ast, 0); - opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD; - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_NO_AUTOLOAD); opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL); @@ -6379,7 +6416,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ break; case ZEND_AST_STATIC_PROP: opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS, 0); - opline->opcode = ZEND_ISSET_ISEMPTY_VAR; + opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP; break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -6559,7 +6596,6 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ znode class_node, const_node; zend_op *opline; - zend_string *resolved_name; if (zend_try_compile_const_expr_resolve_class_name(&result->u.constant, class_ast, const_ast, 0)) { if (Z_TYPE(result->u.constant) == IS_NULL) { @@ -6575,31 +6611,26 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ zend_eval_const_expr(&const_ast); if (class_ast->kind == ZEND_AST_ZVAL) { + zend_string *resolved_name; + resolved_name = zend_resolve_class_name_ast(class_ast); if (const_ast->kind == ZEND_AST_ZVAL && zend_try_ct_eval_class_const(&result->u.constant, resolved_name, zend_ast_get_str(const_ast))) { result->op_type = IS_CONST; zend_string_release(resolved_name); return; } + zend_string_release(resolved_name); } if (const_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(const_ast), "class")) { zend_error_noreturn(E_COMPILE_ERROR, "Dynamic class names are not allowed in compile-time ::class fetch"); } - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, resolved_name); - } else { - if (class_ast->kind == ZEND_AST_ZVAL) { - zend_string_release(resolved_name); - } - zend_compile_class_ref(&class_node, class_ast, 1); - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&const_node, const_ast); - opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node); + opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_CONSTANT, NULL, &const_node); zend_set_class_name_op1(opline, &class_node); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ad6dc58ec9..3296eaaedf 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1470,7 +1470,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type) +ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type) { USE_OPLINE zend_free_op free_op1; @@ -1494,61 +1494,30 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V name = zval_get_string(varname); } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; - - if (OP2_TYPE == IS_CONST) { - if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - FREE_OP1(); - HANDLE_EXCEPTION(); - } - - ZEND_VM_C_GOTO(fetch_var_return); - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (OP1_TYPE != IS_CONST) { - zend_string_release(name); - } - FREE_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (OP1_TYPE == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - FREE_OP1(); - HANDLE_EXCEPTION(); - } - - ZEND_VM_C_GOTO(fetch_var_return); - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - FREE_OP1(); - HANDLE_EXCEPTION(); - } - if (OP1_TYPE == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - FREE_OP1(); - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -1559,52 +1528,30 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); break; EMPTY_SWITCH_DEFAULT_CASE() } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - FREE_OP1(); - HANDLE_EXCEPTION(); - } + } + + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { + if (Z_CONSTANT_P(retval)) { + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + FREE_OP1(); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - FREE_OP1(); } + } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + FREE_OP1(); } if (OP1_TYPE != IS_CONST) { zend_string_release(name); } -ZEND_VM_C_LABEL(fetch_var_return): ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -1617,22 +1564,22 @@ ZEND_VM_C_LABEL(fetch_var_return): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R); } -ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); } -ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW); } -ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED) { USE_OPLINE @@ -1643,16 +1590,146 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CONST|VAR) } } -ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET); } -ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED) { ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS); } +ZEND_VM_HELPER_EX(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + 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); + zend_string_addref(name); + } else { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_string(varname); + } + + if (OP2_TYPE == IS_CONST) { + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + FREE_OP1(); + HANDLE_EXCEPTION(); + } + + ZEND_VM_C_GOTO(fetch_static_prop_return); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (OP2_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (OP1_TYPE == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + FREE_OP1(); + HANDLE_EXCEPTION(); + } + + ZEND_VM_C_GOTO(fetch_static_prop_return); + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + FREE_OP1(); + HANDLE_EXCEPTION(); + } + if (OP1_TYPE == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + FREE_OP1(); + + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); + } + +ZEND_VM_C_LABEL(fetch_static_prop_return): + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_R); +} + +ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_W); +} + +ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_RW); +} + +ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_W); + } else { + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_R); + } +} + +ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_UNSET); +} + +ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_IS); +} + ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE @@ -3007,7 +3084,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVAR|UNUSED|CV) { USE_OPLINE zval *function_name; @@ -3032,6 +3109,8 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -3125,10 +3204,10 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE } } - if (OP1_TYPE != IS_CONST) { + if (OP1_TYPE == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -4892,7 +4971,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) +ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, ANY) { USE_OPLINE zval object_zval; @@ -4909,6 +4988,8 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -5025,110 +5106,122 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) +ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST) { USE_OPLINE + zend_constant *c; SAVE_OPLINE(); - if (OP1_TYPE == IS_UNUSED) { - zend_constant *c; - - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); - if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); - } else { - actual++; - ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { + if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { + char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); + if (!actual) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + actual++; + ZVAL_STRINGL(EX_VAR(opline->result.var), + actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); } + /* non-qualified constant - allow text substitution */ + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } + } else { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + } + #ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else + if (c->flags & CONST_PERSISTENT) { + ZVAL_DUP(EX_VAR(opline->result.var), &c->value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), &c->value); + } +#else + ZVAL_COPY(EX_VAR(opline->result.var), &c->value); #endif - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - do { - if (OP1_TYPE == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - ZVAL_DEREF(value); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED, CONST) +{ + zend_class_entry *ce; + zval *value; + USE_OPLINE + + SAVE_OPLINE(); + + do { + if (OP1_TYPE == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ZVAL_DEREF(value); #ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); #endif - break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + break; + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else { + if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } - - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (OP1_TYPE == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + break; + } + } + + if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + ZVAL_DEREF(value); + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (OP1_TYPE == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } while (0); + +#ifdef ZTS + if (ce->type == ZEND_INTERNAL_CLASS) { + ZVAL_DUP(EX_VAR(opline->result.var), value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -5493,7 +5586,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED) { USE_OPLINE zval tmp, *varname; @@ -5502,7 +5595,6 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) SAVE_OPLINE(); if (OP1_TYPE == IS_CV && - OP2_TYPE == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -5533,33 +5625,58 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) varname = &tmp; } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + USE_OPLINE + zval tmp, *varname; + zend_class_entry *ce; + zend_free_op free_op1; + + SAVE_OPLINE(); + + varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + + ZVAL_UNDEF(&tmp); + if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (OP2_TYPE == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - FREE_OP1(); - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (OP2_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -6358,14 +6475,13 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED) { USE_OPLINE zval *value; int result; if (OP1_TYPE == IS_CV && - OP2_TYPE == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -6386,6 +6502,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) } else { zend_free_op free_op1; zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); @@ -6395,56 +6512,14 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) varname = &tmp; } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; - - if (OP2_TYPE == IS_CONST) { - if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - ZEND_VM_C_GOTO(is_var_return); - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (OP1_TYPE == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - ZEND_VM_C_GOTO(is_var_return); - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (OP1_TYPE == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } FREE_OP1(); -ZEND_VM_C_LABEL(is_var_return): if (opline->extended_value & ZEND_ISSET) { result = value && Z_TYPE_P(value) > IS_NULL && (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); @@ -6458,6 +6533,82 @@ ZEND_VM_C_LABEL(is_var_return): } } +ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +{ + USE_OPLINE + zval *value; + int result; + zend_free_op free_op1; + zval tmp, *varname; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); + ZVAL_UNDEF(&tmp); + if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (OP2_TYPE == IS_CONST) { + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + ZEND_VM_C_GOTO(is_static_prop_return); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (OP2_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (OP1_TYPE == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + ZEND_VM_C_GOTO(is_static_prop_return); + } + } + + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (OP1_TYPE == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + +ZEND_VM_C_LABEL(is_static_prop_return): + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) { USE_OPLINE @@ -6959,7 +7110,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, CONST|VAR) +ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CONST|VAR) { USE_OPLINE zend_free_op free_op1; @@ -6984,6 +7135,8 @@ ZEND_VM_C_LABEL(try_instanceof): } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } + } else if (OP2_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 97e08b75f9..5d5db9130e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3350,6 +3350,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -4922,14 +4924,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -4946,116 +4948,62 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -5068,40 +5016,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -5615,6 +5563,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -5708,10 +5658,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -5848,110 +5798,78 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce; + zval *value; USE_OPLINE SAVE_OPLINE(); - if (IS_CONST == IS_UNUSED) { - zend_constant *c; - - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); - if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); - } else { - actual++; - ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); - } - } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); - } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - do { - if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - ZVAL_DEREF(value); + do { + if (IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ZVAL_DEREF(value); #ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); #endif - break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + break; + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } - - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + break; + } + } + + if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + ZVAL_DEREF(value); + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_CONST == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } while (0); + +#ifdef ZTS + if (ce->type == ZEND_INTERNAL_CLASS) { + ZVAL_DUP(EX_VAR(opline->result.var), value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -6085,34 +6003,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CONST == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = EX_CONSTANT(opline->op1); @@ -6125,33 +6023,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -6160,103 +6053,79 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CONST == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = EX_CONSTANT(opline->op1); + ZVAL_UNDEF(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -6832,14 +6701,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -6856,116 +6725,62 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_VAR == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -6978,70 +6793,50 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CONST == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = EX_CONSTANT(opline->op1); @@ -7054,33 +6849,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -7089,103 +6879,79 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CONST == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = EX_CONSTANT(opline->op1); + ZVAL_UNDEF(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_VAR == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); } + + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -7353,60 +7119,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -7417,52 +7153,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); break; EMPTY_SWITCH_DEFAULT_CASE() } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + } - HANDLE_EXCEPTION(); - } - } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { + if (Z_CONSTANT_P(retval)) { + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + HANDLE_EXCEPTION(); + } } + } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -7511,6 +7225,134 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_UNUSED_HAN ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = EX_CONSTANT(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); + zend_string_addref(name); + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_string(varname); + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -7578,6 +7420,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -7671,10 +7515,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -7883,7 +7727,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA SAVE_OPLINE(); if (IS_CONST == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -7914,33 +7757,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval tmp, *varname; + zend_class_entry *ce; + + + SAVE_OPLINE(); + + varname = EX_CONSTANT(opline->op1); + + ZVAL_UNDEF(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -7956,7 +7824,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U int result; if (IS_CONST == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -7977,6 +7844,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U } else { zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -7986,55 +7854,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } -is_var_return: if (opline->extended_value & ZEND_ISSET) { result = value && Z_TYPE_P(value) > IS_NULL && (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); @@ -8048,6 +7874,81 @@ is_var_return: } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval tmp, *varname; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = EX_CONSTANT(opline->op1); + ZVAL_UNDEF(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9315,6 +9216,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -9408,10 +9311,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -11123,6 +11026,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -11216,10 +11121,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -15322,6 +15227,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -17452,6 +17359,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -17545,10 +17454,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -17561,110 +17470,78 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce; + zval *value; USE_OPLINE SAVE_OPLINE(); - if (IS_VAR == IS_UNUSED) { - zend_constant *c; - - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); - if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); - } else { - actual++; - ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); - } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); - } - } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); - } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - do { - if (IS_VAR == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - ZVAL_DEREF(value); + do { + if (IS_VAR == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ZVAL_DEREF(value); #ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); #endif - break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + break; + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } - - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + break; + } + } + + if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + ZVAL_DEREF(value); + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_VAR == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } while (0); + +#ifdef ZTS + if (ce->type == ZEND_INTERNAL_CLASS) { + ZVAL_DUP(EX_VAR(opline->result.var), value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -19080,6 +18957,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -19173,10 +19052,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -20701,6 +20580,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -20794,10 +20675,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -22271,6 +22152,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -22364,10 +22247,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -22653,6 +22536,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval object_zval; + zend_function *constructor; + zend_class_entry *ce; + + SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { + HANDLE_EXCEPTION(); + } + constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); + + if (constructor == NULL) { + if (EXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); + } else { + OBJ_RELEASE(Z_OBJ(object_zval)); + } + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } else { + /* We are not handling overloaded classes right now */ + zend_execute_data *call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR | + (EXPECTED(RETURN_VALUE_USED(opline)) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED), + constructor, + opline->extended_value, + ce, + Z_OBJ(object_zval)); + call->prev_execute_data = EX(call); + EX(call) = call; + + if (EXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -23754,110 +23691,258 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - if (IS_UNUSED == IS_UNUSED) { - zend_constant *c; - - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); - if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); - } else { - actual++; - ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); + + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); HANDLE_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_CONST == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_CONST == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_CONST != IS_UNUSED) { + + + function_name = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + + HANDLE_EXCEPTION(); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + + HANDLE_EXCEPTION(); + } + 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); + } + } + if (IS_CONST != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + } + if (!object) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_UNUSED == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + ce = EX(called_scope); + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_constant *c; + + SAVE_OPLINE(); + + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { + if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { + char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); + if (!actual) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); + } else { + actual++; + ZVAL_STRINGL(EX_VAR(opline->result.var), + actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); + } + /* non-qualified constant - allow text substitution */ + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); + zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } else { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + } + +#ifdef ZTS + if (c->flags & CONST_PERSISTENT) { + ZVAL_DUP(EX_VAR(opline->result.var), &c->value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), &c->value); + } +#else + ZVAL_COPY(EX_VAR(opline->result.var), &c->value); #endif - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - do { - if (IS_UNUSED == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - ZVAL_DEREF(value); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce; + zval *value; + USE_OPLINE + + SAVE_OPLINE(); + + do { + if (IS_UNUSED == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ZVAL_DEREF(value); #ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); #endif - break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + break; + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } - - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + break; + } + } + + if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + ZVAL_DEREF(value); + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_UNUSED == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } while (0); + +#ifdef ZTS + if (ce->type == ZEND_INTERNAL_CLASS) { + ZVAL_DUP(EX_VAR(opline->result.var), value); + } else { ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -24949,6 +25034,142 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_UNUSED_ #endif } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; + + SAVE_OPLINE(); + + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_UNUSED == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_UNUSED != IS_UNUSED) { + + + function_name = NULL; + if (IS_UNUSED != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + + HANDLE_EXCEPTION(); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + + HANDLE_EXCEPTION(); + } + 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); + } + } + if (IS_UNUSED != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + } + if (!object) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_UNUSED == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + ce = EX(called_scope); + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -26169,6 +26390,142 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; + + SAVE_OPLINE(); + + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_CV == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_CV == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_CV != IS_UNUSED) { + + + function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (IS_CV != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + + HANDLE_EXCEPTION(); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + + HANDLE_EXCEPTION(); + } + 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); + } + } + if (IS_CV != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + } + if (!object) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_UNUSED == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + ce = EX(called_scope); + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; @@ -27662,6 +28019,142 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; + + SAVE_OPLINE(); + + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + 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); + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zval_ptr_dtor_nogc(free_op2); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + } + if (!object) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_UNUSED == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + ce = EX(called_scope); + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; @@ -30921,14 +31414,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HAN ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -30945,116 +31438,62 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -31067,40 +31506,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -32108,34 +32547,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CV == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -32148,33 +32567,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLE varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -32324,103 +32738,79 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CV == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CV == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -32631,6 +33021,8 @@ try_instanceof: } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -33123,14 +33515,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_H ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -33147,116 +33539,62 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_VAR == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -33269,40 +33607,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -33392,34 +33730,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CV == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -33432,33 +33750,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER( varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -33467,103 +33780,79 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CV == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_VAR == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CV == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -33591,6 +33880,8 @@ try_instanceof: } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -34085,60 +34376,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -34149,52 +34410,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); break; EMPTY_SWITCH_DEFAULT_CASE() } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + } - HANDLE_EXCEPTION(); - } - } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { + if (Z_CONSTANT_P(retval)) { + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + HANDLE_EXCEPTION(); + } } + } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -34243,6 +34482,134 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLE ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + zend_string_addref(name); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_string(varname); + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -34631,7 +34998,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL SAVE_OPLINE(); if (IS_CV == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -34662,33 +35028,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval tmp, *varname; + zend_class_entry *ce; + + + SAVE_OPLINE(); + + varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -34704,7 +35095,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS int result; if (IS_CV == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -34725,6 +35115,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS } else { zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); @@ -34734,55 +35125,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } -is_var_return: if (opline->extended_value & ZEND_ISSET) { result = value && Z_TYPE_P(value) > IS_NULL && (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); @@ -34796,6 +35145,127 @@ is_var_return: } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval tmp, *varname; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CV == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *expr; + zend_bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (UNEXPECTED(ce == NULL)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -41247,14 +41717,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zend_free_op free_op1; zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -41271,117 +41741,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if (IS_CONST == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); } - - goto fetch_var_return; + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - - zval_ptr_dtor_nogc(free_op1); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); + + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -41394,40 +41811,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -41827,34 +42244,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; zend_free_op free_op1; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -41867,33 +42264,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -41902,104 +42294,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; + zend_free_op free_op1; + zval tmp, *varname; + zend_class_entry *ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - zend_free_op free_op1; - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_CONST == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -42210,6 +42578,8 @@ try_instanceof: } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -42229,14 +42599,14 @@ try_instanceof: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zend_free_op free_op1; zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42253,117 +42623,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if (IS_VAR == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); } - - goto fetch_var_return; + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - - zval_ptr_dtor_nogc(free_op1); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); + + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -42376,70 +42693,50 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; zend_free_op free_op1; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - GC_ZVAL_CHECK_POSSIBLE_ROOT(var); - ZVAL_UNDEF(var); - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42452,33 +42749,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -42487,104 +42779,80 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; + zend_free_op free_op1; + zval tmp, *varname; + zend_class_entry *ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else { - zend_free_op free_op1; - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + if (IS_VAR == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -42612,6 +42880,8 @@ try_instanceof: } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -42655,61 +42925,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - zval_ptr_dtor_nogc(free_op1); - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -42720,52 +42959,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); break; EMPTY_SWITCH_DEFAULT_CASE() } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + } + + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { + if (Z_CONSTANT_P(retval)) { + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); } + } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + zval_ptr_dtor_nogc(free_op1); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -42814,6 +43031,136 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HA ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + + 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); + zend_string_addref(name); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_string(varname); + } + + if (IS_UNUSED == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -42823,7 +43170,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -42854,33 +43200,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval tmp, *varname; + zend_class_entry *ce; + zend_free_op free_op1; + + SAVE_OPLINE(); + + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + + ZVAL_UNDEF(&tmp); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -42896,7 +43267,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ int result; if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -42917,6 +43287,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ } else { zend_free_op free_op1; zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42926,56 +43297,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } zval_ptr_dtor_nogc(free_op1); -is_var_return: if (opline->extended_value & ZEND_ISSET) { result = value && Z_TYPE_P(value) > IS_NULL && (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); @@ -42989,6 +43318,128 @@ is_var_return: } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + zend_free_op free_op1; + zval tmp, *varname; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } + + if (IS_UNUSED == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *expr; + zend_bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (UNEXPECTED(ce == NULL)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -46993,11 +47444,11 @@ void zend_init_opcodes_handlers(void) ZEND_NEW_SPEC_VAR_HANDLER, ZEND_NEW_SPEC_VAR_HANDLER, ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47128,19 +47579,19 @@ void zend_init_opcodes_handlers(void) ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47148,9 +47599,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47278,19 +47729,19 @@ void zend_init_opcodes_handlers(void) ZEND_EXIT_SPEC_CV_HANDLER, ZEND_EXIT_SPEC_CV_HANDLER, ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_FETCH_R_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47298,9 +47749,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER, @@ -47353,19 +47804,19 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER, - ZEND_FETCH_W_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47373,9 +47824,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47428,19 +47879,19 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER, - ZEND_FETCH_RW_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47448,9 +47899,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47503,19 +47954,19 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER, - ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47523,9 +47974,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER, @@ -47578,19 +48029,19 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47598,9 +48049,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER, @@ -47653,19 +48104,19 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER, - ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47673,9 +48124,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47753,7 +48204,6 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -47763,7 +48213,8 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -48118,6 +48569,11 @@ void zend_init_opcodes_handlers(void) ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -48126,21 +48582,16 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -48148,9 +48599,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER, @@ -48736,12 +49187,12 @@ void zend_init_opcodes_handlers(void) ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -48751,7 +49202,7 @@ void zend_init_opcodes_handlers(void) ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_DECLARE_CLASS_SPEC_HANDLER, ZEND_DECLARE_CLASS_SPEC_HANDLER, @@ -49603,6 +50054,231 @@ void zend_init_opcodes_handlers(void) ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = labels; diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 1f26f0439e..000d39044b 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include #include -const char *zend_vm_opcodes_map[173] = { +const char *zend_vm_opcodes_map[182] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -195,6 +195,15 @@ const char *zend_vm_opcodes_map[173] = { "ZEND_SPACESHIP", "ZEND_DECLARE_ANON_CLASS", "ZEND_DECLARE_ANON_INHERITED_CLASS", + "ZEND_FETCH_STATIC_PROP_R", + "ZEND_FETCH_STATIC_PROP_W", + "ZEND_FETCH_STATIC_PROP_RW", + "ZEND_FETCH_STATIC_PROP_IS", + "ZEND_FETCH_STATIC_PROP_FUNC_ARG", + "ZEND_FETCH_STATIC_PROP_UNSET", + "ZEND_UNSET_STATIC_PROP", + "ZEND_ISSET_ISEMPTY_STATIC_PROP", + "ZEND_FETCH_CLASS_CONSTANT", }; ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index bb2d7717bd..c6fa3a1dc5 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -202,5 +202,14 @@ END_EXTERN_C() #define ZEND_SPACESHIP 170 #define ZEND_DECLARE_ANON_CLASS 171 #define ZEND_DECLARE_ANON_INHERITED_CLASS 172 +#define ZEND_FETCH_STATIC_PROP_R 173 +#define ZEND_FETCH_STATIC_PROP_W 174 +#define ZEND_FETCH_STATIC_PROP_RW 175 +#define ZEND_FETCH_STATIC_PROP_IS 176 +#define ZEND_FETCH_STATIC_PROP_FUNC_ARG 177 +#define ZEND_FETCH_STATIC_PROP_UNSET 178 +#define ZEND_UNSET_STATIC_PROP 179 +#define ZEND_ISSET_ISEMPTY_STATIC_PROP 180 +#define ZEND_FETCH_CLASS_CONSTANT 181 #endif diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index b7e1682866..9a740a8739 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1091,13 +1091,15 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, VAR_SOURCE(opline->op1) && (VAR_SOURCE(opline->op1)->opcode == ZEND_FAST_CONCAT || VAR_SOURCE(opline->op1)->opcode == ZEND_ROPE_END || - VAR_SOURCE(opline->op1)->opcode == ZEND_FETCH_CONSTANT))) && + VAR_SOURCE(opline->op1)->opcode == ZEND_FETCH_CONSTANT || + VAR_SOURCE(opline->op1)->opcode == ZEND_FETCH_CLASS_CONSTANT))) && (opline->op2_type == IS_CONST || (opline->op2_type == IS_TMP_VAR && VAR_SOURCE(opline->op2) && (VAR_SOURCE(opline->op2)->opcode == ZEND_FAST_CONCAT || VAR_SOURCE(opline->op2)->opcode == ZEND_ROPE_END || - VAR_SOURCE(opline->op2)->opcode == ZEND_FETCH_CONSTANT)))) { + VAR_SOURCE(opline->op2)->opcode == ZEND_FETCH_CONSTANT || + VAR_SOURCE(opline->op2)->opcode == ZEND_FETCH_CLASS_CONSTANT)))) { opline->opcode = ZEND_FAST_CONCAT; } } else if (opline->opcode == ZEND_QM_ASSIGN && @@ -1116,6 +1118,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, VAR_SOURCE(opline->op1)->opcode == ZEND_IS_IDENTICAL || VAR_SOURCE(opline->op1)->opcode == ZEND_IS_NOT_IDENTICAL || VAR_SOURCE(opline->op1)->opcode == ZEND_ISSET_ISEMPTY_VAR || + VAR_SOURCE(opline->op1)->opcode == ZEND_ISSET_ISEMPTY_STATIC_PROP || VAR_SOURCE(opline->op1)->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ) && !zend_bitset_in(used_ext, VAR_NUM(ZEND_OP1(opline).var))) { /* T = IS_SMALLER(X, Y), T1 = BOOL(T) => T = IS_SMALLER(X, Y), T1 = QM_ASSIGN(T) */ @@ -1414,6 +1417,7 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra if (src && src->opcode != ZEND_FETCH_R && + src->opcode != ZEND_FETCH_STATIC_PROP_R && src->opcode != ZEND_FETCH_DIM_R && src->opcode != ZEND_FETCH_OBJ_R) { ZEND_RESULT_TYPE(src) |= EXT_TYPE_UNUSED; diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 7650ae1cc5..518708b625 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -177,25 +177,24 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx LITERAL_INFO(opline->op1.constant, LITERAL_CONST, 1, 1, 2); break; case ZEND_FETCH_CONSTANT: - if (ZEND_OP1_TYPE(opline) == IS_UNUSED) { - if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { - LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 5); - } else { - LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 3); - } + if ((opline->extended_value & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 5); } else { - if (ZEND_OP1_TYPE(opline) == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); - } - optimizer_literal_class_info( - info, - opline->op1_type, - opline->op1, - opline->op2.constant, - LITERAL_CLASS_CONST, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 1, - op_array); + LITERAL_INFO(opline->op2.constant, LITERAL_CONST, 1, 1, 3); } break; + case ZEND_FETCH_CLASS_CONSTANT: + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_CLASS, 1, 1, 2); + } + optimizer_literal_class_info( + info, + opline->op1_type, + opline->op1, + opline->op2.constant, + LITERAL_CLASS_CONST, (ZEND_OP1_TYPE(opline) == IS_CONST) ? 1 : 2, 1, + op_array); + break; case ZEND_FETCH_R: case ZEND_FETCH_W: case ZEND_FETCH_RW: @@ -204,23 +203,29 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_FETCH_FUNC_ARG: case ZEND_UNSET_VAR: case ZEND_ISSET_ISEMPTY_VAR: - if (ZEND_OP2_TYPE(opline) == IS_UNUSED) { - if (ZEND_OP1_TYPE(opline) == IS_CONST) { - LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); - } - } else { - if (ZEND_OP2_TYPE(opline) == IS_CONST) { - LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); - } - if (ZEND_OP1_TYPE(opline) == IS_CONST) { - optimizer_literal_class_info( - info, - opline->op2_type, - opline->op2, - opline->op1.constant, - LITERAL_STATIC_PROPERTY, 2, 1, - op_array); - } + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1); + } + 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: + case ZEND_ISSET_ISEMPTY_STATIC_PROP: + if (ZEND_OP2_TYPE(opline) == IS_CONST) { + LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2); + } + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + optimizer_literal_class_info( + info, + opline->op2_type, + opline->op2, + opline->op1.constant, + LITERAL_STATIC_PROPERTY, 2, 1, + op_array); } break; case ZEND_FETCH_CLASS: diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index c82df24c58..68597b1d5d 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -105,15 +105,24 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) call_stack[call].opline = NULL; break; case ZEND_FETCH_FUNC_ARG: + case ZEND_FETCH_STATIC_PROP_FUNC_ARG: case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_FETCH_DIM_FUNC_ARG: if (call_stack[call - 1].func) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { opline->extended_value &= ZEND_FETCH_TYPE_MASK; - opline->opcode -= 9; + if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) { + opline->opcode -= 9; + } else { + opline->opcode = ZEND_FETCH_STATIC_PROP_W; + } } else { opline->extended_value &= ZEND_FETCH_TYPE_MASK; - opline->opcode -= 12; + if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) { + opline->opcode -= 12; + } else { + opline->opcode = ZEND_FETCH_STATIC_PROP_R; + } } } break; diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 766eb2c2d4..0122342798 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -238,8 +238,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) #endif case ZEND_FETCH_CONSTANT: - if (ZEND_OP1_TYPE(opline) == IS_UNUSED && - ZEND_OP2_TYPE(opline) == IS_CONST && + if (ZEND_OP2_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING && Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("__COMPILER_HALT_OFFSET__") - 1 && memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1) == 0) { @@ -263,8 +262,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } - if (ZEND_OP1_TYPE(opline) == IS_UNUSED && - ZEND_OP2_TYPE(opline) == IS_CONST && + if (ZEND_OP2_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { /* substitute persistent constants */ uint32_t tv = ZEND_RESULT(opline).var; @@ -283,10 +281,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) MAKE_NOP(opline); } } + break; - /* class constant */ - if (ZEND_OP1_TYPE(opline) != IS_UNUSED && - ZEND_OP2_TYPE(opline) == IS_CONST && + case ZEND_FETCH_CLASS_CONSTANT: + if (ZEND_OP2_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { zend_class_entry *ce = NULL; @@ -308,6 +306,11 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } } + } else if (op_array->scope && + ZEND_OP1_TYPE(opline) == IS_UNUSED && + (opline->op1.num & ~ZEND_FETCH_CLASS_NO_AUTOLOAD) == ZEND_FETCH_CLASS_SELF) { + /* for self::B */ + ce = op_array->scope; } else if (op_array->scope && ZEND_OP1_TYPE(opline) == IS_VAR && (opline - 1)->opcode == ZEND_FETCH_CLASS && diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 22bb806a4c..f37b5f7241 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -131,6 +131,7 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_INIT_STATIC_METHOD_CALL: case ZEND_CATCH: case ZEND_FETCH_CONSTANT: + case ZEND_FETCH_CLASS_CONSTANT: case ZEND_DEFINED: case ZEND_NEW: opline->op1.constant = zend_optimizer_add_literal(op_array, val); @@ -179,20 +180,20 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, if (Z_TYPE_P(val) == IS_STRING) { zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline))); switch (opline->opcode) { - case ZEND_FETCH_R: - case ZEND_FETCH_W: - case ZEND_FETCH_RW: - case ZEND_FETCH_IS: - case ZEND_FETCH_UNSET: - case ZEND_FETCH_FUNC_ARG: case ZEND_FETCH_CLASS: case ZEND_INIT_FCALL_BY_NAME: /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ - case ZEND_UNSET_VAR: - case ZEND_ISSET_ISEMPTY_VAR: case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: + 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: + case ZEND_ISSET_ISEMPTY_STATIC_PROP: Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; op_array->cache_size += sizeof(void*); zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); @@ -213,7 +214,7 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1])); /* break missing intentionally */ - /*case ZEND_FETCH_CONSTANT:*/ + /*case ZEND_FETCH_CLASS_CONSTANT:*/ case ZEND_ASSIGN_OBJ: case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_W: