From: Brendan Hansen Date: Mon, 17 Jan 2022 01:37:50 +0000 (-0600) Subject: better printing when trap occurs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=85c64dfc226d9622dd03f86c1f0864c107f034bb;p=onyx.git better printing when trap occurs --- diff --git a/core/builtin.onyx b/core/builtin.onyx index 1993aa78..496ac64d 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -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; } } diff --git a/include/onyx_library.h b/include/onyx_library.h index dad767d9..c0c0335a 100644 --- a/include/onyx_library.h +++ b/include/onyx_library.h @@ -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) diff --git a/include/wasm_emit.h b/include/wasm_emit.h index 74569f47..a369bb2f 100644 --- a/include/wasm_emit.h +++ b/include/wasm_emit.h @@ -543,6 +543,7 @@ typedef struct WasmFunc { i32 type_idx; LocalAllocator locals; bh_arr(WasmInstruction) code; + OnyxToken *location; } WasmFunc; typedef struct WasmGlobal { diff --git a/modules/glfw3/onyx_glfw3.so b/modules/glfw3/onyx_glfw3.so index f6e354bb..7649fd89 100755 Binary files a/modules/glfw3/onyx_glfw3.so and b/modules/glfw3/onyx_glfw3.so differ diff --git a/modules/onyx_runtime/onyx_runtime.c b/modules/onyx_runtime/onyx_runtime.c index 66be4314..4ea91594 100644 --- a/modules/onyx_runtime/onyx_runtime.c +++ b/modules/onyx_runtime/onyx_runtime.c @@ -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 +}; diff --git a/src/builtins.c b/src/builtins.c index f18712b2..98dacf4d 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -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); } + diff --git a/src/wasm_emit.c b/src/wasm_emit.c index de253c6e..3b2672e2 100644 --- a/src/wasm_emit.c +++ b/src/wasm_emit.c @@ -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); diff --git a/src/wasm_output.h b/src/wasm_output.h index ae1a7748..231a57ac 100644 --- a/src/wasm_output.h +++ b/src/wasm_output.h @@ -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(§ion_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(§ion_buff, leb, leb_len); + bh_buffer_append(§ion_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(§ion_buff, str_cursor); + + if (i < module->foreign_function_count) { + bh_buffer_append(&name_buff, "", 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(§ion_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(§ion_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) { diff --git a/src/wasm_runtime.c b/src/wasm_runtime.c index e88dc936..7cfba39a 100644 --- a/src/wasm_runtime.c +++ b/src/wasm_runtime.c @@ -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;