Skip to content

Commit a19214d

Browse files
committed
py/emitnative: Place thrown value in dedicated local variable.
A value thrown/injected into a native generator needs to be stored in a dedicated variable outside `nlr_buf_t`, following the `inject_exc` variable in `py/vm.c`. Signed-off-by: Damien George <[email protected]>
1 parent 9dbc787 commit a19214d

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

py/emitnative.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129

130130
// Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND
131131
#define NEED_EXC_HANDLER_UNWIND(emit) ((emit)->scope->exc_stack_size > 0)
132+
#define NEED_THROW_VAL(emit) ((emit)->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR)
132133

133134
// Whether registers can be used to store locals (only true if there are no
134135
// exception handlers, because otherwise an nlr_jump will restore registers to
@@ -139,6 +140,7 @@
139140
#define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL)
140141
#define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1)
141142
#define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (SIZEOF_NLR_BUF + 1) // this needs a dedicated variable outside nlr_buf_t
143+
#define LOCAL_IDX_THROW_VAL(emit) (SIZEOF_NLR_BUF + 2) // needs a dedicated variable outside nlr_buf_t, following inject_exc in py/vm.c
142144
#define LOCAL_IDX_RET_VAL(emit) (SIZEOF_NLR_BUF) // needed when NEED_GLOBAL_EXC_HANDLER is true
143145
#define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC)
144146
#define LOCAL_IDX_OLD_GLOBALS(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP)
@@ -426,7 +428,9 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
426428
if (NEED_GLOBAL_EXC_HANDLER(emit)) {
427429
emit->code_state_start = SIZEOF_NLR_BUF; // for nlr_buf_t
428430
emit->code_state_start += 1; // for return_value
429-
if (NEED_EXC_HANDLER_UNWIND(emit)) {
431+
if (NEED_THROW_VAL(emit)) {
432+
emit->code_state_start += 2;
433+
} else if (NEED_EXC_HANDLER_UNWIND(emit)) {
430434
emit->code_state_start += 1;
431435
}
432436
}
@@ -545,11 +549,11 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
545549
ASM_MOV_REG_REG(emit->as, REG_GENERATOR_STATE, REG_PARENT_ARG_1);
546550
#endif
547551

548-
// Put throw value into LOCAL_IDX_EXC_VAL slot, for yield/yield-from
552+
// Put throw value into LOCAL_IDX_THROW_VAL slot, for yield/yield-from
549553
#if N_X86
550554
asm_x86_mov_arg_to_r32(emit->as, 1, REG_PARENT_ARG_2);
551555
#endif
552-
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_PARENT_ARG_2);
556+
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_PARENT_ARG_2);
553557

554558
// Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
555559
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_GENERATOR_STATE, LOCAL_IDX_FUN_OBJ(emit));
@@ -1252,8 +1256,10 @@ static void emit_native_global_exc_entry(emit_t *emit) {
12521256

12531257
// This is the first entry of the generator
12541258

1255-
// Check LOCAL_IDX_EXC_VAL for any injected value
1256-
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit));
1259+
// Check LOCAL_IDX_THROW_VAL for any injected value
1260+
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit));
1261+
ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL);
1262+
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2);
12571263
emit_call(emit, MP_F_NATIVE_RAISE);
12581264
}
12591265
}
@@ -2988,18 +2994,22 @@ static void emit_native_yield(emit_t *emit, int kind) {
29882994
emit_native_adjust_stack_size(emit, 1); // send_value
29892995

29902996
if (kind == MP_EMIT_YIELD_VALUE) {
2991-
// Check LOCAL_IDX_EXC_VAL for any injected value
2992-
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit));
2997+
// Check LOCAL_IDX_THROW_VAL for any injected value
2998+
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit));
2999+
ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL);
3000+
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2);
29933001
emit_call(emit, MP_F_NATIVE_RAISE);
29943002
} else {
29953003
// Label loop entry
29963004
emit_native_label_assign(emit, *emit->label_slot + 2);
29973005

29983006
// Get the next item from the delegate generator
3007+
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_THROW_VAL(emit)); // throw_value
3008+
ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL);
3009+
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2);
29993010
vtype_kind_t vtype;
30003011
emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // send_value
30013012
emit_access_stack(emit, 1, &vtype, REG_ARG_1); // generator
3002-
ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_EXC_VAL(emit)); // throw_value
30033013
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_3);
30043014
emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 1); // ret_value
30053015
emit_call(emit, MP_F_NATIVE_YIELD_FROM);

tests/run-tests.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -731,10 +731,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
731731
skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info
732732
skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs
733733
skip_tests.add("basics/unboundlocal.py") # requires checking for unbound local
734-
skip_tests.add("extmod/asyncio_event.py") # unknown issue
735734
skip_tests.add("extmod/asyncio_lock.py") # requires async with
736-
skip_tests.add("extmod/asyncio_micropython.py") # unknown issue
737-
skip_tests.add("extmod/asyncio_wait_for.py") # unknown issue
738735
skip_tests.add("misc/features.py") # requires raise_varargs
739736
skip_tests.add(
740737
"misc/print_exception.py"

0 commit comments

Comments
 (0)