@@ -50,7 +50,8 @@ typedef struct _compiler_t {
5050
5151 int break_label ;
5252 int continue_label ;
53- int except_nest_level ;
53+ int break_continue_except_level ;
54+ int cur_except_level ; // increased for SETUP_EXCEPT, SETUP_FINALLY; decreased for POP_BLOCK, POP_EXCEPT
5455
5556 int n_arg_keyword ;
5657 bool have_star_arg ;
@@ -1080,18 +1081,14 @@ void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
10801081 if (comp -> break_label == 0 ) {
10811082 printf ("ERROR: cannot break from here\n" );
10821083 }
1083- EMIT_ARG (break_loop , comp -> break_label );
1084+ EMIT_ARG (break_loop , comp -> break_label , comp -> cur_except_level - comp -> break_continue_except_level );
10841085}
10851086
10861087void compile_continue_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
10871088 if (comp -> continue_label == 0 ) {
10881089 printf ("ERROR: cannot continue from here\n" );
10891090 }
1090- if (comp -> except_nest_level > 0 ) {
1091- EMIT_ARG (continue_loop , comp -> continue_label );
1092- } else {
1093- EMIT_ARG (jump , comp -> continue_label );
1094- }
1091+ EMIT_ARG (continue_loop , comp -> continue_label , comp -> cur_except_level - comp -> break_continue_except_level );
10951092}
10961093
10971094void compile_return_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
@@ -1387,15 +1384,22 @@ void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
13871384 EMIT_ARG (label_assign , l_end );
13881385}
13891386
1390- void compile_while_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
1391- int old_break_label = comp -> break_label ;
1392- int old_continue_label = comp -> continue_label ;
1387+ #define START_BREAK_CONTINUE_BLOCK \
1388+ int old_break_label = comp->break_label; \
1389+ int old_continue_label = comp->continue_label; \
1390+ int break_label = comp_next_label(comp); \
1391+ int continue_label = comp_next_label(comp); \
1392+ comp->break_label = break_label; \
1393+ comp->continue_label = continue_label; \
1394+ comp->break_continue_except_level = comp->cur_except_level;
13931395
1394- int break_label = comp_next_label (comp );
1395- int continue_label = comp_next_label (comp );
1396+ #define END_BREAK_CONTINUE_BLOCK \
1397+ comp->break_label = old_break_label; \
1398+ comp->continue_label = old_continue_label; \
1399+ comp->break_continue_except_level = comp->cur_except_level;
13961400
1397- comp -> break_label = break_label ;
1398- comp -> continue_label = continue_label ;
1401+ void compile_while_stmt ( compiler_t * comp , mp_parse_node_struct_t * pns ) {
1402+ START_BREAK_CONTINUE_BLOCK
13991403
14001404 // compared to CPython, we have an optimised version of while loops
14011405#if MICROPY_EMIT_CPYTHON
@@ -1423,8 +1427,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
14231427#endif
14241428
14251429 // break/continue apply to outer loop (if any) in the else block
1426- comp -> break_label = old_break_label ;
1427- comp -> continue_label = old_continue_label ;
1430+ END_BREAK_CONTINUE_BLOCK
14281431
14291432 compile_node (comp , pns -> nodes [2 ]); // else
14301433
@@ -1434,14 +1437,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
14341437// TODO preload end and step onto stack if they are not constants
14351438// TODO check if step is negative and do opposite test
14361439void compile_for_stmt_optimised_range (compiler_t * comp , mp_parse_node_t pn_var , mp_parse_node_t pn_start , mp_parse_node_t pn_end , mp_parse_node_t pn_step , mp_parse_node_t pn_body , mp_parse_node_t pn_else ) {
1437- int old_break_label = comp -> break_label ;
1438- int old_continue_label = comp -> continue_label ;
1439-
1440- int break_label = comp_next_label (comp );
1441- int continue_label = comp_next_label (comp );
1442-
1443- comp -> break_label = break_label ;
1444- comp -> continue_label = continue_label ;
1440+ START_BREAK_CONTINUE_BLOCK
14451441
14461442 int top_label = comp_next_label (comp );
14471443 int entry_label = comp_next_label (comp );
@@ -1477,8 +1473,7 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
14771473 EMIT_ARG (pop_jump_if_true , top_label );
14781474
14791475 // break/continue apply to outer loop (if any) in the else block
1480- comp -> break_label = old_break_label ;
1481- comp -> continue_label = old_continue_label ;
1476+ END_BREAK_CONTINUE_BLOCK
14821477
14831478 compile_node (comp , pn_else );
14841479
@@ -1531,38 +1526,30 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
15311526 }
15321527#endif
15331528
1534- int old_break_label = comp -> break_label ;
1535- int old_continue_label = comp -> continue_label ;
1529+ START_BREAK_CONTINUE_BLOCK
15361530
1537- int for_label = comp_next_label (comp );
15381531 int pop_label = comp_next_label (comp );
15391532 int end_label = comp_next_label (comp );
15401533
1541- int break_label = comp_next_label (comp );
1542-
1543- comp -> continue_label = for_label ;
1544- comp -> break_label = break_label ;
1545-
15461534 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
15471535#if MICROPY_EMIT_CPYTHON
15481536 EMIT_ARG (setup_loop , end_label );
15491537#endif
15501538
15511539 compile_node (comp , pns -> nodes [1 ]); // iterator
15521540 EMIT (get_iter );
1553- EMIT_ARG (label_assign , for_label );
1541+ EMIT_ARG (label_assign , continue_label );
15541542 EMIT_ARG (for_iter , pop_label );
15551543 c_assign (comp , pns -> nodes [0 ], ASSIGN_STORE ); // variable
15561544 compile_node (comp , pns -> nodes [2 ]); // body
15571545 if (!EMIT (last_emit_was_return_value )) {
1558- EMIT_ARG (jump , for_label );
1546+ EMIT_ARG (jump , continue_label );
15591547 }
15601548 EMIT_ARG (label_assign , pop_label );
15611549 EMIT (for_iter_end );
15621550
15631551 // break/continue apply to outer loop (if any) in the else block
1564- comp -> break_label = old_break_label ;
1565- comp -> continue_label = old_continue_label ;
1552+ END_BREAK_CONTINUE_BLOCK
15661553
15671554#if MICROPY_EMIT_CPYTHON
15681555 EMIT (pop_block );
@@ -1582,8 +1569,10 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
15821569 int stack_size = EMIT (get_stack_size );
15831570 int l1 = comp_next_label (comp );
15841571 int success_label = comp_next_label (comp );
1585- comp -> except_nest_level += 1 ; // for correct handling of continue
1572+
15861573 EMIT_ARG (setup_except , l1 );
1574+ comp -> cur_except_level += 1 ;
1575+
15871576 compile_node (comp , pn_body ); // body
15881577 EMIT (pop_block );
15891578 EMIT_ARG (jump , success_label );
@@ -1634,6 +1623,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
16341623 if (qstr_exception_local != 0 ) {
16351624 l3 = comp_next_label (comp );
16361625 EMIT_ARG (setup_finally , l3 );
1626+ comp -> cur_except_level += 1 ;
16371627 }
16381628 compile_node (comp , pns_except -> nodes [1 ]);
16391629 if (qstr_exception_local != 0 ) {
@@ -1646,15 +1636,18 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
16461636 EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
16471637 EMIT_ARG (store_id , qstr_exception_local );
16481638 EMIT_ARG (delete_id , qstr_exception_local );
1639+
1640+ comp -> cur_except_level -= 1 ;
16491641 EMIT (end_finally );
16501642 }
16511643 EMIT_ARG (jump , l2 );
16521644 EMIT_ARG (label_assign , end_finally_label );
16531645 }
16541646
1647+ comp -> cur_except_level -= 1 ;
16551648 EMIT (end_finally );
1649+
16561650 EMIT_ARG (label_assign , success_label );
1657- comp -> except_nest_level -= 1 ;
16581651 compile_node (comp , pn_else ); // else block, can be null
16591652 EMIT_ARG (label_assign , l2 );
16601653 EMIT_ARG (set_stack_size , stack_size );
@@ -1664,7 +1657,10 @@ void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except
16641657 // don't understand how the stack works with exceptions, so we force it to return to the correct value
16651658 int stack_size = EMIT (get_stack_size );
16661659 int l_finally_block = comp_next_label (comp );
1660+
16671661 EMIT_ARG (setup_finally , l_finally_block );
1662+ comp -> cur_except_level += 1 ;
1663+
16681664 if (n_except == 0 ) {
16691665 assert (MP_PARSE_NODE_IS_NULL (pn_else ));
16701666 compile_node (comp , pn_body );
@@ -1675,7 +1671,10 @@ void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except
16751671 EMIT_ARG (load_const_tok , MP_TOKEN_KW_NONE );
16761672 EMIT_ARG (label_assign , l_finally_block );
16771673 compile_node (comp , pn_finally );
1674+
1675+ comp -> cur_except_level -= 1 ;
16781676 EMIT (end_finally );
1677+
16791678 EMIT_ARG (set_stack_size , stack_size );
16801679}
16811680
@@ -3056,7 +3055,9 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
30563055
30573056 comp -> break_label = 0 ;
30583057 comp -> continue_label = 0 ;
3059- comp -> except_nest_level = 0 ;
3058+ comp -> break_continue_except_level = 0 ;
3059+ comp -> cur_except_level = 0 ;
3060+
30603061 comp -> scope_head = NULL ;
30613062 comp -> scope_cur = NULL ;
30623063
0 commit comments