Skip to content

Commit

Permalink
py: Pass in address to compiled module instead of returning it.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dpgeorge committed Dec 8, 2022
1 parent 96c2343 commit 2283b6d
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 41 deletions.
4 changes: 3 additions & 1 deletion docs/develop/compiler.rst
Expand Up @@ -152,7 +152,9 @@ The most relevant method you should know about is this:
context->module.globals = mp_globals_get();
// 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.
return mp_make_function_from_raw_code(cm.rc, cm.context, NULL);
Expand Down
5 changes: 3 additions & 2 deletions mpy-cross/main.c
Expand Up @@ -73,8 +73,9 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
#endif

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_compile_to_raw_code(&parse_tree, source_name, false, ctx);
mp_compiled_module_t cm;
cm.context = m_new_obj(mp_module_context_t);
mp_compile_to_raw_code(&parse_tree, source_name, false, &cm);

vstr_t vstr;
vstr_init(&vstr, 16);
Expand Down
2 changes: 1 addition & 1 deletion py/bc.h
Expand Up @@ -214,7 +214,7 @@ typedef struct _mp_module_context_t {

// Outer level struct defining a compiled module.
typedef struct _mp_compiled_module_t {
const mp_module_context_t *context;
mp_module_context_t *context;
const struct _mp_raw_code_t *rc;
#if MICROPY_PERSISTENT_CODE_SAVE
bool has_native;
Expand Down
4 changes: 3 additions & 1 deletion py/builtinimport.c
Expand Up @@ -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.
#if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD
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);
return;
}
Expand Down
29 changes: 13 additions & 16 deletions py/compile.c
Expand Up @@ -3427,7 +3427,7 @@ STATIC void scope_compute_things(scope_t *scope) {
#if !MICROPY_PERSISTENT_CODE_SAVE
STATIC
#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
compiler_t comp_state = {0};
compiler_t *comp = &comp_state;
Expand Down Expand Up @@ -3568,34 +3568,32 @@ 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
mp_compiled_module_t cm;
cm.rc = module_scope->raw_code;
cm.context = context;
cm->rc = module_scope->raw_code;
#if MICROPY_PERSISTENT_CODE_SAVE
cm.has_native = false;
cm->has_native = false;
#if MICROPY_EMIT_NATIVE
if (emit_native != NULL) {
cm.has_native = true;
cm->has_native = true;
}
#endif
#if MICROPY_EMIT_INLINE_ASM
if (comp->emit_inline_asm != NULL) {
cm.has_native = true;
cm->has_native = true;
}
#endif
cm.n_qstr = comp->emit_common.qstr_map.used;
cm.n_obj = comp->emit_common.const_obj_list.len;
cm->n_qstr = comp->emit_common.qstr_map.used;
cm->n_obj = comp->emit_common.const_obj_list.len;
#endif
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
// now that the module context is valid, the raw codes can be printed
if (mp_verbose_flag >= 2) {
for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
mp_raw_code_t *rc = s->raw_code;
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);
}
}
}
Expand Down Expand Up @@ -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) {
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_module_context_t *context = m_new_obj(mp_module_context_t);
context->module.globals = mp_globals_get();
mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl, context);
mp_compiled_module_t cm;
cm.context = m_new_obj(mp_module_context_t);
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 mp_make_function_from_raw_code(cm.rc, cm.context, NULL);
}
Expand Down
2 changes: 1 addition & 1 deletion py/compile.h
Expand Up @@ -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
// 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

// this is implemented in runtime.c
Expand Down
28 changes: 12 additions & 16 deletions py/persistentcode.c
Expand Up @@ -390,7 +390,7 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
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];
read_bytes(reader, header, sizeof(header));
byte arch = MPY_FEATURE_DECODE_ARCH(header[2]);
Expand All @@ -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_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.
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.
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.
mp_compiled_module_t cm2;
cm2.rc = load_raw_code(reader, context);
cm2.context = context;
cm->rc = load_raw_code(reader, cm->context);

#if MICROPY_PERSISTENT_CODE_SAVE
cm2.has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE;
cm2.n_qstr = n_qstr;
cm2.n_obj = n_obj;
cm->has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE;
cm->n_qstr = n_qstr;
cm->n_obj = n_obj;
#endif

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_new_mem(&reader, buf, len, 0);
return mp_raw_code_load(&reader, context);
mp_raw_code_load(&reader, context);
}

#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_new_file(&reader, filename);
return mp_raw_code_load(&reader, context);
mp_raw_code_load(&reader, context);
}

#endif // MICROPY_HAS_FILE_READER
Expand Down
6 changes: 3 additions & 3 deletions py/persistentcode.h
Expand Up @@ -111,9 +111,9 @@ enum {
MP_PERSISTENT_OBJ_TUPLE,
};

mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *ctx);
mp_compiled_module_t mp_raw_code_load_mem(const byte *buf, size_t len, mp_module_context_t *ctx);
mp_compiled_module_t mp_raw_code_load_file(const char *filename, mp_module_context_t *ctx);
void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *ctx);
void mp_raw_code_load_mem(const byte *buf, size_t len, mp_compiled_module_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_file(mp_compiled_module_t *cm, const char *filename);
Expand Down

0 comments on commit 2283b6d

Please sign in to comment.