Skip to content

Commit 29637ec

Browse files
committed
Refactor compilation of intersection type
1 parent 1b05e64 commit 29637ec

File tree

1 file changed

+21
-31
lines changed

1 file changed

+21
-31
lines changed

Zend/zend_compile.c

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6302,6 +6302,8 @@ static zend_type zend_compile_typename(
63026302
type_list = do_alloca(ZEND_TYPE_LIST_SIZE(list->children), use_heap);
63036303
type_list->num_types = 0;
63046304

6305+
ZEND_ASSERT(list->children > 1);
6306+
63056307
for (uint32_t i = 0; i < list->children; i++) {
63066308
zend_ast *type_ast = list->child[i];
63076309
zend_type single_type = zend_compile_single_typename(type_ast);
@@ -6320,42 +6322,30 @@ static zend_type zend_compile_typename(
63206322
}
63216323
zend_string_release_ex(standard_type_str, false);
63226324

6323-
if (!ZEND_TYPE_IS_COMPLEX(type)) {
6324-
/* The first class type can be stored directly as the type ptr payload. */
6325-
ZEND_TYPE_SET_PTR(type, ZEND_TYPE_NAME(single_type));
6326-
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_NAME_BIT;
6327-
} else {
6328-
if (type_list->num_types == 0) {
6329-
/* Switch from single name to name list. */
6330-
type_list->num_types = 1;
6331-
type_list->types[0] = type;
6332-
ZEND_TYPE_FULL_MASK(type_list->types[0]) &= ~_ZEND_TYPE_MAY_BE_MASK;
6333-
ZEND_TYPE_SET_LIST(type, type_list);
6334-
}
6335-
6336-
type_list->types[type_list->num_types++] = single_type;
6325+
/* Add type to the type list */
6326+
type_list->types[type_list->num_types++] = single_type;
63376327

6338-
/* Check for trivially redundant class types */
6339-
for (size_t i = 0; i < type_list->num_types - 1; i++) {
6340-
if (zend_string_equals_ci(
6341-
ZEND_TYPE_NAME(type_list->types[i]), ZEND_TYPE_NAME(single_type))) {
6342-
zend_string *single_type_str = zend_type_to_string(single_type);
6343-
zend_error_noreturn(E_COMPILE_ERROR,
6344-
"Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
6345-
}
6328+
/* Check for trivially redundant class types */
6329+
for (size_t i = 0; i < type_list->num_types - 1; i++) {
6330+
if (zend_string_equals_ci(
6331+
ZEND_TYPE_NAME(type_list->types[i]), ZEND_TYPE_NAME(single_type))) {
6332+
zend_string *single_type_str = zend_type_to_string(single_type);
6333+
zend_error_noreturn(E_COMPILE_ERROR,
6334+
"Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
63466335
}
63476336
}
63486337
}
63496338

6350-
if (type_list->num_types) {
6351-
zend_type_list *list = zend_arena_alloc(
6352-
&CG(arena), ZEND_TYPE_LIST_SIZE(type_list->num_types));
6353-
memcpy(list, type_list, ZEND_TYPE_LIST_SIZE(type_list->num_types));
6354-
ZEND_TYPE_SET_LIST(type, list);
6355-
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT;
6356-
/* Inform that the type list is an intersection type */
6357-
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_INTERSECTION_BIT;
6358-
}
6339+
ZEND_ASSERT(type_list->num_types > 1);
6340+
6341+
/* TODO Can be arena allocated directly? */
6342+
zend_type_list *reduced_list = zend_arena_alloc(
6343+
&CG(arena), ZEND_TYPE_LIST_SIZE(type_list->num_types));
6344+
memcpy(reduced_list, type_list, ZEND_TYPE_LIST_SIZE(type_list->num_types));
6345+
ZEND_TYPE_SET_LIST(type, reduced_list);
6346+
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT;
6347+
/* Inform that the type list is an intersection type */
6348+
ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_INTERSECTION_BIT;
63596349

63606350
free_alloca(type_list, use_heap);
63616351
} else {

0 commit comments

Comments
 (0)