From: Nikita Popov Date: Thu, 10 Jul 2014 13:51:47 +0000 (+0200) Subject: Port for X-Git-Tag: POST_AST_MERGE^2~158 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3be63fca48b331766224da07ddeb3f0b78ba9704;p=php Port for --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b08d1a94a7..964b048c63 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7116,6 +7116,54 @@ void zend_compile_do_while(zend_ast *ast TSRMLS_DC) { do_end_loop(opnum_cond, 0 TSRMLS_CC); } +void zend_compile_expr_list(znode *result, zend_ast *ast TSRMLS_DC) { + zend_uint i; + + result->op_type = IS_UNUSED; + for (i = 0; i < ast->children; ++i) { + zend_ast *expr_ast = ast->child[i]; + + zend_do_free(result TSRMLS_CC); + zend_compile_expr(result, expr_ast TSRMLS_CC); + } +} + +void zend_compile_for(zend_ast *ast TSRMLS_DC) { + zend_ast *init_ast = ast->child[0]; + zend_ast *cond_ast = ast->child[1]; + zend_ast *loop_ast = ast->child[2]; + zend_ast *stmt_ast = ast->child[3]; + + znode result; + zend_uint opnum_cond, opnum_jmpz, opnum_loop; + zend_op *opline; + + zend_compile_expr_list(&result, init_ast TSRMLS_CC); + zend_do_free(&result TSRMLS_CC); + + opnum_cond = get_next_op_number(CG(active_op_array)); + zend_compile_expr_list(&result, cond_ast TSRMLS_CC); + zend_do_extended_info(TSRMLS_C); + + opnum_jmpz = get_next_op_number(CG(active_op_array)); + emit_op(NULL, ZEND_JMPZ, &result, NULL TSRMLS_CC); + do_begin_loop(TSRMLS_C); + + zend_compile_stmt(stmt_ast TSRMLS_CC); + + opnum_loop = get_next_op_number(CG(active_op_array)); + zend_compile_expr_list(&result, loop_ast TSRMLS_CC); + zend_do_free(&result TSRMLS_CC); + + opline = emit_op(NULL, ZEND_JMP, NULL, NULL TSRMLS_CC); + opline->op1.opline_num = opnum_cond; + + opline = &CG(active_op_array)->opcodes[opnum_jmpz]; + opline->op2.opline_num = get_next_op_number(CG(active_op_array)); + + do_end_loop(opnum_loop, 0 TSRMLS_CC); +} + void zend_compile_stmt_list(zend_ast *ast TSRMLS_DC) { zend_uint i; for (i = 0; i < ast->children; ++i) { @@ -7907,6 +7955,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) { case ZEND_AST_DO_WHILE: zend_compile_do_while(ast TSRMLS_CC); break; + case ZEND_AST_FOR: + zend_compile_for(ast TSRMLS_CC); + break; default: { znode result; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 6879993282..a3bae7f481 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -330,7 +330,7 @@ unticked_statement: | T_DO statement T_WHILE parenthesis_expr ';' { $$.u.ast = zend_ast_create_binary(ZEND_AST_DO_WHILE, $2.u.ast, $4.u.ast); } | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement - { $$.u.ast = NULL; } + { $$.u.ast = zend_ast_create(4, ZEND_AST_FOR, $3.u.ast, $5.u.ast, $7.u.ast, $9.u.ast); } /*| T_FOR '(' for_expr