1111typedef struct _mp_obj_closure_t {
1212 mp_obj_base_t base ;
1313 mp_obj_t fun ;
14- mp_obj_tuple_t * closure_tuple ;
14+ machine_uint_t n_closed ;
15+ mp_obj_t closed [];
1516} mp_obj_closure_t ;
1617
1718mp_obj_t closure_call (mp_obj_t self_in , uint n_args , uint n_kw , const mp_obj_t * args ) {
1819 mp_obj_closure_t * self = self_in ;
19- mp_obj_tuple_t * t = self -> closure_tuple ;
2020
2121 // need to concatenate closed-over-vars and args
2222
23- int n_total = t -> len + n_args + 2 * n_kw ;
23+ int n_total = self -> n_closed + n_args + 2 * n_kw ;
2424 if (n_total <= 5 ) {
2525 // use stack to allocate temporary args array
2626 mp_obj_t args2 [5 ];
27- memcpy (args2 , t -> items , t -> len * sizeof (mp_obj_t ));
28- memcpy (args2 + t -> len , args , (n_args + 2 * n_kw ) * sizeof (mp_obj_t ));
29- return mp_call_function_n_kw (self -> fun , t -> len + n_args , n_kw , args2 );
27+ memcpy (args2 , self -> closed , self -> n_closed * sizeof (mp_obj_t ));
28+ memcpy (args2 + self -> n_closed , args , (n_args + 2 * n_kw ) * sizeof (mp_obj_t ));
29+ return mp_call_function_n_kw (self -> fun , self -> n_closed + n_args , n_kw , args2 );
3030 } else {
3131 // use heap to allocate temporary args array
3232 mp_obj_t * args2 = m_new (mp_obj_t , n_total );
33- memcpy (args2 , t -> items , t -> len * sizeof (mp_obj_t ));
34- memcpy (args2 + t -> len , args , (n_args + 2 * n_kw ) * sizeof (mp_obj_t ));
35- mp_obj_t res = mp_call_function_n_kw (self -> fun , t -> len + n_args , n_kw , args2 );
33+ memcpy (args2 , self -> closed , self -> n_closed * sizeof (mp_obj_t ));
34+ memcpy (args2 + self -> n_closed , args , (n_args + 2 * n_kw ) * sizeof (mp_obj_t ));
35+ mp_obj_t res = mp_call_function_n_kw (self -> fun , self -> n_closed + n_args , n_kw , args2 );
3636 m_del (mp_obj_t , args2 , n_total );
3737 return res ;
3838 }
@@ -41,13 +41,12 @@ mp_obj_t closure_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *
4141#if 0
4242STATIC void closure_print (void (* print )(void * env , const char * fmt , ...), void * env , mp_obj_t o_in , mp_print_kind_t kind ) {
4343 mp_obj_closure_t * o = o_in ;
44- print (env , "<closure %p (closed: %p) " , o , o -> closure_tuple );
45- mp_obj_tuple_t * t = o -> closure_tuple ;
46- for (int i = 0 ; i < t -> len ; i ++ ) {
47- if (t -> items [i ] == MP_OBJ_NULL ) {
44+ print (env , "<closure %p, n_closed=%u " , o , o -> n_closed );
45+ for (int i = 0 ; i < o -> n_closed ; i ++ ) {
46+ if (o -> closed [i ] == MP_OBJ_NULL ) {
4847 print (env , "(nil)" );
4948 } else {
50- mp_obj_print_helper (print , env , t -> items [i ], PRINT_REPR );
49+ mp_obj_print_helper (print , env , o -> closed [i ], PRINT_REPR );
5150 }
5251 print (env , " " );
5352 }
@@ -62,10 +61,11 @@ const mp_obj_type_t closure_type = {
6261 .call = closure_call ,
6362};
6463
65- mp_obj_t mp_obj_new_closure (mp_obj_t fun , mp_obj_t closure_tuple ) {
66- mp_obj_closure_t * o = m_new_obj (mp_obj_closure_t );
64+ mp_obj_t mp_obj_new_closure (mp_obj_t fun , uint n_closed_over , const mp_obj_t * closed ) {
65+ mp_obj_closure_t * o = m_new_obj_var (mp_obj_closure_t , mp_obj_t , n_closed_over );
6766 o -> base .type = & closure_type ;
6867 o -> fun = fun ;
69- o -> closure_tuple = closure_tuple ;
68+ o -> n_closed = n_closed_over ;
69+ memcpy (o -> closed , closed , n_closed_over * sizeof (mp_obj_t ));
7070 return o ;
7171}
0 commit comments