@@ -60,20 +60,33 @@ static void ZEND_COLD emit_incompatible_method_error(
6060 const zend_function * parent , zend_class_entry * parent_scope ,
6161 inheritance_status status );
6262
63- static void zend_type_copy_ctor (zend_type * type , bool persistent ) {
63+ static void zend_type_copy_ctor (zend_type * const type , bool use_arena , bool persistent );
64+
65+ static void zend_type_list_copy_ctor (
66+ zend_type * const parent_type ,
67+ bool use_arena ,
68+ bool persistent
69+ ) {
70+ const zend_type_list * const old_list = ZEND_TYPE_LIST (* parent_type );
71+ size_t size = ZEND_TYPE_LIST_SIZE (old_list -> num_types );
72+ zend_type_list * new_list = use_arena
73+ ? zend_arena_alloc (& CG (arena ), size ) : pemalloc (size , persistent );
74+
75+ memcpy (new_list , old_list , size );
76+ ZEND_TYPE_SET_LIST (* parent_type , new_list );
77+ if (use_arena ) {
78+ ZEND_TYPE_FULL_MASK (* parent_type ) |= _ZEND_TYPE_ARENA_BIT ;
79+ }
80+
81+ zend_type * list_type ;
82+ ZEND_TYPE_LIST_FOREACH (new_list , list_type ) {
83+ zend_type_copy_ctor (list_type , use_arena , persistent );
84+ } ZEND_TYPE_LIST_FOREACH_END ();
85+ }
86+
87+ static void zend_type_copy_ctor (zend_type * const type , bool use_arena , bool persistent ) {
6488 if (ZEND_TYPE_HAS_LIST (* type )) {
65- zend_type_list * old_list = ZEND_TYPE_LIST (* type );
66- size_t size = ZEND_TYPE_LIST_SIZE (old_list -> num_types );
67- zend_type_list * new_list = ZEND_TYPE_USES_ARENA (* type )
68- ? zend_arena_alloc (& CG (arena ), size ) : pemalloc (size , persistent );
69- memcpy (new_list , old_list , ZEND_TYPE_LIST_SIZE (old_list -> num_types ));
70- ZEND_TYPE_SET_PTR (* type , new_list );
71-
72- zend_type * list_type ;
73- ZEND_TYPE_LIST_FOREACH (new_list , list_type ) {
74- ZEND_ASSERT (ZEND_TYPE_HAS_NAME (* list_type ));
75- zend_string_addref (ZEND_TYPE_NAME (* list_type ));
76- } ZEND_TYPE_LIST_FOREACH_END ();
89+ zend_type_list_copy_ctor (type , use_arena , persistent );
7790 } else if (ZEND_TYPE_HAS_NAME (* type )) {
7891 zend_string_addref (ZEND_TYPE_NAME (* type ));
7992 }
@@ -2506,7 +2519,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
25062519 doc_comment = property_info -> doc_comment ? zend_string_copy (property_info -> doc_comment ) : NULL ;
25072520
25082521 zend_type type = property_info -> type ;
2509- zend_type_copy_ctor (& type , /* persistent */ 0 );
2522+ /* Assumption: only userland classes can use traits, as such the type must be arena allocated */
2523+ zend_type_copy_ctor (& type , /* use arena */ true, /* persistent */ false);
25102524 new_prop = zend_declare_typed_property (ce , prop_name , prop_value , flags , doc_comment , type );
25112525
25122526 if (property_info -> attributes ) {
@@ -2920,15 +2934,8 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
29202934 Z_PTR (p -> val ) = new_prop_info ;
29212935 memcpy (new_prop_info , prop_info , sizeof (zend_property_info ));
29222936 new_prop_info -> ce = ce ;
2923- if (ZEND_TYPE_HAS_LIST (new_prop_info -> type )) {
2924- zend_type_list * new_list ;
2925- zend_type_list * list = ZEND_TYPE_LIST (new_prop_info -> type );
2926-
2927- new_list = zend_arena_alloc (& CG (arena ), ZEND_TYPE_LIST_SIZE (list -> num_types ));
2928- memcpy (new_list , list , ZEND_TYPE_LIST_SIZE (list -> num_types ));
2929- ZEND_TYPE_SET_PTR (new_prop_info -> type , list );
2930- ZEND_TYPE_FULL_MASK (new_prop_info -> type ) |= _ZEND_TYPE_ARENA_BIT ;
2931- }
2937+ /* Deep copy the type information */
2938+ zend_type_copy_ctor (& new_prop_info -> type , /* use_arena */ true, /* persistent */ false);
29322939 }
29332940 }
29342941
0 commit comments