summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 : "");