diff --git a/py/bc.c b/py/bc.c index 1d6e4322b2..4a29f439e3 100644 --- a/py/bc.c +++ b/py/bc.c @@ -321,7 +321,7 @@ STATIC const byte opcode_format_table[64] = { OC4(O, O, U, U), // 0x38-0x3b OC4(U, O, B, O), // 0x3c-0x3f OC4(O, B, B, O), // 0x40-0x43 - OC4(B, B, O, B), // 0x44-0x47 + OC4(O, U, O, B), // 0x44-0x47 OC4(U, U, U, U), // 0x48-0x4b OC4(U, U, U, U), // 0x4c-0x4f OC4(V, V, U, V), // 0x50-0x53 diff --git a/py/bc0.h b/py/bc0.h index 70acfb0cac..175ee263a0 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -77,8 +77,7 @@ #define MP_BC_END_FINALLY (0x41) #define MP_BC_GET_ITER (0x42) #define MP_BC_FOR_ITER (0x43) // rel byte code offset, 16-bit unsigned -#define MP_BC_POP_BLOCK (0x44) -#define MP_BC_POP_EXCEPT (0x45) +#define MP_BC_POP_EXCEPT_JUMP (0x44) // rel byte code offset, 16-bit unsigned #define MP_BC_UNWIND_JUMP (0x46) // rel byte code offset, 16-bit signed, in excess; then a byte #define MP_BC_GET_ITER_STACK (0x47) diff --git a/py/compile.c b/py/compile.c index ca01d74785..b7f1d7b0c1 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1535,8 +1535,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ compile_increase_except_level(comp, l1, MP_EMIT_SETUP_BLOCK_EXCEPT); compile_node(comp, pn_body); // body - EMIT(pop_block); - EMIT_ARG(jump, success_label); // jump over exception handler + EMIT_ARG(pop_except_jump, success_label, false); // jump over exception handler EMIT_ARG(label_assign, l1); // start of exception handler EMIT(start_except_handler); @@ -1607,8 +1606,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ compile_decrease_except_level(comp); } - EMIT(pop_except); - EMIT_ARG(jump, l2); + EMIT_ARG(pop_except_jump, l2, true); EMIT_ARG(label_assign, end_finally_label); EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance } @@ -1741,8 +1739,7 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns compile_load_id(comp, context); compile_await_object_method(comp, MP_QSTR___anext__); c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable - EMIT(pop_block); - EMIT_ARG(jump, try_else_label); + EMIT_ARG(pop_except_jump, try_else_label, false); EMIT_ARG(label_assign, try_exception_label); EMIT(start_except_handler); @@ -1751,8 +1748,7 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH); EMIT_ARG(pop_jump_if, false, try_finally_label); EMIT(pop_top); // pop exception instance - EMIT(pop_except); - EMIT_ARG(jump, while_else_label); + EMIT_ARG(pop_except_jump, while_else_label, true); EMIT_ARG(label_assign, try_finally_label); EMIT_ARG(adjust_stack_size, 1); // if we jump here, the exc is on the stack diff --git a/py/emit.h b/py/emit.h index 3c42bdf143..34c6cfd845 100644 --- a/py/emit.h +++ b/py/emit.h @@ -134,8 +134,7 @@ typedef struct _emit_method_table_t { void (*get_iter)(emit_t *emit, bool use_stack); void (*for_iter)(emit_t *emit, mp_uint_t label); void (*for_iter_end)(emit_t *emit); - void (*pop_block)(emit_t *emit); - void (*pop_except)(emit_t *emit); + void (*pop_except_jump)(emit_t *emit, mp_uint_t label, bool within_exc_handler); void (*unary_op)(emit_t *emit, mp_unary_op_t op); void (*binary_op)(emit_t *emit, mp_binary_op_t op); void (*build)(emit_t *emit, mp_uint_t n_args, int kind); @@ -232,8 +231,7 @@ void mp_emit_bc_end_finally(emit_t *emit); void mp_emit_bc_get_iter(emit_t *emit, bool use_stack); void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label); void mp_emit_bc_for_iter_end(emit_t *emit); -void mp_emit_bc_pop_block(emit_t *emit); -void mp_emit_bc_pop_except(emit_t *emit); +void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler); void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op); void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op); void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind); diff --git a/py/emitbc.c b/py/emitbc.c index 65d6509051..4142e892d6 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -764,14 +764,10 @@ void mp_emit_bc_for_iter_end(emit_t *emit) { emit_bc_pre(emit, -MP_OBJ_ITER_BUF_NSLOTS); } -void mp_emit_bc_pop_block(emit_t *emit) { +void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { + (void)within_exc_handler; emit_bc_pre(emit, 0); - emit_write_bytecode_byte(emit, MP_BC_POP_BLOCK); -} - -void mp_emit_bc_pop_except(emit_t *emit) { - emit_bc_pre(emit, 0); - emit_write_bytecode_byte(emit, MP_BC_POP_EXCEPT); + emit_write_bytecode_byte_unsigned_label(emit, MP_BC_POP_EXCEPT_JUMP, label); } void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) { @@ -958,8 +954,7 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_get_iter, mp_emit_bc_for_iter, mp_emit_bc_for_iter_end, - mp_emit_bc_pop_block, - mp_emit_bc_pop_except, + mp_emit_bc_pop_except_jump, mp_emit_bc_unary_op, mp_emit_bc_binary_op, mp_emit_bc_build, diff --git a/py/emitnative.c b/py/emitnative.c index 8b7ebe5301..c8a1a33d6b 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1916,7 +1916,7 @@ STATIC void emit_native_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t exc prev_finally->unwind_label = UNWIND_LABEL_DO_FINAL_UNWIND; ASM_MOV_REG_PCREL(emit->as, REG_RET, label & ~MP_EMIT_BREAK_FROM_FOR); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_RET); - // Cancel any active exception (see also emit_native_pop_except) + // Cancel any active exception (see also emit_native_pop_except_jump) emit_native_mov_reg_const(emit, REG_RET, MP_F_CONST_NONE_OBJ); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_RET); // Jump to the innermost active finally @@ -2111,18 +2111,15 @@ STATIC void emit_native_for_iter_end(emit_t *emit) { emit_post(emit); } -STATIC void emit_native_pop_block(emit_t *emit) { - emit_native_pre(emit); - if (!emit->exc_stack[emit->exc_stack_size - 1].is_finally) { +STATIC void emit_native_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { + if (within_exc_handler) { + // Cancel any active exception so subsequent handlers don't see it + emit_native_mov_reg_const(emit, REG_TEMP0, MP_F_CONST_NONE_OBJ); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + } else { emit_native_leave_exc_stack(emit, false); } - emit_post(emit); -} - -STATIC void emit_native_pop_except(emit_t *emit) { - // Cancel any active exception so subsequent handlers don't see it - emit_native_mov_reg_const(emit, REG_TEMP0, MP_F_CONST_NONE_OBJ); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + emit_native_jump(emit, label); } STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) { @@ -2726,8 +2723,7 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_get_iter, emit_native_for_iter, emit_native_for_iter_end, - emit_native_pop_block, - emit_native_pop_except, + emit_native_pop_except_jump, emit_native_unary_op, emit_native_binary_op, emit_native_build, diff --git a/py/showbc.c b/py/showbc.c index 3deb18cd31..b9024b716d 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -401,14 +401,9 @@ const byte *mp_bytecode_print_str(const byte *ip) { printf("FOR_ITER " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); break; - case MP_BC_POP_BLOCK: - // pops block and restores the stack - printf("POP_BLOCK"); - break; - - case MP_BC_POP_EXCEPT: - // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate - printf("POP_EXCEPT"); + case MP_BC_POP_EXCEPT_JUMP: + DECODE_ULABEL; // these labels are always forward + printf("POP_EXCEPT_JUMP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); break; case MP_BC_BUILD_TUPLE: diff --git a/py/vm.c b/py/vm.c index a53b4a0838..901a23f225 100644 --- a/py/vm.c +++ b/py/vm.c @@ -759,17 +759,13 @@ unwind_jump:; } // matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH - ENTRY(MP_BC_POP_BLOCK): - // we are exiting an exception handler, so pop the last one of the exception-stack + ENTRY(MP_BC_POP_EXCEPT_JUMP): { assert(exc_sp >= exc_stack); POP_EXC_BLOCK(); - DISPATCH(); - - // matched against: SETUP_EXCEPT - ENTRY(MP_BC_POP_EXCEPT): - assert(exc_sp >= exc_stack); - POP_EXC_BLOCK(); - DISPATCH(); + DECODE_ULABEL; + ip += ulab; + DISPATCH_WITH_PEND_EXC_CHECK(); + } ENTRY(MP_BC_BUILD_TUPLE): { MARK_EXC_IP_SELECTIVE(); diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 615f4e2ce4..641c8ee422 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -76,8 +76,7 @@ static const void *const entry_table[256] = { [MP_BC_GET_ITER] = &&entry_MP_BC_GET_ITER, [MP_BC_GET_ITER_STACK] = &&entry_MP_BC_GET_ITER_STACK, [MP_BC_FOR_ITER] = &&entry_MP_BC_FOR_ITER, - [MP_BC_POP_BLOCK] = &&entry_MP_BC_POP_BLOCK, - [MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT, + [MP_BC_POP_EXCEPT_JUMP] = &&entry_MP_BC_POP_EXCEPT_JUMP, [MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE, [MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST, [MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP, diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index d119a6198b..8d36b89df7 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -257,13 +257,11 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ JUMP \\d\+ \\d\+ LOAD_FAST 0 \\d\+ POP_JUMP_IF_TRUE \\d\+ -\\d\+ POP_BLOCK -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ POP_TOP \\d\+ LOAD_DEREF 14 \\d\+ POP_TOP -\\d\+ POP_EXCEPT -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ END_FINALLY \\d\+ LOAD_CONST_NONE \\d\+ LOAD_FAST 1 @@ -272,11 +270,9 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): \\d\+ JUMP \\d\+ \\d\+ SETUP_EXCEPT \\d\+ \\d\+ UNWIND_JUMP \\d\+ 1 -\\d\+ POP_BLOCK -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ POP_TOP -\\d\+ POP_EXCEPT -\\d\+ JUMP \\d\+ +\\d\+ POP_EXCEPT_JUMP \\d\+ \\d\+ END_FINALLY \\d\+ LOAD_FAST 0 \\d\+ POP_JUMP_IF_TRUE \\d\+ diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 6fbb10a39d..62f2ac4815 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -105,7 +105,7 @@ def make_opcode_format(): OC4(O, O, U, U), # 0x38-0x3b OC4(U, O, B, O), # 0x3c-0x3f OC4(O, B, B, O), # 0x40-0x43 - OC4(B, B, O, B), # 0x44-0x47 + OC4(O, U, O, B), # 0x44-0x47 OC4(U, U, U, U), # 0x48-0x4b OC4(U, U, U, U), # 0x4c-0x4f OC4(V, V, U, V), # 0x50-0x53