authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-28 06:31:26+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:24:08+01:00
log196ba706a05046b2209529744d2df47215819691
tree38939524afabc97b9c56bf8f393bc7bc1990e437
parent5ba5a2c133be5e06083f088aa875ff18658fbf8c
signaturelock-open Commit is signed but in an unrecognized format.

wasm: gc fixes and re-enable linker tests

Certain symbols were left unmarked, meaning they would not be emit into the final binary incorrectly. We now mark the synthetic symbols to ensure they are emit as they are already created under the circumstance they're needed for. This also re-enables disabled tests that were left disabled in a previous merge conflict. Lastly, this adds the shared-memory test to the test harnass as it was previously forgotten and therefore regressed.

8 files changed, 117 insertions(+), 95 deletions(-)

src/link/Wasm.zig+38-17
...@@ -11,6 +11,7 @@ const leb = std.leb;...@@ -11,6 +11,7 @@ const leb = std.leb;
11const link = @import("../link.zig");11const link = @import("../link.zig");
12const lldMain = @import("../main.zig").lldMain;12const lldMain = @import("../main.zig").lldMain;
13const log = std.log.scoped(.link);13const log = std.log.scoped(.link);
14const gc_log = std.log.scoped(.gc);
14const mem = std.mem;15const mem = std.mem;
15const trace = @import("../tracy.zig").trace;16const trace = @import("../tracy.zig").trace;
16const types = @import("Wasm/types.zig");17const types = @import("Wasm/types.zig");
...@@ -525,6 +526,7 @@ pub fn createEmpty(...@@ -525,6 +526,7 @@ pub fn createEmpty(
525 const symbol = loc.getSymbol(wasm);526 const symbol = loc.getSymbol(wasm);
526 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);527 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
527 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);528 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
529 symbol.mark();
528 try wasm.wasm_globals.append(gpa, .{530 try wasm.wasm_globals.append(gpa, .{
529 .global_type = .{ .valtype = .i32, .mutable = true },531 .global_type = .{ .valtype = .i32, .mutable = true },
530 .init = .{ .i32_const = undefined },532 .init = .{ .i32_const = undefined },
...@@ -535,6 +537,7 @@ pub fn createEmpty(...@@ -535,6 +537,7 @@ pub fn createEmpty(
535 const symbol = loc.getSymbol(wasm);537 const symbol = loc.getSymbol(wasm);
536 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);538 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
537 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);539 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
540 symbol.mark();
538 try wasm.wasm_globals.append(gpa, .{541 try wasm.wasm_globals.append(gpa, .{
539 .global_type = .{ .valtype = .i32, .mutable = false },542 .global_type = .{ .valtype = .i32, .mutable = false },
540 .init = .{ .i32_const = undefined },543 .init = .{ .i32_const = undefined },
...@@ -545,6 +548,7 @@ pub fn createEmpty(...@@ -545,6 +548,7 @@ pub fn createEmpty(
545 const symbol = loc.getSymbol(wasm);548 const symbol = loc.getSymbol(wasm);
546 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);549 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
547 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);550 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
551 symbol.mark();
548 try wasm.wasm_globals.append(gpa, .{552 try wasm.wasm_globals.append(gpa, .{
549 .global_type = .{ .valtype = .i32, .mutable = false },553 .global_type = .{ .valtype = .i32, .mutable = false },
550 .init = .{ .i32_const = undefined },554 .init = .{ .i32_const = undefined },
...@@ -968,6 +972,8 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {...@@ -968,6 +972,8 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
968 if (!wasm.hasPassiveInitializationSegments()) {972 if (!wasm.hasPassiveInitializationSegments()) {
969 return;973 return;
970 }974 }
975 const sym_loc = try wasm.createSyntheticSymbol("__wasm_init_memory", .function);
976 sym_loc.getSymbol(wasm).mark();
971977
972 const flag_address: u32 = if (shared_memory) address: {978 const flag_address: u32 = if (shared_memory) address: {
973 // when we have passive initialization segments and shared memory979 // when we have passive initialization segments and shared memory
...@@ -1130,7 +1136,8 @@ fn setupTLSRelocationsFunction(wasm: *Wasm) !void {...@@ -1130,7 +1136,8 @@ fn setupTLSRelocationsFunction(wasm: *Wasm) !void {
1130 return;1136 return;
1131 }1137 }
11321138
1133 // const loc = try wasm.createSyntheticSymbol("__wasm_apply_global_tls_relocs");1139 const loc = try wasm.createSyntheticSymbol("__wasm_apply_global_tls_relocs", .function);
1140 loc.getSymbol(wasm).mark();
1134 var function_body = std.ArrayList(u8).init(gpa);1141 var function_body = std.ArrayList(u8).init(gpa);
1135 defer function_body.deinit();1142 defer function_body.deinit();
1136 const writer = function_body.writer();1143 const writer = function_body.writer();
...@@ -1833,8 +1840,7 @@ fn createSyntheticFunction(...@@ -1833,8 +1840,7 @@ fn createSyntheticFunction(
1833 function_body: *std.ArrayList(u8),1840 function_body: *std.ArrayList(u8),
1834) !void {1841) !void {
1835 const gpa = wasm.base.comp.gpa;1842 const gpa = wasm.base.comp.gpa;
1836 const loc = wasm.findGlobalSymbol(symbol_name) orelse1843 const loc = wasm.findGlobalSymbol(symbol_name).?; // forgot to create symbol?
1837 try wasm.createSyntheticSymbol(symbol_name, .function);
1838 const symbol = loc.getSymbol(wasm);1844 const symbol = loc.getSymbol(wasm);
1839 if (symbol.isDead()) {1845 if (symbol.isDead()) {
1840 return;1846 return;
...@@ -1884,6 +1890,9 @@ fn initializeTLSFunction(wasm: *Wasm) !void {...@@ -1884,6 +1890,9 @@ fn initializeTLSFunction(wasm: *Wasm) !void {
18841890
1885 if (!shared_memory) return;1891 if (!shared_memory) return;
18861892
1893 // ensure function is marked as we must emit it
1894 wasm.findGlobalSymbol("__wasm_init_tls").?.getSymbol(wasm).mark();
1895
1887 var function_body = std.ArrayList(u8).init(gpa);1896 var function_body = std.ArrayList(u8).init(gpa);
1888 defer function_body.deinit();1897 defer function_body.deinit();
1889 const writer = function_body.writer();1898 const writer = function_body.writer();
...@@ -1932,6 +1941,7 @@ fn initializeTLSFunction(wasm: *Wasm) !void {...@@ -1932,6 +1941,7 @@ fn initializeTLSFunction(wasm: *Wasm) !void {
1932 if (wasm.findGlobalSymbol("__wasm_apply_global_tls_relocs")) |loc| {1941 if (wasm.findGlobalSymbol("__wasm_apply_global_tls_relocs")) |loc| {
1933 try writer.writeByte(std.wasm.opcode(.call));1942 try writer.writeByte(std.wasm.opcode(.call));
1934 try leb.writeULEB128(writer, loc.getSymbol(wasm).index);1943 try leb.writeULEB128(writer, loc.getSymbol(wasm).index);
1944 loc.getSymbol(wasm).mark();
1935 }1945 }
19361946
1937 try writer.writeByte(std.wasm.opcode(.end));1947 try writer.writeByte(std.wasm.opcode(.end));
...@@ -2039,14 +2049,19 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2039,14 +2049,19 @@ fn mergeSections(wasm: *Wasm) !void {
2039 // We found an alias to the same function, discard this symbol in favor of2049 // We found an alias to the same function, discard this symbol in favor of
2040 // the original symbol and point the discard function to it. This ensures2050 // the original symbol and point the discard function to it. This ensures
2041 // we only emit a single function, instead of duplicates.2051 // we only emit a single function, instead of duplicates.
2042 symbol.unmark();2052 // we favor keeping the global over a local.
2043 try wasm.discarded.putNoClobber(2053 const original_loc: SymbolLoc = .{ .file = gop.key_ptr.file, .index = gop.value_ptr.sym_index };
2044 gpa,2054 const original_sym = original_loc.getSymbol(wasm);
2045 sym_loc,2055 if (original_sym.isLocal() and symbol.isGlobal()) {
2046 .{ .file = gop.key_ptr.*.file, .index = gop.value_ptr.*.sym_index },2056 original_sym.unmark();
2047 );2057 try wasm.discarded.put(gpa, original_loc, sym_loc);
2048 try removed_duplicates.append(sym_loc);2058 try removed_duplicates.append(original_loc);
2049 continue;2059 } else {
2060 symbol.unmark();
2061 try wasm.discarded.putNoClobber(gpa, sym_loc, original_loc);
2062 try removed_duplicates.append(sym_loc);
2063 continue;
2064 }
2050 }2065 }
2051 gop.value_ptr.* = .{ .func = obj_file.function(sym_loc.index), .sym_index = sym_loc.index };2066 gop.value_ptr.* = .{ .func = obj_file.function(sym_loc.index), .sym_index = sym_loc.index };
2052 symbol.index = @as(u32, @intCast(gop.index)) + wasm.imported_functions_count;2067 symbol.index = @as(u32, @intCast(gop.index)) + wasm.imported_functions_count;
...@@ -2073,6 +2088,7 @@ fn mergeSections(wasm: *Wasm) !void {...@@ -2073,6 +2088,7 @@ fn mergeSections(wasm: *Wasm) !void {
2073 // For any removed duplicates, remove them from the resolved symbols list2088 // For any removed duplicates, remove them from the resolved symbols list
2074 for (removed_duplicates.items) |sym_loc| {2089 for (removed_duplicates.items) |sym_loc| {
2075 assert(wasm.resolved_symbols.swapRemove(sym_loc));2090 assert(wasm.resolved_symbols.swapRemove(sym_loc));
2091 gc_log.debug("Removed duplicate for function '{s}'", .{sym_loc.getName(wasm)});
2076 }2092 }
20772093
2078 log.debug("Merged ({d}) functions", .{wasm.functions.count()});2094 log.debug("Merged ({d}) functions", .{wasm.functions.count()});
...@@ -2119,12 +2135,7 @@ fn mergeTypes(wasm: *Wasm) !void {...@@ -2119,12 +2135,7 @@ fn mergeTypes(wasm: *Wasm) !void {
2119 log.debug("Completed merging and deduplicating types. Total count: ({d})", .{wasm.func_types.items.len});2135 log.debug("Completed merging and deduplicating types. Total count: ({d})", .{wasm.func_types.items.len});
2120}2136}
21212137
2122fn setupExports(wasm: *Wasm) !void {2138fn checkExportNames(wasm: *Wasm) !void {
2123 const comp = wasm.base.comp;
2124 const gpa = comp.gpa;
2125 if (comp.config.output_mode == .Obj) return;
2126 log.debug("Building exports from symbols", .{});
2127
2128 const force_exp_names = wasm.export_symbol_names;2139 const force_exp_names = wasm.export_symbol_names;
2129 if (force_exp_names.len > 0) {2140 if (force_exp_names.len > 0) {
2130 var failed_exports = false;2141 var failed_exports = false;
...@@ -2144,6 +2155,13 @@ fn setupExports(wasm: *Wasm) !void {...@@ -2144,6 +2155,13 @@ fn setupExports(wasm: *Wasm) !void {
2144 return error.FlushFailure;2155 return error.FlushFailure;
2145 }2156 }
2146 }2157 }
2158}
2159
2160fn setupExports(wasm: *Wasm) !void {
2161 const comp = wasm.base.comp;
2162 const gpa = comp.gpa;
2163 if (comp.config.output_mode == .Obj) return;
2164 log.debug("Building exports from symbols", .{});
21472165
2148 for (wasm.resolved_symbols.keys()) |sym_loc| {2166 for (wasm.resolved_symbols.keys()) |sym_loc| {
2149 const symbol = sym_loc.getSymbol(wasm);2167 const symbol = sym_loc.getSymbol(wasm);
...@@ -2272,6 +2290,7 @@ fn setupMemory(wasm: *Wasm) !void {...@@ -2272,6 +2290,7 @@ fn setupMemory(wasm: *Wasm) !void {
2272 memory_ptr = mem.alignForward(u64, memory_ptr, 4);2290 memory_ptr = mem.alignForward(u64, memory_ptr, 4);
2273 const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data);2291 const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data);
2274 const sym = loc.getSymbol(wasm);2292 const sym = loc.getSymbol(wasm);
2293 sym.mark();
2275 sym.virtual_address = @as(u32, @intCast(memory_ptr));2294 sym.virtual_address = @as(u32, @intCast(memory_ptr));
2276 memory_ptr += 4;2295 memory_ptr += 4;
2277 }2296 }
...@@ -2561,6 +2580,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node)...@@ -2561,6 +2580,7 @@ pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node)
2561 if (comp.link_errors.items.len > 0) return error.FlushFailure;2580 if (comp.link_errors.items.len > 0) return error.FlushFailure;
2562 try wasm.resolveLazySymbols();2581 try wasm.resolveLazySymbols();
2563 try wasm.checkUndefinedSymbols();2582 try wasm.checkUndefinedSymbols();
2583 try wasm.checkExportNames();
25642584
2565 try wasm.setupInitFunctions();2585 try wasm.setupInitFunctions();
2566 if (comp.link_errors.items.len > 0) return error.FlushFailure;2586 if (comp.link_errors.items.len > 0) return error.FlushFailure;
...@@ -4044,6 +4064,7 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {...@@ -4044,6 +4064,7 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {
4044 return;4064 return;
4045 }4065 }
4046 symbol.mark();4066 symbol.mark();
4067 gc_log.debug("Marked symbol '{s}'", .{loc.getName(wasm)});
4047 if (symbol.isUndefined()) {4068 if (symbol.isUndefined()) {
4048 // undefined symbols do not have an associated `Atom` and therefore also4069 // undefined symbols do not have an associated `Atom` and therefore also
4049 // do not contain relocations.4070 // do not contain relocations.
src/link/Wasm/Object.zig+1-1
...@@ -15,7 +15,7 @@ const Allocator = std.mem.Allocator;...@@ -15,7 +15,7 @@ const Allocator = std.mem.Allocator;
15const leb = std.leb;15const leb = std.leb;
16const meta = std.meta;16const meta = std.meta;
1717
18const log = std.log.scoped(.link);18const log = std.log.scoped(.object);
1919
20/// Index into the list of relocatable object files within the linker driver.20/// Index into the list of relocatable object files within the linker driver.
21index: File.Index = .null,21index: File.Index = .null,
src/link/Wasm/ZigObject.zig+6-4
...@@ -315,7 +315,7 @@ fn finishUpdateDecl(...@@ -315,7 +315,7 @@ fn finishUpdateDecl(
315 const atom_index = decl_info.atom;315 const atom_index = decl_info.atom;
316 const atom = wasm_file.getAtomPtr(atom_index);316 const atom = wasm_file.getAtomPtr(atom_index);
317 const sym = zig_object.symbol(atom.sym_index);317 const sym = zig_object.symbol(atom.sym_index);
318 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));318 const full_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
319 sym.name = try zig_object.string_table.insert(gpa, full_name);319 sym.name = try zig_object.string_table.insert(gpa, full_name);
320 try atom.code.appendSlice(gpa, code);320 try atom.code.appendSlice(gpa, code);
321 atom.size = @intCast(code.len);321 atom.size = @intCast(code.len);
...@@ -401,7 +401,7 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind...@@ -401,7 +401,7 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
401 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };401 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
402 const mod = wasm_file.base.comp.module.?;402 const mod = wasm_file.base.comp.module.?;
403 const decl = mod.declPtr(decl_index);403 const decl = mod.declPtr(decl_index);
404 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));404 const full_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
405 const sym = zig_object.symbol(sym_index);405 const sym = zig_object.symbol(sym_index);
406 sym.name = try zig_object.string_table.insert(gpa, full_name);406 sym.name = try zig_object.string_table.insert(gpa, full_name);
407 }407 }
...@@ -455,7 +455,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu...@@ -455,7 +455,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
455 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);455 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
456 const parent_atom = wasm_file.getAtom(parent_atom_index);456 const parent_atom = wasm_file.getAtom(parent_atom_index);
457 const local_index = parent_atom.locals.items.len;457 const local_index = parent_atom.locals.items.len;
458 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));458 const fqn = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
459 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{459 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{
460 fqn, local_index,460 fqn, local_index,
461 });461 });
...@@ -838,6 +838,7 @@ pub fn updateExports(...@@ -838,6 +838,7 @@ pub fn updateExports(
838 const atom = wasm_file.getAtom(atom_index);838 const atom = wasm_file.getAtom(atom_index);
839 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;839 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
840 const gpa = mod.gpa;840 const gpa = mod.gpa;
841 log.debug("Updating exports for decl '{s}'", .{mod.intern_pool.stringToSlice(decl.name)});
841842
842 for (exports) |exp| {843 for (exports) |exp| {
843 if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section| {844 if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section| {
...@@ -888,6 +889,7 @@ pub fn updateExports(...@@ -888,6 +889,7 @@ pub fn updateExports(
888 if (exp.opts.visibility == .hidden) {889 if (exp.opts.visibility == .hidden) {
889 sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);890 sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
890 }891 }
892 log.debug(" with name '{s}' - {}", .{ export_string, sym });
891 try zig_object.global_syms.put(gpa, export_name, sym_index);893 try zig_object.global_syms.put(gpa, export_name, sym_index);
892 try wasm_file.symbol_atom.put(gpa, .{ .file = zig_object.index, .index = sym_index }, atom_index);894 try wasm_file.symbol_atom.put(gpa, .{ .file = zig_object.index, .index = sym_index }, atom_index);
893 }895 }
...@@ -1061,7 +1063,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde...@@ -1061,7 +1063,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde
1061pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {1063pub fn updateDeclLineNumber(zig_object: *ZigObject, mod: *Module, decl_index: InternPool.DeclIndex) !void {
1062 if (zig_object.dwarf) |*dw| {1064 if (zig_object.dwarf) |*dw| {
1063 const decl = mod.declPtr(decl_index);1065 const decl = mod.declPtr(decl_index);
1064 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));1066 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
10651067
1066 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });1068 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
1067 try dw.updateDeclLineNumber(mod, decl_index);1069 try dw.updateDeclLineNumber(mod, decl_index);
test/link.zig+12-10
...@@ -35,11 +35,10 @@ pub const cases = [_]Case{...@@ -35,11 +35,10 @@ pub const cases = [_]Case{
35 },35 },
3636
37 // WASM Cases37 // WASM Cases
38 // https://github.com/ziglang/zig/issues/1693838 .{
39 //.{39 .build_root = "test/link/wasm/archive",
40 // .build_root = "test/link/wasm/archive",40 .import = @import("link/wasm/archive/build.zig"),
41 // .import = @import("link/wasm/archive/build.zig"),41 },
42 //},
43 .{42 .{
44 .build_root = "test/link/wasm/basic-features",43 .build_root = "test/link/wasm/basic-features",
45 .import = @import("link/wasm/basic-features/build.zig"),44 .import = @import("link/wasm/basic-features/build.zig"),
...@@ -52,11 +51,10 @@ pub const cases = [_]Case{...@@ -52,11 +51,10 @@ pub const cases = [_]Case{
52 .build_root = "test/link/wasm/export",51 .build_root = "test/link/wasm/export",
53 .import = @import("link/wasm/export/build.zig"),52 .import = @import("link/wasm/export/build.zig"),
54 },53 },
55 // https://github.com/ziglang/zig/issues/1693754 .{
56 //.{55 .build_root = "test/link/wasm/export-data",
57 // .build_root = "test/link/wasm/export-data",56 .import = @import("link/wasm/export-data/build.zig"),
58 // .import = @import("link/wasm/export-data/build.zig"),57 },
59 //},
60 .{58 .{
61 .build_root = "test/link/wasm/extern",59 .build_root = "test/link/wasm/extern",
62 .import = @import("link/wasm/extern/build.zig"),60 .import = @import("link/wasm/extern/build.zig"),
...@@ -81,6 +79,10 @@ pub const cases = [_]Case{...@@ -81,6 +79,10 @@ pub const cases = [_]Case{
81 .build_root = "test/link/wasm/segments",79 .build_root = "test/link/wasm/segments",
82 .import = @import("link/wasm/segments/build.zig"),80 .import = @import("link/wasm/segments/build.zig"),
83 },81 },
82 .{
83 .build_root = "test/link/wasm/shared-memory",
84 .import = @import("link/wasm/shared-memory/build.zig"),
85 },
84 .{86 .{
85 .build_root = "test/link/wasm/stack_pointer",87 .build_root = "test/link/wasm/stack_pointer",
86 .import = @import("link/wasm/stack_pointer/build.zig"),88 .import = @import("link/wasm/stack_pointer/build.zig"),
test/link/wasm/archive/build.zig+2-1
...@@ -19,12 +19,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize...@@ -19,12 +19,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
19 .name = "main",19 .name = "main",
20 .root_source_file = .{ .path = "main.zig" },20 .root_source_file = .{ .path = "main.zig" },
21 .optimize = optimize,21 .optimize = optimize,
22 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },22 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
23 .strip = false,23 .strip = false,
24 });24 });
25 lib.entry = .disabled;25 lib.entry = .disabled;
26 lib.use_llvm = false;26 lib.use_llvm = false;
27 lib.use_lld = false;27 lib.use_lld = false;
28 lib.root_module.export_symbol_names = &.{"foo"};
2829
29 const check = lib.checkObject();30 const check = lib.checkObject();
30 check.checkInHeaders();31 check.checkInHeaders();
test/link/wasm/export-data/build.zig+1-1
...@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {...@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
13 .name = "lib",13 .name = "lib",
14 .root_source_file = .{ .path = "lib.zig" },14 .root_source_file = .{ .path = "lib.zig" },
15 .optimize = .ReleaseSafe, // to make the output deterministic in address positions15 .optimize = .ReleaseSafe, // to make the output deterministic in address positions
16 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },16 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
17 });17 });
18 lib.entry = .disabled;18 lib.entry = .disabled;
19 lib.use_lld = false;19 lib.use_lld = false;
test/link/wasm/shared-memory/build.zig+40-45
...@@ -11,37 +11,39 @@ pub fn build(b: *std.Build) void {...@@ -11,37 +11,39 @@ pub fn build(b: *std.Build) void {
11}11}
1212
13fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode) void {13fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode) void {
14 const lib = b.addExecutable(.{14 const exe = b.addExecutable(.{
15 .name = "lib",15 .name = "lib",
16 .root_source_file = .{ .path = "lib.zig" },16 .root_source_file = .{ .path = "lib.zig" },
17 .target = .{17 .target = b.resolveTargetQuery(.{
18 .cpu_arch = .wasm32,18 .cpu_arch = .wasm32,
19 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },19 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
20 .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }),20 .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }),
21 .os_tag = .freestanding,21 .os_tag = .freestanding,
22 },22 }),
23 .optimize = optimize_mode,23 .optimize = optimize_mode,
24 .strip = false,24 .strip = false,
25 .single_threaded = false,25 .single_threaded = false,
26 });26 });
27 lib.entry = .disabled;27 exe.entry = .disabled;
28 lib.use_lld = false;28 exe.use_lld = false;
29 lib.import_memory = true;29 exe.import_memory = true;
30 lib.export_memory = true;30 exe.export_memory = true;
31 lib.shared_memory = true;31 exe.shared_memory = true;
32 lib.max_memory = 67108864;32 exe.max_memory = 67108864;
33 lib.root_module.export_symbol_names = &.{"foo"};33 exe.root_module.export_symbol_names = &.{"foo"};
3434
35 const check_lib = lib.checkObject();35 const check_exe = exe.checkObject();
3636
37 check_lib.checkStart("Section import");37 check_exe.checkInHeaders();
38 check_lib.checkNext("entries 1");38 check_exe.checkExact("Section import");
39 check_lib.checkNext("module env");39 check_exe.checkExact("entries 1");
40 check_lib.checkNext("name memory"); // ensure we are importing memory40 check_exe.checkExact("module env");
41 check_exe.checkExact("name memory"); // ensure we are importing memory
4142
42 check_lib.checkStart("Section export");43 check_exe.checkInHeaders();
43 check_lib.checkNext("entries 2");44 check_exe.checkExact("Section export");
44 check_lib.checkNext("name memory"); // ensure we also export memory again45 check_exe.checkExact("entries 2");
46 check_exe.checkExact("name memory"); // ensure we also export memory again
4547
46 // This section *must* be emit as the start function is set to the index48 // This section *must* be emit as the start function is set to the index
47 // of __wasm_init_memory49 // of __wasm_init_memory
...@@ -49,49 +51,42 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt...@@ -49,49 +51,42 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
49 // This means we won't have __wasm_init_memory in such case, and therefore51 // This means we won't have __wasm_init_memory in such case, and therefore
50 // should also not have a section "start"52 // should also not have a section "start"
51 if (optimize_mode == .Debug) {53 if (optimize_mode == .Debug) {
52 check_lib.checkStart("Section start");54 check_exe.checkInHeaders();
55 check_exe.checkExact("Section start");
53 }56 }
5457
55 // This section is only and *must* be emit when shared-memory is enabled58 // This section is only and *must* be emit when shared-memory is enabled
56 // release modes will have the TLS segment optimized out in our test-case.59 // release modes will have the TLS segment optimized out in our test-case.
57 if (optimize_mode == .Debug) {60 if (optimize_mode == .Debug) {
58 check_lib.checkStart("Section data_count");61 check_exe.checkInHeaders();
59 check_lib.checkNext("count 3");62 check_exe.checkExact("Section data_count");
63 check_exe.checkExact("count 1");
60 }64 }
6165
62 check_lib.checkStart("Section custom");66 check_exe.checkInHeaders();
63 check_lib.checkNext("name name");67 check_exe.checkExact("Section custom");
64 check_lib.checkNext("type function");68 check_exe.checkExact("name name");
69 check_exe.checkExact("type function");
65 if (optimize_mode == .Debug) {70 if (optimize_mode == .Debug) {
66 check_lib.checkNext("name __wasm_init_memory");71 check_exe.checkExact("name __wasm_init_memory");
67 }72 }
68 check_lib.checkNext("name __wasm_init_tls");73 check_exe.checkExact("name __wasm_init_tls");
69 check_lib.checkNext("type global");74 check_exe.checkExact("type global");
7075
71 // In debug mode the symbol __tls_base is resolved to an undefined symbol76 // In debug mode the symbol __tls_base is resolved to an undefined symbol
72 // from the object file, hence its placement differs than in release modes77 // from the object file, hence its placement differs than in release modes
73 // where the entire tls segment is optimized away, and tls_base will have78 // where the entire tls segment is optimized away, and tls_base will have
74 // its original position.79 // its original position.
75 if (optimize_mode == .Debug) {80 check_exe.checkExact("name __tls_base");
76 check_lib.checkNext("name __tls_size");81 check_exe.checkExact("name __tls_size");
77 check_lib.checkNext("name __tls_align");82 check_exe.checkExact("name __tls_align");
78 check_lib.checkNext("name __tls_base");
79 } else {
80 check_lib.checkNext("name __tls_base");
81 check_lib.checkNext("name __tls_size");
82 check_lib.checkNext("name __tls_align");
83 }
8483
85 check_lib.checkNext("type data_segment");84 check_exe.checkExact("type data_segment");
86 if (optimize_mode == .Debug) {85 if (optimize_mode == .Debug) {
87 check_lib.checkNext("names 3");86 check_exe.checkExact("names 1");
88 check_lib.checkNext("index 0");87 check_exe.checkExact("index 0");
89 check_lib.checkNext("name .rodata");88 check_exe.checkExact("name .tdata");
90 check_lib.checkNext("index 1");
91 check_lib.checkNext("name .bss");
92 check_lib.checkNext("index 2");
93 check_lib.checkNext("name .tdata");
94 }89 }
9590
96 test_step.dependOn(&check_lib.step);91 test_step.dependOn(&check_exe.step);
97}92}
test/link/wasm/type/build.zig+17-16
...@@ -13,31 +13,32 @@ pub fn build(b: *std.Build) void {...@@ -13,31 +13,32 @@ pub fn build(b: *std.Build) void {
13}13}
1414
15fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {15fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const lib = b.addExecutable(.{16 const exe = b.addExecutable(.{
17 .name = "lib",17 .name = "lib",
18 .root_source_file = .{ .path = "lib.zig" },18 .root_source_file = .{ .path = "lib.zig" },
19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
20 .optimize = optimize,20 .optimize = optimize,
21 .strip = false,21 .strip = false,
22 });22 });
23 lib.entry = .disabled;23 exe.entry = .disabled;
24 lib.use_llvm = false;24 exe.use_llvm = false;
25 lib.use_lld = false;25 exe.use_lld = false;
26 b.installArtifact(lib);26 exe.root_module.export_symbol_names = &.{"foo"};
27 b.installArtifact(exe);
2728
28 const check_lib = lib.checkObject();29 const check_exe = exe.checkObject();
29 check_lib.checkInHeaders();30 check_exe.checkInHeaders();
30 check_lib.checkExact("Section type");31 check_exe.checkExact("Section type");
31 // only 2 entries, although we have more functions.32 // only 2 entries, although we have more functions.
32 // This is to test functions with the same function signature33 // This is to test functions with the same function signature
33 // have their types deduplicated.34 // have their types deduplicated.
34 check_lib.checkExact("entries 2");35 check_exe.checkExact("entries 2");
35 check_lib.checkExact("params 1");36 check_exe.checkExact("params 1");
36 check_lib.checkExact("type i32");37 check_exe.checkExact("type i32");
37 check_lib.checkExact("returns 1");38 check_exe.checkExact("returns 1");
38 check_lib.checkExact("type i64");39 check_exe.checkExact("type i64");
39 check_lib.checkExact("params 0");40 check_exe.checkExact("params 0");
40 check_lib.checkExact("returns 0");41 check_exe.checkExact("returns 0");
4142
42 test_step.dependOn(&check_lib.step);43 test_step.dependOn(&check_exe.step);
43}44}