array_pair_list:
- /* empty */ { do_init_array(&$$, NULL, NULL CLS_CC); }
+ /* empty */ { do_init_array(&$$, NULL, NULL, 0 CLS_CC); }
| non_empty_array_pair_list { $$ = $1; }
;
non_empty_array_pair_list:
- non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr { do_add_array_element(&$$, &$5, &$3 CLS_CC); }
- | non_empty_array_pair_list ',' expr { do_add_array_element(&$$, &$3, NULL CLS_CC); }
- | expr T_DOUBLE_ARROW expr { do_init_array(&$$, &$3, &$1 CLS_CC); }
- | expr { do_init_array(&$$, &$1, NULL CLS_CC); }
+ non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr { do_add_array_element(&$$, &$5, &$3, 0 CLS_CC); }
+ | non_empty_array_pair_list ',' expr { do_add_array_element(&$$, &$3, NULL, 0 CLS_CC); }
+ | expr T_DOUBLE_ARROW expr { do_init_array(&$$, &$3, &$1, 0 CLS_CC); }
+ | expr { do_init_array(&$$, &$1, NULL, 0 CLS_CC); }
+ | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_cvar { do_add_array_element(&$$, &$6, &$3, 1 CLS_CC); }
+ | non_empty_array_pair_list ',' '&' w_cvar { do_add_array_element(&$$, &$4, NULL, 1 CLS_CC); }
+ | expr T_DOUBLE_ARROW '&' w_cvar { do_init_array(&$$, &$4, &$1, 1 CLS_CC); }
+ | '&' w_cvar { do_init_array(&$$, &$2, NULL, 1 CLS_CC); }
;
-
encaps_list:
encaps_list encaps_var { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); do_add_variable(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_STRING { do_add_string(&$$, &$1, &$2 CLS_CC); }
-void do_init_array(znode *result, znode *expr, znode *offset CLS_DC)
+void do_init_array(znode *result, znode *expr, znode *offset, int is_ref CLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
SET_UNUSED(opline->op1);
SET_UNUSED(opline->op2);
}
+ opline->extended_value = is_ref;
}
-void do_add_array_element(znode *result, znode *expr, znode *offset CLS_DC)
+void do_add_array_element(znode *result, znode *expr, znode *offset, int is_ref CLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
} else {
SET_UNUSED(opline->op2);
}
+ opline->extended_value = is_ref;
}
void do_shell_exec(znode *result, znode *cmd CLS_DC);
-void do_init_array(znode *result, znode *expr, znode *offset CLS_DC);
-void do_add_array_element(znode *result, znode *expr, znode *offset CLS_DC);
+void do_init_array(znode *result, znode *expr, znode *offset, int is_ref CLS_DC);
+void do_add_array_element(znode *result, znode *expr, znode *offset, int is_ref CLS_DC);
void do_add_static_array_element(znode *result, znode *offset, znode *expr);
void do_list_init();
void do_list_end(znode *result, znode *expr CLS_DC);
case ZEND_INIT_ARRAY:
case ZEND_ADD_ARRAY_ELEMENT: {
zval *array_ptr = &Ts[opline->result.u.var].tmp_var;
- zval *expr=get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
+ zval *expr_ptr, **expr_ptr_ptr;
zval *offset=get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R);
+ if (opline->extended_value) {
+ expr_ptr_ptr=get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R);
+ expr_ptr = *expr_ptr_ptr;
+ } else {
+ expr_ptr=get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
+ }
+
if (opline->opcode==ZEND_INIT_ARRAY) {
array_init(array_ptr);
- if (!expr) {
+ if (!expr_ptr) {
break;
}
}
- if (EG(free_op1)) { /* temporary variable */
+ if (opline->op1.op_type == IS_TMP_VAR) { /* temporary variable */
zval *new_expr = (zval *) emalloc(sizeof(zval));
- *new_expr = *expr;
- expr = new_expr;
- INIT_PZVAL(expr);
+ *new_expr = *expr_ptr;
+ expr_ptr = new_expr;
+ INIT_PZVAL(expr_ptr);
} else {
- if (PZVAL_IS_REF(expr)) {
+ if (opline->extended_value) {
+ if (!PZVAL_IS_REF(expr_ptr)) {
+ SEPARATE_ZVAL(expr_ptr_ptr);
+ expr_ptr = *expr_ptr_ptr;
+ expr_ptr->EA.is_ref = 1;
+ }
+ expr_ptr->refcount++;
+ } else if (PZVAL_IS_REF(expr_ptr)) {
zval *new_expr = (zval *) emalloc(sizeof(zval));
- *new_expr = *expr;
- expr = new_expr;
- zendi_zval_copy_ctor(*expr);
- INIT_PZVAL(expr);
+ *new_expr = *expr_ptr;
+ expr_ptr = new_expr;
+ zendi_zval_copy_ctor(*expr_ptr);
+ INIT_PZVAL(expr_ptr);
} else {
- expr->refcount++;
+ expr_ptr->refcount++;
}
}
if (offset) {
switch(offset->type) {
case IS_DOUBLE:
- zend_hash_index_update(array_ptr->value.ht, (long) offset->value.lval, &expr, sizeof(zval *), NULL);
+ zend_hash_index_update(array_ptr->value.ht, (long) offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
- zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr, sizeof(zval *), NULL);
+ zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_STRING:
- zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr, sizeof(zval *), NULL);
+ zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL);
break;
default:
/* do nothing */
}
FREE_OP(&opline->op2, EG(free_op2));
} else {
- zend_hash_next_index_insert(array_ptr->value.ht, &expr, sizeof(zval *), NULL);
+ zend_hash_next_index_insert(array_ptr->value.ht, &expr_ptr, sizeof(zval *), NULL);
}
}
break;