3939#include "irq.h"
4040#include "usb.h"
4141#endif
42+ #include "extmod/modplatform.h"
4243#include "shared/readline/readline.h"
4344#include "shared/runtime/pyexec.h"
4445#include "genhdr/mpversion.h"
@@ -58,6 +59,25 @@ static bool repl_display_debugging_info = 0;
5859#define EXEC_FLAG_SOURCE_IS_READER (1 << 6)
5960#define EXEC_FLAG_NO_INTERRUPT (1 << 7)
6061
62+ // If exc is SystemExit, return value where FORCED_EXIT bit set,
63+ // and lower 8 bits are SystemExit value. For all other exceptions,
64+ // return 1.
65+ int pyexec_handle_uncaught_exception (mp_obj_base_t * exc ) {
66+ // check for SystemExit
67+ if (mp_obj_is_subclass_fast (MP_OBJ_FROM_PTR (exc -> type ), MP_OBJ_FROM_PTR (& mp_type_SystemExit ))) {
68+
69+ mp_obj_t exit_val = mp_obj_exception_get_value (MP_OBJ_FROM_PTR (exc ));
70+ mp_int_t val = 0 ;
71+ if (exit_val != mp_const_none && !mp_obj_get_int_maybe (exit_val , & val )) {
72+ val = 1 ;
73+ }
74+ return PYEXEC_FORCED_EXIT | (val & 255 );
75+ }
76+
77+ mp_obj_print_exception (& mp_plat_print , MP_OBJ_FROM_PTR (exc ));
78+ return 1 ;
79+ }
80+
6181// parses, compiles and executes the code in the lexer
6282// frees the lexer before returning
6383// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
@@ -139,14 +159,7 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input
139159 mp_hal_stdout_tx_strn ("\x04" , 1 );
140160 }
141161
142- // check for SystemExit
143- 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 ))) {
144- // at the moment, the value of SystemExit is unused
145- ret = PYEXEC_FORCED_EXIT ;
146- } else {
147- mp_obj_print_exception (& mp_plat_print , MP_OBJ_FROM_PTR (nlr .ret_val ));
148- ret = 0 ;
149- }
162+ pyexec_handle_uncaught_exception (nlr .ret_val );
150163 }
151164
152165 #if MICROPY_REPL_INFO
0 commit comments