]> granicus.if.org Git - php/commitdiff
@ Fix problem with nested foreach()'s (Andi, Zend Engine)
authorAndi Gutmans <andi@php.net>
Thu, 10 Aug 2000 22:08:02 +0000 (22:08 +0000)
committerAndi Gutmans <andi@php.net>
Thu, 10 Aug 2000 22:08:02 +0000 (22:08 +0000)
Zend/zend-parser.y
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c

index 482e72267b793ade5807b653583b70e1b820b016..bf7d7261ca9ce08d118008120cd55fbae39b8ed9 100644 (file)
@@ -197,7 +197,8 @@ unticked_statement:
        |       expr ';'                                { do_free(&$1 CLS_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 '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
+       |       T_FOREACH '(' w_cvar T_AS { do_foreach_begin(&$1, &$3, &$2, &$4, 1 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
+       |       T_FOREACH '(' expr_without_variable T_AS { do_foreach_begin(&$1, &$3, &$2, &$4, 0 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
        |       T_DECLARE { do_declare_begin(CLS_C); } '(' declare_list ')' declare_statement { do_declare_end(CLS_C); }
        |       ';'             /* empty statement */
 ;
index 0629190e22267c7dd11b1eae7fbda9760ef3021c..e76e542ba8df8c7ba5e9f8a101fbd8abfad89f74 100644 (file)
@@ -2012,7 +2012,7 @@ void do_isset_or_isempty(int type, znode *result, znode *variable CLS_DC)
 }
 
 
-void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token CLS_DC)
+void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable CLS_DC)
 {
        zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
 
@@ -2022,6 +2022,11 @@ void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_t
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->op1 = *array;
        SET_UNUSED(opline->op2);
+       if (variable) {
+               opline->extended_value = 1;
+       } else {
+               opline->extended_value = 0;
+       }
        *open_brackets_token = opline->result;
 
        zend_stack_push(&CG(foreach_copy_stack), (void *) &opline->result, sizeof(znode));
index 67a49711feaf4d6200a1d2cf7ac1ea027745d0ec..bb49951afb7bdab9817de28bd16f943d218b98b4 100644 (file)
@@ -344,7 +344,7 @@ void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC);
 void do_unset(znode *variable CLS_DC);
 void do_isset_or_isempty(int type, znode *result, znode *variable CLS_DC);
 
-void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token CLS_DC);
+void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable CLS_DC);
 void do_foreach_cont(znode *value, znode *key, znode *as_token CLS_DC);
 void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC);
 
index fbb77e376519e3ec4d7fa1fc98bfe44244aff56b..1017543cf38ae58f189ec41ba72006339b3b4ff6 100644 (file)
@@ -2131,22 +2131,27 @@ send_by_ref:
                                }
                                NEXT_OPCODE();
                        case ZEND_FE_RESET: {
-                                       zval *array_ptr;
+                                       zval *array_ptr, **array_ptr_ptr;
                                        HashTable *fe_ht;
                                        
-                                       array_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
-
-                                       if (EG(free_op1)) { /* IS_TMP_VAR */
-                                               zval *tmp;
-
-                                               ALLOC_ZVAL(tmp);
-                                               *tmp = *array_ptr;
-                                               INIT_PZVAL(tmp);
-                                               array_ptr = tmp;
-                                       } else {
+                                       if (opline->extended_value) {
+                                               array_ptr_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R);
+                                               SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
+                                               array_ptr = *array_ptr_ptr;
                                                array_ptr->refcount++;
+                                       } else {
+                                               array_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
+                                               if (EG(free_op1)) { /* IS_TMP_VAR */
+                                                       zval *tmp;
+
+                                                       ALLOC_ZVAL(tmp);
+                                                       *tmp = *array_ptr;
+                                                       INIT_PZVAL(tmp);
+                                                       array_ptr = tmp;
+                                               } else {
+                                                       array_ptr->refcount++;
+                                               }
                                        }
-
                                        PZVAL_LOCK(array_ptr);
                                        Ts[opline->result.u.var].var.ptr = array_ptr;
                                        Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr;