@@ -60,20 +60,33 @@ static void ZEND_COLD emit_incompatible_method_error(
60
60
const zend_function * parent , zend_class_entry * parent_scope ,
61
61
inheritance_status status );
62
62
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 ) {
64
88
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 );
77
90
} else if (ZEND_TYPE_HAS_NAME (* type )) {
78
91
zend_string_addref (ZEND_TYPE_NAME (* type ));
79
92
}
@@ -2506,7 +2519,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
2506
2519
doc_comment = property_info -> doc_comment ? zend_string_copy (property_info -> doc_comment ) : NULL ;
2507
2520
2508
2521
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);
2510
2524
new_prop = zend_declare_typed_property (ce , prop_name , prop_value , flags , doc_comment , type );
2511
2525
2512
2526
if (property_info -> attributes ) {
@@ -2920,15 +2934,8 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
2920
2934
Z_PTR (p -> val ) = new_prop_info ;
2921
2935
memcpy (new_prop_info , prop_info , sizeof (zend_property_info ));
2922
2936
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);
2932
2939
}
2933
2940
}
2934
2941
0 commit comments