#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;
}
}
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;
#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)
i32 type_idx;
LocalAllocator locals;
bh_arr(WasmInstruction) code;
+ OnyxToken *location;
} WasmFunc;
typedef struct WasmGlobal {
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);
}
}
ONYX_FUNC(__exit)
NULL
-};
\ No newline at end of file
+};
add_entities_for_node(NULL, (AstNode *) os_type, NULL, NULL);
symbol_builtin_introduce(p->scope, "compiler_os", (AstNode *) os_type);
}
+
WasmFunc wasm_func = { 0 };
wasm_func.type_idx = type_idx;
+ wasm_func.location = fd->token;
bh_arr_new(mod->allocator, wasm_func.code, 4);
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, "<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(§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);
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) {
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;
}
}
+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);
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);
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;