]> granicus.if.org Git - php/commitdiff
- Fix bug #27669 (Dmitry).
authorAndi Gutmans <andi@php.net>
Thu, 16 Sep 2004 00:40:38 +0000 (00:40 +0000)
committerAndi Gutmans <andi@php.net>
Thu, 16 Sep 2004 00:40:38 +0000 (00:40 +0000)
Fixes:
<?
        class A
        {
                function hello()
                {
                        echo "Hello World\n";
                }
        }
        $y[0] = 'hello';
        A::$y[0]();
?>

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

index 0e9ae9eafd8d6e4f3a4d1a5e8ce18640402e533a..c2e8c11aaa15c0ba2ce0a12fc95854ca46da56c5 100644 (file)
@@ -1311,36 +1311,27 @@ void zend_do_fetch_class_name(znode *result, znode *class_name_entry, znode *cla
        result->u.constant.value.str.len = length;
 }
 
-void zend_do_begin_class_member_function_call(TSRMLS_D)
+void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC)
 {
        unsigned char *ptr = NULL;
-       long fetch_const_op_number = get_next_op_number(CG(active_op_array));
-       zend_op *last_op = &CG(active_op_array)->opcodes[fetch_const_op_number-1];
-
-       if (last_op->opcode == ZEND_FETCH_CONSTANT) { /* regular method call */
-               /* a tmp var is leaked here */
-               last_op->opcode = ZEND_INIT_STATIC_METHOD_CALL;
-               if(last_op->op2.op_type == IS_CONST &&
-                  (sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(last_op->op2.u.constant) &&
-                  memcmp(Z_STRVAL(last_op->op2.u.constant), ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
-                       zval_dtor(&last_op->op2.u.constant);
-                       SET_UNUSED(last_op->op2);
+       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+       opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
+       opline->op1 = *class_name;
+       opline->op2 = *method_name;
+
+       if (opline->op2.op_type == IS_CONST) {
+               if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(opline->op2.u.constant) &&
+                   memcmp(Z_STRVAL(opline->op2.u.constant), ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
+                       zval_dtor(&opline->op2.u.constant);
+                       SET_UNUSED(opline->op2);
                } else {
-                       zend_lowercase_znode_if_const(&last_op->op2);
+                       zend_str_tolower(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len);
                }
-       } else if (last_op->opcode == ZEND_FETCH_R) { /* indirect method call */
-               zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-               last_op->op2.u.EA.type = ZEND_FETCH_LOCAL;
-               opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
-               opline->op1 = last_op->op2;
-               opline->op2 = last_op->result;
-       } else {
-               zend_error(E_COMPILE_ERROR, "Internal compiler error - please report!");
        }
 
-
        zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
+       zend_do_extended_fcall_begin(TSRMLS_C);
 }
 
 
index 7e6884c060e62fbeefce7b67ba056a7d7c29712a..9f595d4620b54e0e50cab5fc24778c6b33141040 100644 (file)
@@ -374,7 +374,7 @@ void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
 void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
 void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
 void zend_do_fetch_class_name(znode *result, znode *class_entry, znode *class_name TSRMLS_DC);
-void zend_do_begin_class_member_function_call(TSRMLS_D);
+void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
 void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
 void zend_do_handle_exception(TSRMLS_D);
index 6d85f8be7a8745c1289742d1f41bc4888fb25fac..77dc1d0d6586e72415c4bee1ec7b0a11507d1b43 100644 (file)
@@ -614,12 +614,12 @@ function_call:
                T_STRING        '(' { $2.u.opline_num = zend_do_begin_function_call(&$1 TSRMLS_CC); }
                                function_call_parameter_list
                                ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
-       |       class_constant '(' { zend_do_begin_class_member_function_call(TSRMLS_C); zend_do_extended_fcall_begin(TSRMLS_C); } 
+       |       fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_C); } 
                        function_call_parameter_list 
-                       ')' { zend_do_end_function_call(NULL, &$$, &$4, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
-       |       static_member '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(TSRMLS_C); zend_do_extended_fcall_begin(TSRMLS_C); } 
+                       ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+       | fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_C); } 
                        function_call_parameter_list 
-                       ')' { zend_do_end_function_call(NULL, &$$, &$4, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+                       ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
        |       variable_without_objects  '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1 TSRMLS_CC); }
                        function_call_parameter_list ')'
                        { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}