]> granicus.if.org Git - php/commitdiff
Property handle calls on [] and '' consts/tmps
authorNikita Popov <nikic@php.net>
Sat, 31 May 2014 15:36:22 +0000 (17:36 +0200)
committerNikita Popov <nikic@php.net>
Sat, 31 May 2014 15:37:30 +0000 (17:37 +0200)
Zend/tests/varSyntax/indirectFcall.phpt
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 4499f5ab641d1dff3c8716acd1ef82be1cf6fc46..4cc5c1171a99369455dc3f730ed2ef278bd7ebc2 100644 (file)
@@ -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)
index 02698fca18f14408ba8aa707398b4cd642fee4fe..7040ed6c5aa7cd55dfd7b0fb09f2a72bbcf48e9a 100644 (file)
@@ -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);
index 20d350a892387e4d5f832a2d601f9dfdcfaa5d90..2bd02809007218948b0e33980ff218b0ef70cdb9 100644 (file)
@@ -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;
index c2e103965a48efb7de3a700b4b6460861428020b..24f016066cbec9a4e483576632df635aa864fcc4 100644 (file)
@@ -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;