Merge pull request #390 from pfalcon/reraise-recursive
vm: Save current active exception on opening new try block.
This commit is contained in:
commit
f8ff700de8
2
py/bc.h
2
py/bc.h
@ -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;
|
||||||
|
2
py/vm.c
2
py/vm.c
@ -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) {
|
||||||
|
23
tests/basics/try-reraise2.py
Normal file
23
tests/basics/try-reraise2.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 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))
|
Loading…
Reference in New Issue
Block a user