aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-04-11 19:33:19 +0200
committerLuuk de Gram <luuk@degram.dev>2023-04-12 22:23:36 +0200
commit370401cf60f70d6b3a2b3f40253f601b0cb8589d (patch)
treeaeeb0914bb21db5c5aba505bc78ba6aeddd48a9e /src/link
parent3c27df6b135f998facce1aa09a9926e840671a05 (diff)
downloadzig-370401cf60f70d6b3a2b3f40253f601b0cb8589d.tar.gz
zig-370401cf60f70d6b3a2b3f40253f601b0cb8589d.zip
wasm: generate unnamed constant for tag
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Wasm.zig56
-rw-r--r--src/link/Wasm/Atom.zig2
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,