diff --git a/py/dynruntime.h b/py/dynruntime.h index 435b85622a..3e660f19fd 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -209,7 +209,7 @@ static inline void *mp_obj_malloc_helper_dyn(size_t num_bytes, const mp_obj_type mp_obj_t old_globals = mp_fun_table.swap_globals(self->context->module.globals); \ mp_raw_code_truncated_t rc; \ rc.kind = MP_CODE_NATIVE_VIPER; \ - rc.scope_flags = 0; \ + rc.is_generator = 0; \ (void)rc; #define MP_DYNRUNTIME_INIT_EXIT \ diff --git a/py/emitglue.c b/py/emitglue.c index 0ec126fe94..c0003c5cd5 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -71,7 +71,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, uint16_t scope_flags) { rc->kind = MP_CODE_BYTECODE; - rc->scope_flags = scope_flags; + rc->is_generator = (scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0; rc->fun_data = code; #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS rc->fun_data_len = len; @@ -133,7 +133,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void #endif rc->kind = kind; - rc->scope_flags = scope_flags; + rc->is_generator = (scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0; rc->fun_data = fun_data; #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS @@ -191,7 +191,7 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, const mp_module case MP_CODE_NATIVE_VIPER: fun = mp_obj_new_fun_native(def_args, rc->fun_data, context, rc->children); // Check for a generator function, and if so change the type of the object - if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { + if (rc->is_generator) { ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_gen_wrap; } break; @@ -206,7 +206,7 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, const mp_module assert(rc->kind == MP_CODE_BYTECODE); fun = mp_obj_new_fun_bc(def_args, rc->fun_data, context, rc->children); // check for generator functions and if so change the type of the object - if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { + if (rc->is_generator) { ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_gen_wrap; } diff --git a/py/emitglue.h b/py/emitglue.h index b79283541b..125ab2ccd5 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -57,8 +57,8 @@ typedef enum { // mpy file: instance in RAM, created when .mpy file is loaded (same comments as above) // frozen: instance in ROM typedef struct _mp_raw_code_t { - uint32_t kind : 3; // of type mp_raw_code_kind_t - uint32_t scope_flags : 7; + uint8_t kind; // of type mp_raw_code_kind_t; only 3 bits used + bool is_generator; const void *fun_data; struct _mp_raw_code_t **children; #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS @@ -88,8 +88,8 @@ typedef struct _mp_raw_code_t { // only needed when the kind is MP_CODE_NATIVE_ASM. So this struct can be used when the // kind is MP_CODE_BYTECODE, MP_CODE_NATIVE_PY or MP_CODE_NATIVE_VIPER, to reduce its size. typedef struct _mp_raw_code_truncated_t { - uint32_t kind : 3; - uint32_t scope_flags : 7; + uint8_t kind; + bool is_generator; const void *fun_data; struct _mp_raw_code_t **children; #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS diff --git a/py/persistentcode.c b/py/persistentcode.c index 83806febb3..7b002e7fcf 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -577,7 +577,9 @@ STATIC void save_raw_code(mp_print_t *print, const mp_raw_code_t *rc) { mp_print_uint(print, rc->prelude_offset); } else if (rc->kind == MP_CODE_NATIVE_VIPER || rc->kind == MP_CODE_NATIVE_ASM) { // Save basic scope info for viper and asm - mp_print_uint(print, rc->scope_flags & MP_SCOPE_FLAG_ALL_SIG); + // Viper/asm functions don't support generator, variable args, or default keyword args + // so (scope_flags & MP_SCOPE_FLAG_ALL_SIG) for these functions is always 0. + mp_print_uint(print, 0); #if MICROPY_EMIT_INLINE_ASM if (rc->kind == MP_CODE_NATIVE_ASM) { mp_print_uint(print, rc->asm_n_pos_args); diff --git a/py/runtime0.h b/py/runtime0.h index 69af38ddcb..9c6f0e079f 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -26,8 +26,11 @@ #ifndef MICROPY_INCLUDED_PY_RUNTIME0_H #define MICROPY_INCLUDED_PY_RUNTIME0_H -// The first four must fit in 8 bits, see emitbc.c -// The remaining must fit in 16 bits, see scope.h +// These constants are used by: +// - mp_raw_code_t::is_generator (only MP_SCOPE_FLAG_GENERATOR) +// - scope_t::scope_flags (16 bits) +// - MP_BC_PRELUDE_SIG_ENCODE macro, masked by MP_SCOPE_FLAG_ALL_SIG (4 bits) +// - tools/mpy_ld.py, when generating mpy files (maximum 7 bits) #define MP_SCOPE_FLAG_ALL_SIG (0x0f) #define MP_SCOPE_FLAG_GENERATOR (0x01) #define MP_SCOPE_FLAG_VARKEYWORDS (0x02) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 9b824099ea..744800c670 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -126,6 +126,7 @@ MP_PERSISTENT_OBJ_FLOAT = 8 MP_PERSISTENT_OBJ_COMPLEX = 9 MP_PERSISTENT_OBJ_TUPLE = 10 +MP_SCOPE_FLAG_GENERATOR = 0x01 MP_SCOPE_FLAG_VIPERRELOC = 0x10 MP_SCOPE_FLAG_VIPERRODATA = 0x20 MP_SCOPE_FLAG_VIPERBSS = 0x40 @@ -912,7 +913,7 @@ class RawCode(object): raw_code_type = "mp_raw_code_truncated_t" print("static const %s raw_code_%s = {" % (raw_code_type, self.escaped_name)) print(" .kind = %s," % RawCode.code_kind_str[self.code_kind]) - print(" .scope_flags = 0x%02x," % self.scope_flags) + print(" .is_generator = %d," % bool(self.scope_flags & MP_SCOPE_FLAG_GENERATOR)) print(" .fun_data = fun_data_%s," % self.escaped_name) if len(self.children): print(" .children = (void *)&children_%s," % self.escaped_name)