@@ -2247,66 +2247,6 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
22472247}
22482248/* }}} */
22492249
2250- 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 );
2251- static void zend_do_traits_constant_binding (zend_class_entry * ce , zend_class_entry * * traits );
2252- static void zend_do_traits_property_binding (zend_class_entry * ce , zend_class_entry * * traits );
2253- static void zend_fixup_trait_method (zend_function * fn , zend_class_entry * ce );
2254-
2255- ZEND_API void zend_class_use_traits (zend_class_entry * class_entry , int num_traits , ...) /* {{{ */
2256- {
2257- zend_class_entry * trait_entry ;
2258- va_list trait_list ;
2259- zend_class_entry * * traits ;
2260- zend_function * fn ;
2261- bool contains_abstract_methods = false;
2262-
2263- ZEND_ASSERT (class_entry -> ce_flags & ZEND_ACC_LINKED );
2264-
2265- if (num_traits == 0 ) {
2266- return ;
2267- }
2268-
2269- traits = safe_emalloc (num_traits , sizeof (zend_class_entry * ), 0 );
2270- class_entry -> trait_names = safe_pemalloc (num_traits , sizeof (zend_class_name ), 0 , 1 );
2271- class_entry -> num_traits = num_traits ;
2272-
2273- va_start (trait_list , num_traits );
2274- for (int i = 0 ; i < num_traits ; i ++ ) {
2275- trait_entry = va_arg (trait_list , zend_class_entry * );
2276- class_entry -> trait_names [i ].name = zend_string_copy (trait_entry -> name );
2277- class_entry -> trait_names [i ].lc_name = zend_string_tolower_ex (zend_string_copy (trait_entry -> name ), 1 );
2278-
2279- if (UNEXPECTED (!(trait_entry -> ce_flags & ZEND_ACC_TRAIT ))) {
2280- efree (traits );
2281- zend_error_noreturn (E_ERROR , "Class %s cannot use %s - it is not a trait" ,
2282- ZSTR_VAL (class_entry -> name ), ZSTR_VAL (trait_entry -> name ));
2283- return ;
2284- }
2285- traits [i ] = trait_entry ;
2286- }
2287- va_end (trait_list );
2288-
2289- zend_do_traits_method_binding (class_entry , traits , NULL , NULL , false, & contains_abstract_methods );
2290-
2291- zend_do_traits_constant_binding (class_entry , traits );
2292-
2293- zend_do_traits_property_binding (class_entry , traits );
2294-
2295- ZEND_HASH_MAP_FOREACH_PTR (& class_entry -> function_table , fn ) {
2296- zend_fixup_trait_method (fn , class_entry );
2297- } ZEND_HASH_FOREACH_END ();
2298-
2299- if (contains_abstract_methods ) {
2300- zend_do_traits_method_binding (class_entry , traits , NULL , NULL , true, & contains_abstract_methods );
2301- ZEND_HASH_MAP_FOREACH_PTR (& class_entry -> function_table , fn ) {
2302- zend_fixup_trait_method (fn , class_entry );
2303- } ZEND_HASH_FOREACH_END ();
2304- }
2305-
2306- efree (traits );
2307- }
2308- /* }}} */
2309-
23102250static void zend_do_implement_interfaces (zend_class_entry * ce , zend_class_entry * * interfaces ) /* {{{ */
23112251{
23122252 uint32_t num_parent_interfaces = ce -> parent ? ce -> parent -> num_interfaces : 0 ;
@@ -3072,6 +3012,61 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
30723012}
30733013/* }}} */
30743014
3015+ ZEND_API void zend_class_use_internal_traits (zend_class_entry * class_entry , int num_traits , ...) /* {{{ */
3016+ {
3017+ zend_class_entry * trait_entry ;
3018+ va_list trait_list ;
3019+ zend_class_entry * * traits ;
3020+ zend_function * fn ;
3021+ bool contains_abstract_methods = false;
3022+
3023+ ZEND_ASSERT (class_entry -> ce_flags & ZEND_ACC_LINKED );
3024+
3025+ if (num_traits == 0 ) {
3026+ return ;
3027+ }
3028+
3029+ traits = safe_emalloc (num_traits , sizeof (zend_class_entry * ), 0 );
3030+ class_entry -> trait_names = safe_pemalloc (num_traits , sizeof (zend_class_name ), 0 , 1 );
3031+ class_entry -> num_traits = num_traits ;
3032+
3033+ va_start (trait_list , num_traits );
3034+ for (int i = 0 ; i < num_traits ; i ++ ) {
3035+ trait_entry = va_arg (trait_list , zend_class_entry * );
3036+ class_entry -> trait_names [i ].name = zend_string_copy (trait_entry -> name );
3037+ class_entry -> trait_names [i ].lc_name = zend_string_tolower_ex (zend_string_copy (trait_entry -> name ), 1 );
3038+
3039+ if (UNEXPECTED (!(trait_entry -> ce_flags & ZEND_ACC_TRAIT ))) {
3040+ efree (traits );
3041+ zend_error_noreturn (E_ERROR , "Class %s cannot use %s - it is not a trait" ,
3042+ ZSTR_VAL (class_entry -> name ), ZSTR_VAL (trait_entry -> name ));
3043+ return ;
3044+ }
3045+ traits [i ] = trait_entry ;
3046+ }
3047+ va_end (trait_list );
3048+
3049+ zend_do_traits_method_binding (class_entry , traits , NULL , NULL , false, & contains_abstract_methods );
3050+
3051+ zend_do_traits_constant_binding (class_entry , traits );
3052+
3053+ zend_do_traits_property_binding (class_entry , traits );
3054+
3055+ ZEND_HASH_MAP_FOREACH_PTR (& class_entry -> function_table , fn ) {
3056+ zend_fixup_trait_method (fn , class_entry );
3057+ } ZEND_HASH_FOREACH_END ();
3058+
3059+ if (contains_abstract_methods ) {
3060+ zend_do_traits_method_binding (class_entry , traits , NULL , NULL , true, & contains_abstract_methods );
3061+ ZEND_HASH_MAP_FOREACH_PTR (& class_entry -> function_table , fn ) {
3062+ zend_fixup_trait_method (fn , class_entry );
3063+ } ZEND_HASH_FOREACH_END ();
3064+ }
3065+
3066+ efree (traits );
3067+ }
3068+ /* }}} */
3069+
30753070#define MAX_ABSTRACT_INFO_CNT 3
30763071#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
30773072#define DISPLAY_ABSTRACT_FN (idx ) \
0 commit comments