diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-04-11 19:33:19 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-04-12 22:23:36 +0200 |
| commit | 370401cf60f70d6b3a2b3f40253f601b0cb8589d (patch) | |
| tree | aeeb0914bb21db5c5aba505bc78ba6aeddd48a9e /src/link | |
| parent | 3c27df6b135f998facce1aa09a9926e840671a05 (diff) | |
| download | zig-370401cf60f70d6b3a2b3f40253f601b0cb8589d.tar.gz zig-370401cf60f70d6b3a2b3f40253f601b0cb8589d.zip | |
wasm: generate unnamed constant for tag
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 639b7f0776..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, @@ -577,7 +582,7 @@ pub fn getOrCreateAtomForDecl(wasm: *Wasm, decl_index: Module.Decl.Index) !Atom. } /// Creates a new empty `Atom` and returns its `Atom.Index` -pub fn createAtom(wasm: *Wasm) !Atom.Index { +fn createAtom(wasm: *Wasm) !Atom.Index { const index = @intCast(Atom.Index, wasm.managed_atoms.items.len); const atom = try wasm.managed_atoms.addOne(wasm.base.allocator); atom.* = Atom.empty; @@ -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, |
