]> granicus.if.org Git - php/commitdiff
Always use IS_CONSTANT_AST (IS_CONSTANT is removed).
authorDmitry Stogov <dmitry@zend.com>
Tue, 10 Oct 2017 07:11:05 +0000 (10:11 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 10 Oct 2017 07:11:05 +0000 (10:11 +0300)
31 files changed:
UPGRADING.INTERNALS
Zend/zend_API.c
Zend/zend_ast.c
Zend/zend_ast.h
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_constants.c
Zend/zend_execute.c
Zend/zend_execute.h
Zend/zend_execute_API.c
Zend/zend_inheritance.c
Zend/zend_types.h
Zend/zend_variables.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/com_dotnet/com_variant.c
ext/opcache/Optimizer/compact_literals.c
ext/opcache/Optimizer/optimize_func_calls.c
ext/opcache/Optimizer/pass1_5.c
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_inference.h
ext/opcache/zend_file_cache.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c
ext/reflection/php_reflection.c
ext/soap/php_encoding.c
ext/standard/basic_functions.c
ext/xmlrpc/xmlrpc-epi-php.c
sapi/phpdbg/phpdbg_utils.c

index 6fe98f0a4558f00feccb12ba8860f61a1b21cf05..ff56dfa6555f4ccd3b66e2c7d02a3d4949b2248a 100644 (file)
@@ -13,7 +13,7 @@ PHP 7.2 INTERNALS UPGRADE NOTES
   j. Run-time constant operand addressing
   k. Array/Object recursion protection
   l. HASH_FLAG_PERSISTENT
-  m. zend_ast_ref
+  m. AST and IS_CONSTANT
 
 2. Build system changes
   a. Unix build system changes
@@ -94,6 +94,11 @@ PHP 7.2 INTERNALS UPGRADE NOTES
      zend_ast_destroy_and_free() is removed. ZVAL_NEW_AST() is replaced
      by ZVAL_AST().
 
+     IS_CONSTANT type and Z_CONST_FLAGS() are removed. Now constants are always
+     represented using IS_CONSTANT_AST (ZEND_AST_CONSTANT kind). AST node
+     attributes are used instead of constant flags. IS_TYPE_CONSTANT flag is
+     removed, but Z_CONSTANT() macro is kept for compatibility.
+
 ========================
 2. Build system changes
 ========================
index 2e8a99400021f19421068a2e5e4f29993b57d9a4..b9467da710b02170157ba2b5ffb1932d77008ee7 100644 (file)
@@ -1150,7 +1150,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
 
                        ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
                                val = &c->value;
-                               if (Z_CONSTANT_P(val)) {
+                               if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
                                        if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
                                                return FAILURE;
                                        }
@@ -1167,7 +1167,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
                                                        val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
                                                }
                                                ZVAL_DEREF(val);
-                                               if (Z_CONSTANT_P(val)) {
+                                               if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
                                                        if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
                                                                return FAILURE;
                                                        }
@@ -3685,12 +3685,12 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
 
        if (ce->type == ZEND_INTERNAL_CLASS) {
                property_info = pemalloc(sizeof(zend_property_info), 1);
-               if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) {
+               if ((access_type & ZEND_ACC_STATIC) || Z_TYPE_P(property) == IS_CONSTANT_AST) {
                        ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                }
        } else {
                property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
-               if (Z_CONSTANT_P(property)) {
+               if (Z_TYPE_P(property) == IS_CONSTANT_AST) {
                        ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                }
        }
@@ -3846,7 +3846,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
        Z_ACCESS_FLAGS(c->value) = access_type;
        c->doc_comment = doc_comment;
        c->ce = ce;
-       if (Z_CONSTANT_P(value)) {
+       if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
        }
 
index defa5353191ef25e67b73a88fd5050e860f72028..96bedb7b42ea724150c13da54cfcb95e720cd00b 100644 (file)
@@ -25,6 +25,7 @@
 #include "zend_language_parser.h"
 #include "zend_smart_str.h"
 #include "zend_exceptions.h"
+#include "zend_constants.h"
 
 ZEND_API zend_ast_process_t zend_ast_process = NULL;
 
@@ -72,6 +73,17 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
        return zend_ast_create_zval_with_lineno(zv, attr, CG(zend_lineno));
 }
 
+ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
+       zend_ast_zval *ast;
+
+       ast = zend_ast_alloc(sizeof(zend_ast_zval));
+       ast->kind = ZEND_AST_CONSTANT;
+       ast->attr = attr;
+       ZVAL_STR(&ast->val, name);
+       ast->val.u2.lineno = CG(zend_lineno);
+       return (zend_ast *) ast;
+}
+
 ZEND_API zend_ast *zend_ast_create_decl(
        zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
        zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3
@@ -276,25 +288,30 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
                {
                        zval *zv = zend_ast_get_zval(ast);
 
-                       if (Z_OPT_CONSTANT_P(zv)) {
-                               if (Z_TYPE_FLAGS_P(zv) & IS_TYPE_REFCOUNTED) {
-                                       if (UNEXPECTED(zval_update_constant_ex(zv, scope) != SUCCESS)) {
-                                               ret = FAILURE;
-                                               break;
-                                       }
-                                       ZVAL_COPY(result, zv);
-                               } else {
-                                       ZVAL_COPY_VALUE(result, zv);
-                                       if (UNEXPECTED(zval_update_constant_ex(result, scope) != SUCCESS)) {
-                                               ret = FAILURE;
-                                               break;
-                                       }
-                               }
-                       } else {
-                               ZVAL_COPY(result, zv);
+                       ZVAL_COPY(result, zv);
+                       break;
+               }
+               case ZEND_AST_CONSTANT:
+               {
+                       zend_string *name = zend_ast_get_constant_name(ast);
+                       zval *zv = zend_get_constant_ex(name, scope, ast->attr);
+
+                       if (UNEXPECTED(zv == NULL)) {
+                               ZVAL_UNDEF(result);
+                               ret = zend_use_undefined_constant(name, ast->attr, result);
+                               break;
                        }
+                       ZVAL_DUP(result, zv);
                        break;
                }
+               case ZEND_AST_CONSTANT_CLASS:
+                       ZEND_ASSERT(EG(current_execute_data));
+                       if (scope && scope->name) {
+                               ZVAL_STR_COPY(result, scope->name);
+                       } else {
+                               ZVAL_EMPTY_STRING(result);
+                       }
+                       break;
                case ZEND_AST_AND:
                        if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
                                ret = FAILURE;
@@ -455,7 +472,7 @@ static size_t zend_ast_tree_size(zend_ast *ast)
 {
        size_t size;
 
-       if (ast->kind == ZEND_AST_ZVAL) {
+       if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
                size = sizeof(zend_ast_zval);
        } else if (zend_ast_is_list(ast)) {
                uint32_t i;
@@ -488,6 +505,12 @@ static void* zend_ast_tree_copy(zend_ast *ast, void *buf)
                new->attr = ast->attr;
                ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
                buf = (void*)((char*)buf + sizeof(zend_ast_zval));
+       } else if (ast->kind == ZEND_AST_CONSTANT) {
+               zend_ast_zval *new = (zend_ast_zval*)buf;
+               new->kind = ZEND_AST_CONSTANT;
+               new->attr = ast->attr;
+               ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
+               buf = (void*)((char*)buf + sizeof(zend_ast_zval));
        } else if (zend_ast_is_list(ast)) {
                zend_ast_list *list = zend_ast_get_list(ast);
                zend_ast_list *new = (zend_ast_list*)buf;
@@ -548,6 +571,9 @@ ZEND_API void zend_ast_destroy(zend_ast *ast) {
                         * become invalid. GC would cause such a reference in the root buffer. */
                        zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
                        break;
+               case ZEND_AST_CONSTANT:
+                       zend_string_release(zend_ast_get_constant_name(ast));
+                       break;
                case ZEND_AST_FUNC_DECL:
                case ZEND_AST_CLOSURE:
                case ZEND_AST_METHOD:
@@ -996,9 +1022,6 @@ static void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int ind
                        } ZEND_HASH_FOREACH_END();
                        smart_str_appendc(str, ']');
                        break;
-               case IS_CONSTANT:
-                       smart_str_appendl(str, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
-                       break;
                case IS_CONSTANT_AST:
                        zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent);
                        break;
@@ -1078,6 +1101,14 @@ tail_call:
                case ZEND_AST_ZVAL:
                        zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
                        break;
+               case ZEND_AST_CONSTANT: {
+                       zend_string *name = zend_ast_get_constant_name(ast);
+                       smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name));
+                       break;
+               }
+               case ZEND_AST_CONSTANT_CLASS:
+                       smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1);
+                       break;
                case ZEND_AST_ZNODE:
                        /* This AST kind is only used for temporary nodes during compilation */
                        ZEND_ASSERT(0);
index 9e0aeeb54598acfa62ec117f2baafc646945c805..99ad920ad6a5c374ee63ce7e25dad6a86ae59e4b 100644 (file)
@@ -32,6 +32,7 @@
 enum _zend_ast_kind {
        /* special nodes */
        ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT,
+       ZEND_AST_CONSTANT,
        ZEND_AST_ZNODE,
 
        /* declaration nodes */
@@ -61,6 +62,7 @@ enum _zend_ast_kind {
        /* 0 child nodes */
        ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT,
        ZEND_AST_TYPE,
+       ZEND_AST_CONSTANT_CLASS,
 
        /* 1 child node */
        ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT,
@@ -192,6 +194,8 @@ extern ZEND_API zend_ast_process_t zend_ast_process;
 ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno);
 ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr);
 
+ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr);
+
 ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...);
 ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...);
 
@@ -230,6 +234,12 @@ static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
        return Z_STR_P(zv);
 }
 
+static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) {
+       ZEND_ASSERT(ast->kind == ZEND_AST_CONSTANT);
+       ZEND_ASSERT(Z_TYPE(((zend_ast_zval *) ast)->val) == IS_STRING);
+       return Z_STR(((zend_ast_zval *) ast)->val);
+}
+
 static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {
        ZEND_ASSERT(!zend_ast_is_list(ast));
        return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
index 73b1b64c827d8a3157b248212b689f11144a6521..5793ea33084e02f664f28cc9407fb9e4313f00f5 100644 (file)
@@ -1071,7 +1071,7 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
 
                /* this is necessary to make it able to work with default array
                 * properties, returned to user */
-               if (Z_OPT_CONSTANT_P(prop)) {
+               if (Z_OPT_TYPE_P(prop) == IS_CONSTANT_AST) {
                        if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) {
                                return;
                        }
index 2f73afcf9e49489dd624efc5a6388d1a83bce83e..8d353b8c0a85af828f814672e4553b8e7e084a41 100644 (file)
@@ -460,7 +460,7 @@ void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
 /* Common part of zend_add_literal and zend_append_individual_literal */
 static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
 {
-       if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
+       if (Z_TYPE_P(zv) == IS_STRING) {
                zend_string_hash_val(Z_STR_P(zv));
                Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
                if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
@@ -5518,8 +5518,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                        zend_bool allow_null;
                        zend_bool has_null_default = default_ast
                                && (Z_TYPE(default_node.u.constant) == IS_NULL
-                                       || (Z_TYPE(default_node.u.constant) == IS_CONSTANT
-                                               && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0));
+                                       || (Z_TYPE(default_node.u.constant) == IS_CONSTANT_AST
+                                               && Z_ASTVAL(default_node.u.constant)->kind == ZEND_AST_CONSTANT
+                                               && strcasecmp(ZSTR_VAL(zend_ast_get_constant_name(Z_ASTVAL(default_node.u.constant))), "NULL") == 0));
                        zend_bool is_explicitly_nullable = (type_ast->attr & ZEND_TYPE_NULLABLE) == ZEND_TYPE_NULLABLE;
 
                        op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
@@ -5536,19 +5537,19 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                                if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) {
                                        if (default_ast && !has_null_default
                                                && Z_TYPE(default_node.u.constant) != IS_ARRAY
-                                               && !Z_CONSTANT(default_node.u.constant)
+                                               && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST
                                        ) {
                                                zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
                                                        "with array type can only be an array or NULL");
                                        }
                                } else if (ZEND_TYPE_CODE(arg_info->type) == IS_CALLABLE && default_ast) {
-                                       if (!has_null_default && !Z_CONSTANT(default_node.u.constant)) {
+                                       if (!has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) {
                                                zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
                                                        "with callable type can only be NULL");
                                        }
                                }
                        } else {
-                               if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
+                               if (default_ast && !has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) {
                                        if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
                                                zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
                                                        "with a class type can only be NULL");
@@ -7916,6 +7917,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
        zend_ast *const_ast = ast->child[1];
        zend_string *class_name;
        zend_string *const_name = zend_ast_get_str(const_ast);
+       zend_string *name;
        zval result;
        int fetch_type;
 
@@ -7943,16 +7945,13 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
                zend_string_addref(class_name);
        }
 
-       Z_STR(result) = zend_concat3(
+       name = zend_concat3(
                ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", 2, ZSTR_VAL(const_name), ZSTR_LEN(const_name));
 
-       Z_TYPE_INFO(result) = IS_CONSTANT_EX;
-       Z_CONST_FLAGS(result) = fetch_type;
-
        zend_ast_destroy(ast);
        zend_string_release(class_name);
 
-       *ast_ptr = zend_ast_create_zval(&result);
+       *ast_ptr = zend_ast_create_constant(name, fetch_type);
 }
 /* }}} */
 
@@ -7962,25 +7961,21 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
        zend_ast *name_ast = ast->child[0];
        zend_string *orig_name = zend_ast_get_str(name_ast);
        zend_bool is_fully_qualified;
+       zval result;
+       zend_string *resolved_name;
 
-       zval result, resolved_name;
-       ZVAL_STR(&resolved_name, zend_resolve_const_name(
-               orig_name, name_ast->attr, &is_fully_qualified));
+       resolved_name = zend_resolve_const_name(
+               orig_name, name_ast->attr, &is_fully_qualified);
 
-       if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified)) {
-               zend_string_release(Z_STR(resolved_name));
+       if (zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) {
+               zend_string_release(resolved_name);
                zend_ast_destroy(ast);
                *ast_ptr = zend_ast_create_zval(&result);
                return;
        }
 
-       Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
-       if (!is_fully_qualified) {
-               Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED;
-       }
-
        zend_ast_destroy(ast);
-       *ast_ptr = zend_ast_create_zval(&resolved_name);
+       *ast_ptr = zend_ast_create_constant(resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0);
 }
 /* }}} */
 
@@ -7993,14 +7988,8 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
                    CG(active_class_entry) &&
                    (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
 
-       {
-               zval const_zv;
-               Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0);
-               Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT);
-
-               zend_ast_destroy(ast);
-               *ast_ptr = zend_ast_create_zval(&const_zv);
-       }
+       zend_ast_destroy(ast);
+       *ast_ptr = zend_ast_create_ex(ZEND_AST_CONSTANT_CLASS, 0);
 }
 /* }}} */
 
index 6c4a5b51f1b2df2f3749b3bc78a798149f607136..62fcdc9d8df31f53d87ea449c61242d02d4ba64b 100644 (file)
@@ -886,6 +886,10 @@ void zend_assert_valid_class_name(const zend_string *const_name);
 
 #define ZEND_DIM_IS 1
 
+#define IS_CONSTANT_UNQUALIFIED     0x010
+#define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */
+#define IS_CONSTANT_IN_NAMESPACE    0x100
+
 static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask)
 {
        arg_num--;
index f5a71ac6cc03fc555460dd04463dc0e33c692cea..100d0a263bb1cac574b2a60ecb0d55b68cf3ff6b 100644 (file)
@@ -348,7 +348,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
                        }
                }
 
-               if (ret_constant && Z_CONSTANT_P(ret_constant)) {
+               if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
                        if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
                                if (IS_CONSTANT_VISITED(ret_constant)) {
                                        zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
index b608933996819145ed1670d58149c3b8c2e2cc90..b80e7f0af66618402fc1f92cc1269347895cc65d 100644 (file)
@@ -729,7 +729,7 @@ static ZEND_COLD void zend_verify_arg_error(
 
 static int is_null_constant(zend_class_entry *scope, zval *default_value)
 {
-       if (Z_CONSTANT_P(default_value)) {
+       if (Z_TYPE_P(default_value) == IS_CONSTANT_AST) {
                zval constant;
 
                ZVAL_COPY(&constant, default_value);
index ae809ab2240885556bc341d9ca40850cb3765262..39fce43ccc92e93b402d700f6b0215f2f5d062cc 100644 (file)
@@ -131,6 +131,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
 
 ZEND_API int zval_update_constant(zval *pp);
 ZEND_API int zval_update_constant_ex(zval *pp, zend_class_entry *scope);
+ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result);
 
 /* dedicated Zend executor functions - do not use! */
 struct _zend_vm_stack {
index d5d03625e2a379273435d1fc63ce37ccaa520658..e69a84ba6b9442ad513b4cebac29ec70c1336863 100644 (file)
@@ -542,90 +542,63 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ *
 }
 /* }}} */
 
-ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */
+ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result) /* {{{ */
 {
-       zval *const_value;
        char *colon;
-       zend_bool inline_change;
 
-       if (Z_TYPE_P(p) == IS_CONSTANT) {
-               if (IS_CONSTANT_VISITED(p)) {
-                       zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
+       if (UNEXPECTED(EG(exception))) {
+               return FAILURE;
+       } else if ((colon = (char*)zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name)))) {
+               zend_throw_error(NULL, "Undefined class constant '%s'", ZSTR_VAL(name));
+               return FAILURE;
+       } else if ((attr & IS_CONSTANT_UNQUALIFIED) == 0) {
+               zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(name));
+               return FAILURE;
+       } else {
+               char *actual = ZSTR_VAL(name);
+               size_t actual_len = ZSTR_LEN(name);
+               char *slash = (char *) zend_memrchr(actual, '\\', actual_len);
+
+               if (slash) {
+                       actual = slash + 1;
+                       actual_len -= (actual - ZSTR_VAL(name));
+               }
+
+               zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual);
+               if (EG(exception)) {
                        return FAILURE;
+               } else {
+                       zval_ptr_dtor_nogc(result);
+                       ZVAL_STRINGL(result, actual, actual_len);
                }
-               inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0;
-               SEPARATE_ZVAL_NOREF(p);
-               MARK_CONSTANT_VISITED(p);
-               if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) {
-                       ZEND_ASSERT(EG(current_execute_data));
-                       if (inline_change) {
-                               zend_string_release(Z_STR_P(p));
-                       }
-                       if (scope && scope->name) {
-                               ZVAL_STR_COPY(p, scope->name);
-                       } else {
-                               ZVAL_EMPTY_STRING(p);
-                       }
-               } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) {
-                       if (UNEXPECTED(EG(exception))) {
-                               RESET_CONSTANT_VISITED(p);
-                               return FAILURE;
-                       } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
-                               zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(p));
-                               RESET_CONSTANT_VISITED(p);
-                               return FAILURE;
-                       } else {
-                               if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
-                                       zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(p));
-                                       RESET_CONSTANT_VISITED(p);
-                                       return FAILURE;
-                               } else {
-                                       zend_string *save = Z_STR_P(p);
-                                       char *actual = Z_STRVAL_P(p);
-                                       size_t actual_len = Z_STRLEN_P(p);
-                                       char *slash = (char *) zend_memrchr(actual, '\\', actual_len);
-                                       if (slash) {
-                                               actual = slash + 1;
-                                               actual_len -= (actual - Z_STRVAL_P(p));
-                                       }
+       }
+       return SUCCESS;
+}
+/* }}} */
 
-                                       zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual);
-                                       if (EG(exception)) {
-                                               RESET_CONSTANT_VISITED(p);
-                                               return FAILURE;
-                                       }
+ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */
+{
+       if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
+               zend_ast *ast = Z_ASTVAL_P(p);
 
-                                       if (!inline_change) {
-                                               ZVAL_STRINGL(p, actual, actual_len);
-                                       } else {
-                                               if (slash) {
-                                                       ZVAL_STRINGL(p, actual, actual_len);
-                                                       zend_string_release(save);
-                                               } else {
-                                                       Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ?
-                                                               IS_STRING_EX : IS_INTERNED_STRING_EX;
-                                               }
-                                       }
-                               }
+               if (ast->kind == ZEND_AST_CONSTANT) {
+                       zend_string *name = zend_ast_get_constant_name(ast);
+                       zval *zv = zend_get_constant_ex(name, scope, ast->attr);
+
+                       if (UNEXPECTED(zv == NULL)) {
+                               return zend_use_undefined_constant(name, ast->attr, p);
                        }
+                       zval_ptr_dtor_nogc(p);
+                       ZVAL_DUP(p, zv);
                } else {
-                       if (inline_change) {
-                               zend_string_release(Z_STR_P(p));
-                       }
-                       ZVAL_COPY_VALUE(p, const_value);
-                       zval_opt_copy_ctor(p);
-               }
-       } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
-               zval tmp;
+                       zval tmp;
 
-               inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0;
-               if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) {
-                       return FAILURE;
-               }
-               if (inline_change) {
+                       if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) {
+                               return FAILURE;
+                       }
                        zval_ptr_dtor_nogc(p);
+                       ZVAL_COPY_VALUE(p, &tmp);
                }
-               ZVAL_COPY_VALUE(p, &tmp);
        }
        return SUCCESS;
 }
index 3e57343c4cabf34ca41ce7585b3cdd3c02902ddd..b607efa5c941e9b98107a483a5fed0ba461703c4 100644 (file)
@@ -497,9 +497,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
                                        if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
                                                zval *zv = RT_CONSTANT(precv, precv->op2);
 
-                                               if (Z_TYPE_P(zv) == IS_CONSTANT) {
-                                                       smart_str_append(&str, Z_STR_P(zv));
-                                               } else if (Z_TYPE_P(zv) == IS_FALSE) {
+                                               if (Z_TYPE_P(zv) == IS_FALSE) {
                                                        smart_str_appends(&str, "false");
                                                } else if (Z_TYPE_P(zv) == IS_TRUE) {
                                                        smart_str_appends(&str, "true");
@@ -515,7 +513,12 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
                                                } else if (Z_TYPE_P(zv) == IS_ARRAY) {
                                                        smart_str_appends(&str, "Array");
                                                } else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
-                                                       smart_str_appends(&str, "<expression>");
+                                                       zend_ast *ast = Z_ASTVAL_P(zv);
+                                                       if (ast->kind == ZEND_AST_CONSTANT) {
+                                                               smart_str_append(&str, zend_ast_get_constant_name(ast));
+                                                       } else {
+                                                               smart_str_appends(&str, "<expression>");
+                                                       }
                                                } else {
                                                        zend_string *zv_str = zval_get_string(zv);
                                                        smart_str_append(&str, zv_str);
@@ -769,7 +772,7 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
                                ZSTR_VAL(ce->name), ZSTR_VAL(name), zend_visibility_string(Z_ACCESS_FLAGS(parent_const->value)), ZSTR_VAL(ce->parent->name), (Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PUBLIC) ? "" : " or weaker");
                }
        } else if (!(Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PRIVATE)) {
-               if (Z_CONSTANT(parent_const->value)) {
+               if (Z_TYPE(parent_const->value) == IS_CONSTANT_AST) {
                        ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                }
                if (ce->type & ZEND_INTERNAL_CLASS) {
@@ -845,7 +848,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
 #ifdef ZTS
                        if (parent_ce->type != ce->type) {
                                ZVAL_DUP(dst, src);
-                               if (Z_OPT_CONSTANT_P(dst)) {
+                               if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) {
                                        ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                                }
                                continue;
@@ -853,7 +856,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
 #endif
 
                        ZVAL_COPY(dst, src);
-                       if (Z_OPT_CONSTANT_P(dst)) {
+                       if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) {
                                ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                        }
                } while (dst != end);
@@ -894,7 +897,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
                        }
                        ZVAL_COPY_VALUE(dst, src);
                        Z_ADDREF_P(dst);
-                       if (Z_CONSTANT_P(Z_REFVAL_P(dst))) {
+                       if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) {
                                ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                        }
                } while (dst != end);
@@ -982,7 +985,7 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
 {
        if (do_inherit_constant_check(&ce->constants_table, c, name, iface)) {
                zend_class_constant *ct;
-               if (Z_CONSTANT(c->value)) {
+               if (Z_TYPE(c->value) == IS_CONSTANT_AST) {
                        ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
                }
                if (ce->type & ZEND_INTERNAL_CLASS) {
index 9ade3983be02ad84550132f3014f67c08998bc42..c613dfbe1d671e9b87ccab1e00a7c16e43a32280 100644 (file)
@@ -183,8 +183,8 @@ struct _zval_struct {
                        ZEND_ENDIAN_LOHI_4(
                                zend_uchar    type,                     /* active type */
                                zend_uchar    type_flags,
-                               zend_uchar    const_flags,
-                               zend_uchar    reserved)     /* call info for EX(This) */
+                               zend_uchar    _unused,
+                               zend_uchar    _reserved)    /* call info for EX(This) */
                } v;
                uint32_t type_info;
        } u1;
@@ -372,7 +372,6 @@ struct _zend_ast_ref {
 #define IS_REFERENCE                           10
 
 /* constant expressions */
-#define IS_CONSTANT                                    11
 #define IS_CONSTANT_AST                                12
 
 /* fake types */
@@ -402,9 +401,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_TYPE_FLAGS(zval)                     (zval).u1.v.type_flags
 #define Z_TYPE_FLAGS_P(zval_p)         Z_TYPE_FLAGS(*(zval_p))
 
-#define Z_CONST_FLAGS(zval)                    (zval).u1.v.const_flags
-#define Z_CONST_FLAGS_P(zval_p)                Z_CONST_FLAGS(*(zval_p))
-
 #define Z_TYPE_INFO(zval)                      (zval).u1.type_info
 #define Z_TYPE_INFO_P(zval_p)          Z_TYPE_INFO(*(zval_p))
 
@@ -432,7 +428,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_TYPE_MASK                                    0xff
 
 #define Z_TYPE_FLAGS_SHIFT                     8
-#define Z_CONST_FLAGS_SHIFT                    16
 
 #define GC_REFCOUNT(p)                         (p)->gc.refcount
 #define GC_TYPE(p)                                     (p)->gc.u.v.type
@@ -465,31 +460,24 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define GC_OBJECT                                      (IS_OBJECT         | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
 
 /* zval.u1.v.type_flags */
-#define IS_TYPE_CONSTANT                       (1<<0)
 #define IS_TYPE_REFCOUNTED                     (1<<2)
 #define IS_TYPE_COPYABLE                       (1<<4)
+#define IS_CONSTANT_VISITED_MARK    (1<<5)
 
 /* extended types */
 #define IS_INTERNED_STRING_EX          IS_STRING
 
-#define IS_STRING_EX                           (IS_STRING         | ((                   IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
-#define IS_ARRAY_EX                                    (IS_ARRAY          | ((                   IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
-#define IS_OBJECT_EX                           (IS_OBJECT         | ((                   IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
-#define IS_RESOURCE_EX                         (IS_RESOURCE       | ((                   IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
-#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_AST_EX                     (IS_CONSTANT_AST   | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
+#define IS_STRING_EX                           (IS_STRING         | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
+#define IS_ARRAY_EX                                    (IS_ARRAY          | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
+#define IS_OBJECT_EX                           (IS_OBJECT         | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
+#define IS_RESOURCE_EX                         (IS_RESOURCE       | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
+#define IS_REFERENCE_EX                                (IS_REFERENCE      | ((IS_TYPE_REFCOUNTED                   ) << Z_TYPE_FLAGS_SHIFT))
 
-/* zval.u1.v.const_flags */
-#define IS_CONSTANT_UNQUALIFIED                0x010
-#define IS_CONSTANT_VISITED_MARK       0x020
-#define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */
-#define IS_CONSTANT_IN_NAMESPACE       0x100  /* used only in opline->extended_value */
+#define IS_CONSTANT_AST_EX                     (IS_CONSTANT_AST   | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT))
 
-#define IS_CONSTANT_VISITED(p)         (Z_CONST_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
-#define MARK_CONSTANT_VISITED(p)       Z_CONST_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
-#define RESET_CONSTANT_VISITED(p)      Z_CONST_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
+#define IS_CONSTANT_VISITED(p)         (Z_TYPE_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
+#define MARK_CONSTANT_VISITED(p)       Z_TYPE_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
+#define RESET_CONSTANT_VISITED(p)      Z_TYPE_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
 
 /* string flags (zval.value->gc.u.flags) */
 #define IS_STR_INTERNED                                GC_IMMUTABLE  /* interned string */
@@ -526,7 +514,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_UNPROTECT_RECURSION_P(zv) Z_UNPROTECT_RECURSION(*(zv))
 
 /* All data types < IS_STRING have their constructor/destructors skipped */
-#define Z_CONSTANT(zval)                       ((Z_TYPE_FLAGS(zval) & IS_TYPE_CONSTANT) != 0)
+#define Z_CONSTANT(zval)                       (Z_TYPE(zval) == IS_CONSTANT_AST)
 #define Z_CONSTANT_P(zval_p)           Z_CONSTANT(*(zval_p))
 
 #define Z_REFCOUNTED(zval)                     ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0)
@@ -545,7 +533,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_OPT_TYPE(zval)                       (Z_TYPE_INFO(zval) & Z_TYPE_MASK)
 #define Z_OPT_TYPE_P(zval_p)           Z_OPT_TYPE(*(zval_p))
 
-#define Z_OPT_CONSTANT(zval)           ((Z_TYPE_INFO(zval) & (IS_TYPE_CONSTANT << Z_TYPE_FLAGS_SHIFT)) != 0)
+#define Z_OPT_CONSTANT(zval)           (Z_OPT_TYPE(zval) == IS_CONSTANT_AST)
 #define Z_OPT_CONSTANT_P(zval_p)       Z_OPT_CONSTANT(*(zval_p))
 
 #define Z_OPT_REFCOUNTED(zval)         ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)
index 09338013b878f6048897fccadc95f967b7b923e9..d7fd5239d7796bbd6bd5c3f6b524172b738102f5 100644 (file)
@@ -31,8 +31,7 @@
 ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
 {
        switch (GC_TYPE(p)) {
-               case IS_STRING:
-               case IS_CONSTANT: {
+               case IS_STRING: {
                                zend_string *str = (zend_string*)p;
                                CHECK_ZVAL_STRING_REL(str);
                                zend_string_free(str);
@@ -79,7 +78,6 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
 {
        switch (Z_TYPE_P(zvalue)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
                        zend_string_release(Z_STR_P(zvalue));
                        break;
@@ -110,7 +108,6 @@ ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC)
 {
        switch (Z_TYPE_P(zvalue)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
                        zend_string_free(Z_STR_P(zvalue));
                        break;
@@ -170,9 +167,6 @@ ZEND_API void ZEND_FASTCALL _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
        } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) {
                CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
                ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
-       } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT)) {
-               CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
-               Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
        } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT_AST)) {
                ZVAL_AST(zvalue, zend_ast_copy(Z_ASTVAL_P(zvalue)));
        }
index fff72782f7a91ae4df10ee99a3de7dd063fc6161..b8f0aa1f343d25782d580aa29496aff758ec1659 100644 (file)
@@ -4676,7 +4676,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
        param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC);
        if (arg_num > EX_NUM_ARGS()) {
                ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2));
-               if (Z_OPT_CONSTANT_P(param)) {
+               if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
                                zval_ptr_dtor_nogc(param);
@@ -5078,7 +5078,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
-                       if (Z_CONSTANT_P(value)) {
+                       if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                                zval_update_constant_ex(value, c->ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -7932,7 +7932,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
        value = zend_hash_find(ht, Z_STR_P(varname));
 
        if (opline->extended_value) {
-               if (Z_CONSTANT_P(value)) {
+               if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_NULL(variable_ptr);
index b286868cd0511aa6243546900bab772ccd7089bd..9d99daf98684a731e82eb4df39d8b9b5bc33120a 100644 (file)
@@ -2292,7 +2292,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON
        param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC);
        if (arg_num > EX_NUM_ARGS()) {
                ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2));
-               if (Z_OPT_CONSTANT_P(param)) {
+               if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
                                zval_ptr_dtor_nogc(param);
@@ -5746,7 +5746,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
-                       if (Z_CONSTANT_P(value)) {
+                       if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                                zval_update_constant_ex(value, c->ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -19629,7 +19629,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
-                       if (Z_CONSTANT_P(value)) {
+                       if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                                zval_update_constant_ex(value, c->ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -28467,7 +28467,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
-                       if (Z_CONSTANT_P(value)) {
+                       if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                                zval_update_constant_ex(value, c->ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -38504,7 +38504,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND
        value = zend_hash_find(ht, Z_STR_P(varname));
 
        if (opline->extended_value) {
-               if (Z_CONSTANT_P(value)) {
+               if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
                        SAVE_OPLINE();
                        if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_NULL(variable_ptr);
index b74e977f0efddcc16cda9952b9bfaaf3db2da0eb..04c7d5f8c1af1764e5c453a9f0c31113ebcf749b 100644 (file)
@@ -176,7 +176,6 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep
                        break;
 
                case IS_RESOURCE:
-               case IS_CONSTANT:
                case IS_CONSTANT_AST:
                default:
                        V_VT(v) = VT_NULL;
index 0b98da054da389bab9c53178d0cbfd4309aa595e..a8457c9405ca61361888d26ba7e26406813a22c6 100644 (file)
@@ -422,7 +422,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
                                        }
                                        break;
                                case IS_STRING:
-                               case IS_CONSTANT:
                                        if (info[i].flags & LITERAL_MAY_MERGE) {
                                                if (info[i].flags & LITERAL_EX_OBJ) {
                                                        int key_len = sizeof("$this->") - 1 + Z_STRLEN(op_array->literals[i]);
index 1548260b605a92e42d7fca4d19514a21892c596d..81d62ca171ba42e497af2de94e949360d8dbe948 100644 (file)
@@ -123,7 +123,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
                                i = fcall->extended_value;
 
                                do {
-                                       if (Z_CONSTANT_P(RT_CONSTANT(&func->op_array.opcodes[i], func->op_array.opcodes[i].op2))) {
+                                       if (Z_TYPE_P(RT_CONSTANT(&func->op_array.opcodes[i], func->op_array.opcodes[i].op2)) == IS_CONSTANT_AST) {
                                                return;
                                        }
                                        i++;
index 7697fb19433094ec26131f380be6078391bdab2f..9f2801901355e9e57da40f6bb70eddaa6faeaee3 100644 (file)
@@ -35,8 +35,6 @@
 #include "zend_execute.h"
 #include "zend_vm.h"
 
-#define ZEND_IS_CONSTANT_TYPE(t)       ((t) == IS_CONSTANT)
-
 void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
 {
        int i = 0;
@@ -305,11 +303,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                                                (Z_ACCESS_FLAGS(cc->value) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
                                                c = &cc->value;
                                                if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
-                                                       break;
-                                               }
-                                               if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_P(c))) {
-                                                       if (!zend_optimizer_get_persistent_constant(Z_STR_P(c), &t, 1) ||
-                                                           ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) {
+                                                       zend_ast *ast = Z_ASTVAL_P(c);
+                                                       if (ast->kind != ZEND_AST_CONSTANT
+                                                        || !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &t, 1)
+                                                        || Z_TYPE(t) == IS_CONSTANT_AST) {
                                                                break;
                                                        }
                                                } else {
index 1b77eae74e358bd3d232d69499dba457a4f93c7e..ac1318762485e7572222ab005181be6fcaaab427 100644 (file)
@@ -455,9 +455,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
                if (opline->extended_value & IS_CONSTANT_UNQUALIFIED) {
                                fprintf(stderr, " (unqualified)");
                }
-               if (opline->extended_value & IS_CONSTANT_CLASS) {
-                               fprintf(stderr, " (__class__)");
-               }
                if (opline->extended_value & IS_CONSTANT_IN_NAMESPACE) {
                                fprintf(stderr, " (in-namespace)");
                }
index 2e7b00a03ab8a7773ffcbfb8a3b6717d6f6a7d46..7bb906d4a6e4e7a188e1b4ddd314cadd7190b10e 100644 (file)
@@ -2748,7 +2748,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
                        if (arg_info) {
                                tmp = zend_fetch_arg_info(script, arg_info, &ce);
                                if (opline->opcode == ZEND_RECV_INIT &&
-                                          Z_CONSTANT_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants))) {
+                                          Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants)) == IS_CONSTANT_AST) {
                                        /* The constant may resolve to NULL */
                                        tmp |= MAY_BE_NULL;
                                }
@@ -4260,7 +4260,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
                case ZEND_COUNT:
                        return (t1 & MAY_BE_ANY) != MAY_BE_ARRAY;
                case ZEND_RECV_INIT:
-                       if (Z_CONSTANT_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants))) {
+                       if (Z_TYPE_P(CRT_CONSTANT_EX(op_array, opline, opline->op2, ssa->rt_constants)) == IS_CONSTANT_AST) {
                                return 1;
                        }
                        if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
index d7a6f9790169dde3d7153f8af20b79c22c368354..6bd9706fa8952e04d961620ba3a5252d009bafed 100644 (file)
@@ -159,9 +159,7 @@ DEFINE_SSA_OP_RANGE_OVERFLOW(op2)
 #define OP2_RANGE_OVERFLOW()    (_ssa_op2_range_overflow (op_array, ssa, opline))
 
 static zend_always_inline uint32_t _const_op_type(const zval *zv) {
-       if (Z_TYPE_P(zv) == IS_CONSTANT) {
-               return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
-       } else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
+       if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
                return MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
        } else if (Z_TYPE_P(zv) == IS_ARRAY) {
                HashTable *ht = Z_ARRVAL_P(zv);
index a7758058ded190bfb1d2c38b604716f6dc5eee3a..0b95212693f3dbece78d1b76e9dee70b1a2d33e2 100644 (file)
@@ -278,7 +278,7 @@ static zend_ast *zend_file_cache_serialize_ast(zend_ast                 *ast,
        ret = ast;
        UNSERIALIZE_PTR(ast);
 
-       if (ast->kind == ZEND_AST_ZVAL) {
+       if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
                zend_file_cache_serialize_zval(&((zend_ast_zval*)ast)->val, script, info, buf);
        } else if (zend_ast_is_list(ast)) {
                zend_ast_list *list = zend_ast_get_list(ast);
@@ -305,7 +305,6 @@ static void zend_file_cache_serialize_zval(zval                     *zv,
 {
        switch (Z_TYPE_P(zv)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        if (!IS_SERIALIZED(Z_STR_P(zv))) {
                                SERIALIZE_STR(Z_STR_P(zv));
                        }
@@ -893,7 +892,7 @@ static zend_ast *zend_file_cache_unserialize_ast(zend_ast                *ast,
 
        UNSERIALIZE_PTR(ast);
 
-       if (ast->kind == ZEND_AST_ZVAL) {
+       if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
                zend_file_cache_unserialize_zval(&((zend_ast_zval*)ast)->val, script, buf);
        } else if (zend_ast_is_list(ast)) {
                zend_ast_list *list = zend_ast_get_list(ast);
@@ -919,7 +918,6 @@ static void zend_file_cache_unserialize_zval(zval                    *zv,
 {
        switch (Z_TYPE_P(zv)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        if (!IS_UNSERIALIZED(Z_STR_P(zv))) {
                                UNSERIALIZE_STR(Z_STR_P(zv));
                        }
@@ -945,8 +943,6 @@ static void zend_file_cache_unserialize_zval(zval                    *zv,
                        break;
                case IS_CONSTANT_AST:
                        if (!IS_UNSERIALIZED(Z_AST_P(zv))) {
-                               zend_ast_ref *ast;
-
                                UNSERIALIZE_PTR(Z_AST_P(zv));
                                zend_file_cache_unserialize_ast(Z_ASTVAL_P(zv), script, buf);
                        }
index c21842b66f3e4a1c7d5499f0f0f742ebde4ab9a2..8fb7f41e3e76cf8eab4b7f6980daf5856c216120 100644 (file)
@@ -249,7 +249,7 @@ static zend_ast *zend_persist_ast(zend_ast *ast)
        uint32_t i;
        zend_ast *node;
 
-       if (ast->kind == ZEND_AST_ZVAL) {
+       if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
                zend_ast_zval *copy = zend_accel_memdup(ast, sizeof(zend_ast_zval));
                zend_persist_zval(&copy->val);
                node = (zend_ast *) copy;
@@ -282,7 +282,6 @@ static void zend_persist_zval(zval *z)
 
        switch (Z_TYPE_P(z)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        zend_accel_store_interned_string(Z_STR_P(z));
                        Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
                        break;
@@ -320,12 +319,12 @@ static void zend_persist_zval(zval *z)
                        new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z));
                        if (new_ptr) {
                                Z_AST_P(z) = new_ptr;
-                               Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_COPYABLE;
+                               Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
                        } else {
                                zend_ast_ref *old_ref = Z_AST_P(z);
                                Z_ARR_P(z) = zend_accel_memdup(Z_AST_P(z), sizeof(zend_ast_ref));
                                zend_persist_ast(GC_AST(old_ref));
-                               Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_COPYABLE;
+                               Z_TYPE_FLAGS_P(z) = IS_TYPE_COPYABLE;
                                GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
                                efree(old_ref);
                        }
index cb7eb11b7ad68ac7d9c83db0e9fe51799e76b7ad..0c600daef558525285eaac3106bd463c776132e3 100644 (file)
@@ -94,9 +94,9 @@ static void zend_persist_ast_calc(zend_ast *ast)
 {
        uint32_t i;
 
-       if (ast->kind == ZEND_AST_ZVAL) {
+       if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
                ADD_SIZE(sizeof(zend_ast_zval));
-               zend_persist_zval_calc(zend_ast_get_zval(ast));
+               zend_persist_zval_calc(&((zend_ast_zval*)(ast))->val);
        } else if (zend_ast_is_list(ast)) {
                zend_ast_list *list = zend_ast_get_list(ast);
                ADD_SIZE(sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
@@ -122,7 +122,6 @@ static void zend_persist_zval_calc(zval *z)
 
        switch (Z_TYPE_P(z)) {
                case IS_STRING:
-               case IS_CONSTANT:
                        ADD_INTERNED_STRING(Z_STR_P(z), 0);
                        if (ZSTR_IS_INTERNED(Z_STR_P(z))) {
                                Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
index d42299f55d6765321f9928b4e290ac275a66856f..6a199406862eb1b3b6011ecaabdb3469080be7b5 100644 (file)
@@ -2806,7 +2806,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
        }
 
        ZVAL_DUP(return_value, RT_CONSTANT(precv, precv->op2));
-       if (Z_CONSTANT_P(return_value)) {
+       if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
                zval_update_constant_ex(return_value, param->fptr->common.scope);
        }
 }
@@ -2829,8 +2829,13 @@ ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
        }
 
        precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
-       if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT) {
-               RETURN_TRUE;
+       if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
+               zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
+
+               if (ast->kind == ZEND_AST_CONSTANT
+                || ast->kind == ZEND_AST_CONSTANT_CLASS) {
+                       RETURN_TRUE;
+               }
        }
 
        RETURN_FALSE;
@@ -2854,8 +2859,14 @@ ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
        }
 
        precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
-       if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT) {
-               RETURN_STR_COPY(Z_STR_P(RT_CONSTANT(precv, precv->op2)));
+       if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
+               zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
+
+               if (ast->kind == ZEND_AST_CONSTANT) {
+                       RETURN_STR_COPY(zend_ast_get_constant_name(ast));
+               } else if (ast->kind == ZEND_AST_CONSTANT_CLASS) {
+                       RETURN_STRINGL("__CLASS__", sizeof("__CLASS__")-1);
+               }
        }
 }
 /* }}} */
@@ -3698,7 +3709,7 @@ ZEND_METHOD(reflection_class_constant, getValue)
        GET_REFLECTION_OBJECT_PTR(ref);
 
        ZVAL_DUP(return_value, &ref->value);
-       if (Z_CONSTANT_P(return_value)) {
+       if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
                zval_update_constant_ex(return_value, ref->ce);
        }
 }
@@ -3834,7 +3845,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 
                /* this is necessary to make it able to work with default array
                * properties, returned to user */
-               if (Z_CONSTANT(prop_copy)) {
+               if (Z_TYPE(prop_copy) == IS_CONSTANT_AST) {
                        if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) {
                                return;
                        }
index 6d69d81c338430798ce9c1c718c30e41c17e96f1..16b15698c52ce74ed1f846c4da783fa0669a8cfa 100644 (file)
@@ -149,7 +149,6 @@ encode defaultEncoding[] = {
        {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_double, to_xml_double},
        {{IS_FALSE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_bool, to_xml_bool},
        {{IS_TRUE, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_bool, to_xml_bool},
-       {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL, NULL}, to_zval_string, to_xml_string},
        {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL, NULL}, to_zval_array, guess_array_map},
        {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL, NULL}, to_zval_object, to_xml_object},
        {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL, NULL}, to_zval_array, guess_array_map},
index fdcc50b86021b0fd0f64de7a6109fe1291868a77..93d469168b70596e9a839f3298fc9c3794ea0938 100644 (file)
@@ -3880,7 +3880,7 @@ PHP_FUNCTION(constant)
        c = zend_get_constant_ex(const_name, scope, ZEND_FETCH_CLASS_SILENT);
        if (c) {
                ZVAL_DUP(return_value, c);
-               if (Z_CONSTANT_P(return_value)) {
+               if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
                        if (UNEXPECTED(zval_update_constant_ex(return_value, scope) != SUCCESS)) {
                                return;
                        }
index e20b6d68724aef889fbb10dbabd3b39af52a5c6f..88f52519d09af5e891075cc63b090e90403b3f15 100644 (file)
@@ -1339,9 +1339,6 @@ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval* newvalue) /* {{{ */
                        case IS_DOUBLE:
                                type = xmlrpc_double;
                                break;
-                       case IS_CONSTANT:
-                               type = xmlrpc_string;
-                               break;
                        case IS_STRING:
                                type = xmlrpc_string;
                                break;
index bdcb173c24f7b57cea3c0258ca12d3bbc15206f0..fa27fa96a881a8abe00a3d57b1dac211da731258 100644 (file)
@@ -844,12 +844,17 @@ char *phpdbg_short_zval_print(zval *zv, int maxlen) /* {{{ */
                                ZSTR_VAL(str), ZSTR_LEN(str) <= maxlen ? 0 : '+');
                        break;
                }
-               case IS_CONSTANT:
-                       decode = estrdup("<constant>");
-                       break;
-               case IS_CONSTANT_AST:
-                       decode = estrdup("<ast>");
+               case IS_CONSTANT_AST: {
+                       zend_ast *ast = Z_ASTVAL_P(zv);
+
+                       if (ast->kind == ZEND_AST_CONSTANT
+                        || ast->kind == ZEND_AST_CONSTANT_CLASS) {
+                               decode = estrdup("<constant>");
+                       } else {
+                               decode = estrdup("<ast>");
+                       }
                        break;
+               }
                default:
                        spprintf(&decode, 0, "unknown type: %d", Z_TYPE_P(zv));
                        break;