@@ -249,6 +249,10 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
249249 // This function is pretty complicated. It's main aim is to be efficient in speed and RAM
250250 // usage for the common case of positional only args.
251251 //
252+ // TODO Now that we allocate the state for the bytecode execution, we probably don't
253+ // need extra_args anymore, and definitely don't need flat_args.
254+ //
255+ // TODO The following comment is obsolete and probably wrong:
252256 // extra_args layout: def_args, var_arg tuple, kwonly args, var_kw dict
253257
254258 DEBUG_printf ("Input n_args: %d, n_kw: %d\n" , n_args , n_kw );
@@ -260,7 +264,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
260264 DEBUG_printf ("Func n_def_args: %d\n" , self -> n_def_args );
261265
262266 const mp_obj_t * kwargs = args + n_args ;
263- mp_obj_t * extra_args = self -> extra_args + self -> n_def_args ;
267+ mp_obj_t * extra_args = self -> extra_args + self -> n_def_args + self -> has_def_kw_args ;
264268 uint n_extra_args = 0 ;
265269
266270 // check positional arguments
@@ -295,7 +299,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
295299
296300 // check keyword arguments
297301
298- if (n_kw != 0 ) {
302+ if (n_kw != 0 || self -> has_def_kw_args ) {
299303 // We cannot use dynamically-sized array here, because GCC indeed
300304 // deallocates it on leaving defining scope (unlike most static stack allocs).
301305 // So, we have 2 choices: allocate it unconditionally at the top of function
@@ -355,10 +359,19 @@ continue2:;
355359 }
356360
357361 // Check that all mandatory keyword args are specified
362+ // Fill in default kw args if we have them
358363 for (int i = 0 ; i < self -> n_kwonly_args ; i ++ ) {
359364 if (flat_args [self -> n_pos_args + i ] == MP_OBJ_NULL ) {
360- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
361- "function missing required keyword argument '%s'" , qstr_str (self -> args [self -> n_pos_args + i ])));
365+ mp_map_elem_t * elem = NULL ;
366+ if (self -> has_def_kw_args ) {
367+ elem = mp_map_lookup (& ((mp_obj_dict_t * )self -> extra_args [self -> n_def_args ])-> map , MP_OBJ_NEW_QSTR (self -> args [self -> n_pos_args + i ]), MP_MAP_LOOKUP );
368+ }
369+ if (elem != NULL ) {
370+ flat_args [self -> n_pos_args + i ] = elem -> value ;
371+ } else {
372+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
373+ "function missing required keyword argument '%s'" , qstr_str (self -> args [self -> n_pos_args + i ])));
374+ }
362375 }
363376 }
364377
@@ -513,7 +526,7 @@ const mp_obj_type_t mp_type_fun_bc = {
513526 .binary_op = fun_binary_op ,
514527};
515528
516- mp_obj_t mp_obj_new_fun_bc (uint scope_flags , qstr * args , uint n_pos_args , uint n_kwonly_args , mp_obj_t def_args_in , const byte * code ) {
529+ mp_obj_t mp_obj_new_fun_bc (uint scope_flags , qstr * args , uint n_pos_args , uint n_kwonly_args , mp_obj_t def_args_in , mp_obj_t def_kw_args , const byte * code ) {
517530 uint n_def_args = 0 ;
518531 uint n_extra_args = 0 ;
519532 mp_obj_tuple_t * def_args = def_args_in ;
@@ -522,6 +535,9 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_pos_args, uint n
522535 n_def_args = def_args -> len ;
523536 n_extra_args = def_args -> len ;
524537 }
538+ if (def_kw_args != MP_OBJ_NULL ) {
539+ n_extra_args += 1 ;
540+ }
525541 if ((scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
526542 n_extra_args += 1 ;
527543 }
@@ -535,18 +551,24 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_pos_args, uint n
535551 o -> n_pos_args = n_pos_args ;
536552 o -> n_kwonly_args = n_kwonly_args ;
537553 o -> n_def_args = n_def_args ;
554+ o -> has_def_kw_args = def_kw_args != MP_OBJ_NULL ;
538555 o -> takes_var_args = (scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ;
539556 o -> takes_kw_args = (scope_flags & MP_SCOPE_FLAG_VARKEYWORDS ) != 0 ;
540557 o -> bytecode = code ;
541- memset (o -> extra_args , 0 , n_extra_args * sizeof (mp_obj_t ));
558+ mp_obj_t * extra_args = o -> extra_args ;
559+ memset (extra_args , 0 , n_extra_args * sizeof (mp_obj_t ));
542560 if (def_args != MP_OBJ_NULL ) {
543- memcpy (o -> extra_args , def_args -> items , n_def_args * sizeof (mp_obj_t ));
561+ memcpy (extra_args , def_args -> items , n_def_args * sizeof (mp_obj_t ));
562+ extra_args += n_def_args ;
563+ }
564+ if (def_kw_args != MP_OBJ_NULL ) {
565+ * extra_args ++ = def_kw_args ;
544566 }
545567 if ((scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
546- o -> extra_args [ n_def_args ] = MP_OBJ_NULL ;
568+ * extra_args ++ = MP_OBJ_NULL ;
547569 }
548570 if ((scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
549- o -> extra_args [ n_extra_args - 1 ] = MP_OBJ_NULL ;
571+ * extra_args = MP_OBJ_NULL ;
550572 }
551573 return o ;
552574}
0 commit comments