diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/obj.h | 1 | ||||
-rw-r--r-- | py/objexcept.c | 2 | ||||
-rw-r--r-- | py/qstrdefs.h | 1 | ||||
-rw-r--r-- | py/runtime.c | 6 | ||||
-rw-r--r-- | py/runtime.h | 1 | ||||
-rw-r--r-- | py/vm.c | 23 |
6 files changed, 27 insertions, 7 deletions
@@ -330,6 +330,7 @@ extern const mp_obj_type_t mp_type_GeneratorExit; extern const mp_obj_type_t mp_type_ImportError; extern const mp_obj_type_t mp_type_IndentationError; extern const mp_obj_type_t mp_type_IndexError; +extern const mp_obj_type_t mp_type_KeyboardInterrupt; extern const mp_obj_type_t mp_type_KeyError; extern const mp_obj_type_t mp_type_LookupError; extern const mp_obj_type_t mp_type_MemoryError; diff --git a/py/objexcept.c b/py/objexcept.c index 203517b106..9b39788759 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -211,7 +211,7 @@ const mp_obj_type_t mp_type_ ## exc_name = { \ // http://docs.python.org/3/library/exceptions.html MP_DEFINE_EXCEPTION_BASE(BaseException) MP_DEFINE_EXCEPTION(SystemExit, BaseException) -//MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) +MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) MP_DEFINE_EXCEPTION(GeneratorExit, BaseException) MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION_BASE(Exception) diff --git a/py/qstrdefs.h b/py/qstrdefs.h index c87a7a83c1..64658b587c 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -108,6 +108,7 @@ Q(GeneratorExit) Q(ImportError) Q(IndentationError) Q(IndexError) +Q(KeyboardInterrupt) Q(KeyError) Q(LookupError) Q(MemoryError) diff --git a/py/runtime.c b/py/runtime.c index 6cb5c7e197..f6f34be940 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -62,6 +62,9 @@ #define DEBUG_OP_printf(...) (void)0 #endif +// pending exception object (MP_OBJ_NULL if not pending) +mp_obj_t mp_pending_exception; + // locals and globals need to be pointers because they can be the same in outer module scope STATIC mp_obj_dict_t *dict_locals; STATIC mp_obj_dict_t *dict_globals; @@ -79,6 +82,9 @@ void mp_init(void) { qstr_init(); mp_stack_ctrl_init(); + // no pending exceptions to start with + mp_pending_exception = MP_OBJ_NULL; + #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF mp_init_emergency_exception_buf(); #endif diff --git a/py/runtime.h b/py/runtime.h index 967a1fc097..5be470330b 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -116,6 +116,7 @@ mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type); mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args_kw, const mp_obj_t *args); NORETURN void mp_native_raise(mp_obj_t o); +extern mp_obj_t mp_pending_exception; extern struct _mp_obj_list_t mp_sys_path_obj; extern struct _mp_obj_list_t mp_sys_argv_obj; #define mp_sys_path ((mp_obj_t)&mp_sys_path_obj) @@ -110,10 +110,12 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o code_state->ip = ip; \ goto *entry_table[*ip++]; \ } while(0) + #define DISPATCH_WITH_PEND_EXC_CHECK() goto pending_exception_check #define ENTRY(op) entry_##op #define ENTRY_DEFAULT entry_default #else #define DISPATCH() break + #define DISPATCH_WITH_PEND_EXC_CHECK() goto pending_exception_check #define ENTRY(op) case op #define ENTRY_DEFAULT default #endif @@ -372,21 +374,21 @@ dispatch_loop: ENTRY(MP_BC_JUMP): DECODE_SLABEL; ip += unum; - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); ENTRY(MP_BC_POP_JUMP_IF_TRUE): DECODE_SLABEL; if (mp_obj_is_true(POP())) { ip += unum; } - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); ENTRY(MP_BC_POP_JUMP_IF_FALSE): DECODE_SLABEL; if (!mp_obj_is_true(POP())) { ip += unum; } - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); ENTRY(MP_BC_JUMP_IF_TRUE_OR_POP): DECODE_SLABEL; @@ -395,7 +397,7 @@ dispatch_loop: } else { sp--; } - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); ENTRY(MP_BC_JUMP_IF_FALSE_OR_POP): DECODE_SLABEL; @@ -404,7 +406,7 @@ dispatch_loop: } else { ip += unum; } - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); ENTRY(MP_BC_SETUP_WITH): { mp_obj_t obj = TOP(); @@ -502,7 +504,7 @@ unwind_jump: if (unum != 0) { sp--; } - DISPATCH(); + DISPATCH_WITH_PEND_EXC_CHECK(); // matched against: POP_BLOCK or POP_EXCEPT (anything else?) ENTRY(MP_BC_SETUP_EXCEPT): @@ -909,6 +911,15 @@ yield: #if !MICROPY_OPT_COMPUTED_GOTO } // switch #endif + +pending_exception_check: + if (mp_pending_exception != MP_OBJ_NULL) { + mp_obj_t obj = mp_pending_exception; + mp_pending_exception = MP_OBJ_NULL; + RAISE(obj); + } + DISPATCH(); + } // for loop } else { |