Commit f8ff700d authored by Damien George's avatar Damien George
Browse files

Merge pull request #390 from pfalcon/reraise-recursive

vm: Save current active exception on opening new try block.
parents d54b8a47 0c904df8
...@@ -9,6 +9,8 @@ typedef struct _mp_exc_stack { ...@@ -9,6 +9,8 @@ typedef struct _mp_exc_stack {
const byte *handler; const byte *handler;
// bit 0 is saved currently_in_except_block value // bit 0 is saved currently_in_except_block value
mp_obj_t *val_sp; mp_obj_t *val_sp;
// Saved exception, valid if currently_in_except_block bit is 1
mp_obj_t prev_exc;
// We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY, // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
// consider storing it in bit 1 of val_sp. TODO: SETUP_WITH? // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
byte opcode; byte opcode;
......
...@@ -51,10 +51,12 @@ typedef enum { ...@@ -51,10 +51,12 @@ typedef enum {
exc_sp->opcode = op; \ exc_sp->opcode = op; \
exc_sp->handler = ip + unum; \ exc_sp->handler = ip + unum; \
exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \ exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \
exc_sp->prev_exc = nlr.ret_val; \
currently_in_except_block = 0; /* in a try block now */ currently_in_except_block = 0; /* in a try block now */
#define POP_EXC_BLOCK() \ #define POP_EXC_BLOCK() \
currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \ 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 */ 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) { 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) {
......
# Reraise not the latest occured exception
def f():
try:
raise ValueError("val", 3)
except:
try:
raise TypeError
except:
try:
try:
raise AttributeError
except:
pass
raise
except TypeError:
pass
# This should raise original ValueError, not the most recently occurred AttributeError
raise
try:
f()
except ValueError as e:
print(repr(e))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment