Skip to content

Commit a3b03a0

Browse files
committed
Refactor compilation of intersection type
1 parent 42fffcd commit a3b03a0

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
@@ -6306,6 +6306,8 @@ static zend_type zend_compile_typename(
63066306
type_list = do_alloca(ZEND_TYPE_LIST_SIZE(list->children), use_heap);
63076307
type_list->num_types = 0;
63086308

6309+
ZEND_ASSERT(list->children > 1);
6310+
63096311
for (uint32_t i = 0; i < list->children; i++) {
63106312
zend_ast *type_ast = list->child[i];
63116313
zend_type single_type = zend_compile_single_typename(type_ast);
@@ -6324,42 +6326,30 @@ static zend_type zend_compile_typename(
63246326
}
63256327
zend_string_release_ex(standard_type_str, false);
63266328

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

6342-
/* Check for trivially redundant class types */
6343-
for (size_t i = 0; i < type_list->num_types - 1; i++) {
6344-
if (zend_string_equals_ci(
6345-
ZEND_TYPE_NAME(type_list->types[i]), ZEND_TYPE_NAME(single_type))) {
6346-
zend_string *single_type_str = zend_type_to_string(single_type);
6347-
zend_error_noreturn(E_COMPILE_ERROR,
6348-
"Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
6349-
}
6332+
/* Check for trivially redundant class types */
6333+
for (size_t i = 0; i < type_list->num_types - 1; i++) {
6334+
if (zend_string_equals_ci(
6335+
ZEND_TYPE_NAME(type_list->types[i]), ZEND_TYPE_NAME(single_type))) {
6336+
zend_string *single_type_str = zend_type_to_string(single_type);
6337+
zend_error_noreturn(E_COMPILE_ERROR,
6338+
"Duplicate type %s is redundant", ZSTR_VAL(single_type_str));
63506339
}
63516340
}
63526341
}
63536342

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

63646354
free_alloca(type_list, use_heap);
63656355
} else {

0 commit comments

Comments
 (0)