diff options
author | Damien George <damien.p.george@gmail.com> | 2014-10-25 18:19:55 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-10-25 23:37:57 +0100 |
commit | 124df6f8d07b53542b6960dbeea9b63bff469a67 (patch) | |
tree | 39ea11d0bed72ed828c406d2b4a8fc069b00ca4e /py/vm.c | |
parent | d7353fe6fe9c9d421ef045c0eea8d4591710e1ba (diff) | |
download | micropython-124df6f8d07b53542b6960dbeea9b63bff469a67.tar.gz micropython-124df6f8d07b53542b6960dbeea9b63bff469a67.zip |
py: Add mp_pending_exception global variable, for VM soft interrupt.
This allows to implement KeyboardInterrupt on unix, and a much safer
ctrl-C in stmhal port. First ctrl-C is a soft one, with hope that VM
will notice it; second ctrl-C is a hard one that kills anything (for
both unix and stmhal).
One needs to check for a pending exception in the VM only for jump
opcodes. Others can't produce an infinite loop (infinite recursion is
caught by stack check).
Diffstat (limited to 'py/vm.c')
-rw-r--r-- | py/vm.c | 23 |
1 files changed, 17 insertions, 6 deletions
@@ -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 { |