3131
3232#include "py/nlr.h"
3333#include "py/objfun.h"
34+ #include "py/runtime0.h"
3435#include "py/bc.h"
3536
3637#if 0 // print debugging info
@@ -100,6 +101,12 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
100101 code_state -> prev = NULL ;
101102 #endif
102103
104+ // get params
105+ mp_uint_t scope_flags = * code_state -> ip ++ ;
106+ mp_uint_t n_pos_args = * code_state -> ip ++ ;
107+ mp_uint_t n_kwonly_args = * code_state -> ip ++ ;
108+ mp_uint_t n_def_pos_args = * code_state -> ip ++ ;
109+
103110 // align ip
104111 code_state -> ip = MP_ALIGN (code_state -> ip , sizeof (mp_uint_t ));
105112
@@ -112,33 +119,33 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
112119 const mp_obj_t * kwargs = args + n_args ;
113120
114121 // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed)
115- mp_obj_t * var_pos_kw_args = & code_state -> state [n_state - 1 - self -> n_pos_args - self -> n_kwonly_args ];
122+ mp_obj_t * var_pos_kw_args = & code_state -> state [n_state - 1 - n_pos_args - n_kwonly_args ];
116123
117124 // check positional arguments
118125
119- if (n_args > self -> n_pos_args ) {
126+ if (n_args > n_pos_args ) {
120127 // given more than enough arguments
121- if (! self -> takes_var_args ) {
122- fun_pos_args_mismatch (self , self -> n_pos_args , n_args );
128+ if (( scope_flags & MP_SCOPE_FLAG_VARARGS ) == 0 ) {
129+ fun_pos_args_mismatch (self , n_pos_args , n_args );
123130 }
124131 // put extra arguments in varargs tuple
125- * var_pos_kw_args -- = mp_obj_new_tuple (n_args - self -> n_pos_args , args + self -> n_pos_args );
126- n_args = self -> n_pos_args ;
132+ * var_pos_kw_args -- = mp_obj_new_tuple (n_args - n_pos_args , args + n_pos_args );
133+ n_args = n_pos_args ;
127134 } else {
128- if (self -> takes_var_args ) {
135+ if (( scope_flags & MP_SCOPE_FLAG_VARARGS ) != 0 ) {
129136 DEBUG_printf ("passing empty tuple as *args\n" );
130137 * var_pos_kw_args -- = mp_const_empty_tuple ;
131138 }
132139 // Apply processing and check below only if we don't have kwargs,
133140 // otherwise, kw handling code below has own extensive checks.
134- if (n_kw == 0 && ! self -> has_def_kw_args ) {
135- if (n_args >= (mp_uint_t )(self -> n_pos_args - self -> n_def_args )) {
141+ if (n_kw == 0 && ( scope_flags & MP_SCOPE_FLAG_DEFKWARGS ) == 0 ) {
142+ if (n_args >= (mp_uint_t )(n_pos_args - n_def_pos_args )) {
136143 // given enough arguments, but may need to use some default arguments
137- for (mp_uint_t i = n_args ; i < self -> n_pos_args ; i ++ ) {
138- code_state -> state [n_state - 1 - i ] = self -> extra_args [i - (self -> n_pos_args - self -> n_def_args )];
144+ for (mp_uint_t i = n_args ; i < n_pos_args ; i ++ ) {
145+ code_state -> state [n_state - 1 - i ] = self -> extra_args [i - (n_pos_args - n_def_pos_args )];
139146 }
140147 } else {
141- fun_pos_args_mismatch (self , self -> n_pos_args - self -> n_def_args , n_args );
148+ fun_pos_args_mismatch (self , n_pos_args - n_def_pos_args , n_args );
142149 }
143150 }
144151 }
@@ -150,12 +157,12 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
150157
151158 // check keyword arguments
152159
153- if (n_kw != 0 || self -> has_def_kw_args ) {
160+ if (n_kw != 0 || ( scope_flags & MP_SCOPE_FLAG_DEFKWARGS ) != 0 ) {
154161 DEBUG_printf ("Initial args: " );
155- dump_args (code_state -> state + n_state - self -> n_pos_args - self -> n_kwonly_args , self -> n_pos_args + self -> n_kwonly_args );
162+ dump_args (code_state -> state + n_state - n_pos_args - n_kwonly_args , n_pos_args + n_kwonly_args );
156163
157164 mp_obj_t dict = MP_OBJ_NULL ;
158- if (self -> takes_kw_args ) {
165+ if (( scope_flags & MP_SCOPE_FLAG_VARKEYWORDS ) != 0 ) {
159166 dict = mp_obj_new_dict (n_kw ); // TODO: better go conservative with 0?
160167 * var_pos_kw_args = dict ;
161168 }
@@ -165,7 +172,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
165172
166173 for (mp_uint_t i = 0 ; i < n_kw ; i ++ ) {
167174 mp_obj_t wanted_arg_name = kwargs [2 * i ];
168- for (mp_uint_t j = 0 ; j < self -> n_pos_args + self -> n_kwonly_args ; j ++ ) {
175+ for (mp_uint_t j = 0 ; j < n_pos_args + n_kwonly_args ; j ++ ) {
169176 if (wanted_arg_name == arg_names [j ]) {
170177 if (code_state -> state [n_state - 1 - j ] != MP_OBJ_NULL ) {
171178 nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
@@ -176,27 +183,27 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t
176183 }
177184 }
178185 // Didn't find name match with positional args
179- if (! self -> takes_kw_args ) {
186+ if (( scope_flags & MP_SCOPE_FLAG_VARKEYWORDS ) == 0 ) {
180187 nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "function does not take keyword arguments" ));
181188 }
182189 mp_obj_dict_store (dict , kwargs [2 * i ], kwargs [2 * i + 1 ]);
183190continue2 :;
184191 }
185192
186193 DEBUG_printf ("Args with kws flattened: " );
187- dump_args (code_state -> state + n_state - self -> n_pos_args - self -> n_kwonly_args , self -> n_pos_args + self -> n_kwonly_args );
194+ dump_args (code_state -> state + n_state - n_pos_args - n_kwonly_args , n_pos_args + n_kwonly_args );
188195
189196 // fill in defaults for positional args
190- mp_obj_t * d = & code_state -> state [n_state - self -> n_pos_args ];
191- mp_obj_t * s = & self -> extra_args [self -> n_def_args - 1 ];
192- for (mp_uint_t i = self -> n_def_args ; i > 0 ; i -- , d ++ , s -- ) {
197+ mp_obj_t * d = & code_state -> state [n_state - n_pos_args ];
198+ mp_obj_t * s = & self -> extra_args [n_def_pos_args - 1 ];
199+ for (mp_uint_t i = n_def_pos_args ; i > 0 ; i -- , d ++ , s -- ) {
193200 if (* d == MP_OBJ_NULL ) {
194201 * d = * s ;
195202 }
196203 }
197204
198205 DEBUG_printf ("Args after filling default positional: " );
199- dump_args (code_state -> state + n_state - self -> n_pos_args - self -> n_kwonly_args , self -> n_pos_args + self -> n_kwonly_args );
206+ dump_args (code_state -> state + n_state - n_pos_args - n_kwonly_args , n_pos_args + n_kwonly_args );
200207
201208 // Check that all mandatory positional args are specified
202209 while (d < & code_state -> state [n_state ]) {
@@ -208,35 +215,35 @@ continue2:;
208215
209216 // Check that all mandatory keyword args are specified
210217 // Fill in default kw args if we have them
211- for (mp_uint_t i = 0 ; i < self -> n_kwonly_args ; i ++ ) {
212- if (code_state -> state [n_state - 1 - self -> n_pos_args - i ] == MP_OBJ_NULL ) {
218+ for (mp_uint_t i = 0 ; i < n_kwonly_args ; i ++ ) {
219+ if (code_state -> state [n_state - 1 - n_pos_args - i ] == MP_OBJ_NULL ) {
213220 mp_map_elem_t * elem = NULL ;
214- if (self -> has_def_kw_args ) {
215- elem = mp_map_lookup (& ((mp_obj_dict_t * )self -> extra_args [self -> n_def_args ])-> map , arg_names [self -> n_pos_args + i ], MP_MAP_LOOKUP );
221+ if (( scope_flags & MP_SCOPE_FLAG_DEFKWARGS ) != 0 ) {
222+ elem = mp_map_lookup (& ((mp_obj_dict_t * )self -> extra_args [n_def_pos_args ])-> map , arg_names [n_pos_args + i ], MP_MAP_LOOKUP );
216223 }
217224 if (elem != NULL ) {
218- code_state -> state [n_state - 1 - self -> n_pos_args - i ] = elem -> value ;
225+ code_state -> state [n_state - 1 - n_pos_args - i ] = elem -> value ;
219226 } else {
220227 nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_TypeError ,
221- "function missing required keyword argument '%q'" , MP_OBJ_QSTR_VALUE (arg_names [self -> n_pos_args + i ])));
228+ "function missing required keyword argument '%q'" , MP_OBJ_QSTR_VALUE (arg_names [n_pos_args + i ])));
222229 }
223230 }
224231 }
225232
226233 } else {
227234 // no keyword arguments given
228- if (self -> n_kwonly_args != 0 ) {
235+ if (n_kwonly_args != 0 ) {
229236 nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError ,
230237 "function missing keyword-only argument" ));
231238 }
232- if (self -> takes_kw_args ) {
239+ if (( scope_flags & MP_SCOPE_FLAG_VARKEYWORDS ) != 0 ) {
233240 * var_pos_kw_args = mp_obj_new_dict (0 );
234241 }
235242 }
236243
237244 // get the ip and skip argument names
238245 const byte * ip = code_state -> ip ;
239- ip += (self -> n_pos_args + self -> n_kwonly_args ) * sizeof (mp_uint_t );
246+ ip += (n_pos_args + n_kwonly_args ) * sizeof (mp_uint_t );
240247
241248 // store pointer to code_info and jump over it
242249 {
@@ -256,7 +263,7 @@ continue2:;
256263 // now that we skipped over the prelude, set the ip for the VM
257264 code_state -> ip = ip ;
258265
259- DEBUG_printf ("Calling: n_pos_args=%d, n_kwonly_args=%d\n" , self -> n_pos_args , self -> n_kwonly_args );
260- dump_args (code_state -> state + n_state - self -> n_pos_args - self -> n_kwonly_args , self -> n_pos_args + self -> n_kwonly_args );
266+ DEBUG_printf ("Calling: n_pos_args=%d, n_kwonly_args=%d\n" , n_pos_args , n_kwonly_args );
267+ dump_args (code_state -> state + n_state - n_pos_args - n_kwonly_args , n_pos_args + n_kwonly_args );
261268 dump_args (code_state -> state , n_state );
262269}
0 commit comments