partially fixed long standing linking limitation
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Nov 2022 05:05:51 +0000 (23:05 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Nov 2022 05:05:51 +0000 (23:05 -0600)
compiler/include/wasm_emit.h
compiler/src/checker.c
compiler/src/wasm_emit.c
core/io/stdio.onyx

index d057f5a96905ccc339933bab335fc5b67fbcb59f..f54daf910940a85ad1dfbddb2780f7c4f56afb96 100644 (file)
@@ -628,6 +628,8 @@ typedef struct DatumPatchInfo {
     u32 offset;
     u32 location;
     u32 index;
+
+    AstNode *node_to_use_if_data_id_is_null;
 } DatumPatchInfo;
 
 // Context used when building a constexpr buffer
index 7b3ab8ccdf81f6dad90011f0ec14b8484e5998d7..edd0427442f38a251c67ace70ee1339118c531de 100644 (file)
@@ -1649,6 +1649,10 @@ CheckStatus check_address_of(AstAddressOf** paof) {
 
     aof->type = type_make_pointer(context.ast_alloc, expr->type);
 
+    if (expr->kind == Ast_Kind_Memres) {
+        aof->flags |= Ast_Flag_Comptime;
+    }
+
     return Check_Success;
 }
 
index 5a31d87fe9fa8f3aaf3209335154dc317c933f79..b8a046bc4d05a4cc3a3e6ba099678639b23d1c10 100644 (file)
@@ -4210,6 +4210,29 @@ static b32 emit_constexpr_(ConstExprContext *ctx, AstTyped *node, u32 offset) {
         break;
     }
 
+    case Ast_Kind_Address_Of: {
+        AstAddressOf *aof = (AstAddressOf *) node;
+        AstNode *expr = strip_aliases((AstNode *) aof->expr);
+        assert(expr->kind == Ast_Kind_Memres);
+
+        DatumPatchInfo patch;
+        patch.kind = Datum_Patch_Data;
+        patch.index = ctx->data_id;
+        patch.location = offset;
+        patch.offset = 0;
+
+        // Here, we cannot use the data_id property of the
+        // memory reservation because there is no guarantee that
+        // it will be assigned yet. And unlike the rest of the
+        // compiler, we cannot yield here, so we simply set a
+        // pointer that will be used later in the linking phase
+        // to get the actual data id of the addressed node.
+        patch.node_to_use_if_data_id_is_null = expr;
+
+        bh_arr_push(ctx->module->data_patches, patch);
+        break;
+    }
+
     case Ast_Kind_NumLit: {
         // NOTE: This makes a big assumption that we are running on a
         // little endian machine, since WebAssembly is little endian
@@ -4643,7 +4666,17 @@ void onyx_wasm_module_link(OnyxWasmModule *module, OnyxWasmLinkOptions *options)
     }
 
     bh_arr_each(DatumPatchInfo, patch, module->data_patches) {
-        assert(patch->data_id > 0);
+        if (patch->data_id == 0) {
+            if (patch->node_to_use_if_data_id_is_null
+                && patch->node_to_use_if_data_id_is_null->kind == Ast_Kind_Memres) {
+
+                patch->data_id = ((AstMemRes *) patch->node_to_use_if_data_id_is_null)->data_id;
+
+            } else {
+                assert(("Unexpected empty data_id in linking!", 0));
+            }
+        }
+
         WasmDatum *datum = &module->data[patch->data_id - 1];
         assert(datum->id == patch->data_id);
 
index 43fa58a371d2ce9fdb9f97990db23c003b271966..34a7dd545ea771d2d2988d3dfd5f830f8583f4ff 100644 (file)
@@ -11,7 +11,7 @@ package core
     #error "'stdio' can only be included in the 'wasi' or 'js' runtime."
 }
 
-stdio_stream: io.Stream;
+stdio_stream: io.Stream = .{ vtable = ^stdio_vtable };
 
 auto_flush_stdio := true
 
@@ -122,10 +122,6 @@ byte_dump :: (ptr: rawptr, byte_count: u32, bytes_per_line := 8) {
 __stdio_init :: () {
     stdio.print_stream = io.buffer_stream_make(2048, context.allocator);
     stdio.print_writer = io.writer_make(^stdio.print_stream, 0);
-    
-    // This shouldn't need to be here, but because ^stdin_vtable is not a compile-time
-    // known value (even through it should be).
-    stdio_stream.vtable = ^stdio_vtable;
 }