@@ -55,8 +55,6 @@ void pbsys_main_stop_program(bool force_stop) {
5555 if (force_stop ) {
5656 mp_sched_vm_abort ();
5757 } else {
58- pyexec_system_exit = PYEXEC_FORCED_EXIT ;
59-
6058 static mp_obj_exception_t system_exit ;
6159 system_exit .base .type = & mp_type_SystemExit ;
6260 system_exit .traceback_alloc = system_exit .traceback_len = 0 ;
@@ -106,9 +104,9 @@ static void mp_vfs_map_minimal_new_reader(mp_reader_t *reader, mp_vfs_map_minima
106104}
107105
108106// Prints the exception that ended the program.
109- static void print_final_exception (mp_obj_t exc ) {
107+ static void print_final_exception (mp_obj_t exc , int ret ) {
110108 // Handle graceful stop with button.
111- if (pyexec_system_exit == PYEXEC_FORCED_EXIT &&
109+ if (( ret & PYEXEC_FORCED_EXIT ) &&
112110 mp_obj_exception_match (exc , MP_OBJ_FROM_PTR (& mp_type_SystemExit ))) {
113111 mp_printf (& mp_plat_print , "The program was stopped (%q).\n" ,
114112 ((mp_obj_exception_t * )MP_OBJ_TO_PTR (exc ))-> base .type -> name );
@@ -121,8 +119,9 @@ static void print_final_exception(mp_obj_t exc) {
121119
122120#if PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_REPL
123121static void run_repl (void ) {
122+ int ret = 0 ;
123+
124124 readline_init0 ();
125- pyexec_system_exit = 0 ;
126125
127126 nlr_buf_t nlr ;
128127 nlr .ret_val = NULL ;
@@ -134,12 +133,12 @@ static void run_repl(void) {
134133 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL ) {
135134 // Compatibility with mpremote.
136135 mp_printf (& mp_plat_print , "MPY: soft reboot\n" );
137- pyexec_raw_repl ();
136+ ret = pyexec_raw_repl ();
138137 } else {
139- pyexec_friendly_repl ();
138+ ret = pyexec_friendly_repl ();
140139 }
141140 #else // PYBRICKS_OPT_RAW_REPL
142- pyexec_friendly_repl ();
141+ ret = pyexec_friendly_repl ();
143142 #endif // PYBRICKS_OPT_RAW_REPL
144143 nlr_pop ();
145144 } else {
@@ -152,7 +151,7 @@ static void run_repl(void) {
152151 // clear any pending exceptions (and run any callbacks).
153152 mp_handle_pending (false);
154153 // Print which exception triggered this.
155- print_final_exception (MP_OBJ_FROM_PTR (nlr .ret_val ));
154+ print_final_exception (MP_OBJ_FROM_PTR (nlr .ret_val ), ret );
156155 }
157156
158157 nlr_set_abort (NULL );
@@ -175,7 +174,7 @@ static void do_execute_raw_code(mp_module_context_t *context, const mp_raw_code_
175174
176175 nlr_buf_t nlr ;
177176 if (nlr_push (& nlr ) == 0 ) {
178- mp_obj_t module_fun = mp_make_function_from_raw_code (rc , mc , NULL );
177+ mp_obj_t module_fun = mp_make_function_from_proto_fun (rc , mc , NULL );
179178 mp_call_function_0 (module_fun );
180179
181180 // finish nlr block, restore context
@@ -241,7 +240,7 @@ static mpy_info_t *mpy_data_find(qstr name) {
241240 * Runs the __main__ module from user RAM.
242241 */
243242static void run_user_program (void ) {
244- pyexec_system_exit = 0 ;
243+ int ret = 0 ;
245244
246245 nlr_buf_t nlr ;
247246 nlr .ret_val = NULL ;
@@ -264,7 +263,7 @@ static void run_user_program(void) {
264263 mp_compiled_module_t compiled_module ;
265264 compiled_module .context = context ;
266265 mp_raw_code_load (& reader , & compiled_module );
267- mp_obj_t module_fun = mp_make_function_from_raw_code (compiled_module .rc , context , NULL );
266+ mp_obj_t module_fun = mp_make_function_from_proto_fun (compiled_module .rc , context , NULL );
268267
269268 // Run the script while letting CTRL-C interrupt it.
270269 mp_hal_set_interrupt_char (CHAR_CTRL_C );
@@ -287,7 +286,12 @@ static void run_user_program(void) {
287286 // Clear any pending exceptions (and run any callbacks).
288287 mp_handle_pending (false);
289288
290- print_final_exception (MP_OBJ_FROM_PTR (nlr .ret_val ));
289+ if (mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (((mp_obj_base_t * )nlr .ret_val )-> type ), MP_OBJ_FROM_PTR (& mp_type_SystemExit ))) {
290+ // at the moment, the value of SystemExit is unused
291+ ret = PYEXEC_FORCED_EXIT ;
292+ }
293+
294+ print_final_exception (MP_OBJ_FROM_PTR (nlr .ret_val ), ret );
291295
292296 #if PBSYS_CONFIG_FEATURE_BUILTIN_USER_PROGRAM_REPL
293297 // On KeyboardInterrupt, drop to REPL for debugging.
@@ -430,9 +434,21 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) {
430434 mp_raise_NotImplementedError (MP_ERROR_TEXT ("relative import" ));
431435 }
432436
433- // Check if module already exists, and return it if it does
437+ // Check if the module is already loaded.
438+ mp_map_elem_t * elem = mp_map_lookup (& MP_STATE_VM (mp_loaded_modules_dict ).map , args [0 ], MP_MAP_LOOKUP );
439+ if (elem ) {
440+ return elem -> value ;
441+ }
442+
443+ // Try the name directly as a non-extensible built-in (e.g. `micropython`).
434444 qstr module_name_qstr = mp_obj_str_get_qstr (args [0 ]);
435- mp_obj_t module_obj = mp_module_get_loaded_or_builtin (module_name_qstr );
445+ mp_obj_t module_obj = mp_module_get_builtin (module_name_qstr , false);
446+ if (module_obj != MP_OBJ_NULL ) {
447+ return module_obj ;
448+ }
449+
450+ // Now try as an extensible built-in (e.g. `struct`/`ustruct`).
451+ module_obj = mp_module_get_builtin (module_name_qstr , true);
436452 if (module_obj != MP_OBJ_NULL ) {
437453 return module_obj ;
438454 }
@@ -473,7 +489,7 @@ mp_obj_t pb_builtin_import(size_t n_args, const mp_obj_t *args) {
473489 mp_module_context_t * context = MP_OBJ_TO_PTR (module_obj );
474490 const mp_frozen_module_t * frozen = modref ;
475491 context -> constants = frozen -> constants ;
476- do_execute_raw_code (context , frozen -> rc , context );
492+ do_execute_raw_code (context , frozen -> proto_fun , context );
477493 return module_obj ;
478494 }
479495 #endif
@@ -486,7 +502,7 @@ mp_import_stat_t mp_import_stat(const char *path) {
486502 return MP_IMPORT_STAT_NO_EXIST ;
487503}
488504
489- mp_lexer_t * mp_lexer_new_from_file (const char * filename ) {
505+ mp_lexer_t * mp_lexer_new_from_file (qstr filename ) {
490506 mp_raise_OSError (MP_ENOENT );
491507}
492508
0 commit comments