From: Andi Gutmans Date: Fri, 1 Oct 1999 10:00:05 +0000 (+0000) Subject: - For Andrei. Implement references in array() initializations X-Git-Tag: php-4.0b3_RC2~382 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03d354dcf9203c64ac0a443b5ef9ff61c1b0542e;p=php - For Andrei. Implement references in array() initializations --- diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index 58d39091fe..7081b4c3d4 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -602,18 +602,21 @@ assignment_list_element: 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); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 16f2da3bf8..c85ccf983e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1602,7 +1602,7 @@ void do_shell_exec(znode *result, znode *cmd CLS_DC) -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); @@ -1621,10 +1621,11 @@ void do_init_array(znode *result, znode *expr, znode *offset CLS_DC) 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); @@ -1636,6 +1637,7 @@ void do_add_array_element(znode *result, znode *expr, znode *offset CLS_DC) } else { SET_UNUSED(opline->op2); } + opline->extended_value = is_ref; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5d368d2229..c1e886cbb1 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -304,8 +304,8 @@ void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC); 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); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 604fdb0702..ece2f77404 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1804,43 +1804,57 @@ send_by_ref: 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 */ @@ -1848,7 +1862,7 @@ send_by_ref: } 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;