]> granicus.if.org Git - php/commitdiff
Make zend_type a 2-field struct
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 20 Sep 2019 15:01:19 +0000 (17:01 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 8 Nov 2019 14:15:48 +0000 (15:15 +0100)
We now store the pointer payload and the type mask separately. This
is in preparation for union types, where we will be using both at
the same time.

To avoid increasing the size of arginfo structures, the
pass_by_reference and is_variadic fields are now stored as part of
the type_mask (8-bit are reserved for custom use).

Different types of pointer payloads are distinguished based on bits
in the type_mask.

28 files changed:
Zend/zend.c
Zend/zend_API.c
Zend/zend_API.h
Zend/zend_closures.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_inheritance.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/com_dotnet/com_com.c
ext/com_dotnet/com_handlers.c
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/Optimizer/optimize_func_calls.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/ZendAccelerator.c
ext/opcache/jit/zend_jit_helpers.c
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_file_cache.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c
ext/pdo/pdo_dbh.c
ext/reflection/php_reflection.c
ext/zend_test/test.c
sapi/phpdbg/phpdbg_frame.c

index ce98f50025ffafa3ec7d60b0251017a3ee23fbef..8c9ae86d747ca45ebf4df60266834e9374f28335 100644 (file)
@@ -594,10 +594,7 @@ static void function_copy_ctor(zval *zv) /* {{{ */
                for (i = 0 ; i < num_args; i++) {
                        if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
                                zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
-
-                               new_arg_info[i].type =
-                                       ZEND_TYPE_ENCODE_CLASS(
-                                               name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type));
+                               ZEND_TYPE_SET_PTR(new_arg_info[i].type, name);
                        }
                }
                func->common.arg_info = new_arg_info + 1;
@@ -968,7 +965,7 @@ static void zend_resolve_property_types(void) /* {{{ */
                                        zend_class_entry *prop_ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
 
                                        ZEND_ASSERT(prop_ce && prop_ce->type == ZEND_INTERNAL_CLASS);
-                                       prop_info->type = ZEND_TYPE_ENCODE_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
+                                       prop_info->type = (zend_type) ZEND_TYPE_INIT_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type), 0);
                                        zend_string_release(lc_type_name);
                                        zend_string_release(type_name);
                                }
index 387f6e1a9822edc6b592a46a941befa8b52c1aa3..3c1ca4c7188c49595009c8e2f562288067c7a88b 100644 (file)
@@ -2045,21 +2045,17 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
                        } else {
                                internal_function->required_num_args = info->required_num_args;
                        }
-                       if (info->return_reference) {
+                       if (ZEND_ARG_SEND_MODE(info)) {
                                internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
                        }
-                       if (ptr->arg_info[ptr->num_args].is_variadic) {
+                       if (ZEND_ARG_IS_VARIADIC(&ptr->arg_info[ptr->num_args])) {
                                internal_function->fn_flags |= ZEND_ACC_VARIADIC;
                                /* Don't count the variadic argument */
                                internal_function->num_args--;
                        }
                        if (ZEND_TYPE_IS_SET(info->type)) {
                                if (ZEND_TYPE_IS_CLASS(info->type)) {
-                                       const char *type_name = (const char*)info->type;
-
-                                       if (type_name[0] == '?') {
-                                               type_name++;
-                                       }
+                                       const char *type_name = ZEND_TYPE_LITERAL_NAME(info->type);
                                        if (!scope && (!strcasecmp(type_name, "self") || !strcasecmp(type_name, "parent"))) {
                                                zend_error_noreturn(E_CORE_ERROR, "Cannot declare a return type of %s outside of a class scope", type_name);
                                        }
@@ -2140,16 +2136,9 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
                        reg_function->common.arg_info = new_arg_info + 1;
                        for (i = 0; i < num_args; i++) {
                                if (ZEND_TYPE_IS_CLASS(new_arg_info[i].type)) {
-                                       const char *class_name = (const char*)new_arg_info[i].type;
-                                       zend_bool allow_null = 0;
-                                       zend_string *str;
-
-                                       if (class_name[0] == '?') {
-                                               class_name++;
-                                               allow_null = 1;
-                                       }
-                                       str = zend_string_init_interned(class_name, strlen(class_name), 1);
-                                       new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null);
+                                       const char *class_name = ZEND_TYPE_LITERAL_NAME(new_arg_info[i].type);
+                                       ZEND_TYPE_SET_PTR(new_arg_info[i].type,
+                                               zend_string_init_interned(class_name, strlen(class_name), 1));
                                }
                        }
                }
@@ -3715,7 +3704,7 @@ ZEND_API int zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval *zv, ze
 
 ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
 {
-       return zend_declare_typed_property(ce, name, property, access_type, doc_comment, ZEND_TYPE_ENCODE_NONE());
+       return zend_declare_typed_property(ce, name, property, access_type, doc_comment, (zend_type) ZEND_TYPE_INIT_NONE(0));
 }
 /* }}} */
 
index 1389f0a6d0f1aa35796b11e36156f65e2db93faa..2801b08266897546f69384a9501ad16f6a8911b1 100644 (file)
@@ -96,34 +96,45 @@ typedef struct _zend_fcall_info_cache {
 
 #define ZEND_FE_END            { NULL, NULL, NULL, 0, 0 }
 
-#define ZEND_ARG_INFO(pass_by_ref, name)                             { #name, 0, pass_by_ref, 0},
-#define ZEND_ARG_PASS_INFO(pass_by_ref)                              { NULL,  0, pass_by_ref, 0},
-#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null)  { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 0 },
-#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null)           { #name, ZEND_TYPE_ENCODE_CODE(IS_ARRAY, allow_null), pass_by_ref, 0 },
-#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null)        { #name, ZEND_TYPE_ENCODE_CODE(IS_CALLABLE, allow_null), pass_by_ref, 0 },
-#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(type_hint, allow_null), pass_by_ref, 0 },
-#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name)                             { #name, 0, pass_by_ref, 1 },
-#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, ZEND_TYPE_ENCODE_CODE(type_hint, allow_null), pass_by_ref, 1 },
-#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null)  { #name, ZEND_TYPE_ENCODE_CLASS_CONST(#classname, allow_null), pass_by_ref, 1 },
+#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
+       (((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
+
+#define ZEND_ARG_INFO(pass_by_ref, name) \
+       { #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0))},
+#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
+       { #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
+#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
+       { #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
+#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
+       { #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
+#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
+       { #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
+#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
+       { #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
+#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
+       { #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
+#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
+       { #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)) },
 
 #define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
        static const zend_internal_arg_info name[] = { \
-               { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CLASS_CONST(#class_name, allow_null), return_reference, 0 },
+               { (const char*)(zend_uintptr_t)(required_num_args), \
+                       ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
 
 #define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
        ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
 
 #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
        static const zend_internal_arg_info name[] = { \
-               { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CODE(type, allow_null), return_reference, 0 },
+               { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
 #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
        ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
 
 #define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args)     \
        static const zend_internal_arg_info name[] = { \
-               { (const char*)(zend_uintptr_t)(required_num_args), 0, return_reference, 0 },
+               { (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)) },
 #define ZEND_BEGIN_ARG_INFO(name, _unused)     \
-       ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1)
+       ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
 #define ZEND_END_ARG_INFO()            };
 
 /* Name macros */
index bb469558a1aeca6d06acf66a8158753163cf35a3..63b91aacbda2be1f157f541035ad63bec6a097ab 100644 (file)
@@ -557,16 +557,16 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
                        if (arg_info->name) {
                                if (zstr_args) {
                                        name = zend_strpprintf(0, "%s$%s",
-                                                       arg_info->pass_by_reference ? "&" : "",
+                                                       ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
                                                        ZSTR_VAL(arg_info->name));
                                } else {
                                        name = zend_strpprintf(0, "%s$%s",
-                                                       arg_info->pass_by_reference ? "&" : "",
+                                                       ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
                                                        ((zend_internal_arg_info*)arg_info)->name);
                                }
                        } else {
                                name = zend_strpprintf(0, "%s$param%d",
-                                               arg_info->pass_by_reference ? "&" : "",
+                                               ZEND_ARG_SEND_MODE(arg_info) ? "&" : "",
                                                i + 1);
                        }
                        ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
index 3800c664e1728ef57db0db71ea32751b1a45f87c..ea93e878d03a387c0546dbc532fc2ace00990334 100644 (file)
@@ -1135,7 +1135,7 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop
        } else if (ZEND_TYPE_IS_CE(type)) {
                str = zend_string_copy(ZEND_TYPE_CE(type)->name);
        } else {
-               uint32_t type_mask = ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(type));
+               uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(type);
                switch (type_mask) {
                        case MAY_BE_FALSE|MAY_BE_TRUE:
                                str = ZSTR_KNOWN(ZEND_STR_BOOL);
@@ -1199,7 +1199,7 @@ static void zend_mark_function_as_generator() /* {{{ */
                                || zend_string_equals_literal_ci(name, "Iterator")
                                || zend_string_equals_literal_ci(name, "Generator");
                } else {
-                       valid_type = (ZEND_TYPE_MASK(return_info.type) & MAY_BE_ITERABLE) != 0;
+                       valid_type = (ZEND_TYPE_FULL_MASK(return_info.type) & MAY_BE_ITERABLE) != 0;
                }
 
                if (!valid_type) {
@@ -2175,7 +2175,7 @@ static void zend_emit_return_type_check(
                zend_op *opline;
 
                /* `return ...;` is illegal in a void function (but `return;` isn't) */
-               if (ZEND_TYPE_IS_MASK(type) && ZEND_TYPE_CONTAINS_CODE(type, IS_VOID)) {
+               if (ZEND_TYPE_CONTAINS_CODE(type, IS_VOID)) {
                        if (expr) {
                                if (expr->op_type == IS_CONST && Z_TYPE(expr->u.constant) == IS_NULL) {
                                        zend_error_noreturn(E_COMPILE_ERROR,
@@ -2201,8 +2201,7 @@ static void zend_emit_return_type_check(
                }
 
                if (expr && expr->op_type == IS_CONST) {
-                       if (ZEND_TYPE_IS_MASK(type)
-                                       && ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) {
+                       if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) {
                                /* we don't need run-time check */
                                return;
                        }
@@ -5359,11 +5358,11 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
                n = MIN(func->common.num_args, MAX_ARG_FLAG_NUM);
                i = 0;
                while (i < n) {
-                       ZEND_SET_ARG_FLAG(func, i + 1, func->common.arg_info[i].pass_by_reference);
+                       ZEND_SET_ARG_FLAG(func, i + 1, ZEND_ARG_SEND_MODE(&func->common.arg_info[i]));
                        i++;
                }
-               if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_VARIADIC && func->common.arg_info[i].pass_by_reference)) {
-                       uint32_t pass_by_reference = func->common.arg_info[i].pass_by_reference;
+               if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_VARIADIC && ZEND_ARG_SEND_MODE(&func->common.arg_info[i]))) {
+                       uint32_t pass_by_reference = ZEND_ARG_SEND_MODE(&func->common.arg_info[i]);
                        while (i < MAX_ARG_FLAG_NUM) {
                                ZEND_SET_ARG_FLAG(func, i + 1, pass_by_reference);
                                i++;
@@ -5382,7 +5381,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
        }
 
        if (ast->kind == ZEND_AST_TYPE) {
-               return ZEND_TYPE_ENCODE_CODE(ast->attr, allow_null);
+               return (zend_type) ZEND_TYPE_INIT_CODE(ast->attr, allow_null, 0);
        } else {
                zend_string *class_name = zend_ast_get_str(ast);
                zend_uchar type = zend_lookup_builtin_type_by_name(class_name);
@@ -5396,7 +5395,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
                        if (type == IS_VOID && allow_null) {
                                zend_error_noreturn(E_COMPILE_ERROR, "Void type cannot be nullable");
                        }
-                       return ZEND_TYPE_ENCODE_CODE(type, allow_null);
+                       return (zend_type) ZEND_TYPE_INIT_CODE(type, allow_null, 0);
                } else {
                        const char *correct_name;
                        zend_string *orig_name = zend_ast_get_str(ast);
@@ -5428,7 +5427,7 @@ static zend_type zend_compile_typename(zend_ast *ast, zend_bool force_allow_null
                                }
                        }
 
-                       return ZEND_TYPE_ENCODE_CLASS(class_name, allow_null);
+                       return (zend_type) ZEND_TYPE_INIT_CLASS(class_name, allow_null, 0);
                }
        }
 }
@@ -5448,12 +5447,12 @@ static zend_bool zend_is_valid_default_value(zend_type type, zval *value)
        if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE_P(value))) {
                return 1;
        }
-       if ((ZEND_TYPE_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) {
+       if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) {
                /* Integers are allowed as initializers for floating-point values. */
                convert_to_double(value);
                return 1;
        }
-       if ((ZEND_TYPE_MASK(type) & MAY_BE_ITERABLE) && Z_TYPE_P(value) == IS_ARRAY) {
+       if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_ITERABLE) && Z_TYPE_P(value) == IS_ARRAY) {
                return 1;
        }
        return 0;
@@ -5470,9 +5469,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                /* Use op_array->arg_info[-1] for return type */
                arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children + 1, 0);
                arg_infos->name = NULL;
-               arg_infos->pass_by_reference = (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
-               arg_infos->is_variadic = 0;
                arg_infos->type = zend_compile_typename(return_type_ast, 0);
+               ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
+                       (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
                arg_infos++;
                op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
        } else {
@@ -5540,23 +5539,18 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
 
                arg_info = &arg_infos[i];
                arg_info->name = zend_string_copy(name);
-               arg_info->pass_by_reference = is_ref;
-               arg_info->is_variadic = is_variadic;
-               arg_info->type = ZEND_TYPE_ENCODE_NONE();
+               arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
 
                if (type_ast) {
                        uint32_t default_type = default_ast ? Z_TYPE(default_node.u.constant) : IS_UNDEF;
 
-                       uint32_t arg_type;
                        zend_bool is_class;
 
                        op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
                        arg_info->type = zend_compile_typename(type_ast, default_type == IS_NULL);
-
                        is_class = ZEND_TYPE_IS_CLASS(arg_info->type);
-                       arg_type = !is_class ? ZEND_TYPE_MASK(arg_info->type) : 0;
 
-                       if (arg_type & MAY_BE_VOID) {
+                       if (!is_class && (ZEND_TYPE_FULL_MASK(arg_info->type) & MAY_BE_VOID)) {
                                zend_error_noreturn(E_COMPILE_ERROR, "void cannot be used as a parameter type");
                        }
 
@@ -5580,6 +5574,8 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                                opline->extended_value = zend_alloc_cache_slot();
                        }
                }
+
+               ZEND_TYPE_FULL_MASK(arg_info->type) |= _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic);
        }
 
        /* These are assigned at the end to avoid uninitialized memory in case of an error */
@@ -6079,13 +6075,12 @@ void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags) /
                zend_string *name = zval_make_interned_string(zend_ast_get_zval(name_ast));
                zend_string *doc_comment = NULL;
                zval value_zv;
-               zend_type type = ZEND_TYPE_ENCODE_NONE();
+               zend_type type = ZEND_TYPE_INIT_NONE(0);
 
                if (type_ast) {
                        type = zend_compile_typename(type_ast, 0);
 
-                       if (ZEND_TYPE_IS_MASK(type)
-                                       && (ZEND_TYPE_MASK(type) & (MAY_BE_VOID|MAY_BE_CALLABLE))) {
+                       if (ZEND_TYPE_FULL_MASK(type) & (MAY_BE_VOID|MAY_BE_CALLABLE)) {
                                zend_string *str = zend_type_to_string(type);
                                zend_error_noreturn(E_COMPILE_ERROR,
                                        "Property %s::$%s cannot have type %s",
index e4096a05a569364efecfc0469a47a21678487521..96db1dcb3a695ef76cf18e54d6d032a0c18b01be 100644 (file)
@@ -383,16 +383,12 @@ typedef struct _zend_class_constant {
 typedef struct _zend_internal_arg_info {
        const char *name;
        zend_type type;
-       zend_uchar pass_by_reference;
-       zend_bool is_variadic;
 } zend_internal_arg_info;
 
 /* arg_info for user functions */
 typedef struct _zend_arg_info {
        zend_string *name;
        zend_type type;
-       zend_uchar pass_by_reference;
-       zend_bool is_variadic;
 } zend_arg_info;
 
 /* the following structure repeats the layout of zend_internal_arg_info,
@@ -403,8 +399,6 @@ typedef struct _zend_arg_info {
 typedef struct _zend_internal_function_info {
        zend_uintptr_t required_num_args;
        zend_type type;
-       zend_bool return_reference;
-       zend_bool _is_variadic;
 } zend_internal_function_info;
 
 struct _zend_op_array {
@@ -934,6 +928,14 @@ zend_string *zend_type_to_string(zend_type type);
 #define ZEND_SEND_BY_REF     1u
 #define ZEND_SEND_PREFER_REF 2u
 
+/* The send mode and is_variadic flag are stored as part of zend_type */
+#define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT
+#define _ZEND_IS_VARIADIC_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 2))
+#define ZEND_ARG_SEND_MODE(arg_info) \
+       ((ZEND_TYPE_FULL_MASK((arg_info)->type) >> _ZEND_SEND_MODE_SHIFT) & 3)
+#define ZEND_ARG_IS_VARIADIC(arg_info) \
+       ((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_VARIADIC_BIT) != 0)
+
 #define ZEND_DIM_IS                                    (1 << 0) /* isset fetch needed for null coalesce */
 #define ZEND_DIM_ALTERNATIVE_SYNTAX    (1 << 1) /* deprecated curly brace usage */
 
@@ -950,7 +952,7 @@ static zend_always_inline int zend_check_arg_send_type(const zend_function *zf,
                }
                arg_num = zf->common.num_args;
        }
-       return UNEXPECTED((zf->common.arg_info[arg_num].pass_by_reference & mask) != 0);
+       return UNEXPECTED((ZEND_ARG_SEND_MODE(&zf->common.arg_info[arg_num]) & mask) != 0);
 }
 
 #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
index 8278f698cdda41c7798fd1bf695ba6083340a607..097137aa5cff04fbc6167810e9a0766833f43073 100644 (file)
@@ -676,8 +676,8 @@ static ZEND_COLD void zend_verify_type_error_common(
                        *need_kind = ZSTR_VAL(ZEND_TYPE_NAME(arg_info->type));
                }
        } else {
-               zend_type type = ZEND_TYPE_WITHOUT_NULL(arg_info->type);
-               switch (ZEND_TYPE_MASK(type)) {
+               uint32_t type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(arg_info->type);
+               switch (type_mask) {
                        case MAY_BE_OBJECT:
                                *need_msg = "be an ";
                                *need_kind = "object";
@@ -691,11 +691,15 @@ static ZEND_COLD void zend_verify_type_error_common(
                                *need_kind = "";
                                break;
                        default:
+                       {
                                /* TODO: The zend_type_to_string() result is guaranteed interned here.
                                 * It would be beter to switch all this code to use zend_string though. */
+                               zend_type type = arg_info->type;
+                               ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL;
                                *need_msg = "be of the type ";
                                *need_kind = ZSTR_VAL(zend_type_to_string(type));
                                break;
+                       }
                }
        }
 
@@ -904,7 +908,7 @@ static zend_bool zend_resolve_class_type(zend_type *type, zend_class_entry *self
        }
 
        zend_string_release(name);
-       *type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(*type));
+       *type = (zend_type) ZEND_TYPE_INIT_CE(ce, ZEND_TYPE_ALLOW_NULL(*type), 0);
        return 1;
 }
 
@@ -924,13 +928,13 @@ static zend_always_inline zend_bool i_zend_check_property_type(zend_property_inf
                return instanceof_function(Z_OBJCE_P(property), ZEND_TYPE_CE(info->type));
        }
 
-       ZEND_ASSERT(!(ZEND_TYPE_MASK(info->type) & MAY_BE_CALLABLE));
+       ZEND_ASSERT(!(ZEND_TYPE_FULL_MASK(info->type) & MAY_BE_CALLABLE));
        if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(info->type, Z_TYPE_P(property)))) {
                return 1;
-       } else if (ZEND_TYPE_MASK(info->type) & MAY_BE_ITERABLE) {
+       } else if (ZEND_TYPE_FULL_MASK(info->type) & MAY_BE_ITERABLE) {
                return zend_is_iterable(property);
        } else {
-               return zend_verify_scalar_type_hint(ZEND_TYPE_MASK(info->type), property, strict, 0);
+               return zend_verify_scalar_type_hint(ZEND_TYPE_FULL_MASK(info->type), property, strict, 0);
        }
 }
 
@@ -996,7 +1000,7 @@ static zend_always_inline zend_bool zend_check_type(
                return 1;
        }
 
-       type_mask = ZEND_TYPE_MASK(type);
+       type_mask = ZEND_TYPE_FULL_MASK(type);
        if (type_mask & MAY_BE_CALLABLE) {
                return zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL);
        } else if (type_mask & MAY_BE_ITERABLE) {
@@ -1184,7 +1188,7 @@ static int zend_verify_internal_return_type(zend_function *zf, zval *ret)
        zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1;
        void *dummy_cache_slot = NULL;
 
-       if (ZEND_TYPE_IS_MASK(ret_info->type) && (ZEND_TYPE_MASK(ret_info->type) & MAY_BE_VOID)) {
+       if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_VOID) {
                if (UNEXPECTED(Z_TYPE_P(ret) != IS_NULL)) {
                        zend_verify_void_return_error(zf, zend_zval_type_name(ret), "");
                        return 0;
@@ -1216,6 +1220,7 @@ static ZEND_COLD int zend_verify_missing_return_type(const zend_function *zf, vo
        zend_arg_info *ret_info = zf->common.arg_info - 1;
 
        // TODO: Eliminate this!
+       zend_class_entry *ce = NULL;
        if (ZEND_TYPE_IS_CLASS(ret_info->type)) {
                if (UNEXPECTED(!*cache_slot)) {
                        zend_class_entry *ce = zend_fetch_class(ZEND_TYPE_NAME(ret_info->type), (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
@@ -1560,7 +1565,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re
 {
        zend_property_info *prop;
        ZEND_REF_FOREACH_TYPE_SOURCES(ref, prop) {
-               if (!ZEND_TYPE_IS_MASK(prop->type) || !(ZEND_TYPE_MASK(prop->type) & MAY_BE_DOUBLE)) {
+               if (!(ZEND_TYPE_FULL_MASK(prop->type) & MAY_BE_DOUBLE)) {
                        return prop;
                }
        } ZEND_REF_FOREACH_TYPE_SOURCES_END();
@@ -2528,7 +2533,7 @@ static zend_always_inline zend_bool check_type_array_assignable(zend_type type)
        if (!ZEND_TYPE_IS_SET(type)) {
                return 1;
        }
-       return ZEND_TYPE_IS_MASK(type) && (ZEND_TYPE_MASK(type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY));
+       return (ZEND_TYPE_FULL_MASK(type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY)) != 0;
 }
 
 /* Checks whether an array can be assigned to the reference. Throws error if not assignable. */
@@ -2959,7 +2964,7 @@ static zend_always_inline int i_zend_verify_type_assignable_zval(
                return 1;
        }
 
-       type_mask = ZEND_TYPE_MASK(type);
+       type_mask = ZEND_TYPE_FULL_MASK(type);
        if (type_mask & MAY_BE_ITERABLE) {
                return zend_is_iterable(zv);
        }
@@ -3013,9 +3018,9 @@ ZEND_API zend_bool ZEND_FASTCALL zend_verify_ref_assignable_zval(zend_reference
                if (!seen_prop) {
                        seen_prop = prop;
                        seen_type_mask = ZEND_TYPE_IS_CLASS(prop->type)
-                               ? MAY_BE_OBJECT : ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop->type));
+                               ? MAY_BE_OBJECT : ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop->type);
                } else if (needs_coercion
-                               && seen_type_mask != ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop->type))) {
+                               && seen_type_mask != ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop->type)) {
                        zend_throw_conflicting_coercion_error(seen_prop, prop, zv);
                        return 0;
                }
@@ -3082,13 +3087,13 @@ ZEND_API zend_bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(zend_propert
 
                if (result < 0) {
                        zend_property_info *ref_prop = ZEND_REF_FIRST_SOURCE(Z_REF_P(orig_val));
-                       if (ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(prop_info->type))
-                                       != ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(ref_prop->type))) {
+                       if (ZEND_TYPE_PURE_MASK_WITHOUT_NULL(prop_info->type)
+                                       != ZEND_TYPE_PURE_MASK_WITHOUT_NULL(ref_prop->type)) {
                                /* Invalid due to conflicting coercion */
                                zend_throw_ref_type_error_type(ref_prop, prop_info, val);
                                return 0;
                        }
-                       if (zend_verify_weak_scalar_type_hint(ZEND_TYPE_MASK(prop_info->type), val)) {
+                       if (zend_verify_weak_scalar_type_hint(ZEND_TYPE_FULL_MASK(prop_info->type), val)) {
                                return 1;
                        }
                }
index a1ecb9e2b70f32c19a89c520a605a95ffe74d6b0..af81c327e158690b71b2be155079227d6ce3ac5f 100644 (file)
@@ -350,7 +350,7 @@ static inheritance_status zend_perform_covariant_type_check(
                }
 
                return unlinked_instanceof(fe_ce, proto_ce) ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
-       } else if (ZEND_TYPE_MASK(proto_type) & MAY_BE_ITERABLE) {
+       } else if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_ITERABLE) {
                if (ZEND_TYPE_IS_CLASS(fe_type)) {
                        zend_string *fe_class_name =
                                resolve_class_name(fe->common.scope, ZEND_TYPE_NAME(fe_type));
@@ -363,9 +363,9 @@ static inheritance_status zend_perform_covariant_type_check(
                                ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
                }
 
-               return ZEND_TYPE_MASK(fe_type) & (MAY_BE_ARRAY|MAY_BE_ITERABLE)
+               return ZEND_TYPE_FULL_MASK(fe_type) & (MAY_BE_ARRAY|MAY_BE_ITERABLE)
                        ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
-       } else if (ZEND_TYPE_MASK(proto_type) & MAY_BE_OBJECT) {
+       } else if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_OBJECT) {
                if (ZEND_TYPE_IS_CLASS(fe_type)) {
                        /* Currently, any class name would be allowed here. We still perform a class lookup
                         * for forward-compatibility reasons, as we may have named types in the future that
@@ -380,10 +380,10 @@ static inheritance_status zend_perform_covariant_type_check(
                        return INHERITANCE_SUCCESS;
                }
 
-               return ZEND_TYPE_MASK(fe_type) & MAY_BE_OBJECT ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
+               return ZEND_TYPE_FULL_MASK(fe_type) & MAY_BE_OBJECT
+                       ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
        } else {
-               return ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(fe_type))
-                       == ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(proto_type))
+               return ZEND_TYPE_PURE_MASK_WITHOUT_NULL(fe_type) == ZEND_TYPE_PURE_MASK_WITHOUT_NULL(proto_type)
                        ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
        }
 }
@@ -490,7 +490,7 @@ static inheritance_status zend_do_perform_implementation_check(
                }
 
                /* by-ref constraints on arguments are invariant */
-               if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
+               if (ZEND_ARG_SEND_MODE(fe_arg_info) != ZEND_ARG_SEND_MODE(proto_arg_info)) {
                        return INHERITANCE_ERROR;
                }
        }
@@ -561,11 +561,11 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
                for (i = 0; i < num_args;) {
                        zend_append_type_hint(&str, fptr, arg_info, 0);
 
-                       if (arg_info->pass_by_reference) {
+                       if (ZEND_ARG_SEND_MODE(arg_info)) {
                                smart_str_appendc(&str, '&');
                        }
 
-                       if (arg_info->is_variadic) {
+                       if (ZEND_ARG_IS_VARIADIC(arg_info)) {
                                smart_str_appends(&str, "...");
                        }
 
@@ -582,7 +582,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function
                                smart_str_append_unsigned(&str, i);
                        }
 
-                       if (i >= required && !arg_info->is_variadic) {
+                       if (i >= required && !ZEND_ARG_IS_VARIADIC(arg_info)) {
                                smart_str_appends(&str, " = ");
                                if (fptr->type == ZEND_USER_FUNCTION) {
                                        zend_op *precv = NULL;
@@ -847,7 +847,8 @@ inheritance_status property_types_compatible(
                const zend_property_info *parent_info, const zend_property_info *child_info) {
        zend_string *parent_name, *child_name;
        zend_class_entry *parent_type_ce, *child_type_ce;
-       if (parent_info->type == child_info->type) {
+       if (ZEND_TYPE_PURE_MASK(parent_info->type) == ZEND_TYPE_PURE_MASK(child_info->type)
+                       && ZEND_TYPE_NAME(parent_info->type) == ZEND_TYPE_NAME(child_info->type)) {
                return INHERITANCE_SUCCESS;
        }
 
index b381eeff1467469f0341b256d6e16c83a4290470..d77fbc68a371891e9c8e770cc3ffa0429daf26ce 100644 (file)
@@ -106,87 +106,106 @@ typedef void (*copy_ctor_func_t)(zval *pElement);
  * It shouldn't be used directly. Only through ZEND_TYPE_* macros.
  *
  * ZEND_TYPE_IS_SET()     - checks if type-hint exists
- * ZEND_TYPE_IS_MASK()    - checks if type-hint refer to standard type
+ * ZEND_TYPE_IS_ONLY_MASK() - checks if type-hint refer to standard type
  * ZEND_TYPE_IS_CLASS()   - checks if type-hint refer to some class
  * ZEND_TYPE_IS_CE()      - checks if type-hint refer to some class by zend_class_entry *
  * ZEND_TYPE_IS_NAME()    - checks if type-hint refer to some class by zend_string *
  *
  * ZEND_TYPE_NAME()       - returns referenced class name
  * ZEND_TYPE_CE()         - returns referenced class entry
- * ZEND_TYPE_MASK()       - returns MAY_BE_* type mask
+ * ZEND_TYPE_PURE_MASK()  - returns MAY_BE_* type mask
+ * ZEND_TYPE_FULL_MASK()  - returns MAY_BE_* type mask together with other flags
  *
  * ZEND_TYPE_ALLOW_NULL() - checks if NULL is allowed
  *
- * ZEND_TYPE_ENCODE_*() should be used for construction.
+ * ZEND_TYPE_INIT_*() should be used for construction.
  */
 
-typedef uintptr_t zend_type;
-
-#define _ZEND_TYPE_CODE_MAX ((Z_L(1)<<(IS_VOID+1))-1)
-#define _ZEND_TYPE_FLAG_MASK Z_L(0x3)
-#define _ZEND_TYPE_CE_BIT Z_L(0x1)
+typedef struct {
+       /* Not using a union here, because there's no good way to initialize them
+        * in a way that is supported in both C and C++ (designated initializers
+        * are only supported since C++20). */
+       void *ptr;
+       uint32_t type_mask;
+       /* TODO: We could use the extra 32-bit of padding on 64-bit systems. */
+} zend_type;
+
+#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 24
+#define _ZEND_TYPE_MASK ((1u << 24) - 1)
+#define _ZEND_TYPE_MAY_BE_MASK ((1u << (IS_VOID+1)) - 1)
+#define _ZEND_TYPE_CE_BIT (1u << 22)
+#define _ZEND_TYPE_NAME_BIT (1u << 23)
 /* Must have same value as MAY_BE_NULL */
-#define _ZEND_TYPE_NULLABLE_BIT Z_L(0x2)
+#define _ZEND_TYPE_NULLABLE_BIT 0x2
 
 #define ZEND_TYPE_IS_SET(t) \
-       ((t) != 0)
-
-#define ZEND_TYPE_IS_MASK(t) \
-       ((t) != 0 && (t) <= _ZEND_TYPE_CODE_MAX)
+       (((t).type_mask & _ZEND_TYPE_MASK) != 0)
 
 #define ZEND_TYPE_IS_CLASS(t) \
-       ((t) > _ZEND_TYPE_CODE_MAX)
+       (((t.type_mask) & (_ZEND_TYPE_NAME_BIT|_ZEND_TYPE_CE_BIT)) != 0)
 
 #define ZEND_TYPE_IS_CE(t) \
-       (((t) & _ZEND_TYPE_CE_BIT) != 0)
+       (((t.type_mask) & _ZEND_TYPE_CE_BIT) != 0)
 
 #define ZEND_TYPE_IS_NAME(t) \
-       (ZEND_TYPE_IS_CLASS(t) && !ZEND_TYPE_IS_CE(t))
+       (((t.type_mask) & _ZEND_TYPE_NAME_BIT) != 0)
+
+#define ZEND_TYPE_IS_ONLY_MASK(t) \
+       (ZEND_TYPE_IS_SET(t) && (t).ptr == NULL)
 
 #define ZEND_TYPE_NAME(t) \
-       ((zend_string*)((t) & ~_ZEND_TYPE_FLAG_MASK))
+       ((zend_string *) (t).ptr)
+
+#define ZEND_TYPE_LITERAL_NAME(t) \
+       ((const char *) (t).ptr)
 
 #define ZEND_TYPE_CE(t) \
-       ((zend_class_entry*)((t) & ~_ZEND_TYPE_FLAG_MASK))
+       ((zend_class_entry *) (t).ptr)
 
-#define ZEND_TYPE_MASK(t) \
-       (t)
+#define ZEND_TYPE_SET_PTR(t, _ptr) \
+       ((t).ptr = (_ptr))
+
+/* FULL_MASK() includes the MAY_BE_* type mask, the CE/NAME bits, as well as extra reserved bits.
+ * The PURE_MASK() only includes the MAY_BE_* type mask. */
+#define ZEND_TYPE_FULL_MASK(t) \
+       ((t).type_mask)
+
+#define ZEND_TYPE_PURE_MASK(t) \
+       ((t).type_mask & _ZEND_TYPE_MAY_BE_MASK)
+
+#define ZEND_TYPE_FULL_MASK_WITHOUT_NULL(t) \
+       ((t).type_mask & ~_ZEND_TYPE_NULLABLE_BIT)
+
+#define ZEND_TYPE_PURE_MASK_WITHOUT_NULL(t) \
+       ((t).type_mask & _ZEND_TYPE_MAY_BE_MASK & ~_ZEND_TYPE_NULLABLE_BIT)
 
 #define ZEND_TYPE_CONTAINS_CODE(t, code) \
-       (((t) & (1 << (code))) != 0)
+       (((t).type_mask & (1u << (code))) != 0)
 
 #define ZEND_TYPE_ALLOW_NULL(t) \
-       (((t) & _ZEND_TYPE_NULLABLE_BIT) != 0)
-
-#define ZEND_TYPE_WITHOUT_NULL(t) \
-       ((t) & ~_ZEND_TYPE_NULLABLE_BIT)
+       (((t).type_mask & _ZEND_TYPE_NULLABLE_BIT) != 0)
 
-#define ZEND_TYPE_ENCODE_NONE() \
-       (0)
+#define ZEND_TYPE_INIT_NONE(extra_flags) \
+       { NULL, (extra_flags) }
 
-#define ZEND_TYPE_ENCODE_MASK(maybe_code) \
-       (maybe_code)
+#define ZEND_TYPE_INIT_MASK(_type_mask) \
+       { NULL, (_type_mask) }
 
-#define ZEND_TYPE_ENCODE_CODE(code, allow_null) \
-       (((code) == _IS_BOOL ? (MAY_BE_FALSE|MAY_BE_TRUE) : (1 << (code))) \
-               | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
+#define ZEND_TYPE_INIT_CODE(code, allow_null, extra_flags) \
+       ZEND_TYPE_INIT_MASK(((code) == _IS_BOOL ? (MAY_BE_FALSE|MAY_BE_TRUE) : (1 << (code))) \
+               | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags))
 
-#define ZEND_TYPE_ENCODE_CE(ce, allow_null) \
-       (((uintptr_t)(ce)) | _ZEND_TYPE_CE_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
+#define ZEND_TYPE_INIT_CE(_ce, allow_null, extra_flags) \
+       { (void *) (_ce), \
+               _ZEND_TYPE_CE_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
 
-#define ZEND_TYPE_ENCODE_CLASS(class_name, allow_null) \
-       (((uintptr_t)(class_name)) | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : Z_L(0x0)))
+#define ZEND_TYPE_INIT_CLASS(class_name, allow_null, extra_flags) \
+       { (void *) (class_name), \
+               _ZEND_TYPE_NAME_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
 
-#define ZEND_TYPE_ENCODE_CLASS_CONST_0(class_name) \
-       ((zend_type) class_name)
-#define ZEND_TYPE_ENCODE_CLASS_CONST_1(class_name) \
-       ((zend_type) "?" class_name)
-#define ZEND_TYPE_ENCODE_CLASS_CONST_Q2(macro, class_name) \
-       macro(class_name)
-#define ZEND_TYPE_ENCODE_CLASS_CONST_Q1(allow_null, class_name) \
-       ZEND_TYPE_ENCODE_CLASS_CONST_Q2(ZEND_TYPE_ENCODE_CLASS_CONST_ ##allow_null, class_name)
-#define ZEND_TYPE_ENCODE_CLASS_CONST(class_name, allow_null) \
-       ZEND_TYPE_ENCODE_CLASS_CONST_Q1(allow_null, class_name)
+#define ZEND_TYPE_INIT_CLASS_CONST(class_name, allow_null, extra_flags) \
+       { (void *) (class_name), \
+               _ZEND_TYPE_NAME_BIT | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
 
 typedef union _zend_value {
        zend_long         lval;                         /* long value */
index 3ba0c41d630d2027b49f1cf9c52ce4cb7117598f..a36458b8995c3f02ba33398e1afe1bb8ff7c0c1d 100644 (file)
@@ -4109,7 +4109,7 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
index f754348bac9dd4b6450e9fcf0133489ba73662aa..be26c30765806204a548cca5fb20ef60a4ce281d 100644 (file)
@@ -8739,7 +8739,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
@@ -18669,7 +18669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
@@ -26096,7 +26096,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
@@ -32718,7 +32718,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
@@ -44161,7 +44161,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
                }
 
                if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type)
-                       && !(ZEND_TYPE_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
+                       && !(ZEND_TYPE_FULL_MASK(ret_info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))
                        && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr))
                        && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)
                        && retval_ref != retval_ptr)
index 2d3f6c8e5cb3623c82010c1e9495a1c57e6fffc5..526ccf79773c9e9a598a2602b70aec5c7e40fca7 100644 (file)
@@ -496,7 +496,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
 
        if (f->arg_info) {
                for (i = 0; i < nargs; i++) {
-                       if (f->arg_info[nargs - i - 1].pass_by_reference) {
+                       if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
                                byref_count++;
                        }
                }
@@ -505,7 +505,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
        if (byref_count) {
                byref_vals = (VARIANT*)safe_emalloc(sizeof(VARIANT), byref_count, 0);
                for (j = 0, i = 0; i < nargs; i++) {
-                       if (f->arg_info[nargs - i - 1].pass_by_reference) {
+                       if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
                                /* put the value into byref_vals instead */
                                php_com_variant_from_zval(&byref_vals[j], &args[nargs - i - 1], obj->code_page);
 
@@ -552,7 +552,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function *
                if (f && f->arg_info) {
                        for (i = 0, j = 0; i < nargs; i++) {
                                /* if this was byref, update the zval */
-                               if (f->arg_info[nargs - i - 1].pass_by_reference) {
+                               if (ZEND_ARG_SEND_MODE(&f->arg_info[nargs - i - 1])) {
                                        zval *arg = &args[nargs - i - 1];
 
                                        ZVAL_DEREF(arg);
index 1a5d9c30461b8f9e42f614c43bffdb22ebf2fa49..ed08494d85721ef577d8862e0061c9c397ca9dbf 100644 (file)
@@ -327,10 +327,8 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name
                                                        f.arg_info = ecalloc(bindptr.lpfuncdesc->cParams, sizeof(zend_arg_info));
 
                                                        for (i = 0; i < bindptr.lpfuncdesc->cParams; i++) {
-                                                               f.arg_info[i].type = ZEND_TYPE_ENCODE_NONE();
-                                                               if (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) {
-                                                                       f.arg_info[i].pass_by_reference = ZEND_SEND_BY_REF;
-                                                               }
+                                                               zend_bool by_ref = (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) != 0;
+                                                               f.arg_info[i].type = (zend_type) ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(by_ref, 0));
                                                        }
 
                                                        f.num_args = bindptr.lpfuncdesc->cParams;
index f4c5dee916209093dc0a12108b67fe9db54ba466..59c562425f13b32e0ddcf619298a920f0e803d3e 100644 (file)
@@ -307,8 +307,7 @@ static inline zend_bool can_elide_return_type_check(
        }
 
        /* These types are not represented exactly */
-       if (ZEND_TYPE_IS_MASK(info->type)
-                       && (ZEND_TYPE_MASK(info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE))) {
+       if (ZEND_TYPE_FULL_MASK(info->type) & (MAY_BE_CALLABLE|MAY_BE_ITERABLE)) {
                return 0;
        }
 
index ea2b904a0f4e67a8c5bfb0570a810fd72ffe6330..2894ca89f4d54d06a8071fb211f48dec32f7d72e 100644 (file)
@@ -116,7 +116,7 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
                        for (i = 0; i < num_args; i++) {
                                /* Don't inline functions with by-reference arguments. This would require
                                 * correct handling of INDIRECT arguments. */
-                               if (func->op_array.arg_info[i].pass_by_reference) {
+                               if (ZEND_ARG_SEND_MODE(&func->op_array.arg_info[i])) {
                                        return;
                                }
                        }
index 51872dcc611b5562aaf22ab10ba5e00c90d93af0..8fc92f842c0705723092b2dc51ebac1c293fe2b7 100644 (file)
@@ -1420,21 +1420,19 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int
                                } else if (op_array->arg_info &&
                                    opline->op1.num <= op_array->num_args) {
                                        zend_type type = op_array->arg_info[opline->op1.num-1].type;
-                                       if (ZEND_TYPE_IS_MASK(type)) {
-                                               uint32_t mask = ZEND_TYPE_MASK(ZEND_TYPE_WITHOUT_NULL(type));
-                                               if (mask == MAY_BE_LONG) {
-                                                       tmp->underflow = 0;
-                                                       tmp->min = ZEND_LONG_MIN;
-                                                       tmp->max = ZEND_LONG_MAX;
-                                                       tmp->overflow = 0;
-                                                       return 1;
-                                               } else if (mask == (MAY_BE_FALSE|MAY_BE_TRUE)) {
-                                                       tmp->underflow = 0;
-                                                       tmp->min = 0;
-                                                       tmp->max = 1;
-                                                       tmp->overflow = 0;
-                                                       return 1;
-                                               }
+                                       uint32_t mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(type);
+                                       if (mask == MAY_BE_LONG) {
+                                               tmp->underflow = 0;
+                                               tmp->min = ZEND_LONG_MIN;
+                                               tmp->max = ZEND_LONG_MAX;
+                                               tmp->overflow = 0;
+                                               return 1;
+                                       } else if (mask == (MAY_BE_FALSE|MAY_BE_TRUE)) {
+                                               tmp->underflow = 0;
+                                               tmp->min = 0;
+                                               tmp->max = 1;
+                                               tmp->overflow = 0;
+                                               return 1;
                                        }
                                }
                        }
@@ -2231,42 +2229,36 @@ static inline zend_class_entry *get_class_entry(const zend_script *script, zend_
 }
 
 static uint32_t zend_convert_type_declaration_mask(uint32_t type_mask) {
+       uint32_t result_mask = type_mask & MAY_BE_ANY;
        if (type_mask & MAY_BE_VOID) {
-               type_mask &= ~MAY_BE_VOID;
-               type_mask |= MAY_BE_NULL;
+               result_mask |= MAY_BE_NULL;
        }
        if (type_mask & MAY_BE_CALLABLE) {
-               type_mask &= ~MAY_BE_CALLABLE;
-               type_mask |= MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+               result_mask |= MAY_BE_STRING|MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
        }
        if (type_mask & MAY_BE_ITERABLE) {
-               type_mask &= ~MAY_BE_ITERABLE;
-               type_mask |= MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+               result_mask |= MAY_BE_OBJECT|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
        }
        if (type_mask & MAY_BE_ARRAY) {
-               type_mask |= MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+               result_mask |= MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
        }
-       return type_mask;
+       return result_mask;
 }
 
 uint32_t zend_fetch_arg_info_type(const zend_script *script, zend_arg_info *arg_info, zend_class_entry **pce)
 {
-       uint32_t tmp = 0;
+       uint32_t tmp;
+       if (!ZEND_TYPE_IS_SET(arg_info->type)) {
+               return MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN;
+       }
 
+       tmp = zend_convert_type_declaration_mask(ZEND_TYPE_PURE_MASK(arg_info->type));
        *pce = NULL;
        if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
-               // class type hinting...
                zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(arg_info->type));
                tmp |= MAY_BE_OBJECT;
                *pce = get_class_entry(script, lcname);
                zend_string_release_ex(lcname, 0);
-       } else if (ZEND_TYPE_IS_MASK(arg_info->type)) {
-               tmp |= zend_convert_type_declaration_mask(ZEND_TYPE_MASK(arg_info->type));
-       } else {
-               tmp |= MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
-       }
-       if (ZEND_TYPE_ALLOW_NULL(arg_info->type)) {
-               tmp |= MAY_BE_NULL;
        }
        if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
                tmp |= MAY_BE_RC1 | MAY_BE_RCN;
@@ -2365,7 +2357,7 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in
        if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
                uint32_t type = ZEND_TYPE_IS_CLASS(prop_info->type)
                        ? MAY_BE_OBJECT
-                       : zend_convert_type_declaration_mask(ZEND_TYPE_MASK(prop_info->type));
+                       : zend_convert_type_declaration_mask(ZEND_TYPE_PURE_MASK(prop_info->type));
 
                if (ZEND_TYPE_ALLOW_NULL(prop_info->type)) {
                        type |= MAY_BE_NULL;
@@ -3097,7 +3089,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
                        ce = NULL;
                        if (arg_info) {
                                tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
-                               if (arg_info->pass_by_reference) {
+                               if (ZEND_ARG_SEND_MODE(arg_info)) {
                                        tmp |= MAY_BE_REF;
                                }
                        } else {
index aa638032cae2ab8d9a186c6c4215b9ced95bf341..08879734a871cca424006f137bf0271cb4611831 100644 (file)
@@ -652,9 +652,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
                                }
                                case ZEND_VERIFY_RETURN_TYPE: {
                                        zend_arg_info *ret_info = op_array->arg_info - 1;
-                                       if (ZEND_TYPE_IS_CLASS(ret_info->type)
-                                               || (ZEND_TYPE_IS_MASK(ret_info->type)
-                                                       && !ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(val)))
+                                       if (!ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(val))
                                                || (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
                                                return 0;
                                        }
index 12dd8aba7aee677f94d5690cca0148158279c5c1..68be526892b3b7b482127ce2ded27a0b2ad8d389 100644 (file)
@@ -602,8 +602,8 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int
                        }
                        for (i = 0 ; i < num_args; i++) {
                                if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
-                                       zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
-                                       arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(new_interned_string(ZEND_TYPE_NAME(arg_info[i].type)), allow_null);
+                                       ZEND_TYPE_SET_PTR(arg_info[i].type,
+                                               new_interned_string(ZEND_TYPE_NAME(arg_info[i].type)));
                                }
                        }
                }
@@ -3580,7 +3580,7 @@ static zend_bool preload_try_resolve_property_types(zend_class_entry *ce)
                        }
 
                        zend_string_release(name);
-                       prop->type = ZEND_TYPE_ENCODE_CE(p, ZEND_TYPE_ALLOW_NULL(prop->type));
+                       prop->type = (zend_type) ZEND_TYPE_INIT_CE(p, ZEND_TYPE_ALLOW_NULL(prop->type), 0);
                } ZEND_HASH_FOREACH_END();
        }
 
index f581841aab5ced256de45ae3800fffbceb6db831..658350794ed110fce0bb21ad8a0979d899e6de97 100644 (file)
@@ -1177,7 +1177,7 @@ static void ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, const zend_op_arra
                goto err;
        }
 
-       type_mask = ZEND_TYPE_MASK(arg_info->type);
+       type_mask = ZEND_TYPE_FULL_MASK(arg_info->type);
        if (type_mask & MAY_BE_CALLABLE) {
                if (zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) == 0) {
                        goto err;
@@ -1188,7 +1188,7 @@ static void ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, const zend_op_arra
                }
        } else  {
                if (Z_ISUNDEF_P(arg) ||
-                   zend_verify_scalar_type_hint(ZEND_TYPE_MASK(arg_info->type), arg, ZEND_ARG_USES_STRICT_TYPES(), /* is_internal */ 0) == 0) {
+                   zend_verify_scalar_type_hint(type_mask, arg, ZEND_ARG_USES_STRICT_TYPES(), /* is_internal */ 0) == 0) {
                        goto err;
                }
        }
@@ -1345,7 +1345,7 @@ static zend_property_info *zend_jit_get_prop_not_accepting_double(zend_reference
 {
        zend_property_info *prop;
        ZEND_REF_FOREACH_TYPE_SOURCES(ref, prop) {
-               if (!ZEND_TYPE_IS_MASK(prop->type) || !(ZEND_TYPE_MASK(prop->type) & MAY_BE_DOUBLE)) {
+               if (!(ZEND_TYPE_FULL_MASK(prop->type) & MAY_BE_DOUBLE)) {
                        return prop;
                }
        } ZEND_REF_FOREACH_TYPE_SOURCES_END();
index 02b6f606aebca6e8f42b347986168898907fcc03..0681a450641cc4d713da1ef0c4aade43cfe7d2bd 100644 (file)
@@ -7102,8 +7102,8 @@ static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ss
                zend_arg_info *arg_info = func->op_array.arg_info + num_args;
 
                if (ZEND_TYPE_IS_SET(arg_info->type)) {
-                       if (ZEND_TYPE_IS_MASK(arg_info->type)) {
-                               uint32_t type_mask = ZEND_TYPE_MASK(arg_info->type);
+                       if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) {
+                               uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
                                uint32_t info = _ssa_op1_info(op_array, ssa, call_info->arg_info[num_args].opline);
                                if ((info & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) {
                                        break;
@@ -9032,12 +9032,12 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
                                zend_jit_addr res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, NULL, -1);
 
                                |       LOAD_ZVAL_ADDR r0, res_addr
-                               if (arg_info->pass_by_reference) {
+                               if (ZEND_ARG_SEND_MODE(arg_info)) {
                                        |       GET_Z_PTR r0, r0
                                        |       add r0, offsetof(zend_reference, val)
                                }
                                if (!ZEND_TYPE_IS_CLASS(type)) {
-                                       uint32_t type_mask = ZEND_TYPE_MASK(type);
+                                       uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
                                        if (is_power_of_two(type_mask)) {
                                                uint32_t type_code = concrete_type(type_mask);
                                                |       cmp byte [r0 + 8], type_code
@@ -9186,7 +9186,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
                        |       LOAD_ZVAL_ADDR r0, res_addr
                        |       ZVAL_DEREF r0, MAY_BE_REF
                        if (!ZEND_TYPE_IS_CLASS(arg_info->type)) {
-                               uint32_t type_mask = ZEND_TYPE_MASK(arg_info->type);
+                               uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type);
                                if (is_power_of_two(type_mask)) {
                                        uint32_t type_code = concrete_type(type_mask);
                                        |       cmp byte [r0 + 8], type_code
index dc7a76b32610f22d55dac83bf040c8e2616e9e93..e74b7bb6689b782b3bbf108f6737a8ffefc6751a 100644 (file)
@@ -237,7 +237,7 @@ static void zend_hash_clone_prop_info(HashTable *ht)
                                zend_class_entry *ce = ZEND_TYPE_CE(prop_info->type);
                                if (IN_ARENA(ce)) {
                                        ce = ARENA_REALLOC(ce);
-                                       prop_info->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop_info->type));
+                                       ZEND_TYPE_SET_PTR(prop_info->type, ce);
                                }
                        }
                }
index 697bb10b0d749876e5194764791e8bf3c28759de..6e4d52cee6ffce8c4c2e613edc79323eecc426a1 100644 (file)
@@ -499,14 +499,9 @@ static void zend_file_cache_serialize_op_array(zend_op_array            *op_arra
                                        SERIALIZE_STR(p->name);
                                }
                                if (ZEND_TYPE_IS_CLASS(p->type)) {
-                                       zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(p->type);
                                        zend_string *type_name = ZEND_TYPE_NAME(p->type);
-
                                        SERIALIZE_STR(type_name);
-                                       p->type =
-                                               (Z_UL(1) << (sizeof(zend_type)*8-1)) | /* type is class */
-                                               (allow_null ? (Z_UL(1) << (sizeof(zend_type)*8-2)) : Z_UL(0)) | /* type allow null */
-                                               (zend_type)type_name;
+                                       ZEND_TYPE_SET_PTR(p->type, type_name);
                                }
                                p++;
                        }
@@ -577,16 +572,14 @@ static void zend_file_cache_serialize_prop_info(zval                     *zv,
                                SERIALIZE_STR(prop->doc_comment);
                        }
                }
-               if (prop->type) {
-                       if (ZEND_TYPE_IS_NAME(prop->type)) {
-                               zend_string *name = ZEND_TYPE_NAME(prop->type);
-                               SERIALIZE_STR(name);
-                               prop->type = ZEND_TYPE_ENCODE_CLASS(name, ZEND_TYPE_ALLOW_NULL(prop->type));
-                       } else if (ZEND_TYPE_IS_CE(prop->type)) {
-                               zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
-                               SERIALIZE_PTR(ce);
-                               prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
-                       }
+               if (ZEND_TYPE_IS_NAME(prop->type)) {
+                       zend_string *name = ZEND_TYPE_NAME(prop->type);
+                       SERIALIZE_STR(name);
+                       ZEND_TYPE_SET_PTR(prop->type, name);
+               } else if (ZEND_TYPE_IS_CE(prop->type)) {
+                       zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
+                       SERIALIZE_PTR(ce);
+                       ZEND_TYPE_SET_PTR(prop->type, ce);
                }
        }
 }
@@ -1202,12 +1195,10 @@ static void zend_file_cache_unserialize_op_array(zend_op_array           *op_arr
                                if (!IS_UNSERIALIZED(p->name)) {
                                        UNSERIALIZE_STR(p->name);
                                }
-                               if (p->type & (Z_UL(1) << (sizeof(zend_type)*8-1))) { /* type is class */
-                                       zend_bool allow_null = (p->type & (Z_UL(1) << (sizeof(zend_type)*8-2))) != 0; /* type allow null */
-                                       zend_string *type_name = (zend_string*)(p->type & ~(((Z_UL(1) << (sizeof(zend_type)*8-1))) | ((Z_UL(1) << (sizeof(zend_type)*8-2)))));
-
+                               if (ZEND_TYPE_IS_CLASS(p->type)) {
+                                       zend_string *type_name = ZEND_TYPE_NAME(p->type);
                                        UNSERIALIZE_STR(type_name);
-                                       p->type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
+                                       ZEND_TYPE_SET_PTR(p->type, type_name);
                                }
                                p++;
                        }
@@ -1278,16 +1269,14 @@ static void zend_file_cache_unserialize_prop_info(zval                    *zv,
                                UNSERIALIZE_STR(prop->doc_comment);
                        }
                }
-               if (prop->type) {
-                       if (ZEND_TYPE_IS_NAME(prop->type)) {
-                               zend_string *name = ZEND_TYPE_NAME(prop->type);
-                               UNSERIALIZE_STR(name);
-                               prop->type = ZEND_TYPE_ENCODE_CLASS(name, ZEND_TYPE_ALLOW_NULL(prop->type));
-                       } else if (ZEND_TYPE_IS_CE(prop->type)) {
-                               zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
-                               UNSERIALIZE_PTR(ce);
-                               prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
-                       }
+               if (ZEND_TYPE_IS_NAME(prop->type)) {
+                       zend_string *name = ZEND_TYPE_NAME(prop->type);
+                       UNSERIALIZE_STR(name);
+                       ZEND_TYPE_SET_PTR(prop->type, name);
+               } else if (ZEND_TYPE_IS_CE(prop->type)) {
+                       zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
+                       UNSERIALIZE_PTR(ce);
+                       ZEND_TYPE_SET_PTR(prop->type, ce);
                }
        }
 }
index 60c7620ee9d99afc81de6bd05625d6718cbe2bbb..56c64dc87d1a8f34ef03d3351c82bc233bf32deb 100644 (file)
@@ -501,10 +501,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                        }
                        if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
                                zend_string *type_name = ZEND_TYPE_NAME(arg_info[i].type);
-                               zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
-
                                zend_accel_store_interned_string(type_name);
-                               arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
+                               ZEND_TYPE_SET_PTR(arg_info[i].type, type_name);
                        }
                }
                if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
@@ -664,7 +662,7 @@ static void zend_persist_property_info(zval *zv)
        if (ZEND_TYPE_IS_NAME(prop->type)) {
                zend_string *class_name = ZEND_TYPE_NAME(prop->type);
                zend_accel_store_interned_string(class_name);
-               prop->type = ZEND_TYPE_ENCODE_CLASS(class_name, ZEND_TYPE_ALLOW_NULL(prop->type));
+               ZEND_TYPE_SET_PTR(prop->type, class_name);
        }
 }
 
@@ -944,7 +942,7 @@ static void zend_update_parent_ce(zend_class_entry *ce)
                                if (ce->type == ZEND_USER_CLASS) {
                                        ce = zend_shared_alloc_get_xlat_entry(ce);
                                        if (ce) {
-                                               prop->type = ZEND_TYPE_ENCODE_CE(ce, ZEND_TYPE_ALLOW_NULL(prop->type));
+                                               ZEND_TYPE_SET_PTR(prop->type, ce);
                                        }
                                }
                        }
index cc798b27de05030ac5cc66fbee19ae34324217c6..62a3deaea0053f28a1bb960d5ce208238ab12bc2 100644 (file)
@@ -224,10 +224,8 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
                        }
                        if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) {
                                zend_string *type_name = ZEND_TYPE_NAME(arg_info[i].type);
-                               zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(arg_info[i].type);
-
                                ADD_INTERNED_STRING(type_name);
-                               arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
+                               ZEND_TYPE_SET_PTR(arg_info[i].type, type_name);
                        }
                }
        }
@@ -307,7 +305,7 @@ static void zend_persist_property_info_calc(zval *zv)
                if (ZEND_TYPE_IS_NAME(prop->type)) {
                        zend_string *class_name = ZEND_TYPE_NAME(prop->type);
                        ADD_INTERNED_STRING(class_name);
-                       prop->type = ZEND_TYPE_ENCODE_CLASS(class_name, ZEND_TYPE_ALLOW_NULL(prop->type));
+                       ZEND_TYPE_SET_PTR(prop->type, class_name);
                }
                if (ZCG(accel_directives).save_comments && prop->doc_comment) {
                        ADD_STRING(prop->doc_comment);
index e5a740d9d7704d63b97251975acaade2ba13a356..28cca1e11b1ff3b959c3ecae51a638d91ed2c199 100644 (file)
@@ -1292,10 +1292,10 @@ int pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind)
                        } else {
                                func.required_num_args = info->required_num_args;
                        }
-                       if (info->return_reference) {
+                       if (ZEND_ARG_SEND_MODE(info)) {
                                func.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
                        }
-                       if (funcs->arg_info[funcs->num_args].is_variadic) {
+                       if (ZEND_ARG_IS_VARIADIC(&funcs->arg_info[funcs->num_args])) {
                                func.fn_flags |= ZEND_ACC_VARIADIC;
                                /* Don't count the variadic argument */
                                func.num_args--;
index 5bfbb5f6f9a603b5829da4bdee7146f2763c6365..522b9d211d32a4cae2ceeed24dd1602767ce8437 100644 (file)
@@ -595,10 +595,10 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_
                smart_str_append_printf(str, "%s ", ZSTR_VAL(type_str));
                zend_string_release(type_str);
        }
-       if (arg_info->pass_by_reference) {
+       if (ZEND_ARG_SEND_MODE(arg_info)) {
                smart_str_appendc(str, '&');
        }
-       if (arg_info->is_variadic) {
+       if (ZEND_ARG_IS_VARIADIC(arg_info)) {
                smart_str_appends(str, "...");
        }
        if (arg_info->name) {
@@ -2572,15 +2572,15 @@ ZEND_METHOD(reflection_parameter, isArray)
 {
        reflection_object *intern;
        parameter_reference *param;
-       zend_type type;
+       uint32_t type_mask;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       type = ZEND_TYPE_WITHOUT_NULL(param->arg_info->type);
-       RETVAL_BOOL(ZEND_TYPE_MASK(type) == MAY_BE_ARRAY);
+       type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type);
+       RETVAL_BOOL(type_mask == MAY_BE_ARRAY);
 }
 /* }}} */
 
@@ -2590,15 +2590,15 @@ ZEND_METHOD(reflection_parameter, isCallable)
 {
        reflection_object *intern;
        parameter_reference *param;
-       zend_type type;
+       uint32_t type_mask;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       type = ZEND_TYPE_WITHOUT_NULL(param->arg_info->type);
-       RETVAL_BOOL(ZEND_TYPE_MASK(type) == MAY_BE_CALLABLE);
+       type_mask = ZEND_TYPE_PURE_MASK_WITHOUT_NULL(param->arg_info->type);
+       RETVAL_BOOL(type_mask == MAY_BE_CALLABLE);
 }
 /* }}} */
 
@@ -2631,7 +2631,7 @@ ZEND_METHOD(reflection_parameter, isPassedByReference)
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       RETVAL_BOOL(param->arg_info->pass_by_reference);
+       RETVAL_BOOL(ZEND_ARG_SEND_MODE(param->arg_info));
 }
 /* }}} */
 
@@ -2648,7 +2648,7 @@ ZEND_METHOD(reflection_parameter, canBePassedByValue)
        GET_REFLECTION_OBJECT_PTR(param);
 
        /* true if it's ZEND_SEND_BY_VAL or ZEND_SEND_PREFER_REF */
-       RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF);
+       RETVAL_BOOL(ZEND_ARG_SEND_MODE(param->arg_info) != ZEND_SEND_BY_REF);
 }
 /* }}} */
 
@@ -2809,7 +2809,7 @@ ZEND_METHOD(reflection_parameter, isVariadic)
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       RETVAL_BOOL(param->arg_info->is_variadic);
+       RETVAL_BOOL(ZEND_ARG_IS_VARIADIC(param->arg_info));
 }
 /* }}} */
 
@@ -2829,6 +2829,11 @@ ZEND_METHOD(reflection_type, allowsNull)
 }
 /* }}} */
 
+static zend_string *zend_type_to_string_without_null(zend_type type) {
+       ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL;
+       return zend_type_to_string(type);
+}
+
 /* {{{ proto public string ReflectionType::__toString()
    Return the text of the type hint */
 ZEND_METHOD(reflection_type, __toString)
@@ -2857,7 +2862,7 @@ ZEND_METHOD(reflection_named_type, getName)
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       RETURN_STR(zend_type_to_string(ZEND_TYPE_WITHOUT_NULL(param->type)));
+       RETURN_STR(zend_type_to_string_without_null(param->type));
 }
 /* }}} */
 
@@ -2873,7 +2878,7 @@ ZEND_METHOD(reflection_named_type, isBuiltin)
        }
        GET_REFLECTION_OBJECT_PTR(param);
 
-       RETVAL_BOOL(ZEND_TYPE_IS_MASK(param->type));
+       RETVAL_BOOL(ZEND_TYPE_IS_ONLY_MASK(param->type));
 }
 /* }}} */
 
index cdff844ea9eb8f1ddaca2612ee1dce5155ee5aa5..3b2cb7376e039ba77c27fd854ee6735fe547d5ed 100644 (file)
@@ -237,7 +237,8 @@ PHP_MINIT_FUNCTION(zend_test)
                zval val;
                ZVAL_LONG(&val, 123);
                zend_declare_typed_property(
-                       zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL, ZEND_TYPE_ENCODE_CODE(IS_LONG, 0));
+                       zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL,
+                       (zend_type) ZEND_TYPE_INIT_CODE(IS_LONG, 0, 0));
                zend_string_release(name);
        }
 
@@ -248,7 +249,7 @@ PHP_MINIT_FUNCTION(zend_test)
                ZVAL_NULL(&val);
                zend_declare_typed_property(
                        zend_test_class, name, &val, ZEND_ACC_PUBLIC, NULL,
-                       ZEND_TYPE_ENCODE_CLASS(class_name, 1));
+                       (zend_type) ZEND_TYPE_INIT_CLASS(class_name, 1, 0));
                zend_string_release(name);
        }
 
@@ -258,7 +259,7 @@ PHP_MINIT_FUNCTION(zend_test)
                ZVAL_LONG(&val, 123);
                zend_declare_typed_property(
                        zend_test_class, name, &val, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC, NULL,
-                       ZEND_TYPE_ENCODE_CODE(IS_LONG, 0));
+                       (zend_type) ZEND_TYPE_INIT_CODE(IS_LONG, 0, 0));
                zend_string_release(name);
        }
 
index d8c7d3941a8db1bc0a96a521e70f2a370eb4e479..453a0d74ba374215dc3db3608e4c7806024b5eab 100644 (file)
@@ -229,7 +229,7 @@ static void phpdbg_dump_prototype(zval *tmp) /* {{{ */
                                }
 
                                if (!is_variadic) {
-                                       is_variadic = arginfo ? arginfo[j].is_variadic : 0;
+                                       is_variadic = arginfo ? ZEND_ARG_IS_VARIADIC(&arginfo[j]) : 0;
                                }
 
                                phpdbg_xml(" variadic=\"%s\" name=\"%s\">", is_variadic ? "variadic" : "", arg_name ? arg_name : "");