Commit 3819371163

Luuk de Gram <luuk@degram.dev>
2023-06-18 17:50:51
wasm-ld: implement `--export-memory` flag
This flag allows the user to force export the memory to the host environment. This is useful when the memory is imported from the host but must also be exported. This is (currently) required to pass the memory validation for runtimes when using threads. In this future this may become an error instead.
1 parent 7322aa1
Changed files (4)
src/link/Wasm.zig
@@ -4251,6 +4251,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
         man.hash.addOptional(wasm.base.options.stack_size_override);
         man.hash.add(wasm.base.options.build_id);
         man.hash.add(wasm.base.options.import_memory);
+        man.hash.add(wasm.base.options.export_memory);
         man.hash.add(wasm.base.options.import_table);
         man.hash.add(wasm.base.options.export_table);
         man.hash.addOptional(wasm.base.options.initial_memory);
@@ -4338,6 +4339,10 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
             try argv.append("--import-memory");
         }
 
+        if (wasm.base.options.export_memory) {
+            try argv.append("--export-memory");
+        }
+
         if (wasm.base.options.import_table) {
             assert(!wasm.base.options.export_table);
             try argv.append("--import-table");
src/Compilation.zig
@@ -557,6 +557,7 @@ pub const InitOptions = struct {
     linker_allow_shlib_undefined: ?bool = null,
     linker_bind_global_refs_locally: ?bool = null,
     linker_import_memory: ?bool = null,
+    linker_export_memory: ?bool = null,
     linker_import_symbols: bool = false,
     linker_import_table: bool = false,
     linker_export_table: bool = false,
@@ -1463,6 +1464,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
             .module_definition_file = options.linker_module_definition_file,
             .sort_section = options.linker_sort_section,
             .import_memory = options.linker_import_memory orelse false,
+            .export_memory = options.linker_export_memory orelse !(options.linker_import_memory orelse false),
             .import_symbols = options.linker_import_symbols,
             .import_table = options.linker_import_table,
             .export_table = options.linker_export_table,
@@ -2324,6 +2326,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
 
     // WASM specific stuff
     man.hash.add(comp.bin_file.options.import_memory);
+    man.hash.add(comp.bin_file.options.export_memory);
     man.hash.addOptional(comp.bin_file.options.initial_memory);
     man.hash.addOptional(comp.bin_file.options.max_memory);
     man.hash.add(comp.bin_file.options.shared_memory);
src/link.zig
@@ -133,6 +133,7 @@ pub const Options = struct {
     compress_debug_sections: CompressDebugSections,
     bind_global_refs_locally: bool,
     import_memory: bool,
+    export_memory: bool,
     import_symbols: bool,
     import_table: bool,
     export_table: bool,
src/main.zig
@@ -544,6 +544,7 @@ const usage_build_generic =
     \\  -dead_strip                    (Darwin) remove functions and data that are unreachable by the entry point or exported symbols
     \\  -dead_strip_dylibs             (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
     \\  --import-memory                (WebAssembly) import memory from the environment
+    \\  --export-memory                (WebAssembly) export memory to the host (Default unless --import-memory used)
     \\  --import-symbols               (WebAssembly) import missing symbols from the host environment
     \\  --import-table                 (WebAssembly) import function table from the host environment
     \\  --export-table                 (WebAssembly) export function table to the host environment
@@ -787,6 +788,7 @@ fn buildOutputType(
     var linker_allow_shlib_undefined: ?bool = null;
     var linker_bind_global_refs_locally: ?bool = null;
     var linker_import_memory: ?bool = null;
+    var linker_export_memory: ?bool = null;
     var linker_import_symbols: bool = false;
     var linker_import_table: bool = false;
     var linker_export_table: bool = false;
@@ -1419,6 +1421,8 @@ fn buildOutputType(
                         }
                     } else if (mem.eql(u8, arg, "--import-memory")) {
                         linker_import_memory = true;
+                    } else if (mem.eql(u8, arg, "--export-memory")) {
+                        linker_export_memory = true;
                     } else if (mem.eql(u8, arg, "--import-symbols")) {
                         linker_import_symbols = true;
                     } else if (mem.eql(u8, arg, "--import-table")) {
@@ -1982,6 +1986,8 @@ fn buildOutputType(
                     linker_bind_global_refs_locally = true;
                 } else if (mem.eql(u8, arg, "--import-memory")) {
                     linker_import_memory = true;
+                } else if (mem.eql(u8, arg, "--export-memory")) {
+                    linker_export_memory = true;
                 } else if (mem.eql(u8, arg, "--import-symbols")) {
                     linker_import_symbols = true;
                 } else if (mem.eql(u8, arg, "--import-table")) {
@@ -3113,6 +3119,7 @@ fn buildOutputType(
         .linker_allow_shlib_undefined = linker_allow_shlib_undefined,
         .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
         .linker_import_memory = linker_import_memory,
+        .linker_export_memory = linker_export_memory,
         .linker_import_symbols = linker_import_symbols,
         .linker_import_table = linker_import_table,
         .linker_export_table = linker_export_table,