]> granicus.if.org Git - php/commitdiff
Make unticked_statement an ast node (usually NULL)
authorNikita Popov <nikic@php.net>
Wed, 9 Jul 2014 21:39:21 +0000 (23:39 +0200)
committerNikita Popov <nikic@php.net>
Wed, 9 Jul 2014 21:39:21 +0000 (23:39 +0200)
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_language_parser.y

index b3d696986763c81552119629e8108a743cd7a214..12d51dc13779bf6c006490f9aebf2ee717927552 100644 (file)
@@ -69,6 +69,8 @@ enum _zend_ast_kind {
        ZEND_AST_ARRAY_ELEM,
        ZEND_AST_ENCAPS_LIST,
 
+       ZEND_AST_STMT_LIST,
+
        ZEND_AST_GLOBAL,
        ZEND_AST_UNSET,
        ZEND_AST_RETURN,
@@ -158,7 +160,7 @@ static inline zend_ast *zend_ast_create_assign_op(zend_uint opcode, zend_ast *op
 #define AST_COMPILE_STMT(ast) do { \
        zend_ast *_ast = (ast); \
        zend_compile_stmt(_ast TSRMLS_CC); \
-       zend_ast_destroy(_ast); \
+       if (_ast) zend_ast_destroy(_ast); \
 } while (0)
 
 #define AST_ZNODE(znode) zend_ast_create_znode((znode))
@@ -167,5 +169,6 @@ static inline zend_ast *zend_ast_create_assign_op(zend_uint opcode, zend_ast *op
 #define AC(znode) AST_COMPILE(&znode, znode.u.ast)
 #define AS(znode) AST_COMPILE_STMT(znode.u.ast)
 #define AZ(znode) ((znode).u.ast = AST_ZNODE(&znode))
+#define AN(znode) ((znode).u.ast = NULL)
 
 #endif
index 4d893f777eeb165829f5b71b3ea5500ad305de4f..664883657a764f56f414db6d1a9882519858926d 100644 (file)
@@ -7036,6 +7036,13 @@ void zend_compile_goto(zend_ast *ast TSRMLS_DC) {
        zend_resolve_goto_label(CG(active_op_array), opline, 0 TSRMLS_CC);
 }
 
+void zend_compile_stmt_list(zend_ast *ast TSRMLS_DC) {
+       zend_uint i;
+       for (i = 0; i < ast->children; ++i) {
+               zend_compile_stmt(ast->child[i] TSRMLS_CC);
+       }
+}
+
 void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) {
        zend_ast *left_ast = ast->child[0];
        zend_ast *right_ast = ast->child[1];
@@ -7781,7 +7788,14 @@ void zend_compile_const_expr(zend_ast **ast_ptr TSRMLS_DC) {
 }
 
 void zend_compile_stmt(zend_ast *ast TSRMLS_DC) {
+       if (!ast) {
+               return;
+       }
+
        switch (ast->kind) {
+               case ZEND_AST_STMT_LIST:
+                       zend_compile_stmt_list(ast TSRMLS_CC);
+                       return;
                case ZEND_AST_GLOBAL:
                        zend_compile_global_var(ast TSRMLS_CC);
                        return;
index dbecd9da4afe8d9d4af82972706612ac557da03b..27432886765a6c9e9f3226d4590c762ae5d05d8c 100644 (file)
@@ -317,16 +317,16 @@ inner_statement:
 
 
 statement:
-               unticked_statement { DO_TICKS(); }
+               unticked_statement { AS($$); DO_TICKS(); }
        |       T_STRING ':' { zend_do_label(&$1 TSRMLS_CC); }
 ;
 
 unticked_statement:
-               '{' inner_statement_list '}'
-       |       T_IF parenthesis_expr { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } statement { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
-       |       T_IF parenthesis_expr ':' { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
-       |       T_WHILE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr { AC($3); zend_do_while_cond(&$3, &$$ TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$4 TSRMLS_CC); }
-       |       T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));  zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr ';' { AC($6); zend_do_do_while_end(&$1, &$4, &$6 TSRMLS_CC); }
+               '{' inner_statement_list '}' { AN($$); }
+       |       T_IF parenthesis_expr { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } statement { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); AN($$); }
+       |       T_IF parenthesis_expr ':' { AC($2); zend_do_if_cond(&$2, &$1 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); AN($$); }
+       |       T_WHILE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr { AC($3); zend_do_while_cond(&$3, &$$ TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$4 TSRMLS_CC); AN($$); }
+       |       T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array));  zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr ';' { AC($6); zend_do_do_while_end(&$1, &$4, &$6 TSRMLS_CC); AN($$); }
        |       T_FOR
                        '('
                                for_expr
@@ -335,37 +335,37 @@ unticked_statement:
                        ';' { zend_do_extended_info(TSRMLS_C); zend_do_for_cond(&$6, &$7 TSRMLS_CC); }
                                for_expr
                        ')' { zend_do_free(&$9 TSRMLS_CC); zend_do_for_before_statement(&$4, &$7 TSRMLS_CC); }
-                       for_statement { zend_do_for_end(&$7 TSRMLS_CC); }
-       |       T_SWITCH parenthesis_expr       { AC($2); zend_do_switch_cond(&$2 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$4 TSRMLS_CC); }
-       |       T_BREAK ';'                     { $$.u.ast = zend_ast_create_unary(ZEND_BRK, NULL); AS($$); }
-       |       T_BREAK expr ';'        { $$.u.ast = zend_ast_create_unary(ZEND_BRK, $2.u.ast); AS($$); }
-       |       T_CONTINUE ';'          { $$.u.ast = zend_ast_create_unary(ZEND_CONT, NULL); AS($$); }
-       |       T_CONTINUE expr ';'     { $$.u.ast = zend_ast_create_unary(ZEND_CONT, $2.u.ast); AS($$); }
+                       for_statement { zend_do_for_end(&$7 TSRMLS_CC); AN($$); }
+       |       T_SWITCH parenthesis_expr       { AC($2); zend_do_switch_cond(&$2 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$4 TSRMLS_CC); AN($$); }
+       |       T_BREAK ';'                     { $$.u.ast = zend_ast_create_unary(ZEND_BRK, NULL); }
+       |       T_BREAK expr ';'        { $$.u.ast = zend_ast_create_unary(ZEND_BRK, $2.u.ast); }
+       |       T_CONTINUE ';'          { $$.u.ast = zend_ast_create_unary(ZEND_CONT, NULL); }
+       |       T_CONTINUE expr ';'     { $$.u.ast = zend_ast_create_unary(ZEND_CONT, $2.u.ast); }
        |       T_RETURN ';'
-                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_RETURN, NULL); AS($$); }
+                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_RETURN, NULL); }
        |       T_RETURN expr ';'
-                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_RETURN, $2.u.ast); AS($$); }
-       |       T_GLOBAL global_var_list ';'
-       |       T_STATIC static_var_list ';'
-       |       T_ECHO echo_expr_list ';'
-       |       T_INLINE_HTML { $$.u.ast = zend_ast_create_unary(ZEND_ECHO, AST_ZVAL(&$1)); AS($$); }
-       |       expr ';'                                { AC($1); zend_do_free(&$1 TSRMLS_CC); }
-       |       T_UNSET '(' unset_variables ')' ';'
+                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_RETURN, $2.u.ast); }
+       |       T_GLOBAL global_var_list ';' { $$.u.ast = $2.u.ast; }
+       |       T_STATIC static_var_list ';' { AN($$); }
+       |       T_ECHO echo_expr_list ';' { $$.u.ast = $2.u.ast; }
+       |       T_INLINE_HTML { $$.u.ast = zend_ast_create_unary(ZEND_ECHO, AST_ZVAL(&$1)); }
+       |       expr ';'                                { AC($1); zend_do_free(&$1 TSRMLS_CC); AN($$); }
+       |       T_UNSET '(' unset_variables ')' ';' { $$.u.ast = $3.u.ast; }
        |       T_FOREACH '(' variable T_AS
                { zend_do_foreach_begin(&$1, &$2, &$3, &$4, 1 TSRMLS_CC); }
                foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
-               foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
+               foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); AN($$); }
        |       T_FOREACH '(' expr_without_variable T_AS
                { AC($3); zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
                foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
-               foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
-       |       T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
-       |       ';'             /* empty statement */
+               foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); AN($$); }
+       |       T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); AN($$); }
+       |       ';'     /* empty statement */ { AN($$); }
        |       T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
                catch_statement { zend_do_bind_catch(&$1, &$6 TSRMLS_CC); }
-               finally_statement { zend_do_end_finally(&$1, &$6, &$8 TSRMLS_CC); }
-       |       T_THROW expr ';' { $$.u.ast = zend_ast_create_unary(ZEND_THROW, $2.u.ast); AS($$); }
-       |       T_GOTO T_STRING ';' { $$.u.ast = zend_ast_create_unary(ZEND_GOTO, AST_ZVAL(&$2)); AS($$); }
+               finally_statement { zend_do_end_finally(&$1, &$6, &$8 TSRMLS_CC); AN($$); }
+       |       T_THROW expr ';' { $$.u.ast = zend_ast_create_unary(ZEND_THROW, $2.u.ast); }
+       |       T_GOTO T_STRING ';' { $$.u.ast = zend_ast_create_unary(ZEND_GOTO, AST_ZVAL(&$2)); }
 ;
 
 catch_statement:
@@ -396,13 +396,12 @@ additional_catch:
 ;
 
 unset_variables:
-               unset_variable
-       |       unset_variables ',' unset_variable
+               unset_variable { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.u.ast); }
+       |       unset_variables ',' unset_variable { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
 ;
 
 unset_variable:
-               variable
-                       { $$.u.ast = zend_ast_create_unary(ZEND_AST_UNSET, $1.u.ast); AST_COMPILE_STMT($$.u.ast); }
+               variable { $$.u.ast = zend_ast_create_unary(ZEND_AST_UNSET, $1.u.ast); }
 ;
 
 function_declaration_statement:
@@ -609,13 +608,13 @@ function_call_parameter:
 ;
 
 global_var_list:
-               global_var_list ',' global_var
-       |       global_var
+               global_var_list ',' global_var { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
+       |       global_var { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.u.ast); }
 ;
 
 global_var:
        simple_variable
-               { $$.u.ast = zend_ast_create_unary(ZEND_AST_GLOBAL, $1.u.ast); AST_COMPILE_STMT($$.u.ast); }
+               { $$.u.ast = zend_ast_create_unary(ZEND_AST_GLOBAL, $1.u.ast); }
 ;
 
 
@@ -742,11 +741,11 @@ class_constant_declaration:
 ;
 
 echo_expr_list:
-               echo_expr_list ',' echo_expr
-       |       echo_expr
+               echo_expr_list ',' echo_expr { $$.u.ast = zend_ast_dynamic_add($1.u.ast, $3.u.ast); }
+       |       echo_expr { $$.u.ast = zend_ast_create_dynamic_and_add(ZEND_AST_STMT_LIST, $1.u.ast); }
 ;
 echo_expr:
-       expr { $$.u.ast = zend_ast_create_unary(ZEND_ECHO, $1.u.ast); AS($$); }
+       expr { $$.u.ast = zend_ast_create_unary(ZEND_ECHO, $1.u.ast); }
 ;
 
 for_expr: