started working on conditional segment initialization
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 19 Oct 2021 04:05:53 +0000 (23:05 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 19 Oct 2021 04:05:53 +0000 (23:05 -0500)
core/builtin.onyx
docs/todo
include/wasm.h
src/builtins.c
src/wasm_output.c

index 7cfa05c1499f4c92027a01b740d221f07fafc313..27778d6d68128b105093f3a29ad352ad47f0b424 100644 (file)
@@ -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 ---
+
index d207a0078073f7909c6badeed8dad7d017017ff0..dbbb2ea81b565276fab441eff9eda1c4d18f9022 100644 (file)
--- 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
index 45c9824d93657f34c8cece4c3a6b226049972d4e..36f93a16f0e3ae8cad2d2f9a5316b22a23a36e9e 100644 (file)
@@ -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,
 
index 6376397b309e67833cfce0f102e7c8debea59fad..27db173f822e417ce33f46b9c64f3bac46065ead 100644 (file)
@@ -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");
index 92223cd42fc58ee9235a3c4b1a2a352a922bea74..f6a2ab61d2cb5d325b6c0c452f060d2ec11b396a 100644 (file)
@@ -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);