py: Pass in address to compiled module instead of returning it.

This change makes it so the compiler and persistent code loader take a
mp_compiled_module_t* as their last argument, instead of returning this
struct.  This eliminates a duplicate context variable for all callers of
these functions (because the context is now stored in the
mp_compiled_module_t by the caller), and also eliminates any confusion
about which context to use after the mp_compile_to_raw_code or
mp_raw_code_load function returns (because there is now only one context,
that stored in mp_compiled_module_t.context).

Reduces code size by 16 bytes on ARM Cortex-based ports.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2022-12-07 14:42:35 +11:00
parent 96c23432f6
commit 2283b6d68f
8 changed files with 39 additions and 41 deletions

View File

@ -152,7 +152,9 @@ The most relevant method you should know about is this:
context->module.globals = mp_globals_get(); context->module.globals = mp_globals_get();
// Compile the input parse_tree to a raw-code structure. // Compile the input parse_tree to a raw-code structure.
mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl, context); mp_compiled_module_t cm;
cm.context = context;
mp_compile_to_raw_code(parse_tree, source_file, is_repl, &cm);
// Create and return a function object that executes the outer module. // Create and return a function object that executes the outer module.
return mp_make_function_from_raw_code(cm.rc, cm.context, NULL); return mp_make_function_from_raw_code(cm.rc, cm.context, NULL);

View File

@ -73,8 +73,9 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
#endif #endif
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_module_context_t *ctx = m_new_obj(mp_module_context_t); mp_compiled_module_t cm;
mp_compiled_module_t cm = mp_compile_to_raw_code(&parse_tree, source_name, false, ctx); cm.context = m_new_obj(mp_module_context_t);
mp_compile_to_raw_code(&parse_tree, source_name, false, &cm);
vstr_t vstr; vstr_t vstr;
vstr_init(&vstr, 16); vstr_init(&vstr, 16);

View File

@ -214,7 +214,7 @@ typedef struct _mp_module_context_t {
// Outer level struct defining a compiled module. // Outer level struct defining a compiled module.
typedef struct _mp_compiled_module_t { typedef struct _mp_compiled_module_t {
const mp_module_context_t *context; mp_module_context_t *context;
const struct _mp_raw_code_t *rc; const struct _mp_raw_code_t *rc;
#if MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_SAVE
bool has_native; bool has_native;

View File

@ -245,7 +245,9 @@ STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) {
// the correct format and, if so, load and execute the file. // the correct format and, if so, load and execute the file.
#if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD
if (file_str[file->len - 3] == 'm') { if (file_str[file->len - 3] == 'm') {
mp_compiled_module_t cm = mp_raw_code_load_file(file_str, module_obj); mp_compiled_module_t cm;
cm.context = module_obj;
mp_raw_code_load_file(file_str, &cm);
do_execute_raw_code(cm.context, cm.rc, file_str); do_execute_raw_code(cm.context, cm.rc, file_str);
return; return;
} }

View File

@ -3427,7 +3427,7 @@ STATIC void scope_compute_things(scope_t *scope) {
#if !MICROPY_PERSISTENT_CODE_SAVE #if !MICROPY_PERSISTENT_CODE_SAVE
STATIC STATIC
#endif #endif
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *context) { void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_compiled_module_t *cm) {
// put compiler state on the stack, it's relatively small // put compiler state on the stack, it's relatively small
compiler_t comp_state = {0}; compiler_t comp_state = {0};
compiler_t *comp = &comp_state; compiler_t *comp = &comp_state;
@ -3568,26 +3568,24 @@ mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr so
} }
// construct the global qstr/const table for this module // construct the global qstr/const table for this module
mp_compiled_module_t cm; cm->rc = module_scope->raw_code;
cm.rc = module_scope->raw_code;
cm.context = context;
#if MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_SAVE
cm.has_native = false; cm->has_native = false;
#if MICROPY_EMIT_NATIVE #if MICROPY_EMIT_NATIVE
if (emit_native != NULL) { if (emit_native != NULL) {
cm.has_native = true; cm->has_native = true;
} }
#endif #endif
#if MICROPY_EMIT_INLINE_ASM #if MICROPY_EMIT_INLINE_ASM
if (comp->emit_inline_asm != NULL) { if (comp->emit_inline_asm != NULL) {
cm.has_native = true; cm->has_native = true;
} }
#endif #endif
cm.n_qstr = comp->emit_common.qstr_map.used; cm->n_qstr = comp->emit_common.qstr_map.used;
cm.n_obj = comp->emit_common.const_obj_list.len; cm->n_obj = comp->emit_common.const_obj_list.len;
#endif #endif
if (comp->compile_error == MP_OBJ_NULL) { if (comp->compile_error == MP_OBJ_NULL) {
mp_emit_common_populate_module_context(&comp->emit_common, source_file, context); mp_emit_common_populate_module_context(&comp->emit_common, source_file, cm->context);
#if MICROPY_DEBUG_PRINTERS #if MICROPY_DEBUG_PRINTERS
// now that the module context is valid, the raw codes can be printed // now that the module context is valid, the raw codes can be printed
@ -3595,7 +3593,7 @@ mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr so
for (scope_t *s = comp->scope_head; s != NULL; s = s->next) { for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
mp_raw_code_t *rc = s->raw_code; mp_raw_code_t *rc = s->raw_code;
if (rc->kind == MP_CODE_BYTECODE) { if (rc->kind == MP_CODE_BYTECODE) {
mp_bytecode_print(&mp_plat_print, rc, &cm.context->constants); mp_bytecode_print(&mp_plat_print, rc, &cm->context->constants);
} }
} }
} }
@ -3629,14 +3627,13 @@ mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr so
if (comp->compile_error != MP_OBJ_NULL) { if (comp->compile_error != MP_OBJ_NULL) {
nlr_raise(comp->compile_error); nlr_raise(comp->compile_error);
} }
return cm;
} }
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) { mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) {
mp_module_context_t *context = m_new_obj(mp_module_context_t); mp_compiled_module_t cm;
context->module.globals = mp_globals_get(); cm.context = m_new_obj(mp_module_context_t);
mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl, context); cm.context->module.globals = mp_globals_get();
mp_compile_to_raw_code(parse_tree, source_file, is_repl, &cm);
// return function that executes the outer module // return function that executes the outer module
return mp_make_function_from_raw_code(cm.rc, cm.context, NULL); return mp_make_function_from_raw_code(cm.rc, cm.context, NULL);
} }

View File

@ -37,7 +37,7 @@ mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl)
#if MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_SAVE
// this has the same semantics as mp_compile // this has the same semantics as mp_compile
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *globals); void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_compiled_module_t *cm);
#endif #endif
// this is implemented in runtime.c // this is implemented in runtime.c

View File

@ -390,7 +390,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
return rc; return rc;
} }
mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *context) { void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) {
byte header[4]; byte header[4];
read_bytes(reader, header, sizeof(header)); read_bytes(reader, header, sizeof(header));
byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); byte arch = MPY_FEATURE_DECODE_ARCH(header[2]);
@ -414,46 +414,42 @@ mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *
size_t n_qstr = read_uint(reader); size_t n_qstr = read_uint(reader);
size_t n_obj = read_uint(reader); size_t n_obj = read_uint(reader);
mp_module_context_alloc_tables(context, n_qstr, n_obj); mp_module_context_alloc_tables(cm->context, n_qstr, n_obj);
// Load qstrs. // Load qstrs.
for (size_t i = 0; i < n_qstr; ++i) { for (size_t i = 0; i < n_qstr; ++i) {
context->constants.qstr_table[i] = load_qstr(reader); cm->context->constants.qstr_table[i] = load_qstr(reader);
} }
// Load constant objects. // Load constant objects.
for (size_t i = 0; i < n_obj; ++i) { for (size_t i = 0; i < n_obj; ++i) {
context->constants.obj_table[i] = load_obj(reader); cm->context->constants.obj_table[i] = load_obj(reader);
} }
// Load top-level module. // Load top-level module.
mp_compiled_module_t cm2; cm->rc = load_raw_code(reader, cm->context);
cm2.rc = load_raw_code(reader, context);
cm2.context = context;
#if MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_SAVE
cm2.has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE; cm->has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE;
cm2.n_qstr = n_qstr; cm->n_qstr = n_qstr;
cm2.n_obj = n_obj; cm->n_obj = n_obj;
#endif #endif
reader->close(reader->data); reader->close(reader->data);
return cm2;
} }
mp_compiled_module_t mp_raw_code_load_mem(const byte *buf, size_t len, mp_module_context_t *context) { void mp_raw_code_load_mem(const byte *buf, size_t len, mp_compiled_module_t *context) {
mp_reader_t reader; mp_reader_t reader;
mp_reader_new_mem(&reader, buf, len, 0); mp_reader_new_mem(&reader, buf, len, 0);
return mp_raw_code_load(&reader, context); mp_raw_code_load(&reader, context);
} }
#if MICROPY_HAS_FILE_READER #if MICROPY_HAS_FILE_READER
mp_compiled_module_t mp_raw_code_load_file(const char *filename, mp_module_context_t *context) { void mp_raw_code_load_file(const char *filename, mp_compiled_module_t *context) {
mp_reader_t reader; mp_reader_t reader;
mp_reader_new_file(&reader, filename); mp_reader_new_file(&reader, filename);
return mp_raw_code_load(&reader, context); mp_raw_code_load(&reader, context);
} }
#endif // MICROPY_HAS_FILE_READER #endif // MICROPY_HAS_FILE_READER

View File

@ -111,9 +111,9 @@ enum {
MP_PERSISTENT_OBJ_TUPLE, MP_PERSISTENT_OBJ_TUPLE,
}; };
mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *ctx); void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *ctx);
mp_compiled_module_t mp_raw_code_load_mem(const byte *buf, size_t len, mp_module_context_t *ctx); void mp_raw_code_load_mem(const byte *buf, size_t len, mp_compiled_module_t *ctx);
mp_compiled_module_t mp_raw_code_load_file(const char *filename, mp_module_context_t *ctx); void mp_raw_code_load_file(const char *filename, mp_compiled_module_t *ctx);
void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print); void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print);
void mp_raw_code_save_file(mp_compiled_module_t *cm, const char *filename); void mp_raw_code_save_file(mp_compiled_module_t *cm, const char *filename);