authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-15 16:43:22+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:03+01:00
log12505c6d3d4ccfc859b67e4b43c5b3844bebb475
tree37c53b1a33ebfc4f7f72ad54254b3b4556ee353e
parentf6896ef2180709fedeb5bafde3fe58ca6d06aa3a
signaturelock-open Commit is signed but in an unrecognized format.

wasm: store `File.Index` on the Atom

Also, consolidate the creation of Atoms so they all use `createAtom`.

3 files changed, 44 insertions(+), 67 deletions(-)

src/link/Wasm.zig+12-30
...@@ -569,6 +569,7 @@ pub fn createEmpty(...@@ -569,6 +569,7 @@ pub fn createEmpty(
569 if (!use_llvm) {569 if (!use_llvm) {
570 const index: File.Index = @enumFromInt(wasm.files.len);570 const index: File.Index = @enumFromInt(wasm.files.len);
571 var zig_object: ZigObject = .{571 var zig_object: ZigObject = .{
572 .index = index,
572 .path = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(zcu.main_mod.root_src_path)}),573 .path = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(zcu.main_mod.root_src_path)}),
573 .stack_pointer_sym = undefined,574 .stack_pointer_sym = undefined,
574 };575 };
...@@ -663,12 +664,11 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool {...@@ -663,12 +664,11 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool {
663}664}
664665
665/// Creates a new empty `Atom` and returns its `Atom.Index`666/// Creates a new empty `Atom` and returns its `Atom.Index`
666pub fn createAtom(wasm: *Wasm, sym_index: u32) !Atom.Index {667pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Index {
667 const gpa = wasm.base.comp.gpa;668 const gpa = wasm.base.comp.gpa;
668 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);669 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
669 const atom = try wasm.managed_atoms.addOne(gpa);670 const atom = try wasm.managed_atoms.addOne(gpa);
670 atom.* = Atom.empty;671 atom.* = .{ .file_index = file_index, .sym_index = sym_index };
671 atom.sym_index = sym_index;
672 try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = sym_index }, index);672 try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = sym_index }, index);
673673
674 return index;674 return index;
...@@ -1825,20 +1825,11 @@ fn createSyntheticFunction(...@@ -1825,20 +1825,11 @@ fn createSyntheticFunction(
1825 symbol.index = func_index;1825 symbol.index = func_index;
18261826
1827 // create the atom that will be output into the final binary1827 // create the atom that will be output into the final binary
1828 const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));1828 const atom_index = try wasm.createAtom(loc.index, .null);
1829 const atom = try wasm.managed_atoms.addOne(gpa);1829 const atom = wasm.getAtomPtr(atom_index);
1830 atom.* = .{1830 atom.code = function_body.moveToUnmanaged();
1831 .size = @as(u32, @intCast(function_body.items.len)),1831 atom.size = @intCast(function_body.items.len);
1832 .offset = 0,
1833 .sym_index = loc.index,
1834 .file = null,
1835 .alignment = .@"1",
1836 .prev = null,
1837 .code = function_body.moveToUnmanaged(),
1838 .original_offset = 0,
1839 };
1840 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);1832 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);
1841 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
1842}1833}
18431834
1844/// Unlike `createSyntheticFunction` this function is to be called by1835/// Unlike `createSyntheticFunction` this function is to be called by
...@@ -1856,19 +1847,11 @@ pub fn createFunction(...@@ -1856,19 +1847,11 @@ pub fn createFunction(
1856 const gpa = wasm.base.comp.gpa;1847 const gpa = wasm.base.comp.gpa;
1857 const loc = try wasm.createSyntheticSymbol(symbol_name, .function);1848 const loc = try wasm.createSyntheticSymbol(symbol_name, .function);
18581849
1859 const atom_index: Atom.Index = @intCast(wasm.managed_atoms.items.len);1850 const atom_index = try wasm.createAtom(loc.index, wasm.zig_object_index);
1860 const atom = try wasm.managed_atoms.addOne(gpa);1851 const atom = wasm.getAtomPtr(atom_index);
1861 atom.* = .{1852 atom.code = function_body.moveToUnmanaged();
1862 .size = @intCast(function_body.items.len),1853 atom.relocs = relocations.moveToUnmanaged();
1863 .offset = 0,1854 atom.size = @intCast(function_body.items.len);
1864 .sym_index = loc.index,
1865 .file = null,
1866 .alignment = .@"1",
1867 .prev = null,
1868 .code = function_body.moveToUnmanaged(),
1869 .relocs = relocations.moveToUnmanaged(),
1870 .original_offset = 0,
1871 };
1872 const symbol = loc.getSymbol(wasm);1855 const symbol = loc.getSymbol(wasm);
1873 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported1856 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); // ensure function does not get exported
18741857
...@@ -1878,7 +1861,6 @@ pub fn createFunction(...@@ -1878,7 +1861,6 @@ pub fn createFunction(
1878 break :idx index;1861 break :idx index;
1879 };1862 };
1880 try wasm.appendAtomAtIndex(section_index, atom_index);1863 try wasm.appendAtomAtIndex(section_index, atom_index);
1881 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
1882 try wasm.zigObjectPtr().?.atom_types.put(1864 try wasm.zigObjectPtr().?.atom_types.put(
1883 gpa,1865 gpa,
1884 atom_index,1866 atom_index,
src/link/Wasm/Atom.zig+24-32
...@@ -1,55 +1,36 @@...@@ -1,55 +1,36 @@
1const Atom = @This();1/// Represents the index of the file this atom was generated from.
22/// This is 'null' when the atom was generated by a synthetic linker symbol.
3const std = @import("std");3file: FileIndex,
4const types = @import("types.zig");
5const Wasm = @import("../Wasm.zig");
6const Symbol = @import("Symbol.zig");
7
8const leb = std.leb;
9const log = std.log.scoped(.link);
10const mem = std.mem;
11const Allocator = mem.Allocator;
12
13/// symbol index of the symbol representing this atom4/// symbol index of the symbol representing this atom
14sym_index: u32,5sym_index: u32,
15/// Size of the atom, used to calculate section sizes in the final binary6/// Size of the atom, used to calculate section sizes in the final binary
16size: u32,7size: u32 = 0,
17/// List of relocations belonging to this atom8/// List of relocations belonging to this atom
18relocs: std.ArrayListUnmanaged(types.Relocation) = .{},9relocs: std.ArrayListUnmanaged(types.Relocation) = .{},
19/// Contains the binary data of an atom, which can be non-relocated10/// Contains the binary data of an atom, which can be non-relocated
20code: std.ArrayListUnmanaged(u8) = .{},11code: std.ArrayListUnmanaged(u8) = .{},
21/// For code this is 1, for data this is set to the highest value of all segments12/// For code this is 1, for data this is set to the highest value of all segments
22alignment: Wasm.Alignment,13alignment: Wasm.Alignment = .@"1",
23/// Offset into the section where the atom lives, this already accounts14/// Offset into the section where the atom lives, this already accounts
24/// for alignment.15/// for alignment.
25offset: u32,16offset: u32 = 0,
26/// The original offset within the object file. This value is substracted from17/// The original offset within the object file. This value is substracted from
27/// relocation offsets to determine where in the `data` to rewrite the value18/// relocation offsets to determine where in the `data` to rewrite the value
28original_offset: u32,19original_offset: u32 = 0,
29/// Represents the index of the file this atom was generated from.20/// Next atom in relation to this atom.
30/// This is 'null' when the atom was generated by a Decl from Zig code.21/// When null, this atom is the last atom
31file: ?u16,22next: ?Atom.Index = null,
32/// Previous atom in relation to this atom.23/// Previous atom in relation to this atom.
33/// is null when this atom is the first in its order24/// is null when this atom is the first in its order
34prev: ?Atom.Index,25prev: ?Atom.Index = null,
35/// Contains atoms local to a decl, all managed by this `Atom`.26/// Contains atoms local to a decl, all managed by this `Atom`.
36/// When the parent atom is being freed, it will also do so for all local atoms.27/// When the parent atom is being freed, it will also do so for all local atoms.
37locals: std.ArrayListUnmanaged(Atom.Index) = .{},28locals: std.ArrayListUnmanaged(Atom.Index) = .{},
3829
39/// Alias to an unsigned 32-bit integer30/// Alias to an unsigned 32-bit integer.
31// TODO: Make this a non-exhaustive enum.
40pub const Index = u32;32pub const Index = u32;
4133
42/// Represents a default empty wasm `Atom`
43pub const empty: Atom = .{
44 .alignment = .@"1",
45 .file = null,
46 .offset = 0,
47 .prev = null,
48 .size = 0,
49 .sym_index = 0,
50 .original_offset = 0,
51};
52
53/// Frees all resources owned by this `Atom`.34/// Frees all resources owned by this `Atom`.
54pub fn deinit(atom: *Atom, gpa: std.mem.Allocator) void {35pub fn deinit(atom: *Atom, gpa: std.mem.Allocator) void {
55 atom.relocs.deinit(gpa);36 atom.relocs.deinit(gpa);
...@@ -217,3 +198,14 @@ fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 {...@@ -217,3 +198,14 @@ fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 {
217 }198 }
218 return null;199 return null;
219}200}
201const leb = std.leb;
202const log = std.log.scoped(.link);
203const mem = std.mem;
204const std = @import("std");
205const types = @import("types.zig");
206
207const Allocator = mem.Allocator;
208const Atom = @This();
209const FileIndex = @import("file.zig").File.Index;
210const Symbol = @import("Symbol.zig");
211const Wasm = @import("../Wasm.zig");
src/link/Wasm/ZigObject.zig+8-5
...@@ -4,6 +4,8 @@...@@ -4,6 +4,8 @@
4//! Think about this as fake in-memory Object file for the Zig module.4//! Think about this as fake in-memory Object file for the Zig module.
55
6path: []const u8,6path: []const u8,
7/// Index within the list of relocatable objects of the linker driver.
8index: File.Index,
7/// List of all `Decl` that are currently alive.9/// List of all `Decl` that are currently alive.
8/// Each index maps to the corresponding `Atom.Index`.10/// Each index maps to the corresponding `Atom.Index`.
9decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{},11decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index) = .{},
...@@ -292,7 +294,7 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind...@@ -292,7 +294,7 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
292 const gop = try zig_object.decls.getOrPut(gpa, decl_index);294 const gop = try zig_object.decls.getOrPut(gpa, decl_index);
293 if (!gop.found_existing) {295 if (!gop.found_existing) {
294 const sym_index = try zig_object.allocateSymbol(gpa);296 const sym_index = try zig_object.allocateSymbol(gpa);
295 gop.value_ptr.* = try wasm_file.createAtom(sym_index);297 gop.value_ptr.* = try wasm_file.createAtom(sym_index, zig_object.index);
296 const mod = wasm_file.base.comp.module.?;298 const mod = wasm_file.base.comp.module.?;
297 const decl = mod.declPtr(decl_index);299 const decl = mod.declPtr(decl_index);
298 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));300 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
...@@ -379,7 +381,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty...@@ -379,7 +381,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
379381
380 // Create and initialize a new local symbol and atom382 // Create and initialize a new local symbol and atom
381 const sym_index = try zig_object.allocateSymbol(gpa);383 const sym_index = try zig_object.allocateSymbol(gpa);
382 const atom_index = try wasm_file.createAtom(sym_index);384 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
383 var value_bytes = std.ArrayList(u8).init(gpa);385 var value_bytes = std.ArrayList(u8).init(gpa);
384 defer value_bytes.deinit();386 defer value_bytes.deinit();
385387
...@@ -432,7 +434,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {...@@ -432,7 +434,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
432 // during `flush` when we know all possible error names.434 // during `flush` when we know all possible error names.
433 const gpa = wasm_file.base.comp.gpa;435 const gpa = wasm_file.base.comp.gpa;
434 const sym_index = try zig_object.allocateSymbol(gpa);436 const sym_index = try zig_object.allocateSymbol(gpa);
435 const atom_index = try wasm_file.createAtom(sym_index);437 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
436 const atom = wasm_file.getAtomPtr(atom_index);438 const atom = wasm_file.getAtomPtr(atom_index);
437 const slice_ty = Type.slice_const_u8_sentinel_0;439 const slice_ty = Type.slice_const_u8_sentinel_0;
438 const mod = wasm_file.base.comp.module.?;440 const mod = wasm_file.base.comp.module.?;
...@@ -468,7 +470,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -468,7 +470,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
468 // we create a symbol for the entire region of error names. We then calculate470 // we create a symbol for the entire region of error names. We then calculate
469 // the pointers into the list using addends which are appended to the relocation.471 // the pointers into the list using addends which are appended to the relocation.
470 const names_sym_index = try zig_object.allocateSymbol(gpa);472 const names_sym_index = try zig_object.allocateSymbol(gpa);
471 const names_atom_index = try wasm_file.createAtom(names_sym_index);473 const names_atom_index = try wasm_file.createAtom(names_sym_index, zig_object.index);
472 const names_atom = wasm_file.getAtomPtr(names_atom_index);474 const names_atom = wasm_file.getAtomPtr(names_atom_index);
473 names_atom.alignment = .@"1";475 names_atom.alignment = .@"1";
474 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_names");476 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_names");
...@@ -1087,7 +1089,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde...@@ -1087,7 +1089,7 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm_file: *Wasm, inde
1087 try zig_object.appendDummySegment();1089 try zig_object.appendDummySegment();
10881090
1089 const sym_index = try zig_object.allocateSymbol(gpa);1091 const sym_index = try zig_object.allocateSymbol(gpa);
1090 const atom_index = try wasm_file.createAtom(sym_index);1092 const atom_index = try wasm_file.createAtom(sym_index, zig_object.index);
1091 const atom = wasm_file.getAtomPtr(atom_index);1093 const atom = wasm_file.getAtomPtr(atom_index);
1092 zig_object.symbols.items[sym_index] = .{1094 zig_object.symbols.items[sym_index] = .{
1093 .tag = .section,1095 .tag = .section,
...@@ -1161,6 +1163,7 @@ const types = @import("types.zig");...@@ -1161,6 +1163,7 @@ const types = @import("types.zig");
1161const Air = @import("../../Air.zig");1163const Air = @import("../../Air.zig");
1162const Atom = @import("Atom.zig");1164const Atom = @import("Atom.zig");
1163const Dwarf = @import("../Dwarf.zig");1165const Dwarf = @import("../Dwarf.zig");
1166const File = @import("file.zig").File;
1164const InternPool = @import("../../InternPool.zig");1167const InternPool = @import("../../InternPool.zig");
1165const Liveness = @import("../../Liveness.zig");1168const Liveness = @import("../../Liveness.zig");
1166const Module = @import("../../Module.zig");1169const Module = @import("../../Module.zig");