better printing when trap occurs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 17 Jan 2022 01:37:50 +0000 (19:37 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 17 Jan 2022 01:37:50 +0000 (19:37 -0600)
core/builtin.onyx
include/onyx_library.h
include/wasm_emit.h
modules/glfw3/onyx_glfw3.so
modules/onyx_runtime/onyx_runtime.c
src/builtins.c
src/wasm_emit.c
src/wasm_output.h
src/wasm_runtime.c

index 1993aa7857a580111c17f4ed2b07c9552a879530..496ac64dad74f334966813d0726661a9a0649cef 100644 (file)
@@ -138,15 +138,21 @@ cfree   :: (ptr: rawptr) do raw_free(context.allocator, ptr);
 #if runtime.runtime != .Custom {
     new :: ($T: type_expr, allocator := context.allocator) -> ^T {
         use package core.intrinsics.onyx { __initialize }
+        memory :: package core.memory
 
         res := cast(^T) raw_alloc(allocator, sizeof T);
+        memory.set(res, 0, sizeof T);
         __initialize(res);
 
         return res;
     }
 
     make :: ($T: type_expr, allocator := context.allocator) -> ^T {
-        return cast(^T) raw_alloc(allocator, sizeof T);
+        memory :: package core.memory
+
+        res := cast(^T) raw_alloc(allocator, sizeof T);
+        memory.set(res, 0, sizeof T);
+        return res;
     }
 }
 
index dad767d9ec4c4d3350bbb7ca5dde651769b09011..c0c0335aafa3e43ef883539a2a0e394528053848 100644 (file)
@@ -31,6 +31,7 @@ typedef struct OnyxRuntime {
     wasm_func_t* (*wasm_extern_as_func)(wasm_extern_t* ext);
     wasm_trap_t* (*wasm_func_call)(const wasm_func_t* wasm_func, const wasm_val_vec_t* args, wasm_val_vec_t* results);
     wasm_instance_t* (*wasm_instance_new)(wasm_store_t* store, const wasm_module_t* module, const wasm_extern_vec_t* imports, wasm_trap_t** traps);
+    void (*onyx_print_trap)(wasm_trap_t* trap);
 } OnyxRuntime;
 
 OnyxRuntime* runtime;
@@ -96,4 +97,4 @@ typedef struct WasmFuncDefinition {
 #define PTR WASM_I32
 #endif
 
-#define ONYX_PTR(p) (p != 0 ? (runtime->wasm_memory_data(runtime->wasm_memory) + p) : NULL)
\ No newline at end of file
+#define ONYX_PTR(p) (p != 0 ? (runtime->wasm_memory_data(runtime->wasm_memory) + p) : NULL)
index 74569f47cfdd2d83fd463e37f0a02386097f73dd..a369bb2f627a60c3f828e454b834300a4df9c357 100644 (file)
@@ -543,6 +543,7 @@ typedef struct WasmFunc {
     i32 type_idx;
     LocalAllocator locals;
     bh_arr(WasmInstruction) code;
+    OnyxToken *location;
 } WasmFunc;
 
 typedef struct WasmGlobal {
index f6e354bb1fdade5d43e982e4434db86929f2eaab..7649fd898b7d96b340f8f876407580f57c37a386 100755 (executable)
Binary files a/modules/glfw3/onyx_glfw3.so and b/modules/glfw3/onyx_glfw3.so differ
index 66be43143e3fcd8cfd7c1502b135bb64196f2b05..4ea915949dd8b5d6f9dffd54c0bf24e886ab432e 100644 (file)
@@ -357,19 +357,8 @@ static i32 onyx_run_thread(void *data) {
 
         trap = runtime->wasm_func_call(start_func, &args_array, &results);
         if (trap != NULL) {
-            /*
-            When proper linking is available for Wasmer, re-enable this code. At the moment
-            I don't see too much value in passing all of these functions on the Runtime object
-            especially since it is a hack to pass functions there anyway.
-
-            wasm_message_t msg;
-            wasm_trap_message(trap, &msg);
-            bh_printf("TRAP: %b\n", msg.data, msg.size);
-
-            wasm_frame_t *origin = wasm_trap_origin(trap);
-            bh_printf("HERE: func[%d] at %p.\n", wasm_frame_func_index(origin), wasm_frame_module_offset(origin));
-            */
-            bh_printf("ERROR: WebAssembly trap in thread: %d\n", thread_id);
+            bh_printf("THREAD: %d\n", thread_id);
+            runtime->onyx_print_trap(trap);
         }
     }
 
@@ -819,4 +808,4 @@ ONYX_LIBRARY {
 
     ONYX_FUNC(__exit)
     NULL
-};
\ No newline at end of file
+};
index f18712b21207ed7c0071a038d909ffe98f572938..98dacf4d1649c1dd4e5df44af4e3a95456883b03 100644 (file)
@@ -512,3 +512,4 @@ void introduce_build_options(bh_allocator a) {
     add_entities_for_node(NULL, (AstNode *) os_type, NULL, NULL);
     symbol_builtin_introduce(p->scope, "compiler_os", (AstNode *) os_type);
 }
+
index de253c6ef44c613573a99abeae67e072a2f017a0..3b2672e27f1ee438b987341c7bc570f3e9b7a285 100644 (file)
@@ -3251,6 +3251,7 @@ static void emit_function(OnyxWasmModule* mod, AstFunction* fd) {
 
     WasmFunc wasm_func = { 0 };
     wasm_func.type_idx = type_idx;
+    wasm_func.location = fd->token;
 
     bh_arr_new(mod->allocator, wasm_func.code, 4);
 
index ae1a77484be9cd4ed50832a4af0c812c161e6749..231a57ace08986021157bd81b90f2e75f616f9f1 100644 (file)
@@ -713,6 +713,52 @@ static i32 output_onyx_libraries_section(OnyxWasmModule* module, bh_buffer* buff
     return buff->length - prev_len;
 }
 
+static i32 output_onyx_func_offset_section(OnyxWasmModule* module, bh_buffer* buff) {
+    i32 prev_len = buff->length;
+
+    bh_buffer_write_byte(buff, WASM_SECTION_ID_CUSTOM);
+
+    bh_buffer section_buff;
+    bh_buffer_init(&section_buff, buff->allocator, 128);
+
+    const char *custom_name = "_onyx_func_offsets";
+    i32 leb_len;
+    u8* leb = uint_to_uleb128(strlen(custom_name), &leb_len);
+    bh_buffer_append(&section_buff, leb, leb_len);
+    bh_buffer_append(&section_buff, custom_name, strlen(custom_name));
+
+    i32 func_count = bh_arr_length(module->funcs) + module->foreign_function_count;
+
+    bh_buffer name_buff;
+    bh_buffer_init(&name_buff, buff->allocator, 1024);
+    u32 str_cursor = func_count * 4;
+    fori (i, 0, func_count) {
+        bh_buffer_write_u32(&section_buff, str_cursor);
+
+        if (i < module->foreign_function_count) {
+            bh_buffer_append(&name_buff, "<imported function>", 20);
+            str_cursor += 20;
+        } else {
+            WasmFunc *func = &module->funcs[i - module->foreign_function_count];
+            assert(func->location);
+            char *str = bh_bprintf("%s:%d,%d\0", func->location->pos.filename, func->location->pos.line, func->location->pos.column);
+            i32 len = strlen(str);
+            bh_buffer_append(&name_buff, str, len + 1);
+            str_cursor += len + 1;
+        }
+    }
+
+    bh_buffer_concat(&section_buff, name_buff);
+
+    leb = uint_to_uleb128((u64) (section_buff.length), &leb_len);
+    bh_buffer_append(buff, leb, leb_len);
+
+    bh_buffer_concat(buff, section_buff);
+    bh_buffer_free(&section_buff);
+
+    return buff->length - prev_len;
+}
+
 void onyx_wasm_module_write_to_buffer(OnyxWasmModule* module, bh_buffer* buffer) {
     bh_buffer_init(buffer, global_heap_allocator, 128);
     bh_buffer_append(buffer, WASM_MAGIC_STRING, 4);
@@ -731,6 +777,7 @@ void onyx_wasm_module_write_to_buffer(OnyxWasmModule* module, bh_buffer* buffer)
     output_codesection(module, buffer);
     output_datasection(module, buffer);
     output_onyx_libraries_section(module, buffer);
+    output_onyx_func_offset_section(module, buffer);
 }
 
 void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file) {
index e88dc93670cd0b08d40da9f89ac7aef2ffde8390..7cfba39a1f64eac312a9ee53a20965cc9d247f28 100644 (file)
@@ -20,6 +20,7 @@ static wasm_config_t*    wasm_config;
 static wasm_engine_t*    wasm_engine;
 static wasm_store_t*     wasm_store;
 static wasm_extern_vec_t wasm_imports;
+static bh_buffer         wasm_raw_bytes;
 wasm_instance_t*  wasm_instance;
 wasm_module_t*    wasm_module;
 wasm_memory_t*    wasm_memory;
@@ -165,10 +166,46 @@ static void onyx_lookup_and_load_custom_libraries(bh_buffer wasm_bytes) {
     }
 }
 
+static void onyx_print_trap(wasm_trap_t* trap) {
+    wasm_message_t msg;
+    wasm_trap_message(trap, &msg);
+    bh_printf("TRAP: %b\n", msg.data, msg.size);
+
+    wasm_frame_t *origin = wasm_trap_origin(trap);
+    i32 index = wasm_frame_func_index(origin);
+
+    i32 cursor = 8; // skip the magic number and version
+    while (cursor < wasm_raw_bytes.length) {
+        u64 section_number = uleb128_to_uint(wasm_raw_bytes.data, &cursor);
+        u64 section_size   = uleb128_to_uint(wasm_raw_bytes.data, &cursor);
+
+        i32 section_start = cursor;
+        if (section_number == 0) {
+            u64 name_len = uleb128_to_uint(wasm_raw_bytes.data, &cursor);
+            if (!strncmp(wasm_raw_bytes.data + cursor, "_onyx_func_offsets", name_len)) {
+                cursor += name_len;
+                i32 section_start = cursor;
+
+                cursor += 4 * index;
+                i32 func_offset = *(i32 *) (wasm_raw_bytes.data + cursor);
+                char* func_name = wasm_raw_bytes.data + section_start + func_offset;
+
+                bh_printf("HERE: %s\n", func_name);
+                bh_printf("OFFSET: %p\n", wasm_frame_module_offset(origin));
+                break;
+            }
+        }
+
+        cursor = section_start + section_size;
+    }
+}
+
 // Returns 1 if successful
 b32 onyx_run_wasm(bh_buffer wasm_bytes, int argc, char *argv[]) {
     runtime = &wasm_runtime;
 
+    wasm_raw_bytes = wasm_bytes;
+
     bh_arr_new(bh_heap_allocator(), linkable_functions, 4);
     onyx_lookup_and_load_custom_libraries(wasm_bytes);
 
@@ -283,6 +320,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes, int argc, char *argv[]) {
     wasm_runtime.wasm_extern_as_func = &wasm_extern_as_func;
     wasm_runtime.wasm_func_call = &wasm_func_call;
     wasm_runtime.wasm_instance_new = &wasm_instance_new;
+    wasm_runtime.onyx_print_trap = &onyx_print_trap;
 
     wasm_extern_t* start_extern = wasm_extern_lookup_by_name(wasm_module, wasm_instance, "_start");
     wasm_func_t*   start_func   = wasm_extern_as_func(start_extern);
@@ -294,14 +332,7 @@ b32 onyx_run_wasm(bh_buffer wasm_bytes, int argc, char *argv[]) {
     run_trap = wasm_func_call(start_func, &args, &results);
 
 #if 1
-    if (run_trap != NULL) {
-        wasm_message_t msg;
-        wasm_trap_message(run_trap, &msg);
-        bh_printf("TRAP: %b\n", msg.data, msg.size);
-
-        wasm_frame_t *origin = wasm_trap_origin(run_trap);
-        bh_printf("HERE: func[%d] at %p.\n", wasm_frame_func_index(origin), wasm_frame_module_offset(origin));
-    }
+    if (run_trap != NULL) onyx_print_trap(run_trap);
 #endif
 
     goto cleanup;