summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/py/compile.c b/py/compile.c
index 4f91ca49b9..a9b34ce5d9 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1650,9 +1650,11 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
if (qstr_exception_local != 0) {
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
EMIT_ARG(label_assign, l3);
+ EMIT_ARG(adjust_stack_size, 1); // stack adjust for possible return value
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
compile_store_id(comp, qstr_exception_local);
compile_delete_id(comp, qstr_exception_local);
+ EMIT_ARG(adjust_stack_size, -1);
compile_decrease_except_level(comp);
}
@@ -1682,9 +1684,18 @@ STATIC void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n
} else {
compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
}
+
+ // If the code reaches this point then the try part of the try-finally exited normally.
+ // This is indicated to the runtime by None sitting on the stack.
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
+
+ // Compile the finally block.
+ // The stack needs to be adjusted by 1 to account for the possibility that the finally is
+ // being executed as part of a return, and the return value is on the top of the stack.
EMIT_ARG(label_assign, l_finally_block);
+ EMIT_ARG(adjust_stack_size, 1);
compile_node(comp, pn_finally);
+ EMIT_ARG(adjust_stack_size, -1);
compile_decrease_except_level(comp);
}