From a3a73b64a3be5b5cc2b50444c819d81f8347d52f Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Feb 2024 17:41:48 +1100 Subject: [PATCH] tools/mpy-tool.py: Skip generating frozen mp_raw_code_t when possible. This reduces frozen code size by using the bytecode directly as the `mp_proto_fun_t`. Signed-off-by: Damien George --- py/emitglue.c | 12 ++++++++++++ tools/mpy-tool.py | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/py/emitglue.c b/py/emitglue.c index 1c7e013294..9d671b710e 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -183,6 +183,18 @@ mp_obj_t mp_make_function_from_proto_fun(mp_proto_fun_t proto_fun, const mp_modu // def_kw_args must be MP_OBJ_NULL or a dict assert(def_args == NULL || def_args[1] == MP_OBJ_NULL || mp_obj_is_type(def_args[1], &mp_type_dict)); + #if MICROPY_MODULE_FROZEN_MPY + if (mp_proto_fun_is_bytecode(proto_fun)) { + const uint8_t *bc = proto_fun; + mp_obj_t fun = mp_obj_new_fun_bc(def_args, bc, context, NULL); + MP_BC_PRELUDE_SIG_DECODE(bc); + if (scope_flags & MP_SCOPE_FLAG_GENERATOR) { + ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_gen_wrap; + } + return fun; + } + #endif + // the proto-function is a mp_raw_code_t const mp_raw_code_t *rc = proto_fun; diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 33e59c807a..38567b37e5 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -911,6 +911,13 @@ class RawCode(object): raw_code_type = "mp_raw_code_t" else: raw_code_type = "mp_raw_code_truncated_t" + + empty_children = len(self.children) == 0 and prelude_ptr is None + generate_minimal = self.code_kind == MP_CODE_BYTECODE and empty_children + + if generate_minimal: + print("#if MICROPY_PERSISTENT_CODE_SAVE") + print("static const %s proto_fun_%s = {" % (raw_code_type, self.escaped_name)) print(" .proto_fun_indicator[0] = MP_PROTO_FUN_INDICATOR_RAW_CODE_0,") print(" .proto_fun_indicator[1] = MP_PROTO_FUN_INDICATOR_RAW_CODE_1,") @@ -961,6 +968,11 @@ class RawCode(object): print(" .asm_type_sig = %u," % type_sig) print("};") + if generate_minimal: + print("#else") + print("#define proto_fun_%s fun_data_%s[0]" % (self.escaped_name, self.escaped_name)) + print("#endif") + global raw_code_count, raw_code_content raw_code_count += 1 raw_code_content += 4 * 4