Skip to content

Commit

Permalink
py/emitnative: Cancel caught exception once handled to prevent reraise.
Browse files Browse the repository at this point in the history
The native emitter keeps the current exception in a slot in its C stack
(instead of on its Python value stack), so when it catches an exception it
must explicitly clear that slot so the same exception is not reraised later
on.
  • Loading branch information
dpgeorge committed Sep 3, 2018
1 parent b735208 commit 3cd2c28
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
4 changes: 3 additions & 1 deletion py/emitnative.c
Original file line number Diff line number Diff line change
Expand Up @@ -1892,7 +1892,9 @@ STATIC void emit_native_pop_block(emit_t *emit) {
}

STATIC void emit_native_pop_except(emit_t *emit) {
(void)emit;
// Cancel any active exception so subsequent handlers don't see it
ASM_MOV_REG_IMM(emit->as, REG_TEMP0, (mp_uint_t)mp_const_none);
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0);
}

STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
Expand Down
13 changes: 13 additions & 0 deletions tests/basics/try_finally1.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,16 @@ def func2():
except:
print("catch-all except")
print()

# case where a try-except within a finally cancels the exception
print("exc-finally-subexcept")
try:
print("try1")
finally:
try:
print("try2")
foo
except:
print("except2")
print("finally1")
print()

0 comments on commit 3cd2c28

Please sign in to comment.