diff options
author | Damien George <damien@micropython.org> | 2024-04-16 09:29:13 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-06-21 16:21:29 +1000 |
commit | a19214d897f7891d177dc22bb8fc555f7e6b65bb (patch) | |
tree | f1761a45679957a672138bef2bacbf8b0cbeefef | |
parent | 9dbc787ce8dda9df39eb68c03de144155b2253f0 (diff) | |
download | micropython-a19214d897f7891d177dc22bb8fc555f7e6b65bb.tar.gz micropython-a19214d897f7891d177dc22bb8fc555f7e6b65bb.zip |
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 <damien@micropython.org>
-rw-r--r-- | py/emitnative.c | 26 | ||||
-rwxr-xr-x | tests/run-tests.py | 3 |
2 files changed, 18 insertions, 11 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index 9d3f698b25..db31f51e65 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -129,6 +129,7 @@ // Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND #define NEED_EXC_HANDLER_UNWIND(emit) ((emit)->scope->exc_stack_size > 0) +#define NEED_THROW_VAL(emit) ((emit)->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) // Whether registers can be used to store locals (only true if there are no // exception handlers, because otherwise an nlr_jump will restore registers to @@ -139,6 +140,7 @@ #define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL) #define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1) #define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (SIZEOF_NLR_BUF + 1) // this needs a dedicated variable outside nlr_buf_t +#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 #define LOCAL_IDX_RET_VAL(emit) (SIZEOF_NLR_BUF) // needed when NEED_GLOBAL_EXC_HANDLER is true #define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC) #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 if (NEED_GLOBAL_EXC_HANDLER(emit)) { emit->code_state_start = SIZEOF_NLR_BUF; // for nlr_buf_t emit->code_state_start += 1; // for return_value - if (NEED_EXC_HANDLER_UNWIND(emit)) { + if (NEED_THROW_VAL(emit)) { + emit->code_state_start += 2; + } else if (NEED_EXC_HANDLER_UNWIND(emit)) { emit->code_state_start += 1; } } @@ -545,11 +549,11 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop ASM_MOV_REG_REG(emit->as, REG_GENERATOR_STATE, REG_PARENT_ARG_1); #endif - // Put throw value into LOCAL_IDX_EXC_VAL slot, for yield/yield-from + // Put throw value into LOCAL_IDX_THROW_VAL slot, for yield/yield-from #if N_X86 asm_x86_mov_arg_to_r32(emit->as, 1, REG_PARENT_ARG_2); #endif - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_PARENT_ARG_2); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_PARENT_ARG_2); // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table 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) { // This is the first entry of the generator - // Check LOCAL_IDX_EXC_VAL for any injected value - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); + // Check LOCAL_IDX_THROW_VAL for any injected value + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit)); + ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); emit_call(emit, MP_F_NATIVE_RAISE); } } @@ -2988,18 +2994,22 @@ static void emit_native_yield(emit_t *emit, int kind) { emit_native_adjust_stack_size(emit, 1); // send_value if (kind == MP_EMIT_YIELD_VALUE) { - // Check LOCAL_IDX_EXC_VAL for any injected value - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); + // Check LOCAL_IDX_THROW_VAL for any injected value + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit)); + ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); emit_call(emit, MP_F_NATIVE_RAISE); } else { // Label loop entry emit_native_label_assign(emit, *emit->label_slot + 2); // Get the next item from the delegate generator + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_THROW_VAL(emit)); // throw_value + ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); vtype_kind_t vtype; emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // send_value emit_access_stack(emit, 1, &vtype, REG_ARG_1); // generator - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_EXC_VAL(emit)); // throw_value emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_3); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 1); // ret_value emit_call(emit, MP_F_NATIVE_YIELD_FROM); diff --git a/tests/run-tests.py b/tests/run-tests.py index fa6c2a0331..a551f35c67 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -731,10 +731,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs skip_tests.add("basics/unboundlocal.py") # requires checking for unbound local - skip_tests.add("extmod/asyncio_event.py") # unknown issue skip_tests.add("extmod/asyncio_lock.py") # requires async with - skip_tests.add("extmod/asyncio_micropython.py") # unknown issue - skip_tests.add("extmod/asyncio_wait_for.py") # unknown issue skip_tests.add("misc/features.py") # requires raise_varargs skip_tests.add( "misc/print_exception.py" |