Skip to content

Commit 49df795

Browse files
committed
objfun: Factor out mp_setup_code_state() function to set up code_state object.
It needs to be reused for generator functions, too.
1 parent 8208967 commit 49df795

1 file changed

Lines changed: 47 additions & 35 deletions

File tree

py/objfun.c

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -244,46 +244,16 @@ bool mp_obj_fun_prepare_simple_args(mp_obj_t self_in, uint n_args, uint n_kw, co
244244
// Set this to enable a simple stack overflow check.
245245
#define VM_DETECT_STACK_OVERFLOW (0)
246246

247-
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
248-
// This function is pretty complicated. It's main aim is to be efficient in speed and RAM
249-
// usage for the common case of positional only args.
250-
251-
DEBUG_printf("Input n_args: %d, n_kw: %d\n", n_args, n_kw);
252-
DEBUG_printf("Input pos args: ");
253-
dump_args(args, n_args);
254-
DEBUG_printf("Input kw args: ");
255-
dump_args(args + n_args, n_kw * 2);
247+
// code_state should have ->ip filled in (pointing past code info block),
248+
// as well as ->n_state.
249+
void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
256250
mp_obj_fun_bc_t *self = self_in;
257-
DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);
258-
259-
const byte *ip = self->bytecode;
260-
261-
// get code info size, and skip line number table
262-
machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
263-
ip += code_info_size;
264-
265-
// bytecode prelude: state size and exception stack size; 16 bit uints
266-
machine_uint_t n_state = ip[0] | (ip[1] << 8);
267-
machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8);
268-
ip += 4;
269-
270-
#if VM_DETECT_STACK_OVERFLOW
271-
n_state += 1;
272-
#endif
273-
274-
// allocate state for locals and stack
275-
uint state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
276-
mp_code_state *code_state;
277-
if (state_size > VM_MAX_STATE_ON_STACK) {
278-
code_state = m_new_obj_var(mp_code_state, byte, state_size);
279-
} else {
280-
code_state = alloca(sizeof(mp_code_state) + state_size);
281-
}
251+
machine_uint_t n_state = code_state->n_state;
252+
const byte *ip = code_state->ip;
282253

283254
code_state->code_info = self->bytecode;
284255
code_state->sp = &code_state->state[0] - 1;
285256
code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
286-
code_state->n_state = n_state;
287257

288258
// zero out the local stack to begin with
289259
memset(code_state->state, 0, n_state * sizeof(*code_state->state));
@@ -422,6 +392,48 @@ continue2:;
422392
DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args);
423393
dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);
424394
dump_args(code_state->state, n_state);
395+
}
396+
397+
398+
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
399+
// This function is pretty complicated. It's main aim is to be efficient in speed and RAM
400+
// usage for the common case of positional only args.
401+
402+
DEBUG_printf("Input n_args: %d, n_kw: %d\n", n_args, n_kw);
403+
DEBUG_printf("Input pos args: ");
404+
dump_args(args, n_args);
405+
DEBUG_printf("Input kw args: ");
406+
dump_args(args + n_args, n_kw * 2);
407+
mp_obj_fun_bc_t *self = self_in;
408+
DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);
409+
410+
const byte *ip = self->bytecode;
411+
412+
// get code info size, and skip line number table
413+
machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
414+
ip += code_info_size;
415+
416+
// bytecode prelude: state size and exception stack size; 16 bit uints
417+
machine_uint_t n_state = ip[0] | (ip[1] << 8);
418+
machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8);
419+
ip += 4;
420+
421+
#if VM_DETECT_STACK_OVERFLOW
422+
n_state += 1;
423+
#endif
424+
425+
// allocate state for locals and stack
426+
uint state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
427+
mp_code_state *code_state;
428+
if (state_size > VM_MAX_STATE_ON_STACK) {
429+
code_state = m_new_obj_var(mp_code_state, byte, state_size);
430+
} else {
431+
code_state = alloca(sizeof(mp_code_state) + state_size);
432+
}
433+
434+
code_state->n_state = n_state;
435+
code_state->ip = ip;
436+
mp_setup_code_state(code_state, self_in, n_args, n_kw, args);
425437

426438
// execute the byte code with the correct globals context
427439
mp_obj_dict_t *old_globals = mp_globals_get();

0 commit comments

Comments
 (0)