bugfixes: many things with error handling
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 6 Nov 2023 22:12:24 +0000 (16:12 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 6 Nov 2023 22:12:24 +0000 (16:12 -0600)
compiler/src/wasm_runtime.c
core/alloc/memdebug.onyx
interpreter/include/vm.h
interpreter/src/vm/vm_instrs.h
interpreter/src/wasm/instance.c
interpreter/src/wasm/trap.c
runtime/src/ort_threads.h
shared/include/onyx_library.h

index c90b395dde55a1ce3df10abaeebe274cf80b65e6..1fcfbbe9b7ae50a8f3d2cf55cdf0368361d92168 100644 (file)
@@ -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")
     );
index fa64e9679fb690532f3e2b891f5254382b0c183e..0c7f9c4093dd9d619b274ef2d7d36ed7dbcc85d7 100644 (file)
@@ -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 = .{
index 633a643483df2add1e1da9678e6469b9d8ae078b..6ebaa4749242392b92eb013579d5715f8cd40db9 100644 (file)
@@ -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 {
index 312b6291cc062c5a1e9070344af26999c2a7e6d4..a6c615856010335d073ee207d80254fa25431cb7 100644 (file)
@@ -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];
index d2a9a3975f9ea4681568c3df08e2ab3e605c6b41..d910d54586cef5511429af6d66af4536b0ac0d28 100644 (file)
@@ -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;
index cb4ba746995a3b8b28b1ba5aa5c6e342e62b7e49..41c2a84ee9b0bda6c79f10b93ac4eebbb4f4c68a 100644 (file)
@@ -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;
 }
index c0ef8d741ccd2cac0af4f3d76bb0ed89d4aec357..c58114d63ccfd0a5136f7f7d0d578f5cdbe3c781 100644 (file)
@@ -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;
 }
index 1e2ef235b73f6a20df4206cf9d923443b6247539..eb5c3ce4da4786f8b55f906081d6bd0d5783297a 100644 (file)
@@ -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;