authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-09 16:36:09+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:24:07+01:00
log5ef832133895fd69fc8378463b86759eaab6913a
tree08bc27cd8f20de4c928ca0bdc411b6c8d59be465
parentc99ef23862573269ae4052bd2236f9803f9e36a2
signaturelock-open Commit is signed but in an unrecognized format.

wasm: make symbol indexes a non-exhaustive enum

This introduces some type safety so we cannot accidently give an atom index as a symbol index. This also means we do not have to store any optionals and therefore allow for memory optimizations. Lastly, we can now always simply access the symbol index of an atom, rather than having to call `getSymbolIndex` as it is easy to forget.

7 files changed, 141 insertions(+), 143 deletions(-)

src/arch/wasm/CodeGen.zig+14-12
......@@ -1286,8 +1286,9 @@ fn genFunc(func: *CodeGen) InnerError!void {
12861286 var prologue = std.ArrayList(Mir.Inst).init(func.gpa);
12871287 defer prologue.deinit();
12881288
1289 const sp = @intFromEnum(func.bin_file.zigObjectPtr().?.stack_pointer_sym);
12891290 // load stack pointer
1290 try prologue.append(.{ .tag = .global_get, .data = .{ .label = 0 } });
1291 try prologue.append(.{ .tag = .global_get, .data = .{ .label = sp } });
12911292 // store stack pointer so we can restore it when we return from the function
12921293 try prologue.append(.{ .tag = .local_tee, .data = .{ .label = func.initial_stack_value.local.value } });
12931294 // get the total stack size
......@@ -1303,7 +1304,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
13031304 try prologue.append(.{ .tag = .local_tee, .data = .{ .label = func.bottom_stack_value.local.value } });
13041305 // Store the current stack pointer value into the global stack pointer so other function calls will
13051306 // start from this value instead and not overwrite the current stack.
1306 try prologue.append(.{ .tag = .global_set, .data = .{ .label = 0 } });
1307 try prologue.append(.{ .tag = .global_set, .data = .{ .label = sp } });
13071308
13081309 // reserve space and insert all prologue instructions at the front of the instruction list
13091310 // We insert them in reserve order as there is no insertSlice in multiArrayList.
......@@ -1502,7 +1503,7 @@ fn restoreStackPointer(func: *CodeGen) !void {
15021503 try func.emitWValue(func.initial_stack_value);
15031504
15041505 // save its value in the global stack pointer
1505 try func.addLabel(.global_set, 0);
1506 try func.addLabel(.global_set, @intFromEnum(func.bin_file.zigObjectPtr().?.stack_pointer_sym));
15061507}
15071508
15081509/// From a given type, will create space on the virtual stack to store the value of such type.
......@@ -2205,7 +2206,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22052206 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
22062207 try func.bin_file.addOrUpdateImport(
22072208 mod.intern_pool.stringToSlice(ext_decl.name),
2208 atom.getSymbolIndex().?,
2209 atom.sym_index,
22092210 mod.intern_pool.stringToSliceUnwrap(ext_decl.getOwnedExternFunc(mod).?.lib_name),
22102211 type_index,
22112212 );
......@@ -2240,7 +2241,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22402241
22412242 if (callee) |direct| {
22422243 const atom_index = func.bin_file.zigObjectPtr().?.decls_map.get(direct).?.atom;
2243 try func.addLabel(.call, func.bin_file.getAtom(atom_index).sym_index);
2244 try func.addLabel(.call, @intFromEnum(func.bin_file.getAtom(atom_index).sym_index));
22442245 } else {
22452246 // in this case we call a function pointer
22462247 // so load its value onto the stack
......@@ -3158,7 +3159,7 @@ fn lowerAnonDeclRef(
31583159 },
31593160 }
31603161 const target_atom_index = func.bin_file.zigObjectPtr().?.anon_decls.get(decl_val).?;
3161 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;
3162 const target_sym_index = @intFromEnum(func.bin_file.getAtom(target_atom_index).sym_index);
31623163 if (is_fn_body) {
31633164 return WValue{ .function_index = target_sym_index };
31643165 } else if (offset == 0) {
......@@ -3189,7 +3190,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl
31893190 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
31903191 const atom = func.bin_file.getAtom(atom_index);
31913192
3192 const target_sym_index = atom.sym_index;
3193 const target_sym_index = @intFromEnum(atom.sym_index);
31933194 if (decl.ty.zigTypeTag(mod) == .Fn) {
31943195 return WValue{ .function_index = target_sym_index };
31953196 } else if (offset == 0) {
......@@ -3711,7 +3712,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37113712 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
37123713 const operand = try func.resolveInst(un_op);
37133714 const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
3714 const errors_len = WValue{ .memory = sym_index };
3715 const errors_len = WValue{ .memory = @intFromEnum(sym_index) };
37153716
37163717 try func.emitWValue(operand);
37173718 const mod = func.bin_file.base.comp.module.?;
......@@ -7153,7 +7154,7 @@ fn callIntrinsic(
71537154 args: []const WValue,
71547155) InnerError!WValue {
71557156 assert(param_types.len == args.len);
7156 const symbol_index = func.bin_file.base.getGlobalSymbol(name, null) catch |err| {
7157 const symbol_index = func.bin_file.getGlobalSymbol(name, null) catch |err| {
71577158 return func.fail("Could not find or create global symbol '{s}'", .{@errorName(err)});
71587159 };
71597160
......@@ -7181,7 +7182,7 @@ fn callIntrinsic(
71817182 }
71827183
71837184 // Actually call our intrinsic
7184 try func.addLabel(.call, symbol_index);
7185 try func.addLabel(.call, @intFromEnum(symbol_index));
71857186
71867187 if (!return_type.hasRuntimeBitsIgnoreComptime(mod)) {
71877188 return WValue.none;
......@@ -7224,7 +7225,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
72247225
72257226 // check if we already generated code for this.
72267227 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
7227 return loc.index;
7228 return @intFromEnum(loc.index);
72287229 }
72297230
72307231 const int_tag_ty = enum_ty.intTagType(mod);
......@@ -7364,7 +7365,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
73647365
73657366 const slice_ty = Type.slice_const_u8_sentinel_0;
73667367 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, mod);
7367 return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
7368 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
7369 return @intFromEnum(sym_index);
73687370}
73697371
73707372fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
src/link/Wasm.zig+40-37
......@@ -127,7 +127,7 @@ func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},
127127/// This allows us to map multiple symbols to the same function.
128128functions: std.AutoArrayHashMapUnmanaged(
129129 struct { file: File.Index, index: u32 },
130 struct { func: std.wasm.Func, sym_index: u32 },
130 struct { func: std.wasm.Func, sym_index: Symbol.Index },
131131) = .{},
132132/// Output global section
133133wasm_globals: std.ArrayListUnmanaged(std.wasm.Global) = .{},
......@@ -208,13 +208,9 @@ pub const Segment = struct {
208208 }
209209};
210210
211pub const Export = struct {
212 sym_index: ?u32 = null,
213};
214
215211pub const SymbolLoc = struct {
216212 /// The index of the symbol within the specified file
217 index: u32,
213 index: Symbol.Index,
218214 /// The index of the object file where the symbol resides.
219215 file: File.Index,
220216
......@@ -226,7 +222,7 @@ pub const SymbolLoc = struct {
226222 if (wasm_file.file(loc.file)) |obj_file| {
227223 return obj_file.symbol(loc.index);
228224 }
229 return &wasm_file.synthetic_symbols.items[loc.index];
225 return &wasm_file.synthetic_symbols.items[@intFromEnum(loc.index)];
230226 }
231227
232228 /// From a given location, returns the name of the symbol.
......@@ -237,7 +233,8 @@ pub const SymbolLoc = struct {
237233 if (wasm_file.file(loc.file)) |obj_file| {
238234 return obj_file.symbolName(loc.index);
239235 }
240 return wasm_file.string_table.get(wasm_file.synthetic_symbols.items[loc.index].name);
236 const sym = wasm_file.synthetic_symbols.items[@intFromEnum(loc.index)];
237 return wasm_file.string_table.get(sym.name);
241238 }
242239
243240 /// From a given symbol location, returns the final location.
......@@ -272,7 +269,7 @@ pub const InitFuncLoc = struct {
272269
273270 /// Turns the given `InitFuncLoc` into a `SymbolLoc`
274271 fn getSymbolLoc(loc: InitFuncLoc) SymbolLoc {
275 return .{ .file = loc.file, .index = loc.index };
272 return .{ .file = loc.file, .index = @enumFromInt(loc.index) };
276273 }
277274
278275 /// Returns true when `lhs` has a higher priority (e.i. value closer to 0) than `rhs`.
......@@ -566,7 +563,7 @@ pub fn createEmpty(
566563 var zig_object: ZigObject = .{
567564 .index = index,
568565 .path = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(zcu.main_mod.root_src_path)}),
569 .stack_pointer_sym = undefined,
566 .stack_pointer_sym = .null,
570567 };
571568 try zig_object.init(wasm);
572569 try wasm.files.append(gpa, .{ .zig_object = zig_object });
......@@ -607,7 +604,7 @@ pub fn addOrUpdateImport(
607604 /// Name of the import
608605 name: []const u8,
609606 /// Symbol index that is external
610 symbol_index: u32,
607 symbol_index: Symbol.Index,
611608 /// Optional library name (i.e. `extern "c" fn foo() void`
612609 lib_name: ?[:0]const u8,
613610 /// The index of the type that represents the function signature
......@@ -627,7 +624,7 @@ fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !Symbol
627624}
628625
629626fn createSyntheticSymbolOffset(wasm: *Wasm, name_offset: u32, tag: Symbol.Tag) !SymbolLoc {
630 const sym_index = @as(u32, @intCast(wasm.synthetic_symbols.items.len));
627 const sym_index: Symbol.Index = @enumFromInt(wasm.synthetic_symbols.items.len);
631628 const loc: SymbolLoc = .{ .index = sym_index, .file = .null };
632629 const gpa = wasm.base.comp.gpa;
633630 try wasm.synthetic_symbols.append(gpa, .{
......@@ -670,9 +667,9 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool {
670667}
671668
672669/// Creates a new empty `Atom` and returns its `Atom.Index`
673pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Index {
670pub fn createAtom(wasm: *Wasm, sym_index: Symbol.Index, file_index: File.Index) !Atom.Index {
674671 const gpa = wasm.base.comp.gpa;
675 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
672 const index: Atom.Index = @enumFromInt(wasm.managed_atoms.items.len);
676673 const atom = try wasm.managed_atoms.addOne(gpa);
677674 atom.* = .{ .file = file_index, .sym_index = sym_index };
678675 try wasm.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), index);
......@@ -681,11 +678,11 @@ pub fn createAtom(wasm: *Wasm, sym_index: u32, file_index: File.Index) !Atom.Ind
681678}
682679
683680pub inline fn getAtom(wasm: *const Wasm, index: Atom.Index) Atom {
684 return wasm.managed_atoms.items[index];
681 return wasm.managed_atoms.items[@intFromEnum(index)];
685682}
686683
687684pub inline fn getAtomPtr(wasm: *Wasm, index: Atom.Index) *Atom {
688 return &wasm.managed_atoms.items[index];
685 return &wasm.managed_atoms.items[@intFromEnum(index)];
689686}
690687
691688/// Parses an archive file and will then parse each object file
......@@ -757,7 +754,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, file_index: File.Index) !void {
757754 log.debug("Resolving symbols in object: '{s}'", .{obj_file.path()});
758755
759756 for (obj_file.symbols(), 0..) |symbol, i| {
760 const sym_index: u32 = @intCast(i);
757 const sym_index: Symbol.Index = @enumFromInt(i);
761758 const location: SymbolLoc = .{ .file = file_index, .index = sym_index };
762759 const sym_name = obj_file.string(symbol.name);
763760 if (mem.eql(u8, sym_name, "__indirect_function_table")) {
......@@ -1489,7 +1486,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
14891486/// such as an exported or imported symbol.
14901487/// If the symbol does not yet exist, creates a new one symbol instead
14911488/// and then returns the index to it.
1492pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 {
1489pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Symbol.Index {
14931490 _ = lib_name;
14941491 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);
14951492}
......@@ -1609,19 +1606,20 @@ fn allocateAtoms(wasm: *Wasm) !void {
16091606 const sym = if (wasm.file(symbol_loc.file)) |obj_file|
16101607 obj_file.symbol(symbol_loc.index).*
16111608 else
1612 wasm.synthetic_symbols.items[symbol_loc.index];
1609 wasm.synthetic_symbols.items[@intFromEnum(symbol_loc.index)];
16131610
16141611 // Dead symbols must be unlinked from the linked-list to prevent them
16151612 // from being emit into the binary.
16161613 if (sym.isDead()) {
1617 if (entry.value_ptr.* == atom_index and atom.prev != null) {
1614 if (entry.value_ptr.* == atom_index and atom.prev != .null) {
16181615 // When the atom is dead and is also the first atom retrieved from wasm.atoms(index) we update
16191616 // the entry to point it to the previous atom to ensure we do not start with a dead symbol that
16201617 // was removed and therefore do not emit any code at all.
1621 entry.value_ptr.* = atom.prev.?;
1618 entry.value_ptr.* = atom.prev;
16221619 }
1623 atom_index = atom.prev orelse break;
1624 atom.prev = null;
1620 if (atom.prev == .null) break;
1621 atom_index = atom.prev;
1622 atom.prev = .null;
16251623 continue;
16261624 }
16271625 offset = @intCast(atom.alignment.forward(offset));
......@@ -1633,7 +1631,8 @@ fn allocateAtoms(wasm: *Wasm) !void {
16331631 atom.size,
16341632 });
16351633 offset += atom.size;
1636 atom_index = atom.prev orelse break;
1634 if (atom.prev == .null) break;
1635 atom_index = atom.prev;
16371636 }
16381637 segment.size = @intCast(segment.alignment.forward(offset));
16391638 }
......@@ -1738,7 +1737,7 @@ fn setupInitFunctions(wasm: *Wasm) !void {
17381737 .file = file_index,
17391738 .priority = init_func.priority,
17401739 });
1741 try wasm.mark(.{ .index = init_func.symbol_index, .file = file_index });
1740 try wasm.mark(.{ .index = @enumFromInt(init_func.symbol_index), .file = file_index });
17421741 }
17431742 }
17441743
......@@ -1844,7 +1843,7 @@ pub fn createFunction(
18441843 func_ty: std.wasm.Type,
18451844 function_body: *std.ArrayList(u8),
18461845 relocations: *std.ArrayList(Relocation),
1847) !u32 {
1846) !Symbol.Index {
18481847 return wasm.zigObjectPtr().?.createFunction(wasm, symbol_name, func_ty, function_body, relocations);
18491848}
18501849
......@@ -2324,11 +2323,11 @@ fn setupMemory(wasm: *Wasm) !void {
23242323/// From a given object's index and the index of the segment, returns the corresponding
23252324/// index of the segment within the final data section. When the segment does not yet
23262325/// exist, a new one will be initialized and appended. The new index will be returned in that case.
2327pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: u32) !u32 {
2326pub fn getMatchingSegment(wasm: *Wasm, file_index: File.Index, symbol_index: Symbol.Index) !u32 {
23282327 const comp = wasm.base.comp;
23292328 const gpa = comp.gpa;
23302329 const obj_file = wasm.file(file_index).?;
2331 const symbol = obj_file.symbols()[symbol_index];
2330 const symbol = obj_file.symbols()[@intFromEnum(symbol_index)];
23322331 const index: u32 = @intCast(wasm.segments.items.len);
23332332 const shared_memory = comp.config.shared_memory;
23342333
......@@ -2889,8 +2888,8 @@ fn writeToFile(
28892888 try binary_writer.writeAll(atom.code.items);
28902889
28912890 current_offset += atom.size;
2892 if (atom.prev) |prev| {
2893 atom_index = prev;
2891 if (atom.prev != .null) {
2892 atom_index = atom.prev;
28942893 } else {
28952894 // also pad with zeroes when last atom to ensure
28962895 // segments are aligned.
......@@ -2984,7 +2983,8 @@ fn writeToFile(
29842983 while (true) {
29852984 atom.resolveRelocs(wasm);
29862985 try debug_bytes.appendSlice(atom.code.items);
2987 atom = if (atom.prev) |prev| wasm.getAtomPtr(prev) else break;
2986 if (atom.prev == .null) break;
2987 atom = wasm.getAtomPtr(atom.prev);
29882988 }
29892989 try emitDebugSection(&binary_bytes, debug_bytes.items, item.name);
29902990 debug_bytes.clearRetainingCapacity();
......@@ -3853,7 +3853,7 @@ fn emitCodeRelocations(
38533853 size_offset += getULEB128Size(atom.size);
38543854 for (atom.relocs.items) |relocation| {
38553855 count += 1;
3856 const sym_loc: SymbolLoc = .{ .file = atom.file, .index = relocation.index };
3856 const sym_loc: SymbolLoc = .{ .file = atom.file, .index = @enumFromInt(relocation.index) };
38573857 const symbol_index = symbol_table.get(sym_loc).?;
38583858 try leb.writeULEB128(writer, @intFromEnum(relocation.relocation_type));
38593859 const offset = atom.offset + relocation.offset + size_offset;
......@@ -3864,7 +3864,8 @@ fn emitCodeRelocations(
38643864 }
38653865 log.debug("Emit relocation: {}", .{relocation});
38663866 }
3867 atom = if (atom.prev) |prev| wasm.getAtomPtr(prev) else break;
3867 if (atom.prev == .null) break;
3868 atom = wasm.getAtomPtr(atom.prev);
38683869 }
38693870 if (count == 0) return;
38703871 var buf: [5]u8 = undefined;
......@@ -3900,7 +3901,7 @@ fn emitDataRelocations(
39003901 size_offset += getULEB128Size(atom.size);
39013902 for (atom.relocs.items) |relocation| {
39023903 count += 1;
3903 const sym_loc: SymbolLoc = .{ .file = atom.file, .index = relocation.index };
3904 const sym_loc: SymbolLoc = .{ .file = atom.file, .index = @enumFromInt(relocation.index) };
39043905 const symbol_index = symbol_table.get(sym_loc).?;
39053906 try leb.writeULEB128(writer, @intFromEnum(relocation.relocation_type));
39063907 const offset = atom.offset + relocation.offset + size_offset;
......@@ -3911,7 +3912,8 @@ fn emitDataRelocations(
39113912 }
39123913 log.debug("Emit relocation: {}", .{relocation});
39133914 }
3914 atom = if (atom.prev) |prev| wasm.getAtomPtr(prev) else break;
3915 if (atom.prev == .null) break;
3916 atom = wasm.getAtomPtr(atom.prev);
39153917 }
39163918 }
39173919 if (count == 0) return;
......@@ -3969,7 +3971,8 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s
39693971///
39703972/// When the symbol does not yet exist, it will create a new one instead.
39713973pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 {
3972 return wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file);
3974 const sym_index = try wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file);
3975 return @intFromEnum(sym_index);
39733976}
39743977
39753978/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
......@@ -4029,7 +4032,7 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {
40294032
40304033 const atom = wasm.getAtom(atom_index);
40314034 for (atom.relocs.items) |reloc| {
4032 const target_loc: SymbolLoc = .{ .index = reloc.index, .file = loc.file };
4035 const target_loc: SymbolLoc = .{ .index = @enumFromInt(reloc.index), .file = loc.file };
40334036 try wasm.mark(target_loc.finalLoc(wasm));
40344037 }
40354038}
src/link/Wasm/Atom.zig+13-17
......@@ -2,7 +2,7 @@
22/// This is 'null' when the atom was generated by a synthetic linker symbol.
33file: FileIndex,
44/// symbol index of the symbol representing this atom
5sym_index: u32,
5sym_index: Symbol.Index,
66/// Size of the atom, used to calculate section sizes in the final binary
77size: u32 = 0,
88/// List of relocations belonging to this atom
......@@ -17,19 +17,19 @@ offset: u32 = 0,
1717/// The original offset within the object file. This value is substracted from
1818/// relocation offsets to determine where in the `data` to rewrite the value
1919original_offset: u32 = 0,
20/// Next atom in relation to this atom.
21/// When null, this atom is the last atom
22next: ?Atom.Index = null,
2320/// Previous atom in relation to this atom.
2421/// is null when this atom is the first in its order
25prev: ?Atom.Index = null,
22prev: Atom.Index = .null,
2623/// Contains atoms local to a decl, all managed by this `Atom`.
2724/// When the parent atom is being freed, it will also do so for all local atoms.
2825locals: std.ArrayListUnmanaged(Atom.Index) = .{},
2926
30/// Alias to an unsigned 32-bit integer.
31// TODO: Make this a non-exhaustive enum.
32pub const Index = u32;
27/// Represents the index of an Atom where `null` is considered
28/// an invalid atom.
29pub const Index = enum(u32) {
30 null = std.math.maxInt(u32),
31 _,
32};
3333
3434/// Frees all resources owned by this `Atom`.
3535pub fn deinit(atom: *Atom, gpa: std.mem.Allocator) void {
......@@ -50,7 +50,7 @@ pub fn format(atom: Atom, comptime fmt: []const u8, options: std.fmt.FormatOptio
5050 _ = fmt;
5151 _ = options;
5252 try writer.print("Atom{{ .sym_index = {d}, .alignment = {d}, .size = {d}, .offset = 0x{x:0>8} }}", .{
53 atom.sym_index,
53 @intFromEnum(atom.sym_index),
5454 atom.alignment,
5555 atom.size,
5656 atom.offset,
......@@ -62,11 +62,6 @@ pub fn symbolLoc(atom: Atom) Wasm.SymbolLoc {
6262 return .{ .file = atom.file, .index = atom.sym_index };
6363}
6464
65pub fn getSymbolIndex(atom: Atom) ?u32 {
66 if (atom.sym_index == 0) return null;
67 return atom.sym_index;
68}
69
7065/// Resolves the relocations within the atom, writing the new value
7166/// at the calculated offset.
7267pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
......@@ -80,7 +75,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
8075 for (atom.relocs.items) |reloc| {
8176 const value = atom.relocationValue(reloc, wasm_bin);
8277 log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{
83 (Wasm.SymbolLoc{ .file = atom.file, .index = reloc.index }).getName(wasm_bin),
78 (Wasm.SymbolLoc{ .file = atom.file, .index = @enumFromInt(reloc.index) }).getName(wasm_bin),
8479 symbol_name,
8580 reloc.offset,
8681 value,
......@@ -119,7 +114,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
119114/// All values will be represented as a `u64` as all values can fit within it.
120115/// The final value must be casted to the correct size.
121116fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
122 const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin);
117 const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = @enumFromInt(relocation.index) }).finalLoc(wasm_bin);
123118 const symbol = target_loc.getSymbol(wasm_bin);
124119 if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and
125120 symbol.tag != .section and
......@@ -135,7 +130,7 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
135130 .R_WASM_TABLE_INDEX_I64,
136131 .R_WASM_TABLE_INDEX_SLEB,
137132 .R_WASM_TABLE_INDEX_SLEB64,
138 => return wasm_bin.function_table.get(.{ .file = atom.file, .index = relocation.index }) orelse 0,
133 => return wasm_bin.function_table.get(.{ .file = atom.file, .index = @enumFromInt(relocation.index) }) orelse 0,
139134 .R_WASM_TYPE_INDEX_LEB => {
140135 const obj_file = wasm_bin.file(atom.file) orelse return relocation.index;
141136 const original_type = obj_file.funcTypes()[relocation.index];
......@@ -195,6 +190,7 @@ fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 {
195190 }
196191 return null;
197192}
193
198194const leb = std.leb;
199195const log = std.log.scoped(.link);
200196const mem = std.mem;
src/link/Wasm/Object.zig+4-4
......@@ -907,10 +907,10 @@ fn assertEnd(reader: anytype) !void {
907907}
908908
909909/// Parses an object file into atoms, for code and data sections
910pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Atom.Index {
910pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: Symbol.Index) !Atom.Index {
911911 const comp = wasm.base.comp;
912912 const gpa = comp.gpa;
913 const symbol = &object.symtable[symbol_index];
913 const symbol = &object.symtable[@intFromEnum(symbol_index)];
914914 const relocatable_data: RelocatableData = switch (symbol.tag) {
915915 .function => object.relocatable_data.get(.code).?[symbol.index - object.imported_functions_count],
916916 .data => object.relocatable_data.get(.data).?[symbol.index],
......@@ -953,7 +953,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato
953953 => {
954954 try wasm.function_table.put(gpa, .{
955955 .file = object.index,
956 .index = reloc.index,
956 .index = @enumFromInt(reloc.index),
957957 }, 0);
958958 },
959959 .R_WASM_GLOBAL_INDEX_I32,
......@@ -961,7 +961,7 @@ pub fn parseSymbolIntoAtom(object: *Object, wasm: *Wasm, symbol_index: u32) !Ato
961961 => {
962962 const sym = object.symtable[reloc.index];
963963 if (sym.tag != .global) {
964 try wasm.got_symbols.append(gpa, .{ .file = object.index, .index = reloc.index });
964 try wasm.got_symbols.append(gpa, .{ .file = object.index, .index = @enumFromInt(reloc.index) });
965965 }
966966 },
967967 else => {},
src/link/Wasm/Symbol.zig+11-5
......@@ -1,12 +1,8 @@
1//! Represents a wasm symbol. Containing all of its properties,
1//! Represents a WebAssembly symbol. Containing all of its properties,
22//! as well as providing helper methods to determine its functionality
33//! and how it will/must be linked.
44//! The name of the symbol can be found by providing the offset, found
55//! on the `name` field, to a string table in the wasm binary or object file.
6const Symbol = @This();
7
8const std = @import("std");
9const types = @import("types.zig");
106
117/// Bitfield containings flags for a symbol
128/// Can contain any of the flags defined in `Flag`
......@@ -24,6 +20,12 @@ tag: Tag,
2420/// This differs from the offset of an `Atom` which is relative to the start of a segment.
2521virtual_address: u32,
2622
23/// Represents a symbol index where `null` represents an invalid index.
24pub const Index = enum(u32) {
25 null,
26 _,
27};
28
2729pub const Tag = enum {
2830 function,
2931 data,
......@@ -202,3 +204,7 @@ pub fn format(symbol: Symbol, comptime fmt: []const u8, options: std.fmt.FormatO
202204 .{ kind_fmt, binding, visible, symbol.index, symbol.name, undef },
203205 );
204206}
207
208const std = @import("std");
209const types = @import("types.zig");
210const Symbol = @This();
src/link/Wasm/ZigObject.zig+47-56
......@@ -17,7 +17,7 @@ functions: std.ArrayListUnmanaged(std.wasm.Func) = .{},
1717/// List of indexes pointing to an entry within the `functions` list which has been removed.
1818functions_free_list: std.ArrayListUnmanaged(u32) = .{},
1919/// Map of symbol locations, represented by its `types.Import`.
20imports: std.AutoHashMapUnmanaged(u32, types.Import) = .{},
20imports: std.AutoHashMapUnmanaged(Symbol.Index, types.Import) = .{},
2121/// List of WebAssembly globals.
2222globals: std.ArrayListUnmanaged(std.wasm.Global) = .{},
2323/// Mapping between an `Atom` and its type index representing the Wasm
......@@ -26,9 +26,9 @@ atom_types: std.AutoHashMapUnmanaged(Atom.Index, u32) = .{},
2626/// List of all symbols generated by Zig code.
2727symbols: std.ArrayListUnmanaged(Symbol) = .{},
2828/// Map from symbol name offset to their index into the `symbols` list.
29global_syms: std.AutoHashMapUnmanaged(u32, u32) = .{},
29global_syms: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
3030/// List of symbol indexes which are free to be used.
31symbols_free_list: std.ArrayListUnmanaged(u32) = .{},
31symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{},
3232/// Extra metadata about the linking section, such as alignment of segments and their name.
3333segment_info: std.ArrayListUnmanaged(types.Segment) = .{},
3434/// List of indexes which contain a free slot in the `segment_info` list.
......@@ -42,7 +42,7 @@ anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
4242/// During initializion, a symbol with corresponding atom will be created that is
4343/// used to perform relocations to the pointer of this table.
4444/// The actual table is populated during `flush`.
45error_table_symbol: ?u32 = null,
45error_table_symbol: Symbol.Index = .null,
4646/// Amount of functions in the `import` sections.
4747imported_functions_count: u32 = 0,
4848/// Amount of globals in the `import` section.
......@@ -50,7 +50,7 @@ imported_globals_count: u32 = 0,
5050/// Symbol index representing the stack pointer. This will be set upon initializion
5151/// of a new `ZigObject`. Codegen will make calls into this to create relocations for
5252/// this symbol each time the stack pointer is moved.
53stack_pointer_sym: u32,
53stack_pointer_sym: Symbol.Index,
5454/// Debug information for the Zig module.
5555dwarf: ?Dwarf = null,
5656// Debug section atoms. These are only set when the current compilation
......@@ -83,10 +83,10 @@ debug_str_index: ?u32 = null,
8383debug_abbrev_index: ?u32 = null,
8484
8585const DeclInfo = struct {
86 atom: Atom.Index = std.math.maxInt(Atom.Index),
87 exports: std.ArrayListUnmanaged(u32) = .{},
86 atom: Atom.Index = .null,
87 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
8888
89 fn @"export"(di: DeclInfo, zig_object: *const ZigObject, name: []const u8) ?u32 {
89 fn @"export"(di: DeclInfo, zig_object: *const ZigObject, name: []const u8) ?Symbol.Index {
9090 for (di.exports.items) |sym_index| {
9191 const sym_name_index = zig_object.symbol(sym_index).name;
9292 const sym_name = zig_object.string_table.getAssumeExists(sym_name_index);
......@@ -97,11 +97,11 @@ const DeclInfo = struct {
9797 return null;
9898 }
9999
100 fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: u32) !void {
100 fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: Symbol.Index) !void {
101101 return di.exports.append(gpa, sym_index);
102102 }
103103
104 fn deleteExport(di: *DeclInfo, sym_index: u32) void {
104 fn deleteExport(di: *DeclInfo, sym_index: Symbol.Index) void {
105105 for (di.exports.items, 0..) |idx, index| {
106106 if (idx == sym_index) {
107107 _ = di.exports.swapRemove(index);
......@@ -138,8 +138,8 @@ fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {
138138 zig_object.stack_pointer_sym = sym_index;
139139}
140140
141fn symbol(zig_object: *const ZigObject, index: u32) *Symbol {
142 return &zig_object.symbols.items[index];
141fn symbol(zig_object: *const ZigObject, index: Symbol.Index) *Symbol {
142 return &zig_object.symbols.items[@intFromEnum(index)];
143143}
144144
145145/// Frees and invalidates all memory of the incrementally compiled Zig module.
......@@ -192,7 +192,7 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
192192
193193/// Allocates a new symbol and returns its index.
194194/// Will re-use slots when a symbol was freed at an earlier stage.
195pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
195pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.Index {
196196 try zig_object.symbols.ensureUnusedCapacity(gpa, 1);
197197 const sym: Symbol = .{
198198 .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls
......@@ -202,10 +202,10 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
202202 .virtual_address = std.math.maxInt(u32), // will be set during atom allocation
203203 };
204204 if (zig_object.symbols_free_list.popOrNull()) |index| {
205 zig_object.symbols.items[index] = sym;
205 zig_object.symbols.items[@intFromEnum(index)] = sym;
206206 return index;
207207 }
208 const index = @as(u32, @intCast(zig_object.symbols.items.len));
208 const index: Symbol.Index = @enumFromInt(zig_object.symbols.items.len);
209209 zig_object.symbols.appendAssumeCapacity(sym);
210210 return index;
211211}
......@@ -247,7 +247,7 @@ pub fn updateDecl(
247247 .{ .ty = decl.ty, .val = val },
248248 &code_writer,
249249 .none,
250 .{ .parent_atom_index = atom.sym_index },
250 .{ .parent_atom_index = @intFromEnum(atom.sym_index) },
251251 );
252252
253253 const code = switch (res) {
......@@ -464,7 +464,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
464464 switch (try zig_object.lowerConst(wasm_file, name, tv, decl.srcLoc(mod))) {
465465 .ok => |atom_index| {
466466 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
467 return wasm_file.getAtom(atom_index).getSymbolIndex().?;
467 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
468468 },
469469 .fail => |em| {
470470 decl.analysis = .codegen_failure;
......@@ -494,7 +494,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
494494 atom.alignment = tv.ty.abiAlignment(mod);
495495 const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name });
496496 errdefer gpa.free(segment_name);
497 zig_object.symbols.items[sym_index] = .{
497 zig_object.symbol(sym_index).* = .{
498498 .name = try zig_object.string_table.insert(gpa, name),
499499 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
500500 .tag = .data,
......@@ -513,7 +513,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
513513 &value_bytes,
514514 .none,
515515 .{
516 .parent_atom_index = atom.sym_index,
516 .parent_atom_index = @intFromEnum(atom.sym_index),
517517 .addend = null,
518518 },
519519 );
......@@ -534,9 +534,9 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
534534/// Returns the symbol index of the error name table.
535535///
536536/// When the symbol does not yet exist, it will create a new one instead.
537pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
538 if (zig_object.error_table_symbol) |sym| {
539 return sym;
537pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !Symbol.Index {
538 if (zig_object.error_table_symbol != .null) {
539 return zig_object.error_table_symbol;
540540 }
541541
542542 // no error was referenced yet, so create a new symbol and atom for it
......@@ -561,7 +561,7 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
561561 .virtual_address = undefined,
562562 };
563563
564 log.debug("Error name table was created with symbol index: ({d})", .{sym_index});
564 log.debug("Error name table was created with symbol index: ({d})", .{@intFromEnum(sym_index)});
565565 zig_object.error_table_symbol = sym_index;
566566 return sym_index;
567567}
......@@ -571,9 +571,9 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
571571/// This creates a table that consists of pointers and length to each error name.
572572/// The table is what is being pointed to within the runtime bodies that are generated.
573573fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
574 const symbol_index = zig_object.error_table_symbol orelse return;
574 if (zig_object.error_table_symbol == .null) return;
575575 const gpa = wasm_file.base.comp.gpa;
576 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = symbol_index }).?;
576 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol }).?;
577577
578578 // Rather than creating a symbol for each individual error name,
579579 // we create a symbol for the entire region of error names. We then calculate
......@@ -584,7 +584,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
584584 names_atom.alignment = .@"1";
585585 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_names");
586586 const segment_name = try gpa.dupe(u8, ".rodata.__zig_err_names");
587 const names_symbol = &zig_object.symbols.items[names_sym_index];
587 const names_symbol = zig_object.symbol(names_sym_index);
588588 names_symbol.* = .{
589589 .name = sym_name,
590590 .tag = .data,
......@@ -611,7 +611,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
611611 try atom.code.writer(gpa).writeInt(u32, len - 1, .little);
612612 // create relocation to the error name
613613 try atom.relocs.append(gpa, .{
614 .index = names_atom.sym_index,
614 .index = @intFromEnum(names_atom.sym_index),
615615 .relocation_type = .R_WASM_MEMORY_ADDR_I32,
616616 .offset = offset,
617617 .addend = @as(i32, @intCast(addend)),
......@@ -638,7 +638,7 @@ pub fn addOrUpdateImport(
638638 /// Name of the import
639639 name: []const u8,
640640 /// Symbol index that is external
641 symbol_index: u32,
641 symbol_index: Symbol.Index,
642642 /// Optional library name (i.e. `extern "c" fn foo() void`
643643 lib_name: ?[:0]const u8,
644644 /// The index of the type that represents the function signature
......@@ -647,7 +647,7 @@ pub fn addOrUpdateImport(
647647 type_index: ?u32,
648648) !void {
649649 const gpa = wasm_file.base.comp.gpa;
650 std.debug.assert(symbol_index != 0);
650 std.debug.assert(symbol_index != .null);
651651 // For the import name, we use the decl's name, rather than the fully qualified name
652652 // Also mangle the name when the lib name is set and not equal to "C" so imports with the same
653653 // name but different module can be resolved correctly.
......@@ -659,7 +659,7 @@ pub fn addOrUpdateImport(
659659 defer if (mangle_name) gpa.free(full_name);
660660
661661 const decl_name_index = try zig_object.string_table.insert(gpa, full_name);
662 const sym: *Symbol = &zig_object.symbols.items[symbol_index];
662 const sym: *Symbol = &zig_object.symbols.items[@intFromEnum(symbol_index)];
663663 sym.setUndefined(true);
664664 sym.setGlobal(true);
665665 sym.name = decl_name_index;
......@@ -689,7 +689,7 @@ pub fn addOrUpdateImport(
689689/// such as an exported or imported symbol.
690690/// If the symbol does not yet exist, creates a new one symbol instead
691691/// and then returns the index to it.
692pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []const u8) !u32 {
692pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []const u8) !Symbol.Index {
693693 const name_index = try zig_object.string_table.insert(gpa, name);
694694 const gop = try zig_object.global_syms.getOrPut(gpa, name_index);
695695 if (gop.found_existing) {
......@@ -707,12 +707,12 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
707707 sym.setUndefined(true);
708708
709709 const sym_index = if (zig_object.symbols_free_list.popOrNull()) |index| index else blk: {
710 const index: u32 = @intCast(zig_object.symbols.items.len);
710 const index: Symbol.Index = @enumFromInt(zig_object.symbols.items.len);
711711 try zig_object.symbols.ensureUnusedCapacity(gpa, 1);
712712 zig_object.symbols.items.len += 1;
713713 break :blk index;
714714 };
715 zig_object.symbols.items[sym_index] = sym;
715 zig_object.symbol(sym_index).* = sym;
716716 gop.value_ptr.* = sym_index;
717717 return sym_index;
718718}
......@@ -731,10 +731,10 @@ pub fn getDeclVAddr(
731731 const decl = mod.declPtr(decl_index);
732732
733733 const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
734 const target_symbol_index = wasm_file.getAtom(target_atom_index).sym_index;
734 const target_symbol_index = @intFromEnum(wasm_file.getAtom(target_atom_index).sym_index);
735735
736736 std.debug.assert(reloc_info.parent_atom_index != 0);
737 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = reloc_info.parent_atom_index }).?;
737 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
738738 const atom = wasm_file.getAtomPtr(atom_index);
739739 const is_wasm32 = target.cpu.arch == .wasm32;
740740 if (decl.ty.zigTypeTag(mod) == .Fn) {
......@@ -769,9 +769,9 @@ pub fn getAnonDeclVAddr(
769769 const gpa = wasm_file.base.comp.gpa;
770770 const target = wasm_file.base.comp.root_mod.resolved_target.result;
771771 const atom_index = zig_object.anon_decls.get(decl_val).?;
772 const target_symbol_index = wasm_file.getAtom(atom_index).getSymbolIndex().?;
772 const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
773773
774 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = reloc_info.parent_atom_index }).?;
774 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
775775 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);
776776 const is_wasm32 = target.cpu.arch == .wasm32;
777777 const mod = wasm_file.base.comp.module.?;
......@@ -930,17 +930,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
930930 // dwarf.freeDecl(decl_index);
931931 // }
932932
933 if (atom.next) |next_atom_index| {
934 const next_atom = wasm_file.getAtomPtr(next_atom_index);
935 next_atom.prev = atom.prev;
936 atom.next = null;
937 }
938 if (atom.prev) |prev_index| {
939 const prev_atom = wasm_file.getAtomPtr(prev_index);
940 prev_atom.next = atom.next;
941 atom.prev = null;
942 }
943
933 atom.prev = null;
944934 sym.tag = .dead;
945935 if (sym.isGlobal()) {
946936 std.debug.assert(zig_object.global_syms.remove(atom.sym_index));
......@@ -998,7 +988,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
998988 // if not, allcoate a new atom.
999989 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {
1000990 const atom = wasm_file.getAtomPtr(index);
1001 atom.prev = null;
991 atom.prev = .null;
1002992 atom.deinit(gpa);
1003993 break :blk index;
1004994 } else idx: {
......@@ -1022,7 +1012,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
10221012 try atom.code.writer(gpa).writeInt(u16, @intCast(errors_len), .little);
10231013}
10241014
1025fn findGlobalSymbol(zig_object: *ZigObject, name: []const u8) ?u32 {
1015fn findGlobalSymbol(zig_object: *ZigObject, name: []const u8) ?Symbol.Index {
10261016 const offset = zig_object.string_table.getOffset(name) orelse return null;
10271017 return zig_object.global_syms.get(offset);
10281018}
......@@ -1121,7 +1111,7 @@ pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index:
11211111/// The symbols in ZigObject are already represented by an atom as we need to store its data.
11221112/// So rather than creating a new Atom and returning its index, we use this oppertunity to scan
11231113/// its relocations and create any GOT symbols or function table indexes it may require.
1124pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) !Atom.Index {
1114pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: Symbol.Index) !Atom.Index {
11251115 const gpa = wasm_file.base.comp.gpa;
11261116 const loc: Wasm.SymbolLoc = .{ .file = zig_object.index, .index = index };
11271117 const atom_index = wasm_file.symbol_atom.get(loc).?;
......@@ -1129,6 +1119,7 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)
11291119 try wasm_file.appendAtomAtIndex(final_index, atom_index);
11301120 const atom = wasm_file.getAtom(atom_index);
11311121 for (atom.relocs.items) |reloc| {
1122 const reloc_index: Symbol.Index = @enumFromInt(reloc.index);
11321123 switch (reloc.relocation_type) {
11331124 .R_WASM_TABLE_INDEX_I32,
11341125 .R_WASM_TABLE_INDEX_I64,
......@@ -1137,17 +1128,17 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)
11371128 => {
11381129 try wasm_file.function_table.put(gpa, .{
11391130 .file = zig_object.index,
1140 .index = reloc.index,
1131 .index = reloc_index,
11411132 }, 0);
11421133 },
11431134 .R_WASM_GLOBAL_INDEX_I32,
11441135 .R_WASM_GLOBAL_INDEX_LEB,
11451136 => {
1146 const sym = zig_object.symbol(reloc.index);
1137 const sym = zig_object.symbol(reloc_index);
11471138 if (sym.tag != .global) {
11481139 try wasm_file.got_symbols.append(gpa, .{
11491140 .file = zig_object.index,
1150 .index = reloc.index,
1141 .index = reloc_index,
11511142 });
11521143 }
11531144 },
......@@ -1166,10 +1157,10 @@ pub fn createFunction(
11661157 func_ty: std.wasm.Type,
11671158 function_body: *std.ArrayList(u8),
11681159 relocations: *std.ArrayList(types.Relocation),
1169) !u32 {
1160) !Symbol.Index {
11701161 const gpa = wasm_file.base.comp.gpa;
11711162 const sym_index = try zig_object.allocateSymbol(gpa);
1172 const sym = &zig_object.symbols.items[sym_index];
1163 const sym = zig_object.symbol(sym_index);
11731164 sym.tag = .function;
11741165 sym.name = try zig_object.string_table.insert(gpa, symbol_name);
11751166 const type_index = try zig_object.putOrGetFuncType(gpa, func_ty);
src/link/Wasm/file.zig+12-12
......@@ -20,10 +20,10 @@ pub const File = union(enum) {
2020 };
2121 }
2222
23 pub fn symbol(file: File, index: u32) *Symbol {
23 pub fn symbol(file: File, index: Symbol.Index) *Symbol {
2424 return switch (file) {
25 .zig_object => |obj| &obj.symbols.items[index],
26 .object => |obj| &obj.symtable[index],
25 .zig_object => |obj| &obj.symbols.items[@intFromEnum(index)],
26 .object => |obj| &obj.symtable[@intFromEnum(index)],
2727 };
2828 }
2929
......@@ -34,20 +34,20 @@ pub const File = union(enum) {
3434 };
3535 }
3636
37 pub fn symbolName(file: File, index: u32) []const u8 {
37 pub fn symbolName(file: File, index: Symbol.Index) []const u8 {
3838 switch (file) {
3939 .zig_object => |obj| {
40 const sym = obj.symbols.items[index];
40 const sym = obj.symbols.items[@intFromEnum(index)];
4141 return obj.string_table.get(sym.name).?;
4242 },
4343 .object => |obj| {
44 const sym = obj.symtable[index];
44 const sym = obj.symtable[@intFromEnum(index)];
4545 return obj.string_table.get(sym.name);
4646 },
4747 }
4848 }
4949
50 pub fn parseSymbolIntoAtom(file: File, wasm_file: *Wasm, index: u32) !AtomIndex {
50 pub fn parseSymbolIntoAtom(file: File, wasm_file: *Wasm, index: Symbol.Index) !AtomIndex {
5151 return switch (file) {
5252 inline else => |obj| obj.parseSymbolIntoAtom(wasm_file, index),
5353 };
......@@ -55,10 +55,10 @@ pub const File = union(enum) {
5555
5656 /// For a given symbol index, find its corresponding import.
5757 /// Asserts import exists.
58 pub fn import(file: File, symbol_index: u32) types.Import {
58 pub fn import(file: File, symbol_index: Symbol.Index) types.Import {
5959 return switch (file) {
6060 .zig_object => |obj| obj.imports.get(symbol_index).?,
61 .object => |obj| obj.findImport(obj.symtable[symbol_index]),
61 .object => |obj| obj.findImport(obj.symtable[@intFromEnum(symbol_index)]),
6262 };
6363 }
6464
......@@ -89,14 +89,14 @@ pub const File = union(enum) {
8989 };
9090 }
9191
92 pub fn function(file: File, sym_index: u32) std.wasm.Func {
92 pub fn function(file: File, sym_index: Symbol.Index) std.wasm.Func {
9393 switch (file) {
9494 .zig_object => |obj| {
95 const sym = obj.symbols.items[sym_index];
95 const sym = obj.symbols.items[@intFromEnum(sym_index)];
9696 return obj.functions.items[sym.index];
9797 },
9898 .object => |obj| {
99 const sym = obj.symtable[sym_index];
99 const sym = obj.symtable[@intFromEnum(sym_index)];
100100 return obj.functions[sym.index - obj.imported_functions_count];
101101 },
102102 }