From 3a3db4dcf0400cffef860f61a84979cb1f7a7541 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Oct 2015 23:45:37 +0100 Subject: [PATCH] py: Put all bytecode state (arg count, etc) in bytecode. --- py/bc.c | 73 ++++++++++++++++++++++++-------------------- py/bc.h | 6 +++- py/compile.c | 6 ++++ py/emitbc.c | 11 +++++-- py/emitglue.c | 22 +++++-------- py/emitglue.h | 4 +-- py/emitinlinethumb.c | 2 +- py/emitnative.c | 7 +++-- py/obj.h | 4 +-- py/objfun.c | 18 +++++------ py/objfun.h | 6 ---- py/runtime0.h | 1 + py/scope.h | 1 + py/showbc.c | 12 +++++--- 14 files changed, 95 insertions(+), 78 deletions(-) diff --git a/py/bc.c b/py/bc.c index a4ee847098..da0ea78765 100644 --- a/py/bc.c +++ b/py/bc.c @@ -31,6 +31,7 @@ #include "py/nlr.h" #include "py/objfun.h" +#include "py/runtime0.h" #include "py/bc.h" #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 code_state->prev = NULL; #endif + // get params + mp_uint_t scope_flags = *code_state->ip++; + mp_uint_t n_pos_args = *code_state->ip++; + mp_uint_t n_kwonly_args = *code_state->ip++; + mp_uint_t n_def_pos_args = *code_state->ip++; + // align ip code_state->ip = MP_ALIGN(code_state->ip, sizeof(mp_uint_t)); @@ -112,33 +119,33 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t const mp_obj_t *kwargs = args + n_args; // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed) - mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - self->n_pos_args - self->n_kwonly_args]; + mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - n_pos_args - n_kwonly_args]; // check positional arguments - if (n_args > self->n_pos_args) { + if (n_args > n_pos_args) { // given more than enough arguments - if (!self->takes_var_args) { - fun_pos_args_mismatch(self, self->n_pos_args, n_args); + if ((scope_flags & MP_SCOPE_FLAG_VARARGS) == 0) { + fun_pos_args_mismatch(self, n_pos_args, n_args); } // put extra arguments in varargs tuple - *var_pos_kw_args-- = mp_obj_new_tuple(n_args - self->n_pos_args, args + self->n_pos_args); - n_args = self->n_pos_args; + *var_pos_kw_args-- = mp_obj_new_tuple(n_args - n_pos_args, args + n_pos_args); + n_args = n_pos_args; } else { - if (self->takes_var_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) { DEBUG_printf("passing empty tuple as *args\n"); *var_pos_kw_args-- = mp_const_empty_tuple; } // Apply processing and check below only if we don't have kwargs, // otherwise, kw handling code below has own extensive checks. - if (n_kw == 0 && !self->has_def_kw_args) { - if (n_args >= (mp_uint_t)(self->n_pos_args - self->n_def_args)) { + if (n_kw == 0 && (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) == 0) { + if (n_args >= (mp_uint_t)(n_pos_args - n_def_pos_args)) { // given enough arguments, but may need to use some default arguments - for (mp_uint_t i = n_args; i < self->n_pos_args; i++) { - code_state->state[n_state - 1 - i] = self->extra_args[i - (self->n_pos_args - self->n_def_args)]; + for (mp_uint_t i = n_args; i < n_pos_args; i++) { + code_state->state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)]; } } else { - fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args); + fun_pos_args_mismatch(self, n_pos_args - n_def_pos_args, n_args); } } } @@ -150,12 +157,12 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t // check keyword arguments - if (n_kw != 0 || self->has_def_kw_args) { + if (n_kw != 0 || (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { DEBUG_printf("Initial args: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); mp_obj_t dict = MP_OBJ_NULL; - if (self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0? *var_pos_kw_args = dict; } @@ -165,7 +172,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t for (mp_uint_t i = 0; i < n_kw; i++) { mp_obj_t wanted_arg_name = kwargs[2 * i]; - for (mp_uint_t j = 0; j < self->n_pos_args + self->n_kwonly_args; j++) { + for (mp_uint_t j = 0; j < n_pos_args + n_kwonly_args; j++) { if (wanted_arg_name == arg_names[j]) { if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, @@ -176,7 +183,7 @@ void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t } } // Didn't find name match with positional args - if (!self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); } mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]); @@ -184,19 +191,19 @@ continue2:; } DEBUG_printf("Args with kws flattened: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // fill in defaults for positional args - mp_obj_t *d = &code_state->state[n_state - self->n_pos_args]; - mp_obj_t *s = &self->extra_args[self->n_def_args - 1]; - for (mp_uint_t i = self->n_def_args; i > 0; i--, d++, s--) { + mp_obj_t *d = &code_state->state[n_state - n_pos_args]; + mp_obj_t *s = &self->extra_args[n_def_pos_args - 1]; + for (mp_uint_t i = n_def_pos_args; i > 0; i--, d++, s--) { if (*d == MP_OBJ_NULL) { *d = *s; } } DEBUG_printf("Args after filling default positional: "); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // Check that all mandatory positional args are specified while (d < &code_state->state[n_state]) { @@ -208,35 +215,35 @@ continue2:; // Check that all mandatory keyword args are specified // Fill in default kw args if we have them - for (mp_uint_t i = 0; i < self->n_kwonly_args; i++) { - if (code_state->state[n_state - 1 - self->n_pos_args - i] == MP_OBJ_NULL) { + for (mp_uint_t i = 0; i < n_kwonly_args; i++) { + if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) { mp_map_elem_t *elem = NULL; - if (self->has_def_kw_args) { - 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); + if ((scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { + 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); } if (elem != NULL) { - code_state->state[n_state - 1 - self->n_pos_args - i] = elem->value; + code_state->state[n_state - 1 - n_pos_args - i] = elem->value; } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[self->n_pos_args + i]))); + "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i]))); } } } } else { // no keyword arguments given - if (self->n_kwonly_args != 0) { + if (n_kwonly_args != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function missing keyword-only argument")); } - if (self->takes_kw_args) { + if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { *var_pos_kw_args = mp_obj_new_dict(0); } } // get the ip and skip argument names const byte *ip = code_state->ip; - ip += (self->n_pos_args + self->n_kwonly_args) * sizeof(mp_uint_t); + ip += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t); // store pointer to code_info and jump over it { @@ -256,7 +263,7 @@ continue2:; // now that we skipped over the prelude, set the ip for the VM code_state->ip = ip; - DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args); - dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); + DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", n_pos_args, n_kwonly_args); + dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); dump_args(code_state->state, n_state); } diff --git a/py/bc.h b/py/bc.h index 73b67bc105..5824688d85 100644 --- a/py/bc.h +++ b/py/bc.h @@ -33,6 +33,10 @@ // // n_state : var uint // n_exc_stack : var uint +// scope_flags : byte +// n_pos_args : byte number of arguments this function takes +// n_kwonly_args : byte number of keyword-only arguments this function takes +// n_def_pos_args : byte number of default positional arguments // // // @@ -85,7 +89,7 @@ mp_uint_t mp_decode_uint(const byte **ptr); mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_obj_t inject_exc); mp_code_state *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args); -void mp_bytecode_print(const void *descr, mp_uint_t n_total_args, const byte *code, mp_uint_t len); +void mp_bytecode_print(const void *descr, const byte *code, mp_uint_t len); void mp_bytecode_print2(const byte *code, mp_uint_t len); const byte *mp_bytecode_print_str(const byte *ip); #define mp_bytecode_print_inst(code) mp_bytecode_print2(code, 1) diff --git a/py/compile.c b/py/compile.c index f10b378074..e0561e6c32 100644 --- a/py/compile.c +++ b/py/compile.c @@ -539,6 +539,12 @@ STATIC void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int assert(n_pos_defaults >= 0); assert(n_kw_defaults >= 0); + // set flags + if (n_kw_defaults > 0) { + this_scope->scope_flags |= MP_SCOPE_FLAG_DEFKWARGS; + } + this_scope->num_def_pos_args = n_pos_defaults; + // make closed over variables, if any // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython) int nfree = 0; diff --git a/py/emitbc.c b/py/emitbc.c index 0ed7828f9f..6b45019015 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -294,6 +294,13 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { emit_write_code_info_uint(emit, scope->exc_stack_size); } + // Write scope flags and number of arguments. + // TODO check that num args all fit in a byte + emit_write_code_info_byte(emit, emit->scope->scope_flags); + emit_write_code_info_byte(emit, emit->scope->num_pos_args); + emit_write_code_info_byte(emit, emit->scope->num_kwonly_args); + emit_write_code_info_byte(emit, emit->scope->num_def_pos_args); + // Align code-info so that following pointers are aligned on a machine word. emit_align_code_info_to_machine_word(emit); @@ -372,9 +379,7 @@ void mp_emit_bc_end_pass(emit_t *emit) { } else if (emit->pass == MP_PASS_EMIT) { mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base, - emit->code_info_size + emit->bytecode_size, - emit->scope->num_pos_args, emit->scope->num_kwonly_args, - emit->scope->scope_flags); + emit->code_info_size + emit->bytecode_size, emit->scope->scope_flags); } } diff --git a/py/emitglue.c b/py/emitglue.c index 610e76d534..83fe420b7b 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -48,11 +48,9 @@ struct _mp_raw_code_t { mp_raw_code_kind_t kind : 3; mp_uint_t scope_flags : 7; mp_uint_t n_pos_args : 11; - mp_uint_t n_kwonly_args : 11; union { struct { - byte *code; - mp_uint_t len; + const byte *code; } u_byte; struct { void *fun_data; @@ -67,36 +65,32 @@ mp_raw_code_t *mp_emit_glue_new_raw_code(void) { return rc; } -void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_uint_t scope_flags) { +void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t scope_flags) { rc->kind = MP_CODE_BYTECODE; rc->scope_flags = scope_flags; - rc->n_pos_args = n_pos_args; - rc->n_kwonly_args = n_kwonly_args; rc->data.u_byte.code = code; - rc->data.u_byte.len = len; #ifdef DEBUG_PRINT - DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " n_kwonly_args=" UINT_FMT " flags=%x\n", code, len, n_pos_args, n_kwonly_args, (uint)scope_flags); + DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " flags=%x\n", code, len, (uint)scope_flags); #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag >= 2) { - mp_bytecode_print(rc, n_pos_args + n_kwonly_args, code, len); + mp_bytecode_print(rc, code, len); } #endif } #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_uint_t scope_flags, mp_uint_t type_sig) { +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) { assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); rc->kind = kind; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; - rc->n_kwonly_args = n_kwonly_args; rc->data.u_native.fun_data = fun_data; rc->data.u_native.type_sig = type_sig; #ifdef DEBUG_PRINT - DEBUG_printf("assign native: kind=%d fun=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " n_kwonly_args=" UINT_FMT " flags=%x\n", kind, fun_data, fun_len, n_pos_args, n_kwonly_args, (uint)scope_flags); + DEBUG_printf("assign native: kind=%d fun=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " flags=%x\n", kind, fun_data, fun_len, n_pos_args, (uint)scope_flags); for (mp_uint_t i = 0; i < fun_len; i++) { if (i > 0 && i % 16 == 0) { DEBUG_printf("\n"); @@ -131,11 +125,11 @@ mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp switch (rc->kind) { case MP_CODE_BYTECODE: no_other_choice: - fun = mp_obj_new_fun_bc(rc->scope_flags, rc->n_pos_args, rc->n_kwonly_args, def_args, def_kw_args, rc->data.u_byte.code); + fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->data.u_byte.code); break; #if MICROPY_EMIT_NATIVE case MP_CODE_NATIVE_PY: - fun = mp_obj_new_fun_native(rc->scope_flags, rc->n_pos_args, rc->n_kwonly_args, def_args, def_kw_args, rc->data.u_native.fun_data); + fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->data.u_native.fun_data); break; case MP_CODE_NATIVE_VIPER: fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig); diff --git a/py/emitglue.h b/py/emitglue.h index 97e680b4c4..56029b3a9b 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -43,8 +43,8 @@ typedef struct _mp_raw_code_t mp_raw_code_t; mp_raw_code_t *mp_emit_glue_new_raw_code(void); -void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_uint_t scope_flags); -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_uint_t scope_flags, mp_uint_t type_sig); +void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, mp_uint_t len, mp_uint_t scope_flags); +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig); mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 9f4ef1209e..14cbf57ec2 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -90,7 +90,7 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) { if (emit->pass == MP_PASS_EMIT) { void *f = asm_thumb_get_code(emit->as); - mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args, 0, 0, 0); + mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args, 0, 0); } } diff --git a/py/emitnative.c b/py/emitnative.c index 1fcc843385..99eac79253 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -824,6 +824,10 @@ STATIC void emit_native_end_pass(emit_t *emit) { if (!emit->do_viper_types) { emit->prelude_offset = ASM_GET_CODE_POS(emit->as); + ASM_DATA(emit->as, 1, emit->scope->scope_flags); + ASM_DATA(emit->as, 1, emit->scope->num_pos_args); + ASM_DATA(emit->as, 1, emit->scope->num_kwonly_args); + ASM_DATA(emit->as, 1, emit->scope->num_def_pos_args); ASM_ALIGN(emit->as, ASM_WORD_SIZE); // write argument names as qstr objects @@ -874,8 +878,7 @@ STATIC void emit_native_end_pass(emit_t *emit) { mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, - f, f_len, emit->scope->num_pos_args, emit->scope->num_kwonly_args, - emit->scope->scope_flags, type_sig); + f, f_len, emit->scope->num_pos_args, emit->scope->scope_flags, type_sig); } } diff --git a/py/obj.h b/py/obj.h index 64395083af..a627a4143b 100644 --- a/py/obj.h +++ b/py/obj.h @@ -537,8 +537,8 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args); mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg); mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) -mp_obj_t mp_obj_new_fun_bc(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code); -mp_obj_t mp_obj_new_fun_native(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data); +mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code); +mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data); mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); diff --git a/py/objfun.c b/py/objfun.c index 53ddb0a7b9..a54e50d2cd 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -125,8 +125,12 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) { const byte *bc = fun->bytecode; mp_decode_uint(&bc); // skip n_state mp_decode_uint(&bc); // skip n_exc_stack + bc++; // skip scope_params + mp_uint_t n_pos_args = *bc++; + mp_uint_t n_kwonly_args = *bc++; + bc++; // skip n_def_pos_args bc = MP_ALIGN(bc, sizeof(mp_uint_t)); // align - bc += (fun->n_pos_args + fun->n_kwonly_args) * sizeof(mp_uint_t); // skip arg names + bc += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t); // skip arg names return mp_obj_code_get_name(bc); } @@ -316,7 +320,7 @@ const mp_obj_type_t mp_type_fun_bc = { #endif }; -mp_obj_t mp_obj_new_fun_bc(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code) { +mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code) { mp_uint_t n_def_args = 0; mp_uint_t n_extra_args = 0; mp_obj_tuple_t *def_args = def_args_in; @@ -331,12 +335,6 @@ mp_obj_t mp_obj_new_fun_bc(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_ mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args); o->base.type = &mp_type_fun_bc; o->globals = mp_globals_get(); - o->n_pos_args = n_pos_args; - o->n_kwonly_args = n_kwonly_args; - o->n_def_args = n_def_args; - o->has_def_kw_args = def_kw_args != MP_OBJ_NULL; - o->takes_var_args = (scope_flags & MP_SCOPE_FLAG_VARARGS) != 0; - o->takes_kw_args = (scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0; o->bytecode = code; if (def_args != MP_OBJ_NULL) { memcpy(o->extra_args, def_args->items, n_def_args * sizeof(mp_obj_t)); @@ -366,8 +364,8 @@ STATIC const mp_obj_type_t mp_type_fun_native = { .unary_op = mp_generic_unary_op, }; -mp_obj_t mp_obj_new_fun_native(mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t n_kwonly_args, mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data) { - mp_obj_fun_bc_t *o = mp_obj_new_fun_bc(scope_flags, n_pos_args, n_kwonly_args, def_args_in, def_kw_args, (const byte*)fun_data); +mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data) { + mp_obj_fun_bc_t *o = mp_obj_new_fun_bc(def_args_in, def_kw_args, (const byte*)fun_data); o->base.type = &mp_type_fun_native; return o; } diff --git a/py/objfun.h b/py/objfun.h index a5b9f2b5fd..cdc495e5be 100644 --- a/py/objfun.h +++ b/py/objfun.h @@ -31,12 +31,6 @@ typedef struct _mp_obj_fun_bc_t { mp_obj_base_t base; mp_obj_dict_t *globals; // the context within which this function was defined - mp_uint_t n_pos_args : 8; // number of arguments this function takes - mp_uint_t n_kwonly_args : 8; // number of keyword-only arguments this function takes - mp_uint_t n_def_args : 8; // number of default arguments - mp_uint_t has_def_kw_args : 1; // set if this function has default keyword args - mp_uint_t takes_var_args : 1; // set if this function takes variable args - mp_uint_t takes_kw_args : 1; // set if this function takes keyword args const byte *bytecode; // bytecode for the function // the following extra_args array is allocated space to take (in order): // - values of positional default args (if any) diff --git a/py/runtime0.h b/py/runtime0.h index 1d7d64bea6..d00949f929 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -30,6 +30,7 @@ #define MP_SCOPE_FLAG_VARARGS (0x01) #define MP_SCOPE_FLAG_VARKEYWORDS (0x02) #define MP_SCOPE_FLAG_GENERATOR (0x04) +#define MP_SCOPE_FLAG_DEFKWARGS (0x08) // types for native (viper) function signature #define MP_NATIVE_TYPE_OBJ (0x00) diff --git a/py/scope.h b/py/scope.h index 0ea003516a..fac936a729 100644 --- a/py/scope.h +++ b/py/scope.h @@ -66,6 +66,7 @@ typedef struct _scope_t { uint8_t emit_options; // see compile.h uint16_t num_pos_args; uint16_t num_kwonly_args; + uint16_t num_def_pos_args; uint16_t num_locals; uint16_t stack_size; // maximum size of the locals stack uint16_t exc_stack_size; // maximum size of the exception stack diff --git a/py/showbc.c b/py/showbc.c index 87e7c6af46..538eddc40f 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -54,18 +54,22 @@ const byte *mp_showbc_code_start; -void mp_bytecode_print(const void *descr, mp_uint_t n_total_args, const byte *ip, mp_uint_t len) { +void mp_bytecode_print(const void *descr, const byte *ip, mp_uint_t len) { mp_showbc_code_start = ip; - // get state size and exception stack size + // get bytecode parameters mp_uint_t n_state = mp_decode_uint(&ip); mp_uint_t n_exc_stack = mp_decode_uint(&ip); + /*mp_uint_t scope_flags =*/ ip++; + mp_uint_t n_pos_args = *ip++; + mp_uint_t n_kwonly_args = *ip++; + /*mp_uint_t n_def_pos_args =*/ ip++; ip = MP_ALIGN(ip, sizeof(mp_uint_t)); // get and skip arg names const mp_obj_t *arg_names = (const mp_obj_t*)ip; - ip += n_total_args * sizeof(mp_uint_t); + ip += (n_pos_args + n_kwonly_args) * sizeof(mp_uint_t); const byte *code_info = ip; mp_uint_t code_info_size = mp_decode_uint(&code_info); @@ -88,7 +92,7 @@ void mp_bytecode_print(const void *descr, mp_uint_t n_total_args, const byte *ip // bytecode prelude: arg names (as qstr objects) printf("arg names:"); - for (mp_uint_t i = 0; i < n_total_args; i++) { + for (mp_uint_t i = 0; i < n_pos_args + n_kwonly_args; i++) { printf(" %s", qstr_str(MP_OBJ_QSTR_VALUE(arg_names[i]))); } printf("\n");