@@ -2612,7 +2612,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
2612
2612
}
2613
2613
/* }}} */
2614
2614
2615
- static void zend_do_traits_method_binding (zend_class_entry * ce , zend_class_entry * * traits , HashTable * * exclude_tables , zend_class_entry * * aliases , bool verify_abstract ) /* {{{ */
2615
+ static void zend_do_traits_method_binding (zend_class_entry * ce , zend_class_entry * * traits , HashTable * * exclude_tables , zend_class_entry * * aliases , bool verify_abstract , bool * contains_abstract_methods ) /* {{{ */
2616
2616
{
2617
2617
uint32_t i ;
2618
2618
zend_string * key ;
@@ -2624,6 +2624,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
2624
2624
/* copies functions, applies defined aliasing, and excludes unused trait methods */
2625
2625
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (& traits [i ]-> function_table , key , fn ) {
2626
2626
if (verify_abstract != (bool ) (fn -> common .fn_flags & ZEND_ACC_ABSTRACT )) {
2627
+ * contains_abstract_methods = true;
2627
2628
continue ;
2628
2629
}
2629
2630
zend_traits_copy_functions (key , fn , ce , exclude_tables [i ], aliases );
@@ -2641,6 +2642,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
2641
2642
if (traits [i ]) {
2642
2643
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (& traits [i ]-> function_table , key , fn ) {
2643
2644
if (verify_abstract != (bool ) (fn -> common .fn_flags & ZEND_ACC_ABSTRACT )) {
2645
+ * contains_abstract_methods = true;
2644
2646
continue ;
2645
2647
}
2646
2648
zend_traits_copy_functions (key , fn , ce , NULL , aliases );
@@ -2929,29 +2931,6 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
2929
2931
}
2930
2932
/* }}} */
2931
2933
2932
- static void zend_do_bind_traits (zend_class_entry * ce , zend_class_entry * * traits , bool verify_abstract ) /* {{{ */
2933
- {
2934
- HashTable * * exclude_tables ;
2935
- zend_class_entry * * aliases ;
2936
-
2937
- ZEND_ASSERT (ce -> num_traits > 0 );
2938
-
2939
- /* complete initialization of trait structures in ce */
2940
- zend_traits_init_trait_structures (ce , traits , & exclude_tables , & aliases );
2941
-
2942
- /* Flatten all methods into the class */
2943
- zend_do_traits_method_binding (ce , traits , exclude_tables , aliases , verify_abstract );
2944
-
2945
- if (aliases ) {
2946
- efree (aliases );
2947
- }
2948
-
2949
- if (exclude_tables ) {
2950
- efree (exclude_tables );
2951
- }
2952
- }
2953
- /* }}} */
2954
-
2955
2934
#define MAX_ABSTRACT_INFO_CNT 3
2956
2935
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
2957
2936
#define DISPLAY_ABSTRACT_FN (idx ) \
@@ -3560,8 +3539,12 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
3560
3539
zend_enum_register_funcs (ce );
3561
3540
}
3562
3541
3542
+ HashTable * * trait_exclude_tables ;
3543
+ zend_class_entry * * trait_aliases ;
3544
+ bool trait_contains_abstract_methods = false;
3563
3545
if (ce -> num_traits ) {
3564
- zend_do_bind_traits (ce , traits_and_interfaces , false);
3546
+ zend_traits_init_trait_structures (ce , traits_and_interfaces , & trait_exclude_tables , & trait_aliases );
3547
+ zend_do_traits_method_binding (ce , traits_and_interfaces , trait_exclude_tables , trait_aliases , false, & trait_contains_abstract_methods );
3565
3548
zend_do_traits_constant_binding (ce , traits_and_interfaces );
3566
3549
zend_do_traits_property_binding (ce , traits_and_interfaces );
3567
3550
}
@@ -3572,7 +3555,24 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
3572
3555
zend_do_inheritance (ce , parent );
3573
3556
}
3574
3557
if (ce -> num_traits ) {
3575
- zend_do_bind_traits (ce , traits_and_interfaces , true);
3558
+ if (trait_contains_abstract_methods ) {
3559
+ zend_do_traits_method_binding (ce , traits_and_interfaces , trait_exclude_tables , trait_aliases , true, & trait_contains_abstract_methods );
3560
+ }
3561
+
3562
+ if (trait_exclude_tables ) {
3563
+ for (i = 0 ; i < ce -> num_traits ; i ++ ) {
3564
+ if (traits_and_interfaces [i ]) {
3565
+ if (trait_exclude_tables [i ]) {
3566
+ zend_hash_destroy (trait_exclude_tables [i ]);
3567
+ FREE_HASHTABLE (trait_exclude_tables [i ]);
3568
+ }
3569
+ }
3570
+ }
3571
+ efree (trait_exclude_tables );
3572
+ }
3573
+ if (trait_aliases ) {
3574
+ efree (trait_aliases );
3575
+ }
3576
3576
3577
3577
zend_function * fn ;
3578
3578
ZEND_HASH_MAP_FOREACH_PTR (& ce -> function_table , fn ) {
0 commit comments