Skip to content

Commit 432e827

Browse files
committed
py: Allow to import compiled bytecode files.
1 parent d8c834c commit 432e827

1 file changed

Lines changed: 57 additions & 2 deletions

File tree

py/builtinimport.c

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,21 @@ STATIC mp_import_stat_t stat_dir_or_file(vstr_t *path) {
6666
if (stat == MP_IMPORT_STAT_DIR) {
6767
return stat;
6868
}
69+
6970
vstr_add_str(path, ".py");
7071
stat = mp_import_stat(vstr_null_terminated_str(path));
7172
if (stat == MP_IMPORT_STAT_FILE) {
7273
return stat;
7374
}
75+
76+
#if MICROPY_PERSISTENT_CODE_LOAD
77+
vstr_ins_byte(path, path->len - 2, 'm');
78+
stat = mp_import_stat(vstr_null_terminated_str(path));
79+
if (stat == MP_IMPORT_STAT_FILE) {
80+
return stat;
81+
}
82+
#endif
83+
7484
return MP_IMPORT_STAT_NO_EXIST;
7585
}
7686

@@ -132,11 +142,56 @@ STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex, const char
132142
mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mod_globals, mod_globals);
133143
}
134144

145+
#if MICROPY_PERSISTENT_CODE_LOAD
146+
STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code) {
147+
#if MICROPY_PY___FILE__
148+
// TODO
149+
//qstr source_name = lex->source_name;
150+
//mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
151+
#endif
152+
153+
// execute the module in its context
154+
mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj);
155+
156+
// save context
157+
mp_obj_dict_t *volatile old_globals = mp_globals_get();
158+
mp_obj_dict_t *volatile old_locals = mp_locals_get();
159+
160+
// set new context
161+
mp_globals_set(mod_globals);
162+
mp_locals_set(mod_globals);
163+
164+
nlr_buf_t nlr;
165+
if (nlr_push(&nlr) == 0) {
166+
mp_obj_t module_fun = mp_make_function_from_raw_code(raw_code, MP_OBJ_NULL, MP_OBJ_NULL);
167+
mp_call_function_0(module_fun);
168+
169+
// finish nlr block, restore context
170+
nlr_pop();
171+
mp_globals_set(old_globals);
172+
mp_locals_set(old_locals);
173+
} else {
174+
// exception; restore context and re-raise same exception
175+
mp_globals_set(old_globals);
176+
mp_locals_set(old_locals);
177+
nlr_raise(nlr.ret_val);
178+
}
179+
}
180+
#endif
181+
135182
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
136183
// create the lexer
137184
char *file_str = vstr_null_terminated_str(file);
138-
mp_lexer_t *lex = mp_lexer_new_from_file(file_str);
139-
do_load_from_lexer(module_obj, lex, file_str);
185+
#if MICROPY_PERSISTENT_CODE_LOAD
186+
if (file_str[file->len - 3] == 'm') {
187+
mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str);
188+
do_execute_raw_code(module_obj, raw_code);
189+
} else
190+
#endif
191+
{
192+
mp_lexer_t *lex = mp_lexer_new_from_file(file_str);
193+
do_load_from_lexer(module_obj, lex, file_str);
194+
}
140195
}
141196

142197
STATIC void chop_component(const char *start, const char **end) {

0 commit comments

Comments
 (0)