diff options
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 : ""); |