From: Nikita Popov Date: Thu, 10 Dec 2015 17:24:29 +0000 (+0100) Subject: Merge branch 'PHP-7.0' X-Git-Tag: php-7.1.0alpha1~677 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3d4a2d200214c08db23dcff172eb5e48cee5044a;p=php Merge branch 'PHP-7.0' Conflicts: Zend/zend_vm_def.h Zend/zend_vm_execute.h --- 3d4a2d200214c08db23dcff172eb5e48cee5044a diff --cc Zend/zend_compile.c index dd9c5a44de,34246bdc04..a87797bca5 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -2611,11 -2374,12 +2611,12 @@@ zend_op *zend_compile_static_prop_commo 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) { + convert_to_string(CT_CONSTANT(opline->op1)); zend_alloc_polymorphic_cache_slot(opline->op1.constant); } if (class_node.op_type == IS_CONST) { diff --cc Zend/zend_vm_def.h index 45fd6df4cb,4c01a5d1af..0fc70a307d --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@@ -1534,152 -1569,39 +1534,155 @@@ ZEND_VM_HELPER(zend_fetch_var_address_h 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(); + } + + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); + } + + 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(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); +} + +ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W); +} + +ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW); +} + +ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W); + } else { + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); + } +} + +ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET); +} + +ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS); +} + +ZEND_VM_HELPER(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(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - FREE_OP1(); + 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); + } + } 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))) { ++ if (OP1_TYPE != IS_CONST) { ++ zend_string_release(name); ++ } + 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); diff --cc Zend/zend_vm_execute.h index f466dc12db,0fd696d327..4742401ef2 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@@ -4963,59 -4953,112 +4963,62 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - } 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); } + } 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))) { ++ if (IS_CONST != IS_CONST) { ++ zend_string_release(name); + } + + 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) { @@@ -6763,60 -6872,113 +6766,63 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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)); + 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*)); - 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)); - 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); + 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))) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } - - 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); } + } 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))) { ++ if (IS_CONST != IS_CONST) { ++ zend_string_release(name); ++ } + + 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); @@@ -7275,138 -7539,6 +7281,141 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + 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; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { ++ if (IS_CONST != IS_CONST) { ++ zend_string_release(name); ++ } + + 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 @@@ -31556,59 -30979,112 +31565,62 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CV != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); } + } 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))) { ++ if (IS_CV != IS_CONST) { ++ zend_string_release(name); + } + + 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) { @@@ -33673,59 -33190,112 +33685,62 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CV != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); } + } 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))) { ++ if (IS_CV != IS_CONST) { ++ zend_string_release(name); + } + + 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) { @@@ -34632,138 -34298,6 +34647,141 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + 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; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { ++ if (IS_CV != IS_CONST) { ++ zend_string_release(name); ++ } + + 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 @@@ -41911,62 -41332,114 +41929,65 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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))) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_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); + } 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) { - 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() - } + /* 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; } - 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); + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { ++ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { ++ zend_string_release(name); + } + 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); @@@ -42809,63 -42323,115 +42830,66 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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))) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_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); + } 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) { - 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() - } + /* 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; } - 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); + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { ++ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { ++ zend_string_release(name); + } + 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); } @@@ -43233,140 -42896,6 +43257,143 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + 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; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { ++ if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { ++ zend_string_release(name); ++ } + 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 diff --cc ext/opcache/Optimizer/zend_optimizer.c index 3d238acd85,8d13b9f433..3aaae5b915 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@@ -170,16 -171,25 +174,29 @@@ int zend_optimizer_update_op1_const(zen case ZEND_DEFINED: case ZEND_NEW: REQUIRES_STRING(val); - ZEND_OP1_TYPE(opline) = IS_CONST; drop_leading_backslash(val); opline->op1.constant = zend_optimizer_add_literal(op_array, val); - zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline))); - Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size; - op_array->cache_size += sizeof(void*); + alloc_cache_slots_op1(op_array, opline, 1); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); 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: ++ TO_STRING_NOWARN(val); ++ opline->op1.constant = zend_optimizer_add_literal(op_array, val); ++ alloc_cache_slots_op1(op_array, opline, 2); ++ break; + case ZEND_CONCAT: + case ZEND_FAST_CONCAT: + 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: - TO_STRING_NOWARN(val); - opline->op1.constant = zend_optimizer_add_literal(op_array, val); - if (opline->extended_value == ZEND_FETCH_STATIC_MEMBER) { - alloc_cache_slots_op1(op_array, opline, 2); - } - break; - case ZEND_CONCAT: - case ZEND_FAST_CONCAT: TO_STRING_NOWARN(val); /* break missing intentionally */ default: