From e95f87d3bc3feb8eb3abe3558a4cc9f1cc339786 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 18 Oct 2021 23:05:53 -0500 Subject: [PATCH] started working on conditional segment initialization --- core/builtin.onyx | 9 ++++++++- docs/todo | 6 +++++- include/wasm.h | 1 + src/builtins.c | 9 ++++++++- src/wasm_output.c | 1 + 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/core/builtin.onyx b/core/builtin.onyx index 7cfa05c1..27778d6d 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -200,4 +200,11 @@ Code :: struct {_:i32;} #if #defined((package core.set).Set) { Set :: (package core.set).Set; -} \ No newline at end of file +} + + +// This procedure is a special compiler generated procedure that initializes all the data segments +// in the program. It should only be called once, by the main thread, at the start of execution. It +// is undefined behaviour if it is called more than once. +__initialize_data_segments :: () -> i32 --- + diff --git a/docs/todo b/docs/todo index d207a007..dbbb2ea8 100644 --- a/docs/todo +++ b/docs/todo @@ -189,9 +189,13 @@ To-Do list for threading capability in the browser: [X] Write basic threading primatives like mutex and semaphore [X] Make heap and printf take a mutex - [ ] LATER: add thread-local variables + [X] LATER: add thread-local variables - Have a new global that is the TLS base pointer - Any global variable (memres) tagged with #threadlocal will be placed in a block with the base pointer being the new global - The global is initialized to a heap allocated block at the start of each thread +Optimize the generation of multi-threaded modules when post-mvp features are enabled: + [X] memory.init intrinsic + [ ] atomatic generation of initializers for all data segments + [ ] emit datacount section \ No newline at end of file diff --git a/include/wasm.h b/include/wasm.h index 45c9824d..36f93a16 100644 --- a/include/wasm.h +++ b/include/wasm.h @@ -424,6 +424,7 @@ typedef enum WasmInstructionType { WI_F32X4_CONVERT_I32X4_U = SIMD_INSTR_MASK | 251, + WI_MEMORY_INIT = EXT_INSTR_MASK | 0x08, WI_MEMORY_COPY = EXT_INSTR_MASK | 0x0a, WI_MEMORY_FILL = EXT_INSTR_MASK | 0x0b, diff --git a/src/builtins.c b/src/builtins.c index 6376397b..27db173f 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -59,7 +59,8 @@ AstType *builtin_callsite_type; AstType *builtin_any_type; AstType *builtin_code_type; -AstTyped *type_table_node = NULL; +AstFunction *builtin_initialize_data_segments = NULL; +AstTyped *type_table_node = NULL; const BuiltinSymbol builtin_symbols[] = { { NULL, "void", (AstNode *) &basic_type_void }, @@ -431,6 +432,12 @@ void initialize_builtins(bh_allocator a) { return; } + builtin_initialize_data_segments = (AstType *) symbol_raw_resolve(p->scope, "__initialize_data_segments"); + if (builtin_code_type == NULL) { + onyx_report_error((OnyxFilePos) { 0 }, "'__initialize_data_segments' procedure not found in builtin package."); + return; + } + p = package_lookup("builtin.type_info"); if (p != NULL) { type_table_node = (AstTyped *) symbol_raw_resolve(p->scope, "type_table"); diff --git a/src/wasm_output.c b/src/wasm_output.c index 92223cd4..f6a2ab61 100644 --- a/src/wasm_output.c +++ b/src/wasm_output.c @@ -471,6 +471,7 @@ static void output_instruction(WasmFunc* func, WasmInstruction* instr, bh_buffer bh_buffer_append(buff, leb, leb_len); break; + case WI_MEMORY_INIT: case WI_MEMORY_COPY: leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); bh_buffer_append(buff, leb, leb_len); -- 2.25.1