diff options
author | Damien George <damien.p.george@gmail.com> | 2014-03-30 00:54:48 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-03-30 00:54:48 +0000 |
commit | d7592a1c3fa69ecd1f9c654f0172d37e0aa73ba0 (patch) | |
tree | 39414952808f6cfd2af78688fb05f641b612552e /py/vm.c | |
parent | 010043caaf1bf791ab23315d7f5977472e312276 (diff) | |
download | micropython-d7592a1c3fa69ecd1f9c654f0172d37e0aa73ba0.tar.gz micropython-d7592a1c3fa69ecd1f9c654f0172d37e0aa73ba0.zip |
py: Fix reraise logic.
Diffstat (limited to 'py/vm.c')
-rw-r--r-- | py/vm.c | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -51,12 +51,11 @@ typedef enum { exc_sp->opcode = op; \ exc_sp->handler = ip + unum; \ exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \ - exc_sp->prev_exc = nlr.ret_val; \ + exc_sp->prev_exc = MP_OBJ_NULL; \ currently_in_except_block = 0; /* in a try block now */ #define POP_EXC_BLOCK() \ currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \ - if (currently_in_except_block) { nlr.ret_val = exc_sp->prev_exc; } \ exc_sp--; /* pop back to previous exception handler */ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret) { @@ -701,12 +700,17 @@ unwind_return: unum = *ip++; assert(unum <= 1); if (unum == 0) { - if (!currently_in_except_block) { + // search for the inner-most previous exception, to reraise it + obj1 = MP_OBJ_NULL; + for (mp_exc_stack *e = exc_sp; e >= exc_stack; e--) { + if (e->prev_exc != MP_OBJ_NULL) { + obj1 = e->prev_exc; + break; + } + } + if (obj1 == MP_OBJ_NULL) { nlr_jump(mp_obj_new_exception_msg(&mp_type_RuntimeError, "No active exception to reraise")); } - // This assumes that nlr.ret_val holds last raised - // exception and is not overwritten since then. - obj1 = nlr.ret_val; } else { obj1 = POP(); } @@ -844,6 +848,8 @@ yield: // catch exception and pass to byte code sp = MP_TAGPTR_PTR(exc_sp->val_sp); ip = exc_sp->handler; + // save this exception in the stack so it can be used in a reraise, if needed + exc_sp->prev_exc = nlr.ret_val; // push(traceback, exc-val, exc-type) PUSH(mp_const_none); PUSH(nlr.ret_val); |