From a6a0384830222a3b432744e5bbfcb1c80ce01c28 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 6 Nov 2023 16:12:24 -0600 Subject: [PATCH] bugfixes: many things with error handling --- compiler/src/wasm_runtime.c | 15 +++++++++------ core/alloc/memdebug.onyx | 19 +++++++++++-------- interpreter/include/vm.h | 1 + interpreter/src/vm/vm_instrs.h | 3 +++ interpreter/src/wasm/instance.c | 24 +++++++++++++++++++----- interpreter/src/wasm/trap.c | 4 ++-- runtime/src/ort_threads.h | 6 ++---- shared/include/onyx_library.h | 2 ++ 8 files changed, 49 insertions(+), 25 deletions(-) diff --git a/compiler/src/wasm_runtime.c b/compiler/src/wasm_runtime.c index c90b395d..1fcfbbe9 100644 --- a/compiler/src/wasm_runtime.c +++ b/compiler/src/wasm_runtime.c @@ -400,8 +400,6 @@ static void onyx_print_trap(wasm_trap_t* trap) { cursor = section_start + section_size; } - if (func_name_section == 0) return; - bh_printf("TRACE:\n"); wasm_frame_vec_t frames; wasm_trap_trace(trap, &frames); @@ -409,11 +407,15 @@ static void onyx_print_trap(wasm_trap_t* trap) { i32 func_idx = wasm_frame_func_index(frames.data[i]); i32 mod_offset = wasm_frame_module_offset(frames.data[i]); - i32 cursor = func_name_section + 4 * func_idx; - i32 func_offset = *(i32 *) (wasm_raw_bytes.data + cursor); - char* func_name = wasm_raw_bytes.data + func_name_section + func_offset; + if (func_name_section > 0) { + i32 cursor = func_name_section + 4 * func_idx; + i32 func_offset = *(i32 *) (wasm_raw_bytes.data + cursor); + char* func_name = wasm_raw_bytes.data + func_name_section + func_offset; - bh_printf(" func[%d]:%p at %s\n", func_idx, mod_offset, func_name); + bh_printf(" func[%d]:%p at %s\n", func_idx, mod_offset, func_name); + } else { + bh_printf(" func[%d]\n", func_idx); + } } } @@ -644,6 +646,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes, int argc, char *argv[]) { wasm_runtime.wasm_imports = wasm_imports; wasm_runtime.wasm_memory = wasm_memory; wasm_runtime.wasm_instance = wasm_instance; + wasm_runtime.wasm_store = wasm_store; wasm_runtime.wasm_func_table = wasm_extern_as_table( wasm_extern_lookup_by_name(wasm_module, wasm_instance, "__indirect_function_table") ); diff --git a/core/alloc/memdebug.onyx b/core/alloc/memdebug.onyx index fa64e967..0c7f9c40 100644 --- a/core/alloc/memdebug.onyx +++ b/core/alloc/memdebug.onyx @@ -5,7 +5,7 @@ use core {Result} use core.alloc use core.net use core.io -use core.iter +use core.slice use core.encoding.osad use runtime @@ -94,15 +94,18 @@ alloc.as_allocator :: (memdebug: &MemDebugState) => Allocator.{ memdebug, memdeb memdebug_proc :: (m: &MemDebugState, action: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr { newptr := m.wrapped_allocator.func(m.wrapped_allocator.data, action, size, align, oldptr); - trace := iter.as_iter(runtime.info.get_stack_trace()) - |> iter.map(frame => { - info := frame.info; - return MemDebugStackNode.{ - info.file, info.line, frame.current_line, info.func_name + trace: [] MemDebugStackNode = .[]; + stack_trace := runtime.info.get_stack_trace(); + if stack_trace { + slice.init(&trace, stack_trace.count, context.temp_allocator); + for i: stack_trace.count { + info := stack_trace[i].info; + trace[i] = .{ + info.file, info.line, stack_trace[i].current_line, info.func_name }; - }) - |> iter.collect(context.temp_allocator); + } + } memdebug_send_message(m, .{ Action = .{ diff --git a/interpreter/include/vm.h b/interpreter/include/vm.h index 633a6434..6ebaa474 100644 --- a/interpreter/include/vm.h +++ b/interpreter/include/vm.h @@ -56,6 +56,7 @@ struct ovm_static_integer_array_t { #define OVM_TYPE_F32 0x05 #define OVM_TYPE_F64 0x06 #define OVM_TYPE_V128 0x07 +#define OVM_TYPE_ERR 0xff struct ovm_value_t { union { diff --git a/interpreter/src/vm/vm_instrs.h b/interpreter/src/vm/vm_instrs.h index 312b6291..a6c61585 100644 --- a/interpreter/src/vm/vm_instrs.h +++ b/interpreter/src/vm/vm_instrs.h @@ -294,6 +294,9 @@ OVMI_INSTR_EXEC(idx_arr) { ovm_static_integer_array_t data_elem = state->program->static_data[instr->a]; if (VAL(instr->b).u32 >= (u32) data_elem.len) { OVMI_EXCEPTION_HOOK; + ovm_value_t bad_val; + bad_val.type = OVM_TYPE_ERR; + return bad_val; } VAL(instr->r).i32 = state->program->static_integers[data_elem.start_idx + VAL(instr->b).u32]; diff --git a/interpreter/src/wasm/instance.c b/interpreter/src/wasm/instance.c index d2a9a397..d910d545 100644 --- a/interpreter/src/wasm/instance.c +++ b/interpreter/src/wasm/instance.c @@ -12,6 +12,8 @@ struct wasm_ovm_binding { ovm_engine_t *engine; ovm_state_t *state; ovm_program_t *program; + + wasm_instance_t *instance; }; typedef struct ovm_wasm_binding ovm_wasm_binding; @@ -85,6 +87,11 @@ struct ovm_wasm_binding { (w).kind = WASM_F64; \ (w).of.f64 = (o).f64; \ break; \ + \ + case OVM_TYPE_ERR: \ + (w).kind = WASM_I32; \ + (w).of.i32 = 0; \ + break; \ \ default: \ printf("INVALID: %d\n", (o).type); \ @@ -100,6 +107,15 @@ static wasm_trap_t *wasm_to_ovm_func_call_binding(void *vbinding, const wasm_val } ovm_value_t ovm_res = ovm_func_call(binding->engine, binding->state, binding->program, binding->func_idx, args->size, vals); + + // Check for error (trap). + if (ovm_res.type == OVM_TYPE_ERR) { + wasm_byte_vec_t msg; + wasm_byte_vec_new(&msg, 9, "Hit error"); + wasm_trap_t *trap = wasm_trap_new(binding->instance->store, (void *) &msg); + return trap; + } + if (!res || res->size == 0) return NULL; OVM_TO_WASM(ovm_res, res->data[0]); @@ -220,6 +236,7 @@ static void prepare_instance(wasm_instance_t *instance, const wasm_extern_vec_t binding->func_idx = bh_arr_length(instance->funcs); binding->program = ovm_program; binding->state = ovm_state; + binding->instance = instance; wasm_func_t *func = wasm_func_new_with_env(instance->store, instance->module->functypes.data[i], wasm_to_ovm_func_call_binding, binding, NULL); @@ -314,13 +331,10 @@ wasm_instance_t *wasm_instance_new(wasm_store_t *store, const wasm_module_t *mod instance->store = store; instance->module = module; - if (store->instance) { - bh_printf("A WASM store should only be used for a single instance!\n"); - return NULL; + if (!store->instance) { + store->instance = instance; } - store->instance = instance; - instance->funcs = NULL; instance->memories = NULL; instance->tables = NULL; diff --git a/interpreter/src/wasm/trap.c b/interpreter/src/wasm/trap.c index cb4ba746..41c2a84e 100644 --- a/interpreter/src/wasm/trap.c +++ b/interpreter/src/wasm/trap.c @@ -37,6 +37,6 @@ wasm_frame_t *wasm_trap_origin(const wasm_trap_t *trap) { } void wasm_trap_trace(const wasm_trap_t *trap, wasm_frame_vec_t *frames) { - frames->size = 0; - frames->data = NULL; + frames->size = trap->frames.size; + frames->data = trap->frames.data; } diff --git a/runtime/src/ort_threads.h b/runtime/src/ort_threads.h index c0ef8d74..c58114d6 100644 --- a/runtime/src/ort_threads.h +++ b/runtime/src/ort_threads.h @@ -31,10 +31,9 @@ static i32 onyx_run_thread(void *data) { #endif OnyxThread *thread = (OnyxThread *) data; - wasm_store_t *wasm_store = runtime->wasm_store_new(runtime->wasm_engine); - wasm_trap_t* traps = NULL; - thread->instance = runtime->wasm_instance_new(wasm_store, runtime->wasm_module, &runtime->wasm_imports, &traps); + thread->instance = runtime->wasm_instance_new(runtime->wasm_store, runtime->wasm_module, &runtime->wasm_imports, &traps); + assert(thread->instance); wasm_extern_t* start_extern = runtime->wasm_extern_lookup_by_name(runtime->wasm_module, thread->instance, "_thread_start"); wasm_func_t* start_func = runtime->wasm_extern_as_func(start_extern); @@ -79,7 +78,6 @@ static i32 onyx_run_thread(void *data) { } runtime->wasm_instance_delete(thread->instance); - runtime->wasm_store_delete(wasm_store); return 0; } diff --git a/shared/include/onyx_library.h b/shared/include/onyx_library.h index 1e2ef235..eb5c3ce4 100644 --- a/shared/include/onyx_library.h +++ b/shared/include/onyx_library.h @@ -42,6 +42,8 @@ typedef struct OnyxRuntime { void (*(*wasm_func_from_idx)(wasm_table_t *table, unsigned int index, char *signature))(void); void (*wasm_instance_delete)(wasm_instance_t *instance); + + wasm_store_t *wasm_store; } OnyxRuntime; OnyxRuntime* runtime; -- 2.25.1