|
129 | 129 |
|
130 | 130 | // Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND
|
131 | 131 | #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) |
132 | 133 |
|
133 | 134 | // Whether registers can be used to store locals (only true if there are no
|
134 | 135 | // exception handlers, because otherwise an nlr_jump will restore registers to
|
|
139 | 140 | #define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL)
|
140 | 141 | #define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1)
|
141 | 142 | #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 |
142 | 144 | #define LOCAL_IDX_RET_VAL(emit) (SIZEOF_NLR_BUF) // needed when NEED_GLOBAL_EXC_HANDLER is true
|
143 | 145 | #define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC)
|
144 | 146 | #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
|
426 | 428 | if (NEED_GLOBAL_EXC_HANDLER(emit)) {
|
427 | 429 | emit->code_state_start = SIZEOF_NLR_BUF; // for nlr_buf_t
|
428 | 430 | 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)) { |
430 | 434 | emit->code_state_start += 1;
|
431 | 435 | }
|
432 | 436 | }
|
@@ -545,11 +549,11 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
545 | 549 | ASM_MOV_REG_REG(emit->as, REG_GENERATOR_STATE, REG_PARENT_ARG_1);
|
546 | 550 | #endif
|
547 | 551 |
|
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 |
549 | 553 | #if N_X86
|
550 | 554 | asm_x86_mov_arg_to_r32(emit->as, 1, REG_PARENT_ARG_2);
|
551 | 555 | #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); |
553 | 557 |
|
554 | 558 | // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
|
555 | 559 | 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) {
|
1252 | 1256 |
|
1253 | 1257 | // This is the first entry of the generator
|
1254 | 1258 |
|
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); |
1257 | 1263 | emit_call(emit, MP_F_NATIVE_RAISE);
|
1258 | 1264 | }
|
1259 | 1265 | }
|
@@ -2988,18 +2994,22 @@ static void emit_native_yield(emit_t *emit, int kind) {
|
2988 | 2994 | emit_native_adjust_stack_size(emit, 1); // send_value
|
2989 | 2995 |
|
2990 | 2996 | 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); |
2993 | 3001 | emit_call(emit, MP_F_NATIVE_RAISE);
|
2994 | 3002 | } else {
|
2995 | 3003 | // Label loop entry
|
2996 | 3004 | emit_native_label_assign(emit, *emit->label_slot + 2);
|
2997 | 3005 |
|
2998 | 3006 | // 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); |
2999 | 3010 | vtype_kind_t vtype;
|
3000 | 3011 | emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // send_value
|
3001 | 3012 | 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 |
3003 | 3013 | emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_3);
|
3004 | 3014 | emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 1); // ret_value
|
3005 | 3015 | emit_call(emit, MP_F_NATIVE_YIELD_FROM);
|
|
0 commit comments