@@ -144,36 +144,6 @@ static void run_repl(void) {
144144}
145145#endif // PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_REPL
146146
147- // From micropython/py/builtinimport.c, but copied because it is static.
148- static void do_execute_raw_code (mp_module_context_t * context , const mp_raw_code_t * rc , const mp_module_context_t * mc ) {
149-
150- // execute the module in its context
151- mp_obj_dict_t * mod_globals = context -> module .globals ;
152-
153- // save context
154- mp_obj_dict_t * volatile old_globals = mp_globals_get ();
155- mp_obj_dict_t * volatile old_locals = mp_locals_get ();
156-
157- // set new context
158- mp_globals_set (mod_globals );
159- mp_locals_set (mod_globals );
160-
161- nlr_buf_t nlr ;
162- if (nlr_push (& nlr ) == 0 ) {
163- mp_obj_t module_fun = mp_make_function_from_proto_fun (rc , mc , NULL );
164- mp_call_function_0 (module_fun );
165-
166- // finish nlr block, restore context
167- nlr_pop ();
168- mp_globals_set (old_globals );
169- mp_locals_set (old_locals );
170- } else {
171- // exception; restore context and re-raise same exception
172- mp_globals_set (old_globals );
173- mp_locals_set (old_locals );
174- nlr_jump (nlr .ret_val );
175- }
176- }
177147
178148/** mpy info and data for one script or module. */
179149typedef struct {
@@ -222,6 +192,44 @@ static mpy_info_t *mpy_data_find(qstr name) {
222192 return NULL ;
223193}
224194
195+ // From micropython/py/builtinimport.c, but copied because it is static.
196+ static void do_execute_proto_fun (const mp_module_context_t * context , mp_proto_fun_t proto_fun ) {
197+
198+ // execute the module in its context
199+ mp_obj_dict_t * mod_globals = context -> module .globals ;
200+
201+ // save context
202+ nlr_jump_callback_node_globals_locals_t ctx ;
203+ ctx .globals = mp_globals_get ();
204+ ctx .locals = mp_locals_get ();
205+
206+ // set new context
207+ mp_globals_set (mod_globals );
208+ mp_locals_set (mod_globals );
209+
210+ // set exception handler to restore context if an exception is raised
211+ nlr_push_jump_callback (& ctx .callback , mp_globals_locals_set_from_nlr_jump_callback );
212+
213+ // make and execute the function
214+ mp_obj_t module_fun = mp_make_function_from_proto_fun (proto_fun , context , NULL );
215+ mp_call_function_0 (module_fun );
216+
217+ // deregister exception handler and restore context
218+ nlr_pop_jump_callback (true);
219+ }
220+
221+ static void execute_rom_mpy_in_context (mp_module_context_t * module_context , mpy_info_t * mpy_info ) {
222+ // Prepare to execute in its own context.
223+ mp_compiled_module_t compiled_module ;
224+ compiled_module .context = module_context ;
225+
226+ // Execute the MPY file in the new module context.
227+ mp_reader_t reader ;
228+ mp_reader_new_mem (& reader , mpy_data_get_buf (mpy_info ), pbio_get_uint32_le (mpy_info -> mpy_size ), MP_READER_IS_ROM );
229+ mp_raw_code_load (& reader , & compiled_module );
230+ do_execute_proto_fun (compiled_module .context , compiled_module .rc );
231+ }
232+
225233/**
226234 * Runs the __main__ module from user RAM.
227235 */
@@ -234,22 +242,15 @@ static void run_user_program(void) {
234242 if (nlr_push (& nlr ) == 0 ) {
235243 nlr_set_abort (& nlr );
236244
237- // Main program is in the first mpy file.
238- mpy_info_t * info = mpy_first ;
239-
240- // This is similar to __import__ except we don't push/pop globals
241- mp_reader_t reader ;
242- mp_reader_new_mem (& reader , mpy_data_get_buf (info ), pbio_get_uint32_le (info -> mpy_size ), MP_READER_IS_ROM );
243- mp_module_context_t * context = m_new_obj (mp_module_context_t );
244- context -> module .globals = mp_globals_get ();
245- mp_compiled_module_t compiled_module ;
246- compiled_module .context = context ;
247- mp_raw_code_load (& reader , & compiled_module );
248- mp_obj_t module_fun = mp_make_function_from_proto_fun (compiled_module .rc , context , NULL );
249-
250245 // Run the script while letting CTRL-C interrupt it.
251246 mp_hal_set_interrupt_char (CHAR_CTRL_C );
252- mp_call_function_0 (module_fun );
247+
248+ // Main program runs in __main__ module which is already initialized.
249+ mp_module_context_t main_context = {
250+ .module = mp_module___main__
251+ };
252+ execute_rom_mpy_in_context (& main_context , mpy_first );
253+
253254 mp_hal_set_interrupt_char (-1 );
254255
255256 // Handle any pending exceptions (and any callbacks)
@@ -438,20 +439,14 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) {
438439
439440 // If a downloaded module was found but not yet loaded, load it.
440441 if (info ) {
441- // Parse the static script data.
442- mp_reader_t reader ;
443- mp_reader_new_mem (& reader , mpy_data_get_buf (info ), pbio_get_uint32_le (info -> mpy_size ), MP_READER_IS_ROM );
444-
445- // Create new module and execute in its own context.
446- mp_obj_t module_obj = mp_obj_new_module (module_name_qstr );
447- mp_module_context_t * context = MP_OBJ_TO_PTR (module_obj );
448- mp_compiled_module_t compiled_module ;
449- compiled_module .context = context ;
450- mp_raw_code_load (& reader , & compiled_module );
451- do_execute_raw_code (context , compiled_module .rc , compiled_module .context );
442+ // Create new module.
443+ mp_module_context_t * module_context = mp_obj_new_module (module_name_qstr );
444+
445+ // Execute the module in that context.
446+ execute_rom_mpy_in_context (module_context , info );
452447
453448 // Return the newly imported module.
454- return module_obj ;
449+ return MP_OBJ_FROM_PTR ( module_context ) ;
455450 }
456451
457452 // Allow importing of frozen modules if any were included in the firmware.
@@ -462,13 +457,15 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) {
462457 char module_path [(1 << (8 * MICROPY_QSTR_BYTES_IN_LEN )) + sizeof (ext )] = { 0 };
463458 strcpy (module_path , mp_obj_str_get_str (args [0 ]));
464459 strcpy (module_path + qstr_len (module_name_qstr ), ext );
465- if (mp_find_frozen_module (module_path , & frozen_type , & modref ) == MP_IMPORT_STAT_FILE ) {
466- // Create new module and execute in its own context, then return it.
467- mp_obj_t module_obj = mp_obj_new_module (module_name_qstr );
468- mp_module_context_t * context = MP_OBJ_TO_PTR (module_obj );
460+ if (mp_find_frozen_module (module_path , & frozen_type , & modref ) == MP_IMPORT_STAT_FILE && frozen_type == MP_FROZEN_MPY ) {
461+ // Create new module to be returned.
462+ mp_module_context_t * module_context = mp_obj_new_module (module_name_qstr );
463+ mp_obj_t module_obj = MP_OBJ_FROM_PTR (module_context );
464+
465+ // Execute frozen code in the new module context.
469466 const mp_frozen_module_t * frozen = modref ;
470- context -> constants = frozen -> constants ;
471- do_execute_raw_code ( context , frozen -> proto_fun , context );
467+ module_context -> constants = frozen -> constants ;
468+ do_execute_proto_fun ( module_context , frozen -> proto_fun );
472469 return module_obj ;
473470 }
474471 #endif
0 commit comments