]> granicus.if.org Git - php/commitdiff
Reverted Bob's patch (it breaks many tests when run with opcache and needs to be...
authorDmitry Stogov <dmitry@zend.com>
Tue, 6 May 2014 23:26:13 +0000 (03:26 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 6 May 2014 23:26:13 +0000 (03:26 +0400)
17 files changed:
Zend/tests/bug66015.phpt
Zend/tests/errmsg_040.phpt
Zend/tests/ns_059.phpt
Zend/zend_API.c
Zend/zend_ast.c
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c
Zend/zend_language_parser.y
Zend/zend_types.h
Zend/zend_variables.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c

index 99003e6045d757871accc5553b46bb615420ac0d..4f6d51e0dd173957c6020ba9bf5d589965dcf940 100644 (file)
@@ -11,8 +11,7 @@ class Test
    protected static $array = [
        self::FIRST => 'first',
        'second',
-       'third',
-       4,
+       'third'
    ];
 
    public function __construct()
@@ -23,13 +22,9 @@ class Test
 
 $test = new Test();
 ?>
-
-===DONE===
 --EXPECTF--
 array (
   1 => 'first',
   2 => 'second',
   3 => 'third',
-  4 => 4,
 )
-===DONE===
index 2b192d0b83f2ea326b06390e941f426627196a03..f3d0afcf0a32e331e6d0f3dab9038b75d1cb016f 100644 (file)
@@ -1,7 +1,5 @@
 --TEST--
 errmsg: arrays are not allowed in class constants
---XFAIL--
-Actually it's hard to test where the array comes from (property, constant, ...)
 --FILE--
 <?php
 
index b9fcfee5c02e262099c23aaa3cefbb6c357df9ef..ea66037b433a9d49bc11318d9d59c599dff3873e 100644 (file)
@@ -1,7 +1,5 @@
 --TEST--
 059: Constant arrays
---XFAIL--
-Actually it's hard to test where the array comes from (property, constant, ...)
 --FILE--
 <?php
 const C = array();
index f944de9df3a59687375145c74223865467b79154..033927b68a7424132ea1d9e0b8cdbb81a533c9ca 100644 (file)
@@ -3575,6 +3575,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
        if (ce->type & ZEND_INTERNAL_CLASS) {
                switch(Z_TYPE_P(property)) {
                        case IS_ARRAY:
+                       case IS_CONSTANT_ARRAY:
                        case IS_OBJECT:
                        case IS_RESOURCE:
                                zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
index 7d22ea0f0fdf0ad5f2efac1cdf9c81a446bcbf1f..07d38dc6bf05914b45978311f49b7c326c34ebda 100644 (file)
@@ -62,27 +62,6 @@ ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *o
        return ast;
 }
 
-ZEND_API zend_ast* zend_ast_create_dynamic(uint kind)
-{
-       zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 3); /* use 4 children as deafult */
-       ast->kind = kind;
-       ast->children = 0;
-       return ast;
-}
-
-ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op)
-{
-       if ((*ast)->children >= 4 && (*ast)->children == ((*ast)->children & -(*ast)->children)) {
-               *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children * 2 + 1));
-       }
-       (&(*ast)->u.child)[(*ast)->children++] = op;
-}
-
-ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast)
-{
-       *ast = erealloc(*ast, sizeof(zend_ast) + sizeof(zend_ast*) * ((*ast)->children - 1));
-}
-
 ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
 {
        int i;
@@ -303,21 +282,6 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
                        sub_function(result, &op1, &op2 TSRMLS_CC);
                        zval_dtor(&op2);
                        break;
-               case ZEND_INIT_ARRAY:
-                       array_init(result);
-                       {
-                               int i;
-                               for (i = 0; i < ast->children; i+=2) {
-                                       if ((&ast->u.child)[i]) {
-                                               zend_ast_evaluate(&op1, (&ast->u.child)[i], scope TSRMLS_CC);
-                                       } else {
-                                               Z_TYPE_INFO(op1) = IS_UNDEF;
-                                       }
-                                       zend_ast_evaluate(&op2, (&ast->u.child)[i+1], scope TSRMLS_CC);
-                                       zend_do_add_static_array_element(*result, op1, op2 TSRMLS_CC);
-                               }
-                       }
-                       break;
                default:
                        zend_error(E_ERROR, "Unsupported constant expression");
        }
@@ -341,7 +305,7 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
                }
                return new;
        }
-       return zend_ast_create_dynamic(ast->kind);
+       return NULL;
 }
 
 ZEND_API void zend_ast_destroy(zend_ast *ast)
index 8678299f0fabdf35bf49ab2242413fcfc9a90fec..cac3a54dd41ac6575044ed8000fe6d40750c9197 100644 (file)
@@ -48,9 +48,6 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv);
 ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0);
 ZEND_API zend_ast *zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1);
 ZEND_API zend_ast *zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2);
-ZEND_API zend_ast* zend_ast_create_dynamic(uint kind);
-ZEND_API void zend_ast_dynamic_add(zend_ast **ast, zend_ast *op);
-ZEND_API void zend_ast_dynamic_shrink(zend_ast **ast);
 
 ZEND_API int zend_ast_is_ct_constant(zend_ast *ast);
 
index 7d339545011602f90c27cb025d46f7b08efa1e9a..de62e9c43980c3db55f52b26cb1c7507d7848a18 100644 (file)
@@ -1910,7 +1910,7 @@ void zend_do_receive_param(zend_uchar op, znode *varname, znode *initialization,
                                if (op == ZEND_RECV_INIT) {
                                        if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
                                                cur_arg_info->allow_null = 1;
-                                       } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
+                                       } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) {
                                                zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
                                        }
                                }
@@ -5462,6 +5462,10 @@ void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC) /*
 {
        zval property;
 
+       if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
+               zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
+               return;
+       }
        if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
                zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
                return;
@@ -5910,34 +5914,54 @@ void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC) /* {{{
 }
 /* }}} */
 
-void zend_do_add_static_array_element(zval result, zval offset, zval expr TSRMLS_DC) /* {{{ */
+void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr TSRMLS_DC) /* {{{ */
 {
-       switch (Z_TYPE(offset)) {
-               case IS_UNDEF:
-                       zend_hash_next_index_insert(Z_ARRVAL(result), &expr);
-                       break;
-               case IS_STRING:
-                       zend_symtable_update(Z_ARRVAL(result), Z_STR(offset), &expr);
-                       zval_dtor(&offset);
-                       break;
-               case IS_NULL:
-                       zend_symtable_update(Z_ARRVAL(result), STR_EMPTY_ALLOC(), &expr);
-                       break;
-               case IS_LONG:
-                       zend_hash_index_update(Z_ARRVAL(result), Z_LVAL(offset), &expr);
-                       break;
-               case IS_FALSE:
-                       zend_hash_index_update(Z_ARRVAL(result), 0, &expr);
-                       break;
-               case IS_TRUE:
-                       zend_hash_index_update(Z_ARRVAL(result), 1, &expr);
-                       break;
-               case IS_DOUBLE:
-                       zend_hash_index_update(Z_ARRVAL(result), zend_dval_to_lval(Z_DVAL(offset)), &expr);
-                       break;
-               case IS_ARRAY:
-                       zend_error(E_ERROR, "Illegal offset type");
-                       break;
+       zval element;
+
+       ZVAL_COPY_VALUE(&element, &expr->u.constant);
+       if (offset) {
+               switch (Z_TYPE(offset->u.constant)) {
+                       case IS_CONSTANT:
+                               Z_GC_FLAGS(offset->u.constant) |= IS_STR_CONSTANT;
+                               if (Z_CONST_FLAGS(offset->u.constant) & IS_CONSTANT_UNQUALIFIED) {
+                                       Z_GC_FLAGS(offset->u.constant) |= IS_STR_CONSTANT_UNQUALIFIED;
+                               }
+                               zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STR(offset->u.constant), &element);
+                               zval_dtor(&offset->u.constant);
+                               break;
+                       case IS_CONSTANT_AST: {
+                               zend_string *key;
+                               key = STR_INIT((char*)&Z_AST(offset->u.constant), sizeof(zend_ast*), 0);
+                               GC_FLAGS(key) |= IS_STR_AST;
+                               zend_symtable_update(Z_ARRVAL(result->u.constant), key, &element);
+                               STR_RELEASE(key);
+                               break;
+                       }
+                       case IS_STRING:
+                               zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STR(offset->u.constant), &element);
+                               zval_dtor(&offset->u.constant);
+                               break;
+                       case IS_NULL:
+                               zend_symtable_update(Z_ARRVAL(result->u.constant), STR_EMPTY_ALLOC(), &element);
+                               break;
+                       case IS_LONG:
+                               zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_LVAL(offset->u.constant), &element);
+                               break;
+                       case IS_FALSE:
+                               zend_hash_index_update(Z_ARRVAL(result->u.constant), 0, &element);
+                               break;
+                       case IS_TRUE:
+                               zend_hash_index_update(Z_ARRVAL(result->u.constant), 1, &element);
+                               break;
+                       case IS_DOUBLE:
+                               zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_lval(Z_DVAL(offset->u.constant)), &element);
+                               break;
+                       case IS_CONSTANT_ARRAY:
+                               zend_error(E_ERROR, "Illegal offset type");
+                               break;
+               }
+       } else {
+               zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element);
        }
 }
 /* }}} */
@@ -7299,6 +7323,10 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
        zend_op *opline;
        zval *ns_name;
 
+       if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
+               zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants");
+       }
+
        if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) {
                zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant));
        }
index 39d6dff109b2a709092b121aea596aa91125ed24..4288a3b7053ef595f9be4b75c15c512c92054dec 100644 (file)
@@ -587,7 +587,7 @@ void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC);
 void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
 void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC);
 void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC);
-void zend_do_add_static_array_element(zval result, zval offset, zval expr TSRMLS_DC);
+void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr TSRMLS_DC);
 void zend_do_list_init(TSRMLS_D);
 void zend_do_list_end(znode *result, znode *expr TSRMLS_DC);
 void zend_do_add_list_element(const znode *element TSRMLS_DC);
index 15f79738e614fa31efbd16b4ba630293f396a993..3806af0a056849d9913f0e069bbda88f8cef89fb 100644 (file)
@@ -592,6 +592,124 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
                }
 
                if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount);
+       } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) {
+               zval *element, new_val;
+               zend_string *str_index;
+               ulong num_index;
+               int ret;
+
+               SEPARATE_ZVAL_IF_NOT_REF(p);
+
+               Z_TYPE_INFO_P(p) = IS_ARRAY_EX;
+               if (!inline_change) {
+                       HashTable *ht = Z_ARRVAL_P(p);
+                       ZVAL_NEW_ARR(p);
+                       zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0);
+                       zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR);
+               }
+
+               /* First go over the array and see if there are any constant indices */
+               zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
+               while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) {
+                       if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) {
+                               zend_hash_move_forward(Z_ARRVAL_P(p));
+                               continue;
+                       }
+                       if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) {
+                               zend_hash_move_forward(Z_ARRVAL_P(p));
+                               continue;
+                       }
+
+                       if (GC_FLAGS(str_index) & IS_STR_AST) {
+                               zend_ast_ref *ast = *(zend_ast_ref **)str_index->val;
+
+                               zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC);
+                               zend_ast_destroy(ast->ast);
+                               efree(ast);
+                               const_value = &tmp;
+                       } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) {
+                               char *actual, *str;
+                               const char *save = str_index->val;
+                               int len;
+
+                               str = str_index->val;
+                               len = str_index->len;
+                               if ((colon = (char*)zend_memrchr(str, ':', len))) {
+                                       zend_error(E_ERROR, "Undefined class constant '%s'", str);
+                                       len -= ((colon - str) + 1);
+                                       str = colon;
+                               } else {
+                                       if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) {
+                                               if ((actual = (char *)zend_memrchr(str, '\\', len))) {
+                                                       actual++;
+                                                       len -= (actual - str);
+                                                       str = actual;
+                                               }
+                                       }
+                                       if (str[0] == '\\') {
+                                               ++str;
+                                               --len;
+                                       }
+                                       if (save[0] == '\\') {
+                                               ++save;
+                                       }
+                                       if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) {
+                                               zend_error(E_ERROR, "Undefined constant '%s'", save);
+                                       }
+                                       zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",     str, str);
+                               }
+                               if (str == str_index->val && len == str_index->len) {
+                                       ZVAL_STR(&tmp, STR_COPY(str_index));
+                               } else {
+                                       ZVAL_STRINGL(&tmp, str, len);
+                               }
+                               const_value = &tmp;
+                       } else {
+//???!
+                               ZVAL_COPY_VALUE(&tmp, const_value);
+                               if (Z_OPT_CONSTANT(tmp)) {
+                                       zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC);
+                               }
+                               zval_opt_copy_ctor(&tmp);
+                               const_value = &tmp;
+                       }
+
+                       if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) {
+                               ZVAL_DUP(&new_val, element);
+                               zval_ptr_dtor(element);
+                               ZVAL_COPY_VALUE(element, &new_val);
+                       }
+
+                       switch (Z_TYPE_P(const_value)) {
+                               case IS_STRING:
+                                       ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               case IS_FALSE:
+                                       ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               case IS_TRUE:
+                                       ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 1, HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               case IS_LONG:
+                                       ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               case IS_DOUBLE:
+                                       ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               case IS_NULL:
+                                       ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE);
+                                       break;
+                               default:
+                                       ret = SUCCESS;
+                                       break;
+                       }
+                       if (ret == SUCCESS) {
+                               zend_hash_move_forward(Z_ARRVAL_P(p));
+                       }
+                       zval_dtor(const_value);
+               }
+               zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC);
+               zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
        } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
                SEPARATE_ZVAL_IF_NOT_REF(p);
 
index 43e20cd9ce5ed851fa8b3d71f95a3b733dccab31..6f39f4d63faec06f92f27f68bec403eff3786834 100644 (file)
@@ -986,7 +986,9 @@ static_class_constant:
 ;
 
 static_scalar: /* compile-time evaluated scalars */
-       static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); }
+               static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); }
+       |       T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE_INFO($$.u.constant) = IS_CONSTANT_ARRAY_EX; }
+       |       '[' static_array_pair_list ']' { $$ = $2; Z_TYPE_INFO($$.u.constant) = IS_CONSTANT_ARRAY_EX; }
 ;
 
 static_scalar_value:
@@ -995,8 +997,6 @@ static_scalar_value:
        |       namespace_name          { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
        |       T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant);  zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
        |       T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_NEW_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
-       |       T_ARRAY '(' static_array_pair_list ')' { $$ = $3; }
-       |       '[' static_array_pair_list ']' { $$ = $2; }
        |       static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
        |       T_CLASS_C                       { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
        |       static_operation { $$ = $1; }
@@ -1053,8 +1053,8 @@ scalar:
 
 
 static_array_pair_list:
-               /* empty */ { $$.op_type = IS_CONST; array_init(&$$.u.constant); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
-       |       non_empty_static_array_pair_list possible_comma { zend_ast_dynamic_shrink(&$1.u.ast); $$ = $1; }
+               /* empty */ { $$.op_type = IS_CONST; array_init(&$$.u.constant); }
+       |       non_empty_static_array_pair_list possible_comma { $$ = $1; }
 ;
 
 possible_comma:
@@ -1063,10 +1063,10 @@ possible_comma:
 ;
 
 non_empty_static_array_pair_list:
-               non_empty_static_array_pair_list ',' static_scalar_value T_DOUBLE_ARROW static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); zend_ast_dynamic_add(&$$.u.ast, $5.u.ast); }
-       |       non_empty_static_array_pair_list ',' static_scalar_value { zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); }
-       |       static_scalar_value T_DOUBLE_ARROW static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); zend_ast_dynamic_add(&$$.u.ast, $3.u.ast); }
-       |       static_scalar_value { $$.u.ast = zend_ast_create_dynamic(ZEND_INIT_ARRAY); zend_ast_dynamic_add(&$$.u.ast, NULL); zend_ast_dynamic_add(&$$.u.ast, $1.u.ast); }
+               non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW static_scalar { zend_do_add_static_array_element(&$$, &$3, &$5 TSRMLS_CC); }
+       |       non_empty_static_array_pair_list ',' static_scalar { zend_do_add_static_array_element(&$$, NULL, &$3 TSRMLS_CC); }
+       |       static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, &$1, &$3 TSRMLS_CC); }
+       |       static_scalar { $$.op_type = IS_CONST; array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, NULL, &$1 TSRMLS_CC); }
 ;
 
 expr:
index 211c44a9441ca1ca7a8eb334266c3aa9bd3c1d16..3e3cc51b7e7bb4a424c177dc7c51b1501a5abef4 100644 (file)
@@ -212,20 +212,21 @@ struct _zend_ast_ref {
 #define IS_ARRAY                                       7
 #define IS_OBJECT                                      8
 #define IS_RESOURCE                                    9
-#define IS_REFERENCE                                   10
+#define IS_REFERENCE                           10
 
 /* constant expressions */
 #define IS_CONSTANT                                    11
-#define IS_CONSTANT_AST                                        12
+#define IS_CONSTANT_ARRAY                      12
+#define IS_CONSTANT_AST                                13
 
 /* fake types */
-#define _IS_BOOL                                       13
-#define IS_CALLABLE                                    14
+#define _IS_BOOL                                       14
+#define IS_CALLABLE                                    15
 
 /* internal types */
-#define IS_INDIRECT                                    15
-#define IS_STR_OFFSET                                  16
-#define IS_PTR                                         17
+#define IS_INDIRECT                    16
+#define IS_STR_OFFSET                          17
+#define IS_PTR                                         18
 
 static inline zend_uchar zval_get_type(const zval* pz) {
        return pz->u1.v.type;
@@ -293,6 +294,7 @@ static inline zend_uchar zval_get_type(const zval* pz) {
 #define IS_REFERENCE_EX                                (IS_REFERENCE      | ((                   IS_TYPE_REFCOUNTED                                         ) << Z_TYPE_FLAGS_SHIFT))
 
 #define IS_CONSTANT_EX                         (IS_CONSTANT       | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
+#define IS_CONSTANT_ARRAY_EX           (IS_CONSTANT_ARRAY | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 #define IS_CONSTANT_AST_EX                     (IS_CONSTANT_AST   | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED |                       IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 
 /* zval.u1.v.const_flags */
index 64bd1ae844f99444ac27c57a0b2ea957a29e5646..c05e404c06426f3d68f40dbf1ec0ba4ed8ce332c 100644 (file)
@@ -37,9 +37,10 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
                                STR_RELEASE(str);
                                break;
                        }
-               case IS_ARRAY: {
+               case IS_ARRAY:
+               case IS_CONSTANT_ARRAY: {
+                               zend_array *arr =(zend_array*)p;
                                TSRMLS_FETCH();
-                               zend_array *arr = (zend_array*)p;
 
                                if (arr != &EG(symbol_table)) {
                                        /* break possible cycles */
@@ -51,7 +52,7 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
                                break;
                        }
                case IS_CONSTANT_AST: {
-                               zend_ast_ref *ast = (zend_ast_ref*)p;
+                               zend_ast_ref *ast =(zend_ast_ref*)p;
                
                                zend_ast_destroy(ast->ast);
                                efree(ast);
@@ -97,7 +98,8 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
                                STR_FREE(str);
                                break;
                        }
-               case IS_ARRAY: {
+               case IS_ARRAY:
+               case IS_CONSTANT_ARRAY: {
                                zend_array *arr =(zend_array*)p;
                                TSRMLS_FETCH();
 
@@ -153,6 +155,7 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
                        STR_RELEASE(Z_STR_P(zvalue));
                        break;
                case IS_ARRAY:
+               case IS_CONSTANT_ARRAY:
                case IS_CONSTANT_AST:
                case IS_OBJECT:
                case IS_RESOURCE:
@@ -184,6 +187,7 @@ ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC)
                        STR_FREE(Z_STR_P(zvalue));
                        break;
                case IS_ARRAY:
+               case IS_CONSTANT_ARRAY:
                case IS_CONSTANT_AST:
                case IS_OBJECT:
                case IS_RESOURCE:
@@ -236,7 +240,8 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
                        CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
                        Z_STR_P(zvalue) = STR_DUP(Z_STR_P(zvalue), 0);
                        break;
-               case IS_ARRAY: {
+               case IS_ARRAY:
+               case IS_CONSTANT_ARRAY: {
                                HashTable *ht;
                                TSRMLS_FETCH();
 
index afb569bdc26d8b96a50dda2c6dc14c95e557feb5..64b44d067537e77b1ddf6a1d024af9e9ac3640b7 100644 (file)
@@ -5275,6 +5275,9 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
 
        ZVAL_COPY_VALUE(&c.value, val);
        if (Z_OPT_CONSTANT(c.value)) {
+               if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
+                       zval_opt_copy_ctor(&c.value);
+               }
                zval_update_constant(&c.value, 0 TSRMLS_CC);
        } else {
                /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
index d4d58b1bddbe72dedbb973cd5fa81f18e1b3c624..96bbc226e2f651c92ede99254e5affab45a1439c 100644 (file)
@@ -4221,6 +4221,9 @@ static int ZEND_FASTCALL  ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
 
        ZVAL_COPY_VALUE(&c.value, val);
        if (Z_OPT_CONSTANT(c.value)) {
+               if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) {
+                       zval_opt_copy_ctor(&c.value);
+               }
                zval_update_constant(&c.value, 0 TSRMLS_CC);
        } else {
                /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
index c77a4d0149266dd3f716cef4a8fee2788496a59d..3c143de1c12b9bcebae919d17fbd4bcb408b3efe 100644 (file)
@@ -273,7 +273,6 @@ static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
                        Z_STR_P(src) = zend_clone_str(Z_STR_P(src) TSRMLS_CC);
                        break;
                case IS_ARRAY:
-#if ZEND_EXTENSION_API_NO <= PHP_5_5_X_API_NO
            case IS_CONSTANT_ARRAY:
                        if (Z_ARR_P(src) != &EG(symbol_table)) {
                        if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_ARR_P(src))) != NULL) {
@@ -290,7 +289,6 @@ static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
                                }
                        }
                        break;
-#endif
            case IS_REFERENCE:
                if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_REF_P(src))) != NULL) {
                        Z_REF_P(src) = ptr;
@@ -304,7 +302,6 @@ static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
                                zend_clone_zval(Z_REFVAL_P(src), bind TSRMLS_CC);
                        }
                break;
-#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
            case IS_CONSTANT_AST:
                if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) {
                        Z_AST_P(src) = ptr;
@@ -319,7 +316,6 @@ static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
                        Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src) TSRMLS_CC);
                        }
                break;
-#endif
        }
 }
 
index 30818adb30a5ee138a185dd5d3ea5c8674cef1cf..33a99ee9c0fb973f5e5732af88e4c201e835edc8 100644 (file)
@@ -140,9 +140,7 @@ static void zend_persist_zval(zval *z TSRMLS_DC)
                        Z_GC_FLAGS_P(z) |= flags;
                        break;
                case IS_ARRAY:
-#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
                case IS_CONSTANT_ARRAY:
-#endif
                        new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
                        if (new_ptr) {
                                Z_ARR_P(z) = new_ptr;
index b6740db04435f53bad778641124dac64a78c4289..a347a34cf33951a7d9ae787ad1996934ee29c668 100644 (file)
@@ -127,9 +127,7 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC)
                        Z_GC_FLAGS_P(z) |= flags;
                        break;
                case IS_ARRAY:
-#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
                case IS_CONSTANT_ARRAY:
-#endif
                        size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array));
                        if (size) {
                                ADD_SIZE(size);