summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-09-20 17:01:19 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-11-08 15:15:48 +0100
commitac4e0f0852ce780e143013ceff45067a172e8a83 (patch)
treef39eebeb379b6f75e95a333ccec37c4af264d8ee
parenta555cc0b3d4f745e6d0bb8c595de400a0c728827 (diff)
downloadphp-git-ac4e0f0852ce780e143013ceff45067a172e8a83.tar.gz
Make zend_type a 2-field struct
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.
-rw-r--r--Zend/zend.c7
-rw-r--r--Zend/zend_API.c25
-rw-r--r--Zend/zend_API.h37
-rw-r--r--Zend/zend_closures.c6
-rw-r--r--Zend/zend_compile.c45
-rw-r--r--Zend/zend_compile.h16
-rw-r--r--Zend/zend_execute.c37
-rw-r--r--Zend/zend_inheritance.c23
-rw-r--r--Zend/zend_types.h111
-rw-r--r--Zend/zend_vm_def.h2
-rw-r--r--Zend/zend_vm_execute.h10
-rw-r--r--ext/com_dotnet/com_com.c6
-rw-r--r--ext/com_dotnet/com_handlers.c6
-rw-r--r--ext/opcache/Optimizer/dfa_pass.c3
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c2
-rw-r--r--ext/opcache/Optimizer/zend_inference.c60
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c4
-rw-r--r--ext/opcache/ZendAccelerator.c6
-rw-r--r--ext/opcache/jit/zend_jit_helpers.c6
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc10
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c2
-rw-r--r--ext/opcache/zend_file_cache.c51
-rw-r--r--ext/opcache/zend_persist.c8
-rw-r--r--ext/opcache/zend_persist_calc.c6
-rw-r--r--ext/pdo/pdo_dbh.c4
-rw-r--r--ext/reflection/php_reflection.c31
-rw-r--r--ext/zend_test/test.c7
-rw-r--r--sapi/phpdbg/phpdbg_frame.c2
28 files changed, 265 insertions, 268 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index ce98f50025..8c9ae86d74 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -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);
}
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 387f6e1a98..3c1ca4c718 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -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));
}
/* }}} */
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 1389f0a6d0..2801b08266 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -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 */
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index bb469558a1..63b91aacbd 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -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>"));
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 3800c664e1..ea93e878d0 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -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",
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index e4096a05a5..96db1dcb3a 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -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) \
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 8278f698cd..097137aa5c 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -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;
}
}
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index a1ecb9e2b7..af81c327e1 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -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;
}
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index b381eeff14..d77fbc68a3 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -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 */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3ba0c41d63..a36458b899 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -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)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index f754348bac..be26c30765 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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)
diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c
index 2d3f6c8e5c..526ccf7977 100644
--- a/ext/com_dotnet/com_com.c
+++ b/ext/com_dotnet/com_com.c
@@ -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);
diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c
index 1a5d9c3046..ed08494d85 100644
--- a/ext/com_dotnet/com_handlers.c
+++ b/ext/com_dotnet/com_handlers.c
@@ -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;
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index f4c5dee916..59c562425f 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass.c
@@ -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;
}
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index ea2b904a0f..2894ca89f4 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -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;
}
}
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index 51872dcc61..8fc92f842c 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -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 {
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index aa638032ca..08879734a8 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -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;
}
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 12dd8aba7a..68be526892 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -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();
}
diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c
index f581841aab..658350794e 100644
--- a/ext/opcache/jit/zend_jit_helpers.c
+++ b/ext/opcache/jit/zend_jit_helpers.c
@@ -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();
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 02b6f606ae..0681a45064 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -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
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
index dc7a76b326..e74b7bb668 100644
--- a/ext/opcache/zend_accelerator_util_funcs.c
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -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);
}
}
}
diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c
index 697bb10b0d..6e4d52cee6 100644
--- a/ext/opcache/zend_file_cache.c
+++ b/ext/opcache/zend_file_cache.c
@@ -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);
}
}
}
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index 60c7620ee9..56c64dc87d 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -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);
}
}
}
diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c
index cc798b27de..62a3deaea0 100644
--- a/ext/opcache/zend_persist_calc.c
+++ b/ext/opcache/zend_persist_calc.c
@@ -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);
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index e5a740d9d7..28cca1e11b 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -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--;
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 5bfbb5f6f9..522b9d211d 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -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));
}
/* }}} */
diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c
index cdff844ea9..3b2cb7376e 100644
--- a/ext/zend_test/test.c
+++ b/ext/zend_test/test.c
@@ -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);
}
diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c
index d8c7d3941a..453a0d74ba 100644
--- a/sapi/phpdbg/phpdbg_frame.c
+++ b/sapi/phpdbg/phpdbg_frame.c
@@ -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 : "");