|
63 | 63 |
|
64 | 64 | // C stack layout for native functions:
|
65 | 65 | // 0: nlr_buf_t [optional]
|
| 66 | +// exc_handler_unwind [optional word] |
66 | 67 | // emit->code_state_start: mp_code_state_native_t
|
67 | 68 | // emit->stack_start: Python object stack | emit->n_state
|
68 | 69 | // locals (reversed, L0 at end) |
|
69 | 70 | //
|
70 | 71 | // C stack layout for native generator functions:
|
71 | 72 | // 0=emit->stack_start: nlr_buf_t
|
| 73 | +// exc_handler_unwind [optional word] |
72 | 74 | //
|
73 | 75 | // Then REG_GENERATOR_STATE points to:
|
74 | 76 | // 0=emit->code_state_start: mp_code_state_native_t
|
|
77 | 79 | //
|
78 | 80 | // C stack layout for viper functions:
|
79 | 81 | // 0: nlr_buf_t [optional]
|
| 82 | +// exc_handler_unwind [optional word] |
80 | 83 | // emit->code_state_start: fun_obj, old_globals [optional]
|
81 | 84 | // emit->stack_start: Python object stack | emit->n_state
|
82 | 85 | // locals (reversed, L0 at end) |
|
|
120 | 123 | #define NEED_GLOBAL_EXC_HANDLER(emit) ((emit)->scope->exc_stack_size > 0 \
|
121 | 124 | || ((emit)->scope->scope_flags & (MP_SCOPE_FLAG_GENERATOR | MP_SCOPE_FLAG_REFGLOBALS)))
|
122 | 125 |
|
| 126 | +// Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND |
| 127 | +#define NEED_EXC_HANDLER_UNWIND(emit) ((emit)->scope->exc_stack_size > 0) |
| 128 | + |
123 | 129 | // Whether registers can be used to store locals (only true if there are no
|
124 | 130 | // exception handlers, because otherwise an nlr_jump will restore registers to
|
125 | 131 | // their state at the start of the function and updates to locals will be lost)
|
|
128 | 134 | // Indices within the local C stack for various variables
|
129 | 135 | #define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL)
|
130 | 136 | #define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1)
|
131 |
| -#define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (NLR_BUF_IDX_LOCAL_2) |
| 137 | +#define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (SIZEOF_NLR_BUF) // this needs a dedicated variable outside nlr_buf_t |
132 | 138 | #define LOCAL_IDX_RET_VAL(emit) (NLR_BUF_IDX_LOCAL_3)
|
133 | 139 | #define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC)
|
134 | 140 | #define LOCAL_IDX_OLD_GLOBALS(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP)
|
@@ -403,6 +409,9 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
403 | 409 | emit->code_state_start = 0;
|
404 | 410 | if (NEED_GLOBAL_EXC_HANDLER(emit)) {
|
405 | 411 | emit->code_state_start = SIZEOF_NLR_BUF;
|
| 412 | + if (NEED_EXC_HANDLER_UNWIND(emit)) { |
| 413 | + emit->code_state_start += 1; |
| 414 | + } |
406 | 415 | }
|
407 | 416 |
|
408 | 417 | size_t fun_table_off = mp_emit_common_use_const_obj(emit->emit_common, MP_OBJ_FROM_PTR(&mp_fun_table));
|
@@ -498,11 +507,13 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
498 | 507 | emit->n_state = scope->num_locals + scope->stack_size;
|
499 | 508 |
|
500 | 509 | if (emit->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) {
|
501 |
| - emit->code_state_start = 0; |
502 |
| - emit->stack_start = SIZEOF_CODE_STATE; |
503 | 510 | mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->prelude_ptr_index);
|
504 | 511 | mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->start_offset);
|
505 |
| - ASM_ENTRY(emit->as, SIZEOF_NLR_BUF); |
| 512 | + ASM_ENTRY(emit->as, emit->code_state_start); |
| 513 | + |
| 514 | + // Reset the state size for the state pointed to by REG_GENERATOR_STATE |
| 515 | + emit->code_state_start = 0; |
| 516 | + emit->stack_start = SIZEOF_CODE_STATE; |
506 | 517 |
|
507 | 518 | // Put address of code_state into REG_GENERATOR_STATE
|
508 | 519 | #if N_X86
|
@@ -1188,14 +1199,12 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
|
1188 | 1199 |
|
1189 | 1200 | // Wrap everything in an nlr context
|
1190 | 1201 | emit_native_label_assign(emit, nlr_label);
|
1191 |
| - ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_2, LOCAL_IDX_EXC_HANDLER_UNWIND(emit)); |
1192 | 1202 | ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0);
|
1193 | 1203 | emit_call(emit, MP_F_NLR_PUSH);
|
1194 | 1204 | #if N_NLR_SETJMP
|
1195 | 1205 | ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 2);
|
1196 | 1206 | emit_call(emit, MP_F_SETJMP);
|
1197 | 1207 | #endif
|
1198 |
| - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_LOCAL_2); |
1199 | 1208 | ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true);
|
1200 | 1209 |
|
1201 | 1210 | // Clear PC of current code block, and jump there to resume execution
|
|
0 commit comments