Removed temorary array creation on each iteration.
}
-void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable TSRMLS_DC)
+void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, int variable TSRMLS_DC)
{
zend_op *opline;
zend_bool is_variable;
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_FE_FETCH;
- 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 = *open_brackets_token;
opline->extended_value = 0;
SET_UNUSED(opline->op2);
- *as_token = opline->result;
+
+ 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;
}
-void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode *foreach_token TSRMLS_DC)
+void zend_do_foreach_cont(znode *value, znode *key, znode *foreach_token TSRMLS_DC)
{
zend_op *opline;
- znode result_value, result_key, dummy;
+ znode dummy;
zend_bool assign_by_ref=0;
+ opline = &CG(active_op_array)->opcodes[foreach_token->u.opline_num];
if (key->op_type != IS_UNUSED) {
znode *tmp;
value = tmp;
/* Mark extended_value in case both key and value are being used */
- CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value |= ZEND_FE_FETCH_WITH_KEY;
+ opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
}
if ((key->op_type != IS_UNUSED) && (key->u.EA.type & ZEND_PARSED_REFERENCE_VARIABLE)) {
zend_error(E_COMPILE_ERROR, "Key element cannot be a reference");
}
-
+
if (value->u.EA.type & ZEND_PARSED_REFERENCE_VARIABLE) {
assign_by_ref = 1;
- if (!CG(active_op_array)->opcodes[foreach_token->u.opline_num-1].extended_value) {
+ if (!(opline-1)->extended_value) {
zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression");
}
/* Mark extended_value for assign-by-reference */
- CG(active_op_array)->opcodes[foreach_token->u.opline_num].extended_value |= ZEND_FE_FETCH_BYREF;
- }
-
- if (key->op_type != IS_UNUSED) {
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
- opline->result.op_type = IS_VAR;
- opline->result.u.EA.type = 0;
- opline->result.u.opline_num = get_temporary_variable(CG(active_op_array));
- opline->op1 = *as_token;
- opline->op2.op_type = IS_CONST;
- opline->op2.u.constant.type = IS_LONG;
- opline->op2.u.constant.value.lval = 0;
- opline->extended_value = ZEND_FETCH_STANDARD; /* ignored in fetch_dim_tmp_var, but what the hell. */
- result_value = opline->result;
-
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
- opline->result.op_type = IS_VAR;
- opline->result.u.EA.type = 0;
- opline->result.u.opline_num = get_temporary_variable(CG(active_op_array));
- opline->op1 = *as_token;
- opline->op2.op_type = IS_CONST;
- opline->op2.u.constant.type = IS_LONG;
- opline->op2.u.constant.value.lval = 1;
- opline->extended_value = ZEND_FETCH_STANDARD; /* ignored in fetch_dim_tmp_var, but what the hell. */
- result_key = opline->result;
- } else {
- result_value = CG(active_op_array)->opcodes[foreach_token->u.opline_num].result;
+ opline->extended_value |= ZEND_FE_FETCH_BYREF;
}
if (assign_by_ref) {
- if (key->op_type == IS_UNUSED) {
- /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
- CG(active_op_array)->opcodes[foreach_token->u.opline_num].result.op_type = IS_VAR;
- zend_do_assign_ref(NULL, value, &CG(active_op_array)->opcodes[foreach_token->u.opline_num].result TSRMLS_CC);
- } else {
- zend_do_assign_ref(NULL, value, &result_value TSRMLS_CC);
- }
+ /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
+ zend_do_assign_ref(NULL, value, &opline->result TSRMLS_CC);
} else {
- zend_do_assign(&dummy, value, &result_value TSRMLS_CC);
+ zend_do_assign(&dummy, value, &opline->result TSRMLS_CC);
+ zend_do_free(&dummy TSRMLS_CC);
}
- CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
+
if (key->op_type != IS_UNUSED) {
- zend_do_assign(&dummy, key, &result_key TSRMLS_CC);
- CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
- zend_do_free(as_token TSRMLS_CC);
+ ++opline;
+ 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));
+
+ zend_do_assign(&dummy, key, &opline->result TSRMLS_CC);
+ zend_do_free(&dummy TSRMLS_CC);
}
do_begin_loop(TSRMLS_C);
}
-void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token TSRMLS_DC)
+void zend_do_foreach_end(znode *foreach_token TSRMLS_DC)
{
zend_op *container_ptr;
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
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, znode *as_token, int variable TSRMLS_DC);
-void zend_do_foreach_cont(znode *value, znode *key, znode *as_token, znode *foreach_token TSRMLS_DC);
-void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token 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_declare_begin(TSRMLS_D);
void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC);
| 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, &$4, 1 TSRMLS_CC); } foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
- | T_FOREACH '(' expr_without_variable T_AS { zend_do_foreach_begin(&$1, &$3, &$2, &$4, 0 TSRMLS_CC); } w_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$6, &$7, &$4, &$1 TSRMLS_CC); } foreach_statement { zend_do_foreach_end(&$1, &$2 TSRMLS_CC); }
+ | 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_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 '}'
zend_op *opline = EX(opline);
zend_free_op free_op1;
zval *array = GET_OP1_ZVAL_PTR(BP_VAR_R);
- zval **value, *key;
+ zval **value;
char *str_key;
uint str_key_len;
ulong int_key;
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
SEPARATE_ZVAL_IF_NOT_REF(value);
(*value)->is_ref = 1;
- }
-
- if (!use_key) {
- if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
- EX_T(opline->result.u.var).var.ptr_ptr = value;
- (*value)->refcount++;
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
- *result = **value;
- zval_copy_ctor(result);
- }
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
(*value)->refcount++;
+ } else {
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
+ PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+ AI_USE_PTR(EX_T(opline->result.u.var).var);
+ }
- array_init(result);
-
- zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
-
- ALLOC_ZVAL(key);
- INIT_PZVAL(key);
+ if (use_key) {
+ zend_op *op_data = opline+1;
+ zval *key = &EX_T(op_data->result.u.var).tmp_var;
switch (key_type) {
case HASH_KEY_IS_STRING:
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
- zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
}
+ ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
zend_op *opline = EX(opline);
zend_free_op free_op1;
zval *array = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- zval **value, *key;
+ zval **value;
char *str_key;
uint str_key_len;
ulong int_key;
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
SEPARATE_ZVAL_IF_NOT_REF(value);
(*value)->is_ref = 1;
- }
-
- if (!use_key) {
- if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
- EX_T(opline->result.u.var).var.ptr_ptr = value;
- (*value)->refcount++;
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
- *result = **value;
- zval_copy_ctor(result);
- }
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
(*value)->refcount++;
+ } else {
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
+ PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+ AI_USE_PTR(EX_T(opline->result.u.var).var);
+ }
- array_init(result);
-
- zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
-
- ALLOC_ZVAL(key);
- INIT_PZVAL(key);
+ if (use_key) {
+ zend_op *op_data = opline+1;
+ zval *key = &EX_T(op_data->result.u.var).tmp_var;
switch (key_type) {
case HASH_KEY_IS_STRING:
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
- zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
}
+ ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}
zend_op *opline = EX(opline);
zend_free_op free_op1;
zval *array = get_zval_ptr(&opline->op1, EX(Ts), &free_op1, BP_VAR_R);
- zval **value, *key;
+ zval **value;
char *str_key;
uint str_key_len;
ulong int_key;
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
SEPARATE_ZVAL_IF_NOT_REF(value);
(*value)->is_ref = 1;
- }
-
- if (!use_key) {
- if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
- EX_T(opline->result.u.var).var.ptr_ptr = value;
- (*value)->refcount++;
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
- *result = **value;
- zval_copy_ctor(result);
- }
- } else {
- zval *result = &EX_T(opline->result.u.var).tmp_var;
-
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
(*value)->refcount++;
+ } else {
+ EX_T(opline->result.u.var).var.ptr_ptr = value;
+ PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+ AI_USE_PTR(EX_T(opline->result.u.var).var);
+ }
- array_init(result);
-
- zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
-
- ALLOC_ZVAL(key);
- INIT_PZVAL(key);
+ if (use_key) {
+ zend_op *op_data = opline+1;
+ zval *key = &EX_T(op_data->result.u.var).tmp_var;
switch (key_type) {
case HASH_KEY_IS_STRING:
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
- zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
}
+ ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
}