@@ -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
249
249
// This function is pretty complicated. It's main aim is to be efficient in speed and RAM
250
250
// usage for the common case of positional only args.
251
251
//
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:
252
256
// extra_args layout: def_args, var_arg tuple, kwonly args, var_kw dict
253
257
254
258
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
260
264
DEBUG_printf ("Func n_def_args: %d\n" , self -> n_def_args );
261
265
262
266
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 ;
264
268
uint n_extra_args = 0 ;
265
269
266
270
// 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
295
299
296
300
// check keyword arguments
297
301
298
- if (n_kw != 0 ) {
302
+ if (n_kw != 0 || self -> has_def_kw_args ) {
299
303
// We cannot use dynamically-sized array here, because GCC indeed
300
304
// deallocates it on leaving defining scope (unlike most static stack allocs).
301
305
// So, we have 2 choices: allocate it unconditionally at the top of function
@@ -355,10 +359,19 @@ continue2:;
355
359
}
356
360
357
361
// Check that all mandatory keyword args are specified
362
+ // Fill in default kw args if we have them
358
363
for (int i = 0 ; i < self -> n_kwonly_args ; i ++ ) {
359
364
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
+ }
362
375
}
363
376
}
364
377
@@ -513,7 +526,7 @@ const mp_obj_type_t mp_type_fun_bc = {
513
526
.binary_op = fun_binary_op ,
514
527
};
515
528
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 ) {
517
530
uint n_def_args = 0 ;
518
531
uint n_extra_args = 0 ;
519
532
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
522
535
n_def_args = def_args -> len ;
523
536
n_extra_args = def_args -> len ;
524
537
}
538
+ if (def_kw_args != MP_OBJ_NULL ) {
539
+ n_extra_args += 1 ;
540
+ }
525
541
if ((scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
526
542
n_extra_args += 1 ;
527
543
}
@@ -535,18 +551,24 @@ mp_obj_t mp_obj_new_fun_bc(uint scope_flags, qstr *args, uint n_pos_args, uint n
535
551
o -> n_pos_args = n_pos_args ;
536
552
o -> n_kwonly_args = n_kwonly_args ;
537
553
o -> n_def_args = n_def_args ;
554
+ o -> has_def_kw_args = def_kw_args != MP_OBJ_NULL ;
538
555
o -> takes_var_args = (scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ;
539
556
o -> takes_kw_args = (scope_flags & MP_SCOPE_FLAG_VARKEYWORDS ) != 0 ;
540
557
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 ));
542
560
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 ;
544
566
}
545
567
if ((scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
546
- o -> extra_args [ n_def_args ] = MP_OBJ_NULL ;
568
+ * extra_args ++ = MP_OBJ_NULL ;
547
569
}
548
570
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 ;
550
572
}
551
573
return o ;
552
574
}
0 commit comments