py/emitnative: Add support for using setjmp with native emitter.

To enable this feature the N_NLR_SETJMP macro should be set to 1 before
including py/emitnative.c.
This commit is contained in:
Damien George 2019-09-10 13:44:22 +10:00
parent 4107597b84
commit 3504edc804
3 changed files with 24 additions and 0 deletions

View File

@ -1154,6 +1154,10 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
// Wrap everything in an nlr context // Wrap everything in an nlr context
ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0); ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0);
emit_call(emit, MP_F_NLR_PUSH); emit_call(emit, MP_F_NLR_PUSH);
#if N_NLR_SETJMP
ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 2);
emit_call(emit, MP_F_SETJMP);
#endif
ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, start_label, true); ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, start_label, true);
} else { } else {
// Clear the unwind state // Clear the unwind state
@ -1168,6 +1172,10 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_2, LOCAL_IDX_EXC_HANDLER_UNWIND(emit)); ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_2, LOCAL_IDX_EXC_HANDLER_UNWIND(emit));
ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0); ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0);
emit_call(emit, MP_F_NLR_PUSH); emit_call(emit, MP_F_NLR_PUSH);
#if N_NLR_SETJMP
ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 2);
emit_call(emit, MP_F_SETJMP);
#endif
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_LOCAL_2); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_LOCAL_2);
ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true); ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true);
@ -1178,6 +1186,12 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
// Global exception handler: check for valid exception handler // Global exception handler: check for valid exception handler
emit_native_label_assign(emit, global_except_label); emit_native_label_assign(emit, global_except_label);
#if N_NLR_SETJMP
// Reload REG_FUN_TABLE, since it may be clobbered by longjmp
emit_native_mov_reg_state(emit, REG_LOCAL_1, LOCAL_IDX_FUN_OBJ(emit));
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_1, REG_LOCAL_1, offsetof(mp_obj_fun_bc_t, const_table) / sizeof(uintptr_t));
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_LOCAL_1, emit->scope->num_pos_args + emit->scope->num_kwonly_args);
#endif
ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_1, LOCAL_IDX_EXC_HANDLER_PC(emit)); ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_1, LOCAL_IDX_EXC_HANDLER_PC(emit));
ASM_JUMP_IF_REG_NONZERO(emit->as, REG_LOCAL_1, nlr_label, false); ASM_JUMP_IF_REG_NONZERO(emit->as, REG_LOCAL_1, nlr_label, false);
} }

View File

@ -244,7 +244,11 @@ const void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_call_method_n_kw_var, mp_call_method_n_kw_var,
mp_native_getiter, mp_native_getiter,
mp_native_iternext, mp_native_iternext,
#if MICROPY_NLR_SETJMP
nlr_push_tail,
#else
nlr_push, nlr_push,
#endif
nlr_pop, nlr_pop,
mp_native_raise, mp_native_raise,
mp_import_name, mp_import_name,
@ -262,6 +266,11 @@ const void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_small_int_floor_divide, mp_small_int_floor_divide,
mp_small_int_modulo, mp_small_int_modulo,
mp_native_yield_from, mp_native_yield_from,
#if MICROPY_NLR_SETJMP
setjmp,
#else
NULL,
#endif
}; };
#endif // MICROPY_EMIT_NATIVE #endif // MICROPY_EMIT_NATIVE

View File

@ -201,6 +201,7 @@ typedef enum {
MP_F_SMALL_INT_FLOOR_DIVIDE, MP_F_SMALL_INT_FLOOR_DIVIDE,
MP_F_SMALL_INT_MODULO, MP_F_SMALL_INT_MODULO,
MP_F_NATIVE_YIELD_FROM, MP_F_NATIVE_YIELD_FROM,
MP_F_SETJMP,
MP_F_NUMBER_OF, MP_F_NUMBER_OF,
} mp_fun_kind_t; } mp_fun_kind_t;