]> granicus.if.org Git - php/commitdiff
- Cleanup foreach handling
authorMarcus Boerger <helly@php.net>
Fri, 11 Feb 2005 22:26:45 +0000 (22:26 +0000)
committerMarcus Boerger <helly@php.net>
Fri, 11 Feb 2005 22:26:45 +0000 (22:26 +0000)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

index 0d7b6130c4c1243d222ce8bb8a500dd8c4d35734..2750fc8c55868f28233185188675eaec16e6a428 100644 (file)
@@ -3343,7 +3343,7 @@ void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type
 }
 
 
-void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, int variable TSRMLS_DC)
+void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, int variable TSRMLS_DC)
 {
        zend_op *opline;
        zend_bool is_variable;
@@ -3367,6 +3367,9 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack
                is_variable = 0;
        }
 
+       /* save the location of FE_RESET */
+       foreach_token->u.opline_num = get_next_op_number(CG(active_op_array));
+
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
        /* Preform array reset */
@@ -3392,9 +3395,15 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack
                }
                zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
        }
+}
+
+
+void zend_do_foreach_fetch(znode *foreach_token, znode *open_brackets_token, znode *as_token TSRMLS_DC)
+{
+       zend_op *opline;
        
-       /* save the location of the beginning of the loop (array fetching) */
-       opline->op2.u.opline_num = foreach_token->u.opline_num = get_next_op_number(CG(active_op_array));
+       /* save the location of FE_FETCH */
+       as_token->u.opline_num = get_next_op_number(CG(active_op_array));
 
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        opline->opcode = ZEND_FE_FETCH;
@@ -3406,19 +3415,19 @@ void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brack
 
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        opline->opcode = ZEND_OP_DATA;
-       opline->op1.op_type = IS_UNUSED;
-       opline->op2.op_type = IS_UNUSED;
-       opline->result.op_type = IS_UNUSED;
+       SET_UNUSED(opline->op1);
+       SET_UNUSED(opline->op2);
+       SET_UNUSED(opline->result);
 }
 
 
-void zend_do_foreach_cont(znode *value, znode *key, znode *foreach_token TSRMLS_DC)
+void zend_do_foreach_cont(znode *foreach_token, znode *as_token, znode *value, znode *key TSRMLS_DC)
 {
        zend_op *opline;
        znode dummy;
        zend_bool assign_by_ref=0;
 
-       opline = &CG(active_op_array)->opcodes[foreach_token->u.opline_num];
+       opline = &CG(active_op_array)->opcodes[as_token->u.opline_num];
        if (key->op_type != IS_UNUSED) {
                znode *tmp;
 
@@ -3453,7 +3462,7 @@ void zend_do_foreach_cont(znode *value, znode *key, znode *foreach_token TSRMLS_
        }
 
        if (key->op_type != IS_UNUSED) {
-               opline = &CG(active_op_array)->opcodes[foreach_token->u.opline_num+1];
+               opline = &CG(active_op_array)->opcodes[as_token->u.opline_num+1];
                opline->result.op_type = IS_TMP_VAR;
                opline->result.u.EA.type = 0;
                opline->result.u.opline_num = get_temporary_variable(CG(active_op_array));
@@ -3467,20 +3476,20 @@ void zend_do_foreach_cont(znode *value, znode *key, znode *foreach_token TSRMLS_
 }
 
 
-void zend_do_foreach_end(znode *foreach_token TSRMLS_DC)
+void zend_do_foreach_end(znode *foreach_token, znode *as_token TSRMLS_DC)
 {
        zend_op *container_ptr;
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
        opline->opcode = ZEND_JMP;
-       opline->op1.u.opline_num = foreach_token->u.opline_num;
+       opline->op1.u.opline_num = as_token->u.opline_num;
        SET_UNUSED(opline->op1);
        SET_UNUSED(opline->op2);
 
-       CG(active_op_array)->opcodes[foreach_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
-       CG(active_op_array)->opcodes[foreach_token->u.opline_num-1].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
+       CG(active_op_array)->opcodes[foreach_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
+       CG(active_op_array)->opcodes[as_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); /* FE_FETCH */
 
-       do_end_loop(foreach_token->u.opline_num TSRMLS_CC);
+       do_end_loop(as_token->u.opline_num TSRMLS_CC);
 
        zend_stack_top(&CG(foreach_copy_stack), (void **) &container_ptr);
        generate_free_foreach_copy(container_ptr TSRMLS_CC);
index 2bf075317d711a4f3081028f6c7fb8e27e94c78b..a154e42c5f69b304108c785a1cb3db73c79f300a 100644 (file)
@@ -461,9 +461,10 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
 
 void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC);
 
-void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, int variable TSRMLS_DC);
-void zend_do_foreach_cont(znode *value, znode *key, znode *foreach_token TSRMLS_DC);
-void zend_do_foreach_end(znode *foreach_token TSRMLS_DC);
+void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, int variable TSRMLS_DC);
+void zend_do_foreach_fetch(znode *foreach_token, znode *open_brackets_token, znode *as_token TSRMLS_DC);
+void zend_do_foreach_cont(znode *foreach_token, znode *as_token, znode *value, znode *key TSRMLS_DC);
+void zend_do_foreach_end(znode *foreach_token, znode *as_token TSRMLS_DC);
 
 void zend_do_declare_begin(TSRMLS_D);
 void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
index 353d712eda0b302b0d6a5d759b2ed29a5d0cf5bf..99be83a078a0a13bde5b92e5b1b81462d39f8924 100644 (file)
@@ -209,8 +209,14 @@ unticked_statement:
        |       expr ';'                                { zend_do_free(&$1 TSRMLS_CC); }
        |       T_USE use_filename ';'          { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()");  zval_dtor(&$2.u.constant); }
        |       T_UNSET '(' unset_variables ')' ';'
-       |       T_FOREACH '(' variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, 1 TSRMLS_CC); } foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1 TSRMLS_CC); }
-       |       T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, 0 TSRMLS_CC); } w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1 TSRMLS_CC); }
+       |       T_FOREACH '(' variable { zend_do_foreach_begin(&$1, &$2, &$3, 1 TSRMLS_CC); } T_AS 
+               { zend_do_foreach_fetch(&$1, &$2, &$5 TSRMLS_CC); } 
+               foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$5, &$7, &$8 TSRMLS_CC); } 
+               foreach_statement { zend_do_foreach_end(&$1, &$5 TSRMLS_CC); }
+       |       T_FOREACH '(' expr_without_variable { zend_do_foreach_begin(&$1, &$2, &$3, 0 TSRMLS_CC); } T_AS 
+               { zend_do_foreach_fetch(&$1, &$2, &$5 TSRMLS_CC); } 
+               w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$5, &$7, &$8 TSRMLS_CC); } 
+               foreach_statement { zend_do_foreach_end(&$1, &$5 TSRMLS_CC); }
        |       T_DECLARE { $1.u.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 */
        |       T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'