{
zend_op *opline;
- if (foreach_copy->op_type!=IS_VAR && foreach_copy->op_type!=IS_TMP_VAR) {
+ if (foreach_copy->op_type != IS_VAR && foreach_copy->op_type != IS_TMP_VAR) {
return 1;
}
{
zend_op *opline;
zend_bool is_variable;
+ zend_bool push_container = 0;
if (variable) {
if (zend_is_function_or_method_call(array)) {
if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) {
/* FIXME: This will cause a leak, we have to unlock at the end of foreach() */
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK;
+ push_container = 1;
}
} else {
is_variable = 0;
*open_brackets_token = opline->result;
zend_stack_push(&CG(foreach_copy_stack), (void *) &opline->result, sizeof(znode));
+ if (push_container) {
+ zend_stack_push(&CG(foreach_copy_stack), (void *) &CG(active_op_array)->opcodes[CG(active_op_array)->last-2].op1, sizeof(znode));
+ } else {
+ znode tmp;
+ tmp.op_type = IS_UNUSED;
+ zend_stack_push(&CG(foreach_copy_stack), (void *) &tmp, sizeof(znode));
+ }
+
/* 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));
void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token TSRMLS_DC)
{
+ znode *container_ptr;
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_JMP;
do_end_loop(foreach_token->u.opline_num TSRMLS_CC);
- generate_free_foreach_copy(open_brackets_token TSRMLS_CC);
+ zend_stack_top(&CG(foreach_copy_stack), &container_ptr);
+ generate_free_foreach_copy(container_ptr TSRMLS_CC);
+ zend_stack_del_top(&CG(foreach_copy_stack));
+ generate_free_foreach_copy(open_brackets_token TSRMLS_CC);
zend_stack_del_top(&CG(foreach_copy_stack));
DEC_BPC(CG(active_op_array));
{
if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
+ EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
}
zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
NEXT_OPCODE();