]> granicus.if.org Git - php/commitdiff
- For Andrei. Implement references in array() initializations
authorAndi Gutmans <andi@php.net>
Fri, 1 Oct 1999 10:00:05 +0000 (10:00 +0000)
committerAndi Gutmans <andi@php.net>
Fri, 1 Oct 1999 10:00:05 +0000 (10:00 +0000)
Zend/zend-parser.y
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c

index 58d39091fe1d15afe4d9380943bbc36227a7fcd2..7081b4c3d426c8efc504402a65caee4eb49404be 100644 (file)
@@ -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); }
index 16f2da3bf862006dcccb1eee20df7b7b98d77e71..c85ccf983e6b2dba4a028088919f7122e1bf8711 100644 (file)
@@ -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;
 }
 
 
index 5d368d22296ac8ba8175deed7764dbb75292196b..c1e886cbb126c4f6d3ba828530de5b447c8141f4 100644 (file)
@@ -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);
index 604fdb0702ba800674638f53d04fb1cb83e0377b..ece2f77404a3aa675f71fdf5d964340f65df0872 100644 (file)
@@ -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;