diff --git a/Zend/tests/closure_047.phpt b/Zend/tests/closure_047.phpt new file mode 100644 index 000000000000..9c607c71c982 --- /dev/null +++ b/Zend/tests/closure_047.phpt @@ -0,0 +1,25 @@ +--TEST-- +Closure 046: Closure instance call +--FILE-- +bindTo(new Stdclass()))(); + +((function() { + return function() { + var_dump(123); + }; +})())(); + +?> +--EXPECTF-- +string(9) "{closure}" +object(stdClass)#3 (0) { +} +int(123) diff --git a/Zend/tests/function_chain_call_001.phpt b/Zend/tests/function_chain_call_001.phpt new file mode 100644 index 000000000000..6ab62aec2820 --- /dev/null +++ b/Zend/tests/function_chain_call_001.phpt @@ -0,0 +1,31 @@ +--TEST-- +function chained call +--FILE-- +dummy(); +var_dump((new Foo())->var); +var_dump((new Foo())->noexists); + +--EXPECT-- +string(10) "Foo::dummy" +string(3) "foo" +string(8) "noexists" diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 6a9a24a87ea7..dc4bebdd1f11 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -45,7 +45,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %} %pure_parser -%expect 3 +%expect 2 %code requires { #ifdef ZTS @@ -735,6 +735,15 @@ new_expr: T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} ; +lambda_function: + function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); } + '(' parameter_list ')' lexical_vars + '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $3; } + | T_STATIC function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); } + '(' parameter_list ')' lexical_vars + '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $4; } + + expr_without_variable: T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); } | variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); } @@ -785,9 +794,8 @@ expr_without_variable: | expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); } | expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); } | expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); } - | parenthesis_expr { $$ = $1; } + | parenthesis_expr { $$ = $1; } instance_call { $$ = $3; } | new_expr { $$ = $1; } - | '(' new_expr ')' { $$ = $2; } instance_call { $$ = $5; } | expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); } expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); } expr { zend_do_qm_false(&$$, &$7, &$2, &$5 TSRMLS_CC); } @@ -809,12 +817,7 @@ expr_without_variable: | '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); } | T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); } | T_YIELD { zend_do_yield(&$$, NULL, NULL, 0 TSRMLS_CC); } - | function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); } - '(' parameter_list ')' lexical_vars - '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $3; } - | T_STATIC function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); } - '(' parameter_list ')' lexical_vars - '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $4; } + | lambda_function { $$ = $1; } ; yield_expr: @@ -866,6 +869,8 @@ function_call: function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} | variable_without_objects { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); } function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);} + | parenthesis_expr { zend_do_begin_variable_parse(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); } + function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); } ; class_name: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 369f9452337d..b2cc7fa0b5ba 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1244,7 +1244,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1332,7 +1332,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV) } } -ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV) +ZEND_VM_HELPER(zend_fetch_property_address_read_helper, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1; @@ -1375,7 +1375,7 @@ ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, VAR|UNUSED|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper); } @@ -1460,7 +1460,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1; @@ -2423,7 +2423,7 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV) } } -ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) { USE_OPLINE zval *function_name; @@ -2484,7 +2484,9 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (IS_OP1_TMP_FREE()) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -2675,18 +2677,23 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) EX(call) = call; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR && + } else if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) { if (call->object) { - Z_ADDREF_P(call->object); + if (IS_OP2_TMP_FREE() && + call->object == function_name) { + MAKE_REAL_ZVAL_PTR(call->object); + } else { + Z_ADDREF_P(call->object); + } } if (OP2_TYPE == IS_VAR && OP2_FREE && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; - } else { + } else if (!IS_OP2_TMP_FREE()) { FREE_OP2(); } call->is_ctor_call = 0; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c947c3e17f59..586ef699fec9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1260,18 +1260,23 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE EX(call) = call; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR && + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) { if (call->object) { - Z_ADDREF_P(call->object); + if (0 && + call->object == function_name) { + MAKE_REAL_ZVAL_PTR(call->object); + } else { + Z_ADDREF_P(call->object); + } } if (IS_CONST == IS_VAR && 0 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; - } else { + } else if (!0) { } call->is_ctor_call = 0; @@ -1587,18 +1592,23 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H EX(call) = call; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR && + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) { if (call->object) { - Z_ADDREF_P(call->object); + if (1 && + call->object == function_name) { + MAKE_REAL_ZVAL_PTR(call->object); + } else { + Z_ADDREF_P(call->object); + } } if (IS_TMP_VAR == IS_VAR && 1 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; - } else { + } else if (!1) { zval_dtor(free_op2.var); } call->is_ctor_call = 0; @@ -1774,18 +1784,23 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H EX(call) = call; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR && + } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) { if (call->object) { - Z_ADDREF_P(call->object); + if (0 && + call->object == function_name) { + MAKE_REAL_ZVAL_PTR(call->object); + } else { + Z_ADDREF_P(call->object); + } } if (IS_VAR == IS_VAR && (free_op2.var != NULL) && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; - } else { + } else if (!0) { zval_ptr_dtor(&free_op2.var); } call->is_ctor_call = 0; @@ -1999,18 +2014,23 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA EX(call) = call; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR && + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) { if (call->object) { - Z_ADDREF_P(call->object); + if (0 && + call->object == function_name) { + MAKE_REAL_ZVAL_PTR(call->object); + } else { + Z_ADDREF_P(call->object); + } } if (IS_CV == IS_VAR && 0 && call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; - } else { + } else if (!0) { } call->is_ctor_call = 0; @@ -3524,6 +3544,109 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC); + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CONST_CONST(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = opline->op2.zv; + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_CONST_CONST(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = opline->op2.zv; + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -3548,6 +3671,87 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + char *function_name_strval; + int function_name_strlen; + + call_slot *call = EX(call_slots) + opline->result.num; + + SAVE_OPLINE(); + + function_name = opline->op2.zv; + + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } + + function_name_strval = Z_STRVAL_P(function_name); + function_name_strlen = Z_STRLEN_P(function_name); + + call->object = opline->op1.zv; + + if (EXPECTED(call->object != NULL) && + EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) { + call->called_scope = Z_OBJCE_P(call->object); + + if (IS_CONST != IS_CONST || + (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) { + zval *object = call->object; + + if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) { + zend_error_noreturn(E_ERROR, "Object does not support method calls"); + } + + /* First, locate the function. */ + call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); + if (UNEXPECTED(call->fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval); + } + if (IS_CONST == IS_CONST && + EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) && + EXPECTED(call->object == object)) { + CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc); + } + } + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + } + + if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + call->object = NULL; + } else { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { + Z_ADDREF_P(call->object); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, call->object); + zval_copy_ctor(this_ptr); + call->object = this_ptr; + } + } + call->is_ctor_call = 0; + EX(call) = call; + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4535,6 +4739,191 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC); + zval_dtor(free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CONST_TMP(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_dtor(free_op2.var); + } else { + zval *retval; + + if (1) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (1) { + zval_ptr_dtor(&offset); + } else { + zval_dtor(free_op2.var); + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_CONST_TMP(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_dtor(free_op2.var); + } else { + zval *retval; + + if (1) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (1) { + zval_ptr_dtor(&offset); + } else { + zval_dtor(free_op2.var); + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + char *function_name_strval; + int function_name_strlen; + zend_free_op free_op2; + call_slot *call = EX(call_slots) + opline->result.num; + + SAVE_OPLINE(); + + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (IS_TMP_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } + + function_name_strval = Z_STRVAL_P(function_name); + function_name_strlen = Z_STRLEN_P(function_name); + + call->object = opline->op1.zv; + + if (EXPECTED(call->object != NULL) && + EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) { + call->called_scope = Z_OBJCE_P(call->object); + + if (IS_TMP_VAR != IS_CONST || + (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) { + zval *object = call->object; + + if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) { + zend_error_noreturn(E_ERROR, "Object does not support method calls"); + } + + /* First, locate the function. */ + call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); + if (UNEXPECTED(call->fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) && + EXPECTED(call->object == object)) { + CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc); + } + } + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_dtor(free_op2.var); + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + } + + if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + call->object = NULL; + } else { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { + Z_ADDREF_P(call->object); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, call->object); + zval_copy_ctor(this_ptr); + call->object = this_ptr; + } + } + call->is_ctor_call = 0; + EX(call) = call; + + zval_dtor(free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -5391,6 +5780,191 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); + zval_ptr_dtor(&free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CONST_VAR(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_ptr_dtor(&free_op2.var); + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + zval_ptr_dtor(&free_op2.var); + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_CONST_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_ptr_dtor(&free_op2.var); + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + zval_ptr_dtor(&free_op2.var); + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + char *function_name_strval; + int function_name_strlen; + zend_free_op free_op2; + call_slot *call = EX(call_slots) + opline->result.num; + + SAVE_OPLINE(); + + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (IS_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } + + function_name_strval = Z_STRVAL_P(function_name); + function_name_strlen = Z_STRLEN_P(function_name); + + call->object = opline->op1.zv; + + if (EXPECTED(call->object != NULL) && + EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) { + call->called_scope = Z_OBJCE_P(call->object); + + if (IS_VAR != IS_CONST || + (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) { + zval *object = call->object; + + if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) { + zend_error_noreturn(E_ERROR, "Object does not support method calls"); + } + + /* First, locate the function. */ + call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); + if (UNEXPECTED(call->fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval); + } + if (IS_VAR == IS_CONST && + EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) && + EXPECTED(call->object == object)) { + CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc); + } + } + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor(&free_op2.var); + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + } + + if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + call->object = NULL; + } else { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { + Z_ADDREF_P(call->object); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, call->object); + zval_copy_ctor(this_ptr); + call->object = this_ptr; + } + } + call->is_ctor_call = 0; + EX(call) = call; + + zval_ptr_dtor(&free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -6963,6 +7537,190 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC); + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CONST_CV(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_CONST_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = opline->op1.zv; + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + char *function_name_strval; + int function_name_strlen; + + call_slot *call = EX(call_slots) + opline->result.num; + + SAVE_OPLINE(); + + function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Method name must be a string"); + } + + function_name_strval = Z_STRVAL_P(function_name); + function_name_strlen = Z_STRLEN_P(function_name); + + call->object = opline->op1.zv; + + if (EXPECTED(call->object != NULL) && + EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) { + call->called_scope = Z_OBJCE_P(call->object); + + if (IS_CV != IS_CONST || + (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) { + zval *object = call->object; + + if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) { + zend_error_noreturn(E_ERROR, "Object does not support method calls"); + } + + /* First, locate the function. */ + call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); + if (UNEXPECTED(call->fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval); + } + if (IS_CV == IS_CONST && + EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) && + EXPECTED(call->object == object)) { + CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc); + } + } + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); + } + + if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + call->object = NULL; + } else { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { + Z_ADDREF_P(call->object); /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + INIT_PZVAL_COPY(this_ptr, call->object); + zval_copy_ctor(this_ptr); + call->object = this_ptr; + } + } + call->is_ctor_call = 0; + EX(call) = call; + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8884,6 +9642,111 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC); + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_TMP_CONST(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = opline->op2.zv; + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_TMP_CONST(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = opline->op2.zv; + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9015,7 +9878,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (1) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -9764,6 +10629,111 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC); + zval_dtor(free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_TMP_TMP(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_dtor(free_op2.var); + } else { + zval *retval; + + if (1) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (1) { + zval_ptr_dtor(&offset); + } else { + zval_dtor(free_op2.var); + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_TMP_TMP(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_dtor(free_op2.var); + } else { + zval *retval; + + if (1) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (1) { + zval_ptr_dtor(&offset); + } else { + zval_dtor(free_op2.var); + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9870,7 +10840,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (1) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -10624,6 +11596,111 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); + zval_ptr_dtor(&free_op2.var); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_TMP_VAR(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_ptr_dtor(&free_op2.var); + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + zval_ptr_dtor(&free_op2.var); + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_TMP_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + zval_ptr_dtor(&free_op2.var); + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + zval_ptr_dtor(&free_op2.var); + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10730,7 +11807,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (1) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -12061,6 +13140,111 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC); + + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_TMP_CV(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + zend_error(E_NOTICE, "Trying to get property of non-object"); + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + return zend_fetch_property_address_read_helper_SPEC_TMP_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +} + +static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || + UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { + PZVAL_LOCK(&EG(uninitialized_zval)); + AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + + } else { + zval *retval; + + if (0) { + MAKE_REAL_ZVAL_PTR(offset); + } + + /* here we are sure we are dealing with an object */ + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + + PZVAL_LOCK(retval); + AI_SET_PTR(&EX_T(opline->result.var), retval); + + if (0) { + zval_ptr_dtor(&offset); + } else { + + } + } + + zval_dtor(free_op1.var); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12166,7 +13350,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (1) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -15399,7 +16585,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -17745,7 +18933,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -20056,7 +21246,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -23507,7 +24699,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -25143,7 +26337,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -26560,7 +27756,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -27883,7 +29081,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -29629,7 +30829,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -32880,7 +34082,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -34996,7 +36200,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -37171,7 +38377,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -40341,7 +41549,9 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { call->object = NULL; } else { - if (!PZVAL_IS_REF(call->object)) { + if (0) { + MAKE_REAL_ZVAL_PTR(call->object); + } else if (!PZVAL_IS_REF(call->object)) { Z_ADDREF_P(call->object); /* For $this pointer */ } else { zval *this_ptr; @@ -42978,16 +44188,16 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_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_OBJ_R_SPEC_TMP_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER, ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER, ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER, @@ -43178,16 +44388,16 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_IS_SPEC_CV_VAR_HANDLER, ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMP_TMP_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMP_VAR_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_DIM_IS_SPEC_TMP_CV_HANDLER, ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER, ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER, ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER, @@ -43203,16 +44413,16 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_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_OBJ_IS_SPEC_TMP_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER, @@ -43728,11 +44938,11 @@ void zend_init_opcodes_handlers(void) ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER, diff --git a/tests/lang/clone_expr_call.phpt b/tests/lang/clone_expr_call.phpt new file mode 100644 index 000000000000..50850598ac57 --- /dev/null +++ b/tests/lang/clone_expr_call.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test call on a clone expression in parentheses +--FILE-- +bar = 'bar'; + } + + public function bar() { + return $this->bar; + } +} + +$foo = new Foo; +var_dump((clone $foo)->bar); +var_dump((clone $foo)->bar()); + +?> +--EXPECT-- +string(3) "bar" +string(3) "bar"