From deb67569ff66b2111cd18679a3bbdb35655cd25d Mon Sep 17 00:00:00 2001 From: Damien George <damien.p.george@gmail.com> Date: Wed, 2 Jan 2019 10:46:51 +1100 Subject: [PATCH] py/compile: Swap order of pop_block/pop_except in "except as" handler. To make the try-finally block self contained. --- py/compile.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/py/compile.c b/py/compile.c index 6db108a59..a5bdfa2af 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1582,25 +1582,32 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ compile_store_id(comp, qstr_exception_local); } + // If the exception is bound to a variable <e> then the <body> of the + // exception handler is wrapped in a try-finally so that the name <e> can + // be deleted (per Python semantics) even if the <body> has an exception. + // In such a case the generated code for the exception handler is: + // try: + // <body> + // finally: + // <e> = None + // del <e> uint l3 = 0; if (qstr_exception_local != 0) { l3 = comp_next_label(comp); compile_increase_except_level(comp, l3, MP_EMIT_SETUP_BLOCK_FINALLY); } - compile_node(comp, pns_except->nodes[1]); + compile_node(comp, pns_except->nodes[1]); // the <body> if (qstr_exception_local != 0) { EMIT(pop_block); - } - EMIT(pop_except); - if (qstr_exception_local != 0) { EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(label_assign, l3); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); compile_store_id(comp, qstr_exception_local); compile_delete_id(comp, qstr_exception_local); - compile_decrease_except_level(comp); } + + EMIT(pop_except); EMIT_ARG(jump, l2); EMIT_ARG(label_assign, end_finally_label); EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance -- GitLab