From 1de1bc96a5b281e9ba764b99bb2a487975806cbc Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 10 Jul 2014 00:00:48 +0200 Subject: [PATCH] Make statement asty --- Zend/zend_compile.c | 35 ++++++++++++++++++++++++++--------- Zend/zend_language_parser.y | 24 ++++++++++++------------ 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 83caf8f07f..294ce9b9a7 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6043,6 +6043,15 @@ static zend_op *emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, znode return opline; } +static void zend_emit_tick(TSRMLS_D) { + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + opline->opcode = ZEND_TICKS; + SET_UNUSED(opline->op1); + SET_UNUSED(opline->op2); + opline->extended_value = Z_LVAL(CG(declarables).ticks); +} + static zend_bool zend_is_variable(zend_ast *ast) { return ast->kind == ZEND_AST_VAR || ast->kind == ZEND_AST_DIM || ast->kind == ZEND_AST_PROP || ast->kind == ZEND_AST_STATIC_PROP @@ -6056,6 +6065,10 @@ static zend_bool zend_is_call(zend_ast *ast) { || ast->kind == ZEND_AST_STATIC_CALL; } +static zend_bool zend_is_unticked_stmt(zend_ast *ast) { + return ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_LABEL; +} + static zend_bool zend_can_write_to_variable(zend_ast *ast) { while (ast->kind == ZEND_AST_DIM || ast->kind == ZEND_AST_PROP) { ast = ast->child[0]; @@ -7814,34 +7827,38 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) { switch (ast->kind) { case ZEND_AST_STMT_LIST: zend_compile_stmt_list(ast TSRMLS_CC); - return; + break; case ZEND_AST_GLOBAL: zend_compile_global_var(ast TSRMLS_CC); - return; + break; case ZEND_AST_UNSET: zend_compile_unset(ast TSRMLS_CC); - return; + break; case ZEND_AST_RETURN: zend_compile_return(ast TSRMLS_CC); - return; + break; case ZEND_ECHO: zend_compile_echo(ast TSRMLS_CC); - return; + break; case ZEND_THROW: zend_compile_throw(ast TSRMLS_CC); - return; + break; case ZEND_BRK: case ZEND_CONT: zend_compile_break_continue(ast TSRMLS_CC); - return; + break; case ZEND_GOTO: zend_compile_goto(ast TSRMLS_CC); - return; + break; case ZEND_AST_LABEL: zend_compile_label(ast TSRMLS_CC); - return; + break; EMPTY_SWITCH_DEFAULT_CASE() } + + if (Z_LVAL(CG(declarables).ticks) && !zend_is_unticked_stmt(ast)) { + zend_emit_tick(TSRMLS_C); + } } void zend_compile_expr(znode *result, zend_ast *ast TSRMLS_DC) { diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index e3cd937824..f5ea217a1a 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -246,7 +246,7 @@ name: ; top_statement: - statement { zend_verify_namespace(TSRMLS_C); } + statement { AS($1); zend_verify_namespace(TSRMLS_C); } | function_declaration_statement { zend_verify_namespace(TSRMLS_C); zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_verify_namespace(TSRMLS_C); zend_do_early_binding(TSRMLS_C); } | T_HALT_COMPILER '(' ')' ';' { zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } @@ -309,7 +309,7 @@ inner_statement_list: inner_statement: - statement + statement { AS($1); } | function_declaration_statement | class_declaration_statement | T_HALT_COMPILER '(' ')' ';' { zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } @@ -317,16 +317,16 @@ inner_statement: statement: - unticked_statement { AS($$); DO_TICKS(); } - | T_STRING ':' { $$.u.ast = zend_ast_create_unary(ZEND_AST_LABEL, AST_ZVAL(&$1)); AS($$); } + unticked_statement { $$.u.ast = $1.u.ast; } + | T_STRING ':' { $$.u.ast = zend_ast_create_unary(ZEND_AST_LABEL, AST_ZVAL(&$1)); } ; unticked_statement: '{' 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); } statement { AS($4); 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_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { AS($3); $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 @@ -487,19 +487,19 @@ foreach_variable: ; for_statement: - statement + statement { AS($1); } | ':' inner_statement_list T_ENDFOR ';' ; foreach_statement: - statement + statement { AS($1); } | ':' inner_statement_list T_ENDFOREACH ';' ; declare_statement: - statement + statement { AS($1); } | ':' inner_statement_list T_ENDDECLARE ';' ; @@ -532,7 +532,7 @@ case_separator: while_statement: - statement + statement { AS($1); } | ':' inner_statement_list T_ENDWHILE ';' ; @@ -540,7 +540,7 @@ while_statement: elseif_list: /* empty */ - | elseif_list T_ELSEIF parenthesis_expr { AC($3); zend_do_if_cond(&$3, &$2 TSRMLS_CC); } statement { zend_do_if_after_statement(&$2, 0 TSRMLS_CC); } + | elseif_list T_ELSEIF parenthesis_expr { AC($3); zend_do_if_cond(&$3, &$2 TSRMLS_CC); } statement { AS($5); zend_do_if_after_statement(&$2, 0 TSRMLS_CC); } ; @@ -552,7 +552,7 @@ new_elseif_list: else_single: /* empty */ - | T_ELSE statement + | T_ELSE statement { AS($2); } ; -- 2.50.1