diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-04-13 19:32:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-13 19:32:22 +0200 |
| commit | 25e3851fe0f7fe254b48c2242ab8d4ef89165fd5 (patch) | |
| tree | c7991ec10945496de6dcb8f8aae32d12c077ecd6 /src/link | |
| parent | fbcf1c0006dc6656deb3f04e2f52d1da4a599952 (diff) | |
| parent | abc1e52e0885c8e46d743d5e48ba260b35ae2769 (diff) | |
| download | zig-25e3851fe0f7fe254b48c2242ab8d4ef89165fd5.tar.gz zig-25e3851fe0f7fe254b48c2242ab8d4ef89165fd5.zip | |
Merge pull request #15257 from Luukdegram/wasm-tagname
wasm: Implement `@tagName` instruction
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 56 | ||||
| -rw-r--r-- | src/link/Wasm/Atom.zig | 2 |
2 files changed, 56 insertions, 2 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index b1fc25bf26..2125a8faaa 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -30,6 +30,7 @@ const Symbol = @import("Wasm/Symbol.zig"); const Object = @import("Wasm/Object.zig"); const Archive = @import("Wasm/Archive.zig"); const types = @import("Wasm/types.zig"); +pub const Relocation = types.Relocation; pub const base_tag: link.File.Tag = .wasm; @@ -178,6 +179,10 @@ debug_str_atom: ?Atom.Index = null, debug_pubnames_atom: ?Atom.Index = null, debug_pubtypes_atom: ?Atom.Index = null, +/// List of atom indexes of functions that are generated by the backend, +/// rather than by the linker. +synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{}, + pub const Segment = struct { alignment: u32, size: u32, @@ -1208,7 +1213,7 @@ fn resolveLazySymbols(wasm: *Wasm) !void { // Tries to find a global symbol by its name. Returns null when not found, /// and its location when it is found. -fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc { +pub fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc { const offset = wasm.string_table.getOffset(name) orelse return null; return wasm.globals.get(offset); } @@ -1287,6 +1292,7 @@ pub fn deinit(wasm: *Wasm) void { wasm.exports.deinit(gpa); wasm.string_table.deinit(gpa); + wasm.synthetic_functions.deinit(gpa); if (wasm.dwarf) |*dwarf| { dwarf.deinit(); @@ -2272,6 +2278,49 @@ fn createSyntheticFunction( atom.offset = prev_atom.offset + prev_atom.size; } +/// Unlike `createSyntheticFunction` this function is to be called by +/// the codegeneration backend. This will not allocate the created Atom yet, +/// but will instead be appended to `synthetic_functions` list and will be +/// parsed at the end of code generation. +/// Returns the index of the symbol. +pub fn createFunction( + wasm: *Wasm, + symbol_name: []const u8, + func_ty: std.wasm.Type, + function_body: *std.ArrayList(u8), + relocations: *std.ArrayList(Relocation), +) !u32 { + const loc = try wasm.createSyntheticSymbol(symbol_name, .function); + + const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len); + const atom = try wasm.managed_atoms.addOne(wasm.base.allocator); + atom.* = .{ + .size = @intCast(u32, function_body.items.len), + .offset = 0, + .sym_index = loc.index, + .file = null, + .alignment = 1, + .next = null, + .prev = null, + .code = function_body.moveToUnmanaged(), + .relocs = relocations.moveToUnmanaged(), + }; + const symbol = loc.getSymbol(wasm); + symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported + + const section_index = wasm.code_section_index orelse idx: { + const index = @intCast(u32, wasm.segments.items.len); + try wasm.appendDummySegment(); + break :idx index; + }; + try wasm.appendAtomAtIndex(section_index, atom_index); + try wasm.symbol_atom.putNoClobber(wasm.base.allocator, loc, atom_index); + try wasm.atom_types.put(wasm.base.allocator, atom_index, try wasm.putOrGetFuncType(func_ty)); + try wasm.synthetic_functions.append(wasm.base.allocator, atom_index); + + return loc.index; +} + fn initializeTLSFunction(wasm: *Wasm) !void { if (!wasm.base.options.shared_memory) return; @@ -3306,6 +3355,11 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod } } + // also parse any backend-generated functions + for (wasm.synthetic_functions.items) |atom_index| { + try wasm.parseAtom(atom_index, .function); + } + if (wasm.dwarf) |*dwarf| { try dwarf.flushModule(wasm.base.options.module.?); } diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index 7d2f5a6696..f8092c6db1 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -43,7 +43,7 @@ pub const Index = u32; /// Represents a default empty wasm `Atom` pub const empty: Atom = .{ - .alignment = 0, + .alignment = 1, .file = null, .next = null, .offset = 0, |
