diff options
Diffstat (limited to 'wasm2c/wasm-rt-impl.c')
-rw-r--r-- | wasm2c/wasm-rt-impl.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/wasm2c/wasm-rt-impl.c b/wasm2c/wasm-rt-impl.c index 885a58a2..96b3b395 100644 --- a/wasm2c/wasm-rt-impl.c +++ b/wasm2c/wasm-rt-impl.c @@ -37,6 +37,7 @@ #endif #define PAGE_SIZE 65536 +#define MAX_EXCEPTION_SIZE PAGE_SIZE typedef struct FuncType { wasm_rt_type_t* params; @@ -58,6 +59,12 @@ static uint32_t g_func_type_count; jmp_buf wasm_rt_jmp_buf; +static uint32_t g_active_exception_tag; +static uint8_t g_active_exception[MAX_EXCEPTION_SIZE]; +static uint32_t g_active_exception_size; + +static jmp_buf* g_unwind_target; + void wasm_rt_trap(wasm_rt_trap_t code) { assert(code != WASM_RT_TRAP_NONE); #if !WASM_RT_MEMCHECK_SIGNAL_HANDLER @@ -112,6 +119,50 @@ uint32_t wasm_rt_register_func_type(uint32_t param_count, return idx + 1; } +uint32_t wasm_rt_register_tag(uint32_t size) { + static uint32_t s_tag_count = 0; + + if (size > MAX_EXCEPTION_SIZE) { + wasm_rt_trap(WASM_RT_TRAP_EXHAUSTION); + } + return s_tag_count++; +} + +void wasm_rt_load_exception(uint32_t tag, uint32_t size, const void* values) { + assert(size <= MAX_EXCEPTION_SIZE); + + g_active_exception_tag = tag; + g_active_exception_size = size; + + if (size) { + memcpy(g_active_exception, values, size); + } +} + +WASM_RT_NO_RETURN void wasm_rt_throw(void) { + WASM_RT_LONGJMP(*g_unwind_target, WASM_RT_TRAP_UNCAUGHT_EXCEPTION); +} + +jmp_buf* wasm_rt_get_unwind_target(void) { + return g_unwind_target; +} + +void wasm_rt_set_unwind_target(jmp_buf* target) { + g_unwind_target = target; +} + +uint32_t wasm_rt_exception_tag(void) { + return g_active_exception_tag; +} + +uint32_t wasm_rt_exception_size(void) { + return g_active_exception_size; +} + +void* wasm_rt_exception(void) { + return g_active_exception; +} + #if WASM_RT_MEMCHECK_SIGNAL_HANDLER_POSIX static void signal_handler(int sig, siginfo_t* si, void* unused) { if (si->si_code == SEGV_ACCERR) { @@ -325,6 +376,8 @@ const char* wasm_rt_strerror(wasm_rt_trap_t trap) { return "Unreachable instruction executed"; case WASM_RT_TRAP_CALL_INDIRECT: return "Invalid call_indirect"; + case WASM_RT_TRAP_UNCAUGHT_EXCEPTION: + return "Uncaught exception"; } return "invalid trap code"; } |