From: Nikita Popov Date: Sat, 31 May 2014 15:36:22 +0000 (+0200) Subject: Property handle calls on [] and '' consts/tmps X-Git-Tag: POST_AST_MERGE^2~213 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c53a7ea4e5e70e6f748f5c13f48c24843a0bac45;p=php Property handle calls on [] and '' consts/tmps --- diff --git a/Zend/tests/varSyntax/indirectFcall.phpt b/Zend/tests/varSyntax/indirectFcall.phpt index 4499f5ab64..4cc5c1171a 100644 --- a/Zend/tests/varSyntax/indirectFcall.phpt +++ b/Zend/tests/varSyntax/indirectFcall.phpt @@ -25,6 +25,16 @@ $id($id)('var_dump')(7); return $x ?: $f; })()()()('var_dump')(9); +class Test { + public static function id($x = [__CLASS__, 'id']) { return $x; } +} + +$obj = new Test; +[$obj, 'id']()('id')($id)('var_dump')(10); +['Test', 'id']()()('var_dump')(11); +'id'()('id')('var_dump')(12); +('i' . 'd')()('var_dump')(13); + ?> --EXPECT-- int(0) @@ -37,3 +47,7 @@ int(6) int(7) int(8) int(9) +int(10) +int(11) +int(12) +int(13) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 02698fca18..7040ed6c5a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2018,7 +2018,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->result.num = CG(context).nested_calls; SET_UNUSED(opline->op1); - if (function_name->op_type == IS_CONST) { + if (function_name->op_type == IS_CONST && Z_TYPE(function_name->u.constant) == IS_STRING) { opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC); GET_CACHE_SLOT(opline->op2.constant); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 20d350a892..2bd0280900 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2595,7 +2595,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) zval *function_name_ptr, *function_name, *func; call_slot *call = EX(call_slots) + opline->result.num; - if (OP2_TYPE == IS_CONST) { + if (OP2_TYPE == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) { function_name_ptr = function_name = (zval*)(opline->op2.zv+1); if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) { call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv)); @@ -2667,8 +2667,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (OP2_TYPE != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; zval *method; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c2e103965a..24f016066c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1465,7 +1465,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE zval *function_name_ptr, *function_name, *func; call_slot *call = EX(call_slots) + opline->result.num; - if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) { function_name_ptr = function_name = (zval*)(opline->op2.zv+1); if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) { call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv)); @@ -1536,8 +1536,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_CONST != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; zval *method; @@ -1795,7 +1794,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H zval *function_name_ptr, *function_name, *func; call_slot *call = EX(call_slots) + opline->result.num; - if (IS_TMP_VAR == IS_CONST) { + if (IS_TMP_VAR == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) { function_name_ptr = function_name = (zval*)(opline->op2.zv+1); if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) { call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv)); @@ -1867,8 +1866,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; zval *method; @@ -1984,7 +1982,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zval *function_name_ptr, *function_name, *func; call_slot *call = EX(call_slots) + opline->result.num; - if (IS_VAR == IS_CONST) { + if (IS_VAR == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) { function_name_ptr = function_name = (zval*)(opline->op2.zv+1); if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) { call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv)); @@ -2056,8 +2054,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_VAR != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; zval *method; @@ -2211,7 +2208,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA zval *function_name_ptr, *function_name, *func; call_slot *call = EX(call_slots) + opline->result.num; - if (IS_CV == IS_CONST) { + if (IS_CV == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) { function_name_ptr = function_name = (zval*)(opline->op2.zv+1); if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) { call->fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv)); @@ -2282,8 +2279,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); - } else if (IS_CV != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { zval *obj; zval *method;