]> granicus.if.org Git - php/commitdiff
- Make foreach() now copy the array but use the original array. It can
authorAndi Gutmans <andi@php.net>
Mon, 24 Jan 2000 19:04:07 +0000 (19:04 +0000)
committerAndi Gutmans <andi@php.net>
Mon, 24 Jan 2000 19:04:07 +0000 (19:04 +0000)
  still be optimized A LOT but it's only a performance issue and not
  a feature issue.

Zend/zend_compile.c
Zend/zend_execute.c

index 664141093d515069720090558c11d393c15ba160..87fe4886d064740b1858934f4b48d64b159a66d5 100644 (file)
@@ -950,6 +950,7 @@ static int generate_free_switch_expr(zend_switch_entry *switch_entry CLS_DC)
        opline->opcode = ZEND_SWITCH_FREE;
        opline->op1 = switch_entry->cond;
        SET_UNUSED(opline->op2);
+       opline->extended_value = 0;
        return 0;
 }
 
@@ -963,9 +964,10 @@ static int generate_free_foreach_copy(znode *foreach_copy CLS_DC)
 
        opline = get_next_op(CG(active_op_array) CLS_CC);
 
-       opline->opcode = ZEND_FREE;
+       opline->opcode = ZEND_SWITCH_FREE;
        opline->op1 = *foreach_copy;
        SET_UNUSED(opline->op2);
+       opline->extended_value = 1;
        return 0;
 }
 
@@ -1950,7 +1952,7 @@ void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_t
 
        /* Preform array reset */
        opline->opcode = ZEND_FE_RESET;
-       opline->result.op_type = IS_TMP_VAR;
+       opline->result.op_type = IS_VAR;
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->op1 = *array;
        SET_UNUSED(opline->op2);
@@ -2036,7 +2038,7 @@ void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC)
 
        do_end_loop(foreach_token->u.opline_num CLS_CC);
 
-       do_free(open_brackets_token CLS_CC);
+       generate_free_foreach_copy(open_brackets_token CLS_CC);
 
        zend_stack_del_top(&CG(foreach_copy_stack));
 
index 0b15b0f8816547c80626ae37ce59dda8ec3edf65..380ba616274eb3c85458fe68a5f39327151ebc0d 100644 (file)
@@ -255,6 +255,9 @@ static inline void zend_switch_free(zend_op *opline, temp_variable *Ts ELS_DC)
                                FREE_OP(&opline->op1, EG(free_op1));
                        } else {
                                zval_ptr_dtor(&Ts[opline->op1.u.var].var.ptr);
+                               if (opline->extended_value) { /* foreach() free */
+                                       zval_ptr_dtor(&Ts[opline->op1.u.var].var.ptr);
+                               }
                        }
                        break;
                case IS_TMP_VAR:
@@ -2093,11 +2096,20 @@ send_by_ref:
                        case ZEND_FE_RESET: {
                                        zval *array = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
 
-                                       Ts[opline->result.u.var].tmp_var = *array;
-                                       array = &Ts[opline->result.u.var].tmp_var;
-                                       if (!EG(free_op1)) {
-                                               zval_copy_ctor(array);
+                                       if (EG(free_op1)) { /* If TMP_VAR then make it a VAR */
+                                               zval *tmp;
+
+                                               ALLOC_ZVAL(tmp);
+                                               *tmp = *array;
+                                               INIT_PZVAL(tmp);
+                                               array = tmp;
+                                       } else {
+                                               array->refcount++;
                                        }
+                                       PZVAL_LOCK(array);
+                                       Ts[opline->result.u.var].var.ptr = array;
+                                       Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr;       
+
                                        if (array->type == IS_ARRAY) {
                                                /* probably redundant */
                                                zend_hash_internal_pointer_reset(array->value.ht);
@@ -2113,6 +2125,8 @@ send_by_ref:
                                        char *str_key;
                                        ulong int_key;
 
+                                       PZVAL_LOCK(array);
+
                                        if (array->type != IS_ARRAY) {
                                                zend_error(E_WARNING, "Non array argument supplied for foreach()");
                                                opline = op_array->opcodes+opline->op2.u.opline_num;