memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
ZEND_TYPE_SET_PTR(new_arg_info[i].type, new_list);
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(new_list, entry) {
- zend_string *name = zend_string_dup(ZEND_TYPE_LIST_GET_NAME(*entry), 1);
- *entry = ZEND_TYPE_LIST_ENCODE_NAME(name);
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
+ zend_string *name = zend_string_dup(ZEND_TYPE_NAME(*list_type), 1);
+ ZEND_TYPE_SET_PTR(*list_type, name);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) {
zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1);
if (UNEXPECTED(ZEND_CLASS_HAS_TYPE_HINTS(ce))) {
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (ZEND_TYPE_HAS_LIST(prop_info->type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(prop_info->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- zend_string *type_name = ZEND_TYPE_LIST_GET_NAME(*entry);
- *entry = ZEND_TYPE_LIST_ENCODE_CE(resolve_type_name(type_name));
- zend_string_release(type_name);
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(prop_info->type)) {
- zend_string *type_name = ZEND_TYPE_NAME(prop_info->type);
- ZEND_TYPE_SET_CE(prop_info->type, resolve_type_name(type_name));
- zend_string_release(type_name);
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop_info->type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ zend_string *type_name = ZEND_TYPE_NAME(*single_type);
+ ZEND_TYPE_SET_CE(*single_type, resolve_type_name(type_name));
+ zend_string_release(type_name);
+ }
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope) {
zend_string *str = NULL;
if (ZEND_TYPE_HAS_LIST(type)) {
- void *elem;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), elem) {
- if (ZEND_TYPE_LIST_IS_CE(elem)) {
- str = add_type_string(str, ZEND_TYPE_LIST_GET_CE(elem)->name);
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) {
+ if (ZEND_TYPE_HAS_CE(*list_type)) {
+ str = add_type_string(str, ZEND_TYPE_CE(*list_type)->name);
} else {
- str = add_type_string(str,
- resolve_class_name(ZEND_TYPE_LIST_GET_NAME(elem), scope));
+ str = add_type_string(str, resolve_class_name(ZEND_TYPE_NAME(*list_type), scope));
}
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(type)) {
if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
zend_type return_type = CG(active_op_array)->arg_info[-1].type;
- zend_bool valid_type = 0;
- if (ZEND_TYPE_HAS_CLASS(return_type)) {
- if (ZEND_TYPE_HAS_LIST(return_type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(return_type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
- if (is_generator_compatible_class_type(ZEND_TYPE_LIST_GET_NAME(entry))) {
- valid_type = 1;
- break;
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else {
- ZEND_ASSERT(ZEND_TYPE_HAS_NAME(return_type));
- valid_type = is_generator_compatible_class_type(ZEND_TYPE_NAME(return_type));
- }
- } else {
- valid_type = (ZEND_TYPE_FULL_MASK(return_type) & MAY_BE_ITERABLE) != 0;
+ zend_bool valid_type = (ZEND_TYPE_FULL_MASK(return_type) & MAY_BE_ITERABLE) != 0;
+ if (!valid_type) {
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(return_type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)
+ && is_generator_compatible_class_type(ZEND_TYPE_NAME(*single_type))) {
+ valid_type = 1;
+ break;
+ }
+ } ZEND_TYPE_FOREACH_END();
}
if (!valid_type) {
}
static zend_bool zend_type_contains_traversable(zend_type type) {
- if (ZEND_TYPE_HAS_LIST(type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
- if (zend_string_equals_literal_ci(ZEND_TYPE_LIST_GET_NAME(entry), "Traversable")) {
- return 1;
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(type)) {
- return zend_string_equals_literal_ci(ZEND_TYPE_NAME(type), "Traversable");
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)
+ && zend_string_equals_literal_ci(ZEND_TYPE_NAME(*single_type), "Traversable")) {
+ return 1;
+ }
+ } ZEND_TYPE_FOREACH_END();
return 0;
}
"Duplicate type %s is redundant", ZSTR_VAL(overlap_type_str));
}
ZEND_TYPE_FULL_MASK(type) |= ZEND_TYPE_PURE_MASK(single_type);
+ ZEND_TYPE_FULL_MASK(single_type) &= ~_ZEND_TYPE_MAY_BE_MASK;
if (ZEND_TYPE_HAS_CLASS(single_type)) {
if (!ZEND_TYPE_HAS_CLASS(type)) {
} else {
list = erealloc(old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types + 1));
}
- list->types[list->num_types++] = ZEND_TYPE_NAME(single_type);
} else {
/* Switch from single name to name list. */
size_t size = ZEND_TYPE_LIST_SIZE(2);
list = use_arena ? zend_arena_alloc(&CG(arena), size) : emalloc(size);
- list->num_types = 2;
- list->types[0] = ZEND_TYPE_NAME(type);
- list->types[1] = ZEND_TYPE_NAME(single_type);
+ list->num_types = 1;
+ list->types[0] = type;
+ ZEND_TYPE_FULL_MASK(list->types[0]) &= ~_ZEND_TYPE_MAY_BE_MASK;
}
+
+ list->types[list->num_types++] = single_type;
ZEND_TYPE_SET_LIST(type, list);
if (use_arena) {
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT;
/* Check for trivially redundant class types */
for (size_t i = 0; i < list->num_types - 1; i++) {
if (zend_string_equals_ci(
- ZEND_TYPE_LIST_GET_NAME(list->types[i]),
- ZEND_TYPE_NAME(single_type))) {
+ ZEND_TYPE_NAME(list->types[i]), ZEND_TYPE_NAME(single_type))) {
zend_string *single_type_str = zend_type_to_string(single_type);
zend_error_noreturn(E_COMPILE_ERROR,
"Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
zend_property_info *info, zend_class_entry *object_ce) {
zend_class_entry *ce;
if (ZEND_TYPE_HAS_LIST(info->type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(info->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- zend_string *name = ZEND_TYPE_LIST_GET_NAME(*entry);
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(info->type), list_type) {
+ if (ZEND_TYPE_HAS_NAME(*list_type)) {
+ zend_string *name = ZEND_TYPE_NAME(*list_type);
ce = resolve_single_class_type(name, info->ce);
if (!ce) {
continue;
}
zend_string_release(name);
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
+ ZEND_TYPE_SET_CE(*list_type, ce);
} else {
- ce = ZEND_TYPE_LIST_GET_CE(*entry);
+ ce = ZEND_TYPE_CE(*list_type);
}
if (instanceof_function(object_ce, ce)) {
return 1;
if (ZEND_TYPE_HAS_CLASS(type) && Z_TYPE_P(arg) == IS_OBJECT) {
zend_class_entry *ce;
if (ZEND_TYPE_HAS_LIST(type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) {
if (*cache_slot) {
ce = *cache_slot;
} else {
- ce = zend_fetch_class(ZEND_TYPE_LIST_GET_NAME(entry),
+ ce = zend_fetch_class(ZEND_TYPE_NAME(*list_type),
(ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
if (!ce) {
cache_slot++;
memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types));
ZEND_TYPE_SET_PTR(*type, new_list);
- void *entry;
- ZEND_TYPE_LIST_FOREACH(new_list, entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
- zend_string_addref(ZEND_TYPE_LIST_GET_NAME(entry));
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(new_list, list_type) {
+ ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type));
+ zend_string_addref(ZEND_TYPE_NAME(*list_type));
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(*type)) {
zend_string_addref(ZEND_TYPE_NAME(*type));
}
static zend_bool zend_type_contains_traversable(zend_type type) {
- if (ZEND_TYPE_HAS_LIST(type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
- if (zend_string_equals_literal_ci(ZEND_TYPE_LIST_GET_NAME(entry), "Traversable")) {
- return 1;
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- return 0;
- }
- if (ZEND_TYPE_HAS_NAME(type)) {
- return zend_string_equals_literal_ci(ZEND_TYPE_NAME(type), "Traversable");
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)
+ && zend_string_equals_literal_ci(ZEND_TYPE_NAME(*single_type), "Traversable")) {
+ return 1;
+ }
+ } ZEND_TYPE_FOREACH_END();
return 0;
}
return INHERITANCE_SUCCESS;
}
}
- if (ZEND_TYPE_HAS_NAME(proto_type)) {
- zend_string *proto_class_name = resolve_class_name(proto_scope, ZEND_TYPE_NAME(proto_type));
- if (zend_string_equals_ci(fe_class_name, proto_class_name)) {
- return INHERITANCE_SUCCESS;
- }
- /* Make sure to always load both classes, to avoid only registering one of them as
- * a delayed autoload. */
- if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
- zend_class_entry *proto_ce =
- lookup_class(proto_scope, proto_class_name, register_unresolved);
- if (!fe_ce || !proto_ce) {
- have_unresolved = 1;
- } else if (unlinked_instanceof(fe_ce, proto_ce)) {
- return INHERITANCE_SUCCESS;
- }
- }
- if (ZEND_TYPE_HAS_LIST(proto_type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(proto_type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(proto_type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
zend_string *proto_class_name =
- resolve_class_name(proto_scope, ZEND_TYPE_LIST_GET_NAME(entry));
+ resolve_class_name(proto_scope, ZEND_TYPE_NAME(*single_type));
if (zend_string_equals_ci(fe_class_name, proto_class_name)) {
return INHERITANCE_SUCCESS;
}
+ /* Make sure to always load both classes, to avoid only registering one of them as
+ * a delayed autoload. */
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
zend_class_entry *proto_ce =
lookup_class(proto_scope, proto_class_name, register_unresolved);
} else if (unlinked_instanceof(fe_ce, proto_ce)) {
return INHERITANCE_SUCCESS;
}
- } ZEND_TYPE_LIST_FOREACH_END();
- }
+ }
+ } ZEND_TYPE_FOREACH_END();
+
return have_unresolved ? INHERITANCE_UNRESOLVED : INHERITANCE_ERROR;
}
}
if (ZEND_TYPE_HAS_LIST(fe_type)) {
- void *entry;
+ zend_type *list_type;
zend_bool all_success = 1;
/* First try to check whether we can succeed without resolving anything */
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(fe_type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(fe_type), list_type) {
+ ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type));
zend_string *fe_class_name =
- resolve_class_name(fe_scope, ZEND_TYPE_LIST_GET_NAME(entry));
+ resolve_class_name(fe_scope, ZEND_TYPE_NAME(*list_type));
inheritance_status status = zend_perform_covariant_class_type_check(
fe_scope, fe_class_name, proto_scope, proto_type, /* register_unresolved */ 0);
if (status == INHERITANCE_ERROR) {
}
/* Register all classes that may have to be resolved */
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(fe_type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(entry));
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(fe_type), list_type) {
+ ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type));
zend_string *fe_class_name =
- resolve_class_name(fe_scope, ZEND_TYPE_LIST_GET_NAME(entry));
+ resolve_class_name(fe_scope, ZEND_TYPE_NAME(*list_type));
zend_perform_covariant_class_type_check(
fe_scope, fe_class_name, proto_scope, proto_type, /* register_unresolved */ 1);
} ZEND_TYPE_LIST_FOREACH_END();
ZEND_API void zend_type_release(zend_type type, zend_bool persistent) {
if (ZEND_TYPE_HAS_LIST(type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(entry)) {
- zend_string_release(ZEND_TYPE_LIST_GET_NAME(entry));
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) {
+ if (ZEND_TYPE_HAS_NAME(*list_type)) {
+ zend_string_release(ZEND_TYPE_NAME(*list_type));
}
} ZEND_TYPE_LIST_FOREACH_END();
if (!ZEND_TYPE_USES_ARENA(type)) {
} zend_type;
typedef struct {
- size_t num_types;
- void *types[1];
+ uint32_t num_types;
+ zend_type types[1];
} zend_type_list;
#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 24
#define ZEND_TYPE_LIST(t) \
((zend_type_list *) (t).ptr)
-/* Type lists use the low bit to distinguish NAME and CE entries,
- * both of which may exist in the same list. */
-#define ZEND_TYPE_LIST_IS_CE(entry) \
- (((uintptr_t) (entry)) & 1)
-
-#define ZEND_TYPE_LIST_IS_NAME(entry) \
- !ZEND_TYPE_LIST_IS_CE(entry)
-
-#define ZEND_TYPE_LIST_GET_NAME(entry) \
- ((zend_string *) (entry))
-
-#define ZEND_TYPE_LIST_GET_CE(entry) \
- ((zend_class_entry *) ((uintptr_t) (entry) & ~1))
-
-#define ZEND_TYPE_LIST_ENCODE_NAME(name) \
- ((void *) (name))
-
-#define ZEND_TYPE_LIST_ENCODE_CE(ce) \
- ((void *) (((uintptr_t) ce) | 1))
-
#define ZEND_TYPE_LIST_SIZE(num_types) \
- (sizeof(zend_type_list) + ((num_types) - 1) * sizeof(void *))
+ (sizeof(zend_type_list) + ((num_types) - 1) * sizeof(zend_type))
-#define ZEND_TYPE_LIST_FOREACH_PTR(list, entry_ptr) do { \
- void **_list = (list)->types; \
- void **_end = _list + (list)->num_types; \
+/* This iterates over a zend_type_list. */
+#define ZEND_TYPE_LIST_FOREACH(list, type_ptr) do { \
+ zend_type *_list = (list)->types; \
+ zend_type *_end = _list + (list)->num_types; \
for (; _list < _end; _list++) { \
- entry_ptr = _list;
-
-#define ZEND_TYPE_LIST_FOREACH(list, entry) do { \
- void **_list = (list)->types; \
- void **_end = _list + (list)->num_types; \
- for (; _list < _end; _list++) { \
- entry = *_list;
+ type_ptr = _list;
#define ZEND_TYPE_LIST_FOREACH_END() \
} \
} while (0)
+/* This iterates over any zend_type. If it's a type list, all list elements will
+ * be visited. If it's a single type, only the single type is visited. */
+#define ZEND_TYPE_FOREACH(type, type_ptr) do { \
+ zend_type *_cur, *_end; \
+ if (ZEND_TYPE_HAS_LIST(type)) { \
+ zend_type_list *_list = ZEND_TYPE_LIST(type); \
+ _cur = _list->types; \
+ _end = _cur + _list->num_types; \
+ } else { \
+ _cur = &(type); \
+ _end = _cur + 1; \
+ } \
+ do { \
+ type_ptr = _cur;
+
+#define ZEND_TYPE_FOREACH_END() \
+ } while (++_cur < _end); \
+} while (0)
+
#define ZEND_TYPE_SET_PTR(t, _ptr) \
((t).ptr = (_ptr))
num_args++;
}
for (i = 0 ; i < num_args; i++) {
- if (ZEND_TYPE_HAS_LIST(arg_info[i].type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(arg_info[i].type), entry) {
- ZEND_ASSERT(ZEND_TYPE_LIST_IS_NAME(*entry));
- *entry = zend_new_interned_string(ZEND_TYPE_LIST_GET_NAME(*entry));
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) {
- ZEND_TYPE_SET_PTR(arg_info[i].type,
- new_interned_string(ZEND_TYPE_NAME(arg_info[i].type)));
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(arg_info[i].type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ ZEND_TYPE_SET_PTR(*single_type,
+ new_interned_string(ZEND_TYPE_NAME(*single_type)));
+ }
+ } ZEND_TYPE_FOREACH_END();
}
}
} ZEND_HASH_FOREACH_END();
static zend_bool preload_try_resolve_property_types(zend_class_entry *ce)
{
zend_bool ok = 1;
- zend_property_info *prop;
- zend_class_entry *p;
-
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
+ zend_property_info *prop;
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
- if (ZEND_TYPE_HAS_LIST(prop->type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(prop->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- p = preload_fetch_resolved_ce(ZEND_TYPE_LIST_GET_NAME(*entry), ce);
- if (!p) {
- ok = 0;
- continue;
- }
- *entry = ZEND_TYPE_LIST_ENCODE_CE(p);
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(prop->type)) {
- p = preload_fetch_resolved_ce(ZEND_TYPE_NAME(prop->type), ce);
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop->type, single_type) {
+ zend_class_entry *p = preload_fetch_resolved_ce(ZEND_TYPE_NAME(*single_type), ce);
if (!p) {
ok = 0;
continue;
}
- ZEND_TYPE_SET_CE(prop->type, p);
- }
+ ZEND_TYPE_SET_CE(*single_type, p);
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
return known;
}
-static zend_bool preload_is_type_known(zend_class_entry *ce, zend_type type) {
- if (ZEND_TYPE_HAS_LIST(type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(entry)
- && !preload_is_class_type_known(ce, ZEND_TYPE_LIST_GET_NAME(entry))) {
+static zend_bool preload_is_type_known(zend_class_entry *ce, zend_type *type) {
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(*type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ if (!preload_is_class_type_known(ce, ZEND_TYPE_NAME(*single_type))) {
return 0;
}
- } ZEND_TYPE_LIST_FOREACH_END();
- }
- if (ZEND_TYPE_HAS_NAME(type)) {
- return preload_is_class_type_known(ce, ZEND_TYPE_NAME(type));
- }
+ }
+ } ZEND_TYPE_FOREACH_END();
return 1;
}
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, lcname, fptr) {
uint32_t i;
if (fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
- if (!preload_is_type_known(ce, fptr->common.arg_info[-1].type) &&
+ if (!preload_is_type_known(ce, &fptr->common.arg_info[-1].type) &&
preload_is_method_maybe_override(ce, lcname)) {
return 0;
}
}
for (i = 0; i < fptr->common.num_args; i++) {
- if (!preload_is_type_known(ce, fptr->common.arg_info[i].type) &&
+ if (!preload_is_type_known(ce, &fptr->common.arg_info[i].type) &&
preload_is_method_maybe_override(ce, lcname)) {
return 0;
}
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_property_info *prop;
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
- if (ZEND_TYPE_HAS_LIST(prop->type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(prop->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- zend_class_entry *ce = preload_load_prop_type(
- prop, ZEND_TYPE_LIST_GET_NAME(*entry));
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(prop->type)) {
- zend_class_entry *ce =
- preload_load_prop_type(prop, ZEND_TYPE_NAME(prop->type));
- ZEND_TYPE_SET_CE(prop->type, ce);
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop->type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ zend_class_entry *ce = preload_load_prop_type(
+ prop, ZEND_TYPE_NAME(*single_type));
+ ZEND_TYPE_SET_CE(*single_type, ce);
+ }
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
if (ZEND_TYPE_HAS_CLASS(arg_info->type) && Z_TYPE_P(arg) == IS_OBJECT) {
zend_class_entry *ce;
if (ZEND_TYPE_HAS_LIST(arg_info->type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), entry) {
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), list_type) {
if (*cache_slot) {
ce = *cache_slot;
} else {
- ce = zend_fetch_class(ZEND_TYPE_LIST_GET_NAME(entry),
+ ce = zend_fetch_class(ZEND_TYPE_NAME(*list_type),
(ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
if (!ce) {
cache_slot++;
list = ARENA_REALLOC(list);
ZEND_TYPE_SET_PTR(prop_info->type, list);
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(prop_info->type), entry) {
- if (ZEND_TYPE_LIST_IS_CE(*entry)) {
- zend_class_entry *ce = ZEND_TYPE_LIST_GET_CE(*entry);
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(prop_info->type), list_type) {
+ if (ZEND_TYPE_HAS_CE(*list_type)) {
+ zend_class_entry *ce = ZEND_TYPE_CE(*list_type);
if (IN_ARENA(ce)) {
ce = ARENA_REALLOC(ce);
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
+ ZEND_TYPE_SET_PTR(*list_type, ce);
}
}
} ZEND_TYPE_LIST_FOREACH_END();
ZEND_TYPE_SET_PTR(*type, list);
UNSERIALIZE_PTR(list);
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(list, entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- zend_string *name = ZEND_TYPE_LIST_GET_NAME(*entry);
- SERIALIZE_STR(name);
- *entry = ZEND_TYPE_LIST_ENCODE_NAME(name);
- } else {
- zend_class_entry *ce = ZEND_TYPE_LIST_GET_CE(*entry);
- SERIALIZE_PTR(ce);
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
- }
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(list, list_type) {
+ zend_file_cache_serialize_type(list_type, script, info, buf);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(*type)) {
zend_string *type_name = ZEND_TYPE_NAME(*type);
UNSERIALIZE_PTR(list);
ZEND_TYPE_SET_PTR(*type, list);
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(list, entry) {
- if (ZEND_TYPE_LIST_IS_NAME(*entry)) {
- zend_string *name = ZEND_TYPE_LIST_GET_NAME(*entry);
- UNSERIALIZE_STR(name);
- *entry = ZEND_TYPE_LIST_ENCODE_NAME(name);
- } else {
- zend_class_entry *ce = ZEND_TYPE_LIST_GET_CE(*entry);
- UNSERIALIZE_PTR(ce);
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
- }
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(list, list_type) {
+ zend_file_cache_unserialize_type(list_type, script, buf);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(*type)) {
zend_string *type_name = ZEND_TYPE_NAME(*type);
static void zend_persist_type(zend_type *type) {
if (ZEND_TYPE_HAS_LIST(*type)) {
- void **entry;
+ zend_type *list_type;
zend_type_list *list = ZEND_TYPE_LIST(*type);
if (ZEND_TYPE_USES_ARENA(*type)) {
if (!ZCG(is_immutable_class)) {
}
ZEND_TYPE_SET_PTR(*type, list);
- ZEND_TYPE_LIST_FOREACH_PTR(list, entry) {
- zend_string *type_name = ZEND_TYPE_LIST_GET_NAME(*entry);
+ ZEND_TYPE_LIST_FOREACH(list, list_type) {
+ zend_string *type_name = ZEND_TYPE_NAME(*list_type);
zend_accel_store_interned_string(type_name);
- *entry = ZEND_TYPE_LIST_ENCODE_NAME(type_name);
+ ZEND_TYPE_SET_PTR(*list_type, type_name);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(*type)) {
zend_string *type_name = ZEND_TYPE_NAME(*type);
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
zend_property_info *prop;
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
- if (ZEND_TYPE_HAS_LIST(prop->type)) {
- void **entry;
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(prop->type), entry) {
- if (ZEND_TYPE_LIST_IS_CE(*entry)) {
- zend_class_entry *ce = ZEND_TYPE_LIST_GET_CE(*entry);
- if (ce->type == ZEND_USER_CLASS) {
- ce = zend_shared_alloc_get_xlat_entry(ce);
- if (ce) {
- *entry = ZEND_TYPE_LIST_ENCODE_CE(ce);
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop->type, single_type) {
+ if (ZEND_TYPE_HAS_CE(*single_type)) {
+ zend_class_entry *ce = ZEND_TYPE_CE(*single_type);
+ if (ce->type == ZEND_USER_CLASS) {
+ ce = zend_shared_alloc_get_xlat_entry(ce);
+ if (ce) {
+ ZEND_TYPE_SET_PTR(*single_type, ce);
}
}
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_CE(prop->type)) {
- zend_class_entry *ce = ZEND_TYPE_CE(prop->type);
- if (ce->type == ZEND_USER_CLASS) {
- ce = zend_shared_alloc_get_xlat_entry(ce);
- if (ce) {
- ZEND_TYPE_SET_PTR(prop->type, ce);
- }
}
- }
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
static void zend_persist_type_calc(zend_type *type)
{
if (ZEND_TYPE_HAS_LIST(*type)) {
- void **entry;
+ zend_type *list_type;
if (ZEND_TYPE_USES_ARENA(*type) && !ZCG(is_immutable_class)) {
ADD_ARENA_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types));
} else {
ADD_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types));
}
- ZEND_TYPE_LIST_FOREACH_PTR(ZEND_TYPE_LIST(*type), entry) {
- zend_string *type_name = ZEND_TYPE_LIST_GET_NAME(*entry);
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), list_type) {
+ zend_string *type_name = ZEND_TYPE_NAME(*list_type);
ADD_INTERNED_STRING(type_name);
- *entry = ZEND_TYPE_LIST_ENCODE_NAME(type_name);
+ ZEND_TYPE_SET_PTR(*list_type, type_name);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(*type)) {
zend_string *type_name = ZEND_TYPE_NAME(*type);
if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) {
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
- if (ZEND_TYPE_HAS_LIST(prop->type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(prop->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(entry)) {
- return;
- }
- } ZEND_TYPE_LIST_FOREACH_END();
- } else if (ZEND_TYPE_HAS_NAME(prop->type)) {
- return;
- }
+ zend_type *single_type;
+ ZEND_TYPE_FOREACH(prop->type, single_type) {
+ if (ZEND_TYPE_HAS_NAME(*single_type)) {
+ return;
+ }
+ } ZEND_TYPE_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED;
array_init(return_value);
if (ZEND_TYPE_HAS_LIST(param->type)) {
- void *entry;
- ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(param->type), entry) {
- if (ZEND_TYPE_LIST_IS_NAME(entry)) {
- append_type(return_value,
- (zend_type) ZEND_TYPE_INIT_CLASS(ZEND_TYPE_LIST_GET_NAME(entry), 0, 0));
- } else {
- append_type(return_value,
- (zend_type) ZEND_TYPE_INIT_CE(ZEND_TYPE_LIST_GET_CE(entry), 0, 0));
- }
+ zend_type *list_type;
+ ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(param->type), list_type) {
+ append_type(return_value, *list_type);
} ZEND_TYPE_LIST_FOREACH_END();
} else if (ZEND_TYPE_HAS_NAME(param->type)) {
append_type(return_value,
zend_string *class_name2 = zend_string_init("Iterator", sizeof("Iterator") - 1, 1);
zend_type_list *type_list = malloc(ZEND_TYPE_LIST_SIZE(2));
type_list->num_types = 2;
- type_list->types[0] = ZEND_TYPE_LIST_ENCODE_NAME(class_name1);
- type_list->types[1] = ZEND_TYPE_LIST_ENCODE_NAME(class_name2);
+ type_list->types[0] = (zend_type) ZEND_TYPE_INIT_CLASS(class_name1, 0, 0);
+ type_list->types[1] = (zend_type) ZEND_TYPE_INIT_CLASS(class_name2, 0, 0);
zend_type type = ZEND_TYPE_INIT_PTR(type_list, _ZEND_TYPE_LIST_BIT, 1, 0);
zval val;
ZVAL_NULL(&val);