authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-01-15 16:05:39+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:03+01:00
logf6896ef2180709fedeb5bafde3fe58ca6d06aa3a
tree0436e2b8ca804d0d34e288db8675788b2a07f643
parent9b3c8fd3a8aef81f3a6face78f9e0b34508edc1b
signaturelock-open Commit is signed but in an unrecognized format.

wasm: create linking objects in correct module

CodeGen will create linking objects such as symbols, function types, etc in ZigObject, rather than in the linker driver where the final result will be stored. They will end up in the linker driver module during the `flush` phase instead. This must mean we must call functions such as `addOrGetFuncType` in the correct namespace or else it will be created in the incorrect list and therefore return incorrect indexes.

4 files changed, 176 insertions(+), 154 deletions(-)

src/arch/wasm/CodeGen.zig+4-4
......@@ -2239,7 +2239,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22392239 }
22402240
22412241 if (callee) |direct| {
2242 const atom_index = func.bin_file.decls.get(direct).?;
2242 const atom_index = func.bin_file.zigObjectPtr().?.decls.get(direct).?;
22432243 try func.addLabel(.call, func.bin_file.getAtom(atom_index).sym_index);
22442244 } else {
22452245 // in this case we call a function pointer
......@@ -2251,7 +2251,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22512251 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);
22522252 defer fn_type.deinit(func.gpa);
22532253
2254 const fn_type_index = try func.bin_file.putOrGetFuncType(fn_type);
2254 const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type);
22552255 try func.addLabel(.call_indirect, fn_type_index);
22562256 }
22572257
......@@ -3157,7 +3157,7 @@ fn lowerAnonDeclRef(
31573157 return error.CodegenFail;
31583158 },
31593159 }
3160 const target_atom_index = func.bin_file.anon_decls.get(decl_val).?;
3160 const target_atom_index = func.bin_file.zigObjectPtr().?.anon_decls.get(decl_val).?;
31613161 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;
31623162 if (is_fn_body) {
31633163 return WValue{ .function_index = target_sym_index };
......@@ -7161,7 +7161,7 @@ fn callIntrinsic(
71617161 const mod = func.bin_file.base.comp.module.?;
71627162 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);
71637163 defer func_type.deinit(func.gpa);
7164 const func_type_index = try func.bin_file.putOrGetFuncType(func_type);
7164 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);
71657165 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);
71667166
71677167 const want_sret_param = firstParamSRet(.C, return_type, mod);
src/arch/wasm/Emit.zig+4-4
......@@ -310,7 +310,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
310310 const global_offset = emit.offset();
311311 try emit.code.appendSlice(&buf);
312312
313 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
313 const atom_index = emit.bin_file.zigObjectPtr().?.decls.get(emit.decl_index).?;
314314 const atom = emit.bin_file.getAtomPtr(atom_index);
315315 try atom.relocs.append(gpa, .{
316316 .index = label,
......@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
370370 try emit.code.appendSlice(&buf);
371371
372372 if (label != 0) {
373 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
373 const atom_index = emit.bin_file.zigObjectPtr().?.decls.get(emit.decl_index).?;
374374 const atom = emit.bin_file.getAtomPtr(atom_index);
375375 try atom.relocs.append(gpa, .{
376376 .offset = call_offset,
......@@ -400,7 +400,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
400400 try emit.code.appendSlice(&buf);
401401
402402 if (symbol_index != 0) {
403 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
403 const atom_index = emit.bin_file.zigObjectPtr().?.decls.get(emit.decl_index).?;
404404 const atom = emit.bin_file.getAtomPtr(atom_index);
405405 try atom.relocs.append(gpa, .{
406406 .offset = index_offset,
......@@ -431,7 +431,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
431431 }
432432
433433 if (mem.pointer != 0) {
434 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
434 const atom_index = emit.bin_file.zigObjectPtr().?.decls.get(emit.decl_index).?;
435435 const atom = emit.bin_file.getAtomPtr(atom_index);
436436 try atom.relocs.append(gpa, .{
437437 .offset = mem_offset,
src/link/Wasm.zig+76-89
......@@ -581,11 +581,38 @@ pub fn createEmpty(
581581 return wasm;
582582}
583583
584fn zigObjectPtr(wasm: *Wasm) ?*ZigObject {
584pub fn zigObjectPtr(wasm: *Wasm) ?*ZigObject {
585585 if (wasm.zig_object_index == .null) return null;
586586 return &wasm.files.items(.data)[@intFromEnum(wasm.zig_object_index)].zig_object;
587587}
588588
589pub fn getTypeIndex(wasm: *const Wasm, func_type: std.wasm.Type) ?u32 {
590 var index: u32 = 0;
591 while (index < wasm.func_types.items.len) : (index += 1) {
592 if (wasm.func_types.items[index].eql(func_type)) return index;
593 }
594 return null;
595}
596
597/// Either creates a new import, or updates one if existing.
598/// When `type_index` is non-null, we assume an external function.
599/// In all other cases, a data-symbol will be created instead.
600pub fn addOrUpdateImport(
601 wasm: *Wasm,
602 /// Name of the import
603 name: []const u8,
604 /// Symbol index that is external
605 symbol_index: u32,
606 /// Optional library name (i.e. `extern "c" fn foo() void`
607 lib_name: ?[:0]const u8,
608 /// The index of the type that represents the function signature
609 /// when the extern is a function. When this is null, a data-symbol
610 /// is asserted instead.
611 type_index: ?u32,
612) !void {
613 return wasm.zigObjectPtr().?.addOrUpdateImport(wasm, name, symbol_index, lib_name, type_index);
614}
615
589616/// For a given name, creates a new global synthetic symbol.
590617/// Leaves index undefined and the default flags (0).
591618fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc {
......@@ -1389,64 +1416,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air:
13891416 @panic("Attempted to compile for object format that was disabled by build configuration");
13901417 }
13911418 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);
1392
1393 const tracy = trace(@src());
1394 defer tracy.end();
1395
1396 const gpa = wasm.base.comp.gpa;
1397 const func = mod.funcInfo(func_index);
1398 const decl_index = func.owner_decl;
1399 const decl = mod.declPtr(decl_index);
1400 const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
1401 const atom = wasm.getAtomPtr(atom_index);
1402 atom.clear();
1403
1404 // var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null;
1405 // defer if (decl_state) |*ds| ds.deinit();
1406
1407 var code_writer = std.ArrayList(u8).init(gpa);
1408 defer code_writer.deinit();
1409 // const result = try codegen.generateFunction(
1410 // &wasm.base,
1411 // decl.srcLoc(mod),
1412 // func,
1413 // air,
1414 // liveness,
1415 // &code_writer,
1416 // if (decl_state) |*ds| .{ .dwarf = ds } else .none,
1417 // );
1418 const result = try codegen.generateFunction(
1419 &wasm.base,
1420 decl.srcLoc(mod),
1421 func_index,
1422 air,
1423 liveness,
1424 &code_writer,
1425 .none,
1426 );
1427
1428 const code = switch (result) {
1429 .ok => code_writer.items,
1430 .fail => |em| {
1431 func.analysis(&mod.intern_pool).state = .codegen_failure;
1432 try mod.failed_decls.put(mod.gpa, decl_index, em);
1433 return;
1434 },
1435 };
1436
1437 // if (wasm.dwarf) |*dwarf| {
1438 // try dwarf.commitDeclState(
1439 // mod,
1440 // decl_index,
1441 // // Actual value will be written after relocation.
1442 // // For Wasm, this is the offset relative to the code section
1443 // // which isn't known until flush().
1444 // 0,
1445 // code.len,
1446 // &decl_state.?,
1447 // );
1448 // }
1449 return wasm.finishUpdateDecl(decl_index, code, .function);
1419 try wasm.zigObjectPtr().?.updateFunc(wasm, mod, func_index, air, liveness);
14501420}
14511421
14521422// Generate code for the Decl, storing it in memory to be later written to
......@@ -1456,12 +1426,12 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !
14561426 @panic("Attempted to compile for object format that was disabled by build configuration");
14571427 }
14581428 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
1429 try wasm.zigObjectPtr().?.updateDecl(wasm, mod, decl_index);
14591430}
14601431
14611432pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {
14621433 if (wasm.llvm_object) |_| return;
1463 _ = mod;
1464 _ = decl_index;
1434 try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);
14651435}
14661436
14671437/// From a given symbol location, returns its `wasm.GlobalType`.
......@@ -1511,9 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
15111481/// Returns the symbol index of the local
15121482/// The given `decl` is the parent decl whom owns the constant.
15131483pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1514 _ = wasm;
1515 _ = tv;
1516 _ = decl_index;
1484 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, tv, decl_index);
15171485}
15181486
15191487/// Returns the symbol index from a symbol of which its flag is set global,
......@@ -1522,8 +1490,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
15221490/// and then returns the index to it.
15231491pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 {
15241492 _ = lib_name;
1525 _ = name;
1526 _ = wasm;
1493 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);
15271494}
15281495
15291496/// For a given decl, find the given symbol index's atom, and create a relocation for the type.
......@@ -1533,9 +1500,7 @@ pub fn getDeclVAddr(
15331500 decl_index: InternPool.DeclIndex,
15341501 reloc_info: link.File.RelocInfo,
15351502) !u64 {
1536 _ = wasm;
1537 _ = decl_index;
1538 _ = reloc_info;
1503 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, decl_index, reloc_info);
15391504}
15401505
15411506pub fn lowerAnonDecl(
......@@ -1544,16 +1509,11 @@ pub fn lowerAnonDecl(
15441509 explicit_alignment: Alignment,
15451510 src_loc: Module.SrcLoc,
15461511) !codegen.Result {
1547 _ = wasm;
1548 _ = decl_val;
1549 _ = explicit_alignment;
1550 _ = src_loc;
1512 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, decl_val, explicit_alignment, src_loc);
15511513}
15521514
15531515pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1554 _ = wasm;
1555 _ = decl_val;
1556 _ = reloc_info;
1516 return wasm.zigObjectPtr().?.getAnonDeclVAddr(wasm, decl_val, reloc_info);
15571517}
15581518
15591519pub fn deleteDeclExport(
......@@ -1561,9 +1521,9 @@ pub fn deleteDeclExport(
15611521 decl_index: InternPool.DeclIndex,
15621522 name: InternPool.NullTerminatedString,
15631523) void {
1564 if (wasm.llvm_object) |_| return;
15651524 _ = name;
1566 _ = decl_index;
1525 if (wasm.llvm_object) |_| return;
1526 return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index);
15671527}
15681528
15691529pub fn updateExports(
......@@ -1576,10 +1536,12 @@ pub fn updateExports(
15761536 @panic("Attempted to compile for object format that was disabled by build configuration");
15771537 }
15781538 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
1539 return wasm.zigObjectPtr().?.updateExports(wasm, mod, exported, exports);
15791540}
15801541
15811542pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
15821543 if (wasm.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
1544 return wasm.zigObjectPtr().?.freeDecl(wasm, decl_index);
15831545}
15841546
15851547/// Assigns indexes to all indirect functions.
......@@ -1917,7 +1879,11 @@ pub fn createFunction(
19171879 };
19181880 try wasm.appendAtomAtIndex(section_index, atom_index);
19191881 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
1920 try wasm.atom_types.put(gpa, atom_index, try wasm.putOrGetFuncType(func_ty));
1882 try wasm.zigObjectPtr().?.atom_types.put(
1883 gpa,
1884 atom_index,
1885 try wasm.zigObjectPtr().?.putOrGetFuncType(gpa, func_ty),
1886 );
19211887 try wasm.synthetic_functions.append(gpa, atom_index);
19221888
19231889 return loc.index;
......@@ -4285,22 +4251,43 @@ fn hasPassiveInitializationSegments(wasm: *const Wasm) bool {
42854251/// Searches for a matching function signature. When no matching signature is found,
42864252/// a new entry will be made. The value returned is the index of the type within `wasm.func_types`.
42874253pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
4288 _ = wasm;
4289 _ = func_type;
4254 if (wasm.getTypeIndex(func_type)) |index| {
4255 return index;
4256 }
4257
4258 // functype does not exist.
4259 const gpa = wasm.base.comp.gpa;
4260 const index: u32 = @intCast(wasm.func_types.items.len);
4261 const params = try gpa.dupe(std.wasm.Valtype, func_type.params);
4262 errdefer gpa.free(params);
4263 const returns = try gpa.dupe(std.wasm.Valtype, func_type.returns);
4264 errdefer gpa.free(returns);
4265 try wasm.func_types.append(gpa, .{
4266 .params = params,
4267 .returns = returns,
4268 });
4269 return index;
42904270}
42914271
42924272/// For the given `decl_index`, stores the corresponding type representing the function signature.
42934273/// Asserts declaration has an associated `Atom`.
42944274/// Returns the index into the list of types.
42954275pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
4296 _ = wasm;
4297 _ = decl_index;
4298 _ = func_type;
4299 // const gpa = wasm.base.comp.gpa;
4300 // const atom_index = wasm.decls.get(decl_index).?;
4301 // const index = try wasm.putOrGetFuncType(func_type);
4302 // try wasm.atom_types.put(gpa, atom_index, index);
4303 // return index;
4276 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, decl_index, func_type);
4277}
4278
4279/// Returns the symbol index of the error name table.
4280///
4281/// When the symbol does not yet exist, it will create a new one instead.
4282pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 {
4283 return wasm_file.zigObjectPtr().?.getErrorTableSymbol(wasm_file);
4284}
4285
4286/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
4287/// When the index was not found, a new `Atom` will be created, and its index will be returned.
4288/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
4289pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {
4290 return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, decl_index);
43044291}
43054292
43064293/// Verifies all resolved symbols and checks whether itself needs to be marked alive,
src/link/Wasm/ZigObject.zig+92-57
......@@ -85,11 +85,13 @@ pub fn init(zig_object: *ZigObject, wasm_file: *Wasm) !void {
8585
8686fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {
8787 const gpa = wasm_file.base.comp.gpa;
88 const sym_index = try zig_object.getGlobalSymbol(gpa, "__stack_pointer", .global);
89 zig_object.symbols.items[sym_index].index = zig_object.imported_globals_count;
88 const sym_index = try zig_object.getGlobalSymbol(gpa, "__stack_pointer");
89 const sym = zig_object.symbol(sym_index);
90 sym.index = zig_object.imported_globals_count;
91 sym.tag = .global;
9092 const is_wasm32 = wasm_file.base.comp.root_mod.resolved_target.result.cpu.arch == .wasm32;
9193 try zig_object.imports.putNoClobber(gpa, sym_index, .{
92 .name = zig_object.symbols.items[sym_index].name,
94 .name = sym.name,
9395 .module_name = try zig_object.string_table.insert(gpa, wasm_file.host_name),
9496 .kind = .{ .global = .{ .valtype = if (is_wasm32) .i32 else .i64, .mutable = true } },
9597 });
......@@ -97,6 +99,10 @@ fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {
9799 zig_object.stack_pointer_sym = sym_index;
98100}
99101
102fn symbol(zig_object: *const ZigObject, index: u32) *Symbol {
103 return &zig_object.symbols.items[index];
104}
105
100106/// Frees and invalidates all memory of the incrementally compiled Zig module.
101107/// It is illegal behavior to access the `ZigObject` after calling `deinit`.
102108pub fn deinit(zig_object: *ZigObject, gpa: std.mem.Allocator) void {
......@@ -146,7 +152,7 @@ pub fn deinit(zig_object: *ZigObject, gpa: std.mem.Allocator) void {
146152/// Will re-use slots when a symbol was freed at an earlier stage.
147153pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
148154 try zig_object.symbols.ensureUnusedCapacity(gpa, 1);
149 const symbol: Symbol = .{
155 const sym: Symbol = .{
150156 .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls
151157 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
152158 .tag = .undefined, // will be set after updateDecl
......@@ -154,17 +160,22 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
154160 .virtual_address = std.math.maxInt(u32), // will be set during atom allocation
155161 };
156162 if (zig_object.symbols_free_list.popOrNull()) |index| {
157 zig_object.symbols.items[index] = symbol;
163 zig_object.symbols.items[index] = sym;
158164 return index;
159165 }
160166 const index = @as(u32, @intCast(zig_object.symbols.items.len));
161 zig_object.symbols.appendAssumeCapacity(symbol);
167 zig_object.symbols.appendAssumeCapacity(sym);
162168 return index;
163169}
164170
165171// Generate code for the Decl, storing it in memory to be later written to
166172// the file on flush().
167pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {
173pub fn updateDecl(
174 zig_object: *ZigObject,
175 wasm_file: *Wasm,
176 mod: *Module,
177 decl_index: InternPool.DeclIndex,
178) !void {
168179 const decl = mod.declPtr(decl_index);
169180 if (decl.val.getFunction(mod)) |_| {
170181 return;
......@@ -173,7 +184,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
173184 }
174185
175186 const gpa = wasm_file.base.comp.gpa;
176 const atom_index = try zig_object.getOrCreateAtomForDecl(decl_index);
187 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
177188 const atom = wasm_file.getAtomPtr(atom_index);
178189 atom.clear();
179190
......@@ -181,7 +192,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
181192 const variable = decl.getOwnedVariable(mod).?;
182193 const name = mod.intern_pool.stringToSlice(decl.name);
183194 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
184 return wasm_file.addOrUpdateImport(name, atom.sym_index, lib_name, null);
195 return zig_object.addOrUpdateImport(wasm_file, name, atom.sym_index, lib_name, null);
185196 }
186197 const val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
187198
......@@ -206,15 +217,22 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
206217 },
207218 };
208219
209 return wasm_file.finishUpdateDecl(decl_index, code, .data);
220 return zig_object.finishUpdateDecl(wasm_file, decl_index, code, .data);
210221}
211222
212pub fn updateFunc(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
223pub fn updateFunc(
224 zig_object: *ZigObject,
225 wasm_file: *Wasm,
226 mod: *Module,
227 func_index: InternPool.Index,
228 air: Air,
229 liveness: Liveness,
230) !void {
213231 const gpa = wasm_file.base.comp.gpa;
214232 const func = mod.funcInfo(func_index);
215233 const decl_index = func.owner_decl;
216234 const decl = mod.declPtr(decl_index);
217 const atom_index = try zig_object.getOrCreateAtomForDecl(decl_index);
235 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
218236 const atom = wasm_file.getAtomPtr(atom_index);
219237 atom.clear();
220238
......@@ -242,16 +260,22 @@ pub fn updateFunc(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, func_i
242260 return zig_object.finishUpdateDecl(wasm_file, decl_index, code, .function);
243261}
244262
245fn finishUpdateDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex, code: []const u8, symbol_tag: Symbol.Tag) !void {
263fn finishUpdateDecl(
264 zig_object: *ZigObject,
265 wasm_file: *Wasm,
266 decl_index: InternPool.DeclIndex,
267 code: []const u8,
268 symbol_tag: Symbol.Tag,
269) !void {
246270 const gpa = wasm_file.base.comp.gpa;
247271 const mod = wasm_file.base.comp.module.?;
248272 const decl = mod.declPtr(decl_index);
249273 const atom_index = zig_object.decls.get(decl_index).?;
250274 const atom = wasm_file.getAtomPtr(atom_index);
251 const symbol = &zig_object.symbols.items[atom.sym_index];
275 const sym = zig_object.symbol(atom.getSymbolIndex().?);
252276 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
253 symbol.name = try zig_object.string_table.insert(gpa, full_name);
254 symbol.tag = symbol_tag;
277 sym.name = try zig_object.string_table.insert(gpa, full_name);
278 sym.tag = symbol_tag;
255279 try atom.code.appendSlice(gpa, code);
256280 try wasm_file.resolved_symbols.put(gpa, atom.symbolLoc(), {});
257281
......@@ -267,14 +291,13 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
267291 const gpa = wasm_file.base.comp.gpa;
268292 const gop = try zig_object.decls.getOrPut(gpa, decl_index);
269293 if (!gop.found_existing) {
270 const atom_index = try wasm_file.createAtom();
271 gop.value_ptr.* = atom_index;
272 const atom = wasm_file.getAtom(atom_index);
273 const symbol = atom.symbolLoc().getSymbol(wasm_file);
294 const sym_index = try zig_object.allocateSymbol(gpa);
295 gop.value_ptr.* = try wasm_file.createAtom(sym_index);
274296 const mod = wasm_file.base.comp.module.?;
275297 const decl = mod.declPtr(decl_index);
276298 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
277 symbol.name = try wasm_file.string_table.insert(gpa, full_name);
299 const sym = zig_object.symbol(sym_index);
300 sym.name = try zig_object.string_table.insert(gpa, full_name);
278301 }
279302 return gop.value_ptr.*;
280303}
......@@ -297,7 +320,7 @@ pub fn lowerAnonDecl(
297320 @intFromEnum(decl_val),
298321 }) catch unreachable;
299322
300 switch (try zig_object.lowerConst(name, tv, src_loc)) {
323 switch (try zig_object.lowerConst(wasm_file, name, tv, src_loc)) {
301324 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
302325 .fail => |em| return .{ .fail = em },
303326 }
......@@ -323,7 +346,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
323346 std.debug.assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
324347 const decl = mod.declPtr(decl_index);
325348
326 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(decl_index);
349 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
327350 const parent_atom = wasm_file.getAtom(parent_atom_index);
328351 const local_index = parent_atom.locals.items.len;
329352 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
......@@ -332,7 +355,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
332355 });
333356 defer gpa.free(name);
334357
335 switch (try zig_object.lowerConst(name, tv, decl.srcLoc(mod))) {
358 switch (try zig_object.lowerConst(wasm_file, name, tv, decl.srcLoc(mod))) {
336359 .ok => |atom_index| {
337360 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
338361 return wasm_file.getAtom(atom_index).getSymbolIndex().?;
......@@ -355,14 +378,15 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
355378 const mod = wasm_file.base.comp.module.?;
356379
357380 // Create and initialize a new local symbol and atom
358 const atom_index = try wasm_file.createAtom();
381 const sym_index = try zig_object.allocateSymbol(gpa);
382 const atom_index = try wasm_file.createAtom(sym_index);
359383 var value_bytes = std.ArrayList(u8).init(gpa);
360384 defer value_bytes.deinit();
361385
362386 const code = code: {
363387 const atom = wasm_file.getAtomPtr(atom_index);
364388 atom.alignment = tv.ty.abiAlignment(mod);
365 zig_object.symbols.items[atom.sym_index] = .{
389 zig_object.symbols.items[sym_index] = .{
366390 .name = try zig_object.string_table.insert(gpa, name),
367391 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
368392 .tag = .data,
......@@ -399,14 +423,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
399423///
400424/// When the symbol does not yet exist, it will create a new one instead.
401425pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
402 if (zig_object.error_table_symbol) |symbol| {
403 return symbol;
426 if (zig_object.error_table_symbol) |sym| {
427 return sym;
404428 }
405429
406430 // no error was referenced yet, so create a new symbol and atom for it
407431 // and then return said symbol's index. The final table will be populated
408432 // during `flush` when we know all possible error names.
409 const gpa = wasm_file.base.gpa;
433 const gpa = wasm_file.base.comp.gpa;
410434 const sym_index = try zig_object.allocateSymbol(gpa);
411435 const atom_index = try wasm_file.createAtom(sym_index);
412436 const atom = wasm_file.getAtomPtr(atom_index);
......@@ -415,15 +439,16 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
415439 atom.alignment = slice_ty.abiAlignment(mod);
416440
417441 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");
418 const symbol = &zig_object.symbols.items[sym_index];
419 symbol.* = .{
442 const sym = zig_object.symbol(sym_index);
443 sym.* = .{
420444 .name = sym_name,
421445 .tag = .data,
422446 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
423447 .index = 0,
424448 .virtual_address = undefined,
425449 };
426 symbol.mark();
450 // TODO: can we remove this?
451 // sym.mark();
427452
428453 log.debug("Error name table was created with symbol index: ({d})", .{sym_index});
429454 zig_object.error_table_symbol = sym_index;
......@@ -528,13 +553,13 @@ pub fn addOrUpdateImport(
528553 defer if (mangle_name) gpa.free(full_name);
529554
530555 const decl_name_index = try zig_object.string_table.insert(gpa, full_name);
531 const symbol: *Symbol = &zig_object.symbols.items[symbol_index];
532 symbol.setUndefined(true);
533 symbol.setGlobal(true);
534 symbol.name = decl_name_index;
556 const sym: *Symbol = &zig_object.symbols.items[symbol_index];
557 sym.setUndefined(true);
558 sym.setGlobal(true);
559 sym.name = decl_name_index;
535560 if (mangle_name) {
536561 // we specified a specific name for the symbol that does not match the import name
537 symbol.setFlag(.WASM_SYM_EXPLICIT_NAME);
562 sym.setFlag(.WASM_SYM_EXPLICIT_NAME);
538563 }
539564
540565 if (type_index) |ty_index| {
......@@ -557,22 +582,22 @@ pub fn addOrUpdateImport(
557582/// such as an exported or imported symbol.
558583/// If the symbol does not yet exist, creates a new one symbol instead
559584/// and then returns the index to it.
560pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []const u8, tag: Symbol.Tag) !u32 {
585pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []const u8) !u32 {
561586 const name_index = try zig_object.string_table.insert(gpa, name);
562587 const gop = try zig_object.global_syms.getOrPut(gpa, name_index);
563588 if (gop.found_existing) {
564589 return gop.value_ptr.*;
565590 }
566591
567 var symbol: Symbol = .{
592 var sym: Symbol = .{
568593 .name = name_index,
569594 .flags = 0,
570595 .index = undefined, // index to type will be set after merging symbols
571 .tag = tag,
596 .tag = .function,
572597 .virtual_address = std.math.maxInt(u32),
573598 };
574 symbol.setGlobal(true);
575 symbol.setUndefined(true);
599 sym.setGlobal(true);
600 sym.setUndefined(true);
576601
577602 const sym_index = if (zig_object.symbols_free_list.popOrNull()) |index| index else blk: {
578603 const index: u32 = @intCast(zig_object.symbols.items.len);
......@@ -580,7 +605,7 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
580605 zig_object.symbols.items.len += 1;
581606 break :blk index;
582607 };
583 zig_object.symbols.items[sym_index] = symbol;
608 zig_object.symbols.items[sym_index] = sym;
584609 gop.value_ptr.* = sym_index;
585610 return sym_index;
586611}
......@@ -675,8 +700,8 @@ pub fn deleteDeclExport(
675700 const atom_index = zig_object.decls.get(decl_index) orelse return;
676701 const sym_index = wasm_file.getAtom(atom_index).sym_index;
677702 const loc: Wasm.SymbolLoc = .{ .file = null, .index = sym_index };
678 const symbol = loc.getSymbol(wasm_file);
679 std.debug.assert(zig_object.global_syms.remove(symbol.name));
703 const sym = loc.getSymbol(wasm_file);
704 std.debug.assert(zig_object.global_syms.remove(sym.name));
680705}
681706
682707pub fn updateExports(
......@@ -694,7 +719,7 @@ pub fn updateExports(
694719 },
695720 };
696721 const decl = mod.declPtr(decl_index);
697 const atom_index = try zig_object.getOrCreateAtomForDecl(decl_index);
722 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index);
698723 const atom = wasm_file.getAtom(atom_index);
699724 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
700725 const gpa = mod.gpa;
......@@ -722,24 +747,24 @@ pub fn updateExports(
722747 },
723748 .decl_index => |i| i,
724749 };
725 const exported_atom_index = try zig_object.getOrCreateAtomForDecl(exported_decl_index);
750 const exported_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, exported_decl_index);
726751 const exported_atom = wasm_file.getAtom(exported_atom_index);
727752 // const export_name = try zig_object.string_table.put(gpa, mod.intern_pool.stringToSlice(exp.opts.name));
728753 const sym_loc = exported_atom.symbolLoc();
729 const symbol = sym_loc.getSymbol(wasm_file);
730 symbol.setGlobal(true);
731 symbol.setUndefined(false);
732 symbol.index = atom_sym.index;
733 symbol.tag = atom_sym.tag;
734 symbol.name = atom_sym.name;
754 const sym = sym_loc.getSymbol(wasm_file);
755 sym.setGlobal(true);
756 sym.setUndefined(false);
757 sym.index = atom_sym.index;
758 sym.tag = atom_sym.tag;
759 sym.name = atom_sym.name;
735760
736761 switch (exp.opts.linkage) {
737762 .Internal => {
738 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
739 symbol.setFlag(.WASM_SYM_BINDING_WEAK);
763 sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
764 sym.setFlag(.WASM_SYM_BINDING_WEAK);
740765 },
741766 .Weak => {
742 symbol.setFlag(.WASM_SYM_BINDING_WEAK);
767 sym.setFlag(.WASM_SYM_BINDING_WEAK);
743768 },
744769 .Strong => {}, // symbols are strong by default
745770 .LinkOnce => {
......@@ -840,7 +865,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
840865 }
841866}
842867
843pub fn getTypeIndex(zig_object: *const ZigObject, func_type: std.wasm.Type) ?u32 {
868fn getTypeIndex(zig_object: *const ZigObject, func_type: std.wasm.Type) ?u32 {
844869 var index: u32 = 0;
845870 while (index < zig_object.func_types.items.len) : (index += 1) {
846871 if (zig_object.func_types.items[index].eql(func_type)) return index;
......@@ -1115,6 +1140,16 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {
11151140 try allocAtom(zig_object, &zig_object.debug_pubtypes_index, zig_object.debug_pubtypes_atom.?);
11161141}
11171142
1143/// For the given `decl_index`, stores the corresponding type representing the function signature.
1144/// Asserts declaration has an associated `Atom`.
1145/// Returns the index into the list of types.
1146pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
1147 const atom_index = zig_object.decls.get(decl_index).?;
1148 const index = try zig_object.putOrGetFuncType(gpa, func_type);
1149 try zig_object.atom_types.put(gpa, atom_index, index);
1150 return index;
1151}
1152
11181153const build_options = @import("build_options");
11191154const builtin = @import("builtin");
11201155const codegen = @import("../../codegen.zig");