diff options
author | Damien George <damien.p.george@gmail.com> | 2019-09-10 13:44:22 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-10-05 13:41:58 +1000 |
commit | 3504edc8048f8ab038ace50b0bbdf65b30619cc5 (patch) | |
tree | 81f29a430d623e178ef4f29f9be4bbc592d764d8 /py/emitnative.c | |
parent | 4107597b845c04b7184215b3202d596998141cb9 (diff) | |
download | micropython-3504edc8048f8ab038ace50b0bbdf65b30619cc5.tar.gz micropython-3504edc8048f8ab038ace50b0bbdf65b30619cc5.zip |
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.
Diffstat (limited to 'py/emitnative.c')
-rw-r--r-- | py/emitnative.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index 30f66f6334..22bfa2c78f 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1154,6 +1154,10 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) { // Wrap everything in an nlr context ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0); 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); } else { // 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_ADDR(emit->as, REG_ARG_1, 0); 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_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 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_JUMP_IF_REG_NONZERO(emit->as, REG_LOCAL_1, nlr_label, false); } |