Make unticked_statement an ast node (usually NULL)

This commit is contained in:
Nikita Popov 2014-07-09 23:39:21 +02:00
parent fc541418f2
commit d14b763bb9
3 changed files with 54 additions and 38 deletions

View 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

View 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;

View 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: