@@ -57,20 +57,33 @@ static void ZEND_COLD emit_incompatible_method_error(
57
57
const zend_function * parent , zend_class_entry * parent_scope ,
58
58
inheritance_status status );
59
59
60
- static void zend_type_copy_ctor (zend_type * type , bool persistent ) {
60
+ static void zend_type_copy_ctor (zend_type * const type , bool use_arena , bool persistent );
61
+
62
+ static void zend_type_list_copy_ctor (
63
+ zend_type * const parent_type ,
64
+ bool use_arena ,
65
+ bool persistent
66
+ ) {
67
+ const zend_type_list * const old_list = ZEND_TYPE_LIST (* parent_type );
68
+ size_t size = ZEND_TYPE_LIST_SIZE (old_list -> num_types );
69
+ zend_type_list * new_list = use_arena
70
+ ? zend_arena_alloc (& CG (arena ), size ) : pemalloc (size , persistent );
71
+
72
+ memcpy (new_list , old_list , size );
73
+ ZEND_TYPE_SET_LIST (* parent_type , new_list );
74
+ if (use_arena ) {
75
+ ZEND_TYPE_FULL_MASK (* parent_type ) |= _ZEND_TYPE_ARENA_BIT ;
76
+ }
77
+
78
+ zend_type * list_type ;
79
+ ZEND_TYPE_LIST_FOREACH (new_list , list_type ) {
80
+ zend_type_copy_ctor (list_type , use_arena , persistent );
81
+ } ZEND_TYPE_LIST_FOREACH_END ();
82
+ }
83
+
84
+ static void zend_type_copy_ctor (zend_type * const type , bool use_arena , bool persistent ) {
61
85
if (ZEND_TYPE_HAS_LIST (* type )) {
62
- zend_type_list * old_list = ZEND_TYPE_LIST (* type );
63
- size_t size = ZEND_TYPE_LIST_SIZE (old_list -> num_types );
64
- zend_type_list * new_list = ZEND_TYPE_USES_ARENA (* type )
65
- ? zend_arena_alloc (& CG (arena ), size ) : pemalloc (size , persistent );
66
- memcpy (new_list , old_list , ZEND_TYPE_LIST_SIZE (old_list -> num_types ));
67
- ZEND_TYPE_SET_PTR (* type , new_list );
68
-
69
- zend_type * list_type ;
70
- ZEND_TYPE_LIST_FOREACH (new_list , list_type ) {
71
- ZEND_ASSERT (ZEND_TYPE_HAS_NAME (* list_type ));
72
- zend_string_addref (ZEND_TYPE_NAME (* list_type ));
73
- } ZEND_TYPE_LIST_FOREACH_END ();
86
+ zend_type_list_copy_ctor (type , use_arena , persistent );
74
87
} else if (ZEND_TYPE_HAS_NAME (* type )) {
75
88
zend_string_addref (ZEND_TYPE_NAME (* type ));
76
89
}
@@ -2401,7 +2414,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
2401
2414
doc_comment = property_info -> doc_comment ? zend_string_copy (property_info -> doc_comment ) : NULL ;
2402
2415
2403
2416
zend_type type = property_info -> type ;
2404
- zend_type_copy_ctor (& type , /* persistent */ 0 );
2417
+ /* Assumption: only userland classes can use traits, as such the type must be arena allocated */
2418
+ zend_type_copy_ctor (& type , /* use arena */ true, /* persistent */ false);
2405
2419
new_prop = zend_declare_typed_property (ce , prop_name , prop_value , flags , doc_comment , type );
2406
2420
2407
2421
if (property_info -> attributes ) {
@@ -2789,15 +2803,8 @@ static zend_class_entry *zend_lazy_class_load(zend_class_entry *pce)
2789
2803
Z_PTR (p -> val ) = new_prop_info ;
2790
2804
memcpy (new_prop_info , prop_info , sizeof (zend_property_info ));
2791
2805
new_prop_info -> ce = ce ;
2792
- if (ZEND_TYPE_HAS_LIST (new_prop_info -> type )) {
2793
- zend_type_list * new_list ;
2794
- zend_type_list * list = ZEND_TYPE_LIST (new_prop_info -> type );
2795
-
2796
- new_list = zend_arena_alloc (& CG (arena ), ZEND_TYPE_LIST_SIZE (list -> num_types ));
2797
- memcpy (new_list , list , ZEND_TYPE_LIST_SIZE (list -> num_types ));
2798
- ZEND_TYPE_SET_PTR (new_prop_info -> type , list );
2799
- ZEND_TYPE_FULL_MASK (new_prop_info -> type ) |= _ZEND_TYPE_ARENA_BIT ;
2800
- }
2806
+ /* Deep copy the type information */
2807
+ zend_type_copy_ctor (& new_prop_info -> type , /* use_arena */ true, /* persistent */ false);
2801
2808
}
2802
2809
}
2803
2810
0 commit comments