]> granicus.if.org Git - php/commitdiff
Fix complex expressions for class names in NEW
authorZeev Suraski <zeev@php.net>
Sun, 22 Jun 2003 10:50:43 +0000 (10:50 +0000)
committerZeev Suraski <zeev@php.net>
Sun, 22 Jun 2003 10:50:43 +0000 (10:50 +0000)
Zend/zend_execute.c
Zend/zend_language_parser.y

index 830d59f3591557769f7b1e3ea6d520fff1141a2e..4d065eeda2fc79ea1cdbba04fd60e0098fb1b92d 100644 (file)
@@ -2393,7 +2393,7 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
        } else {
                EX_T(EX(opline)->result.u.var).EA.class_entry = ce;
        }
-       if (!is_const) {
+       if (!is_const && !ce) {
                efree(class_name_strval);
                FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
        }
index 5d8a9d28e54c215945ccdd0db7fb7137975b5428..2e4b5a7dec9ec8ca963db4b6cd474f9c0e060750 100644 (file)
@@ -515,8 +515,8 @@ 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_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
        |       variable '=' '&' variable { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
-       |       variable '=' '&' T_NEW dynamic_class_name { zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
-       |       T_NEW dynamic_class_name { 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);}
+       |       variable '=' '&' T_NEW class_name_reference { zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+       |       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);}
        |       variable T_PLUS_EQUAL expr      { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
        |       variable T_MINUS_EQUAL expr     { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 TSRMLS_CC); }
        |       variable T_MUL_EQUAL expr               { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 TSRMLS_CC); }
@@ -560,7 +560,7 @@ expr_without_variable:
        |       expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
        |       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 dynamic_class_name { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
+       |       expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
        |       '(' expr ')'    { $$ = $2; }
        |       expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
                expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); }
@@ -597,9 +597,28 @@ fully_qualified_class_name:
                T_STRING { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
 ;
 
-dynamic_class_name:
-               T_STRING                                                        { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
-       |       r_variable_without_static_member        { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+class_name_reference:
+               T_STRING                                { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+       |       dynamic_class_name_reference    { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
+;
+
+
+dynamic_class_name_reference:
+               base_variable T_OBJECT_OPERATOR { zend_do_push_object(&$1 TSRMLS_CC); }
+                       object_property { zend_do_push_object(&$4 TSRMLS_CC); zend_do_declare_implicit_property(TSRMLS_C); } dynamic_class_name_variable_properties
+                       { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_MEMBER; }
+       |       base_variable { $$ = $1; }
+;
+
+
+dynamic_class_name_variable_properties:
+               dynamic_class_name_variable_properties dynamic_class_name_variable_property
+       |       /* empty */
+;
+
+
+dynamic_class_name_variable_property:
+               T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); zend_do_declare_implicit_property(TSRMLS_C); }
 ;
 
 exit_expr:
@@ -719,18 +738,13 @@ rw_variable:
                                { zend_check_writable_variable(&$1); }
 ;
 
-r_variable_without_static_member:
-               variable_without_objects { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
-;
-
 variable:
-               base_variable_without_objects T_OBJECT_OPERATOR { zend_do_push_object(&$1 TSRMLS_CC); }
+               base_variable_with_function_calls T_OBJECT_OPERATOR { zend_do_push_object(&$1 TSRMLS_CC); }
                        object_property { zend_do_push_object(&$4 TSRMLS_CC); } method_or_not variable_properties
                        { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = $1.u.EA.type | ($7.u.EA.type ? $7.u.EA.type : $6.u.EA.type); }
-       |       base_variable_without_objects { $$ = $1; }
+       |       base_variable_with_function_calls { $$ = $1; }
 ;
 
-
 variable_properties:
                variable_properties variable_property { $$.u.EA.type = $2.u.EA.type; }
        |       /* empty */ { $$.u.EA.type = 0; }
@@ -759,13 +773,18 @@ static_member:
 ;
 
 
-base_variable_without_objects:
+base_variable_with_function_calls:
+               base_variable           { $$ = $1; }
+       |       function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.u.EA.type = ZEND_PARSED_FUNCTION_CALL; }
+;
+
+
+base_variable:
                reference_variable { $$ = $1; $$.u.EA.type = ZEND_PARSED_VARIABLE; }
        |       simple_indirect_reference reference_variable { zend_do_indirect_references(&$$, &$1, &$2 TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_VARIABLE; }
        |       static_member { $$ = $1; $$.u.EA.type = ZEND_PARSED_STATIC_MEMBER; }
-       |       function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.u.EA.type = ZEND_PARSED_FUNCTION_CALL; }
 ;
-
+       
 reference_variable:
                reference_variable '[' dim_offset ']'   { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
        |       reference_variable '{' expr '}'         { fetch_string_offset(&$$, &$1, &$3 TSRMLS_CC); }