summaryrefslogtreecommitdiff
path: root/py/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/vm.c')
-rw-r--r--py/vm.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/py/vm.c b/py/vm.c
index 498ecb491..bc596b0e8 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -1063,17 +1063,11 @@ unwind_jump:;
ENTRY(MP_BC_RETURN_VALUE):
MARK_EXC_IP_SELECTIVE();
- // These next 3 lines pop a try-finally exception handler, if one
- // is there on the exception stack. Without this the finally block
- // is executed a second time when the return is executed, because
- // the try-finally exception handler is still on the stack.
- // TODO Possibly find a better way to handle this case.
- if (currently_in_except_block) {
- POP_EXC_BLOCK();
- }
unwind_return:
+ // Search for and execute finally handlers that aren't already active
while (exc_sp >= exc_stack) {
- if (MP_TAGPTR_TAG1(exc_sp->val_sp)) {
+ if (!currently_in_except_block && MP_TAGPTR_TAG1(exc_sp->val_sp)) {
+ // Found a finally handler that isn't active.
// Getting here the stack looks like:
// (..., X, [iter0, iter1, ...,] ret_val)
// where X is pointed to by exc_sp->val_sp and in the case
@@ -1092,10 +1086,10 @@ unwind_return:
// done (when WITH_CLEANUP or END_FINALLY reached).
PUSH(MP_OBJ_NEW_SMALL_INT(-1));
ip = exc_sp->handler;
- exc_sp--;
+ POP_EXC_BLOCK();
goto dispatch_loop;
}
- exc_sp--;
+ POP_EXC_BLOCK();
}
nlr_pop();
code_state->sp = sp;