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...@@ -2239,7 +2239,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2239 }2239 }
22402240
2241 if (callee) |direct| {2241 if (callee) |direct| {
2242 const atom_index = func.bin_file.decls.get(direct).?;2242 const atom_index = func.bin_file.zigObjectPtr().?.decls.get(direct).?;
2243 try func.addLabel(.call, func.bin_file.getAtom(atom_index).sym_index);2243 try func.addLabel(.call, func.bin_file.getAtom(atom_index).sym_index);
2244 } else {2244 } else {
2245 // in this case we call a function pointer2245 // in this case we call a function pointer
...@@ -2251,7 +2251,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2251,7 +2251,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2251 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);2251 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);
2252 defer fn_type.deinit(func.gpa);2252 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);
2255 try func.addLabel(.call_indirect, fn_type_index);2255 try func.addLabel(.call_indirect, fn_type_index);
2256 }2256 }
22572257
...@@ -3157,7 +3157,7 @@ fn lowerAnonDeclRef(...@@ -3157,7 +3157,7 @@ fn lowerAnonDeclRef(
3157 return error.CodegenFail;3157 return error.CodegenFail;
3158 },3158 },
3159 }3159 }
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).?;
3161 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;3161 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;
3162 if (is_fn_body) {3162 if (is_fn_body) {
3163 return WValue{ .function_index = target_sym_index };3163 return WValue{ .function_index = target_sym_index };
...@@ -7161,7 +7161,7 @@ fn callIntrinsic(...@@ -7161,7 +7161,7 @@ fn callIntrinsic(
7161 const mod = func.bin_file.base.comp.module.?;7161 const mod = func.bin_file.base.comp.module.?;
7162 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);7162 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);
7163 defer func_type.deinit(func.gpa);7163 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);
7165 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);7165 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);
71667166
7167 const want_sret_param = firstParamSRet(.C, return_type, mod);7167 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 {...@@ -310,7 +310,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
310 const global_offset = emit.offset();310 const global_offset = emit.offset();
311 try emit.code.appendSlice(&buf);311 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).?;
314 const atom = emit.bin_file.getAtomPtr(atom_index);314 const atom = emit.bin_file.getAtomPtr(atom_index);
315 try atom.relocs.append(gpa, .{315 try atom.relocs.append(gpa, .{
316 .index = label,316 .index = label,
...@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
370 try emit.code.appendSlice(&buf);370 try emit.code.appendSlice(&buf);
371371
372 if (label != 0) {372 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).?;
374 const atom = emit.bin_file.getAtomPtr(atom_index);374 const atom = emit.bin_file.getAtomPtr(atom_index);
375 try atom.relocs.append(gpa, .{375 try atom.relocs.append(gpa, .{
376 .offset = call_offset,376 .offset = call_offset,
...@@ -400,7 +400,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -400,7 +400,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
400 try emit.code.appendSlice(&buf);400 try emit.code.appendSlice(&buf);
401401
402 if (symbol_index != 0) {402 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).?;
404 const atom = emit.bin_file.getAtomPtr(atom_index);404 const atom = emit.bin_file.getAtomPtr(atom_index);
405 try atom.relocs.append(gpa, .{405 try atom.relocs.append(gpa, .{
406 .offset = index_offset,406 .offset = index_offset,
...@@ -431,7 +431,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -431,7 +431,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
431 }431 }
432432
433 if (mem.pointer != 0) {433 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).?;
435 const atom = emit.bin_file.getAtomPtr(atom_index);435 const atom = emit.bin_file.getAtomPtr(atom_index);
436 try atom.relocs.append(gpa, .{436 try atom.relocs.append(gpa, .{
437 .offset = mem_offset,437 .offset = mem_offset,
src/link/Wasm.zig+76-89
...@@ -581,11 +581,38 @@ pub fn createEmpty(...@@ -581,11 +581,38 @@ pub fn createEmpty(
581 return wasm;581 return wasm;
582}582}
583583
584fn zigObjectPtr(wasm: *Wasm) ?*ZigObject {584pub fn zigObjectPtr(wasm: *Wasm) ?*ZigObject {
585 if (wasm.zig_object_index == .null) return null;585 if (wasm.zig_object_index == .null) return null;
586 return &wasm.files.items(.data)[@intFromEnum(wasm.zig_object_index)].zig_object;586 return &wasm.files.items(.data)[@intFromEnum(wasm.zig_object_index)].zig_object;
587}587}
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
589/// For a given name, creates a new global synthetic symbol.616/// For a given name, creates a new global synthetic symbol.
590/// Leaves index undefined and the default flags (0).617/// Leaves index undefined and the default flags (0).
591fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc {618fn 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:...@@ -1389,64 +1416,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air:
1389 @panic("Attempted to compile for object format that was disabled by build configuration");1416 @panic("Attempted to compile for object format that was disabled by build configuration");
1390 }1417 }
1391 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);1418 if (wasm.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func_index, air, liveness);
13921419 try wasm.zigObjectPtr().?.updateFunc(wasm, mod, func_index, air, liveness);
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);
1450}1420}
14511421
1452// Generate code for the Decl, storing it in memory to be later written to1422// 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) !...@@ -1456,12 +1426,12 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !
1456 @panic("Attempted to compile for object format that was disabled by build configuration");1426 @panic("Attempted to compile for object format that was disabled by build configuration");
1457 }1427 }
1458 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);1428 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
1429 try wasm.zigObjectPtr().?.updateDecl(wasm, mod, decl_index);
1459}1430}
14601431
1461pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {1432pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !void {
1462 if (wasm.llvm_object) |_| return;1433 if (wasm.llvm_object) |_| return;
1463 _ = mod;1434 try wasm.zigObjectPtr().?.updateDeclLineNumber(mod, decl_index);
1464 _ = decl_index;
1465}1435}
14661436
1467/// From a given symbol location, returns its `wasm.GlobalType`.1437/// From a given symbol location, returns its `wasm.GlobalType`.
...@@ -1511,9 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1511,9 +1481,7 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1511/// Returns the symbol index of the local1481/// Returns the symbol index of the local
1512/// The given `decl` is the parent decl whom owns the constant.1482/// The given `decl` is the parent decl whom owns the constant.
1513pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {1483pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1514 _ = wasm;1484 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, tv, decl_index);
1515 _ = tv;
1516 _ = decl_index;
1517}1485}
15181486
1519/// Returns the symbol index from a symbol of which its flag is set global,1487/// 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...@@ -1522,8 +1490,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
1522/// and then returns the index to it.1490/// and then returns the index to it.
1523pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 {1491pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 {
1524 _ = lib_name;1492 _ = lib_name;
1525 _ = name;1493 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);
1526 _ = wasm;
1527}1494}
15281495
1529/// For a given decl, find the given symbol index's atom, and create a relocation for the type.1496/// 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(...@@ -1533,9 +1500,7 @@ pub fn getDeclVAddr(
1533 decl_index: InternPool.DeclIndex,1500 decl_index: InternPool.DeclIndex,
1534 reloc_info: link.File.RelocInfo,1501 reloc_info: link.File.RelocInfo,
1535) !u64 {1502) !u64 {
1536 _ = wasm;1503 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, decl_index, reloc_info);
1537 _ = decl_index;
1538 _ = reloc_info;
1539}1504}
15401505
1541pub fn lowerAnonDecl(1506pub fn lowerAnonDecl(
...@@ -1544,16 +1509,11 @@ pub fn lowerAnonDecl(...@@ -1544,16 +1509,11 @@ pub fn lowerAnonDecl(
1544 explicit_alignment: Alignment,1509 explicit_alignment: Alignment,
1545 src_loc: Module.SrcLoc,1510 src_loc: Module.SrcLoc,
1546) !codegen.Result {1511) !codegen.Result {
1547 _ = wasm;1512 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, decl_val, explicit_alignment, src_loc);
1548 _ = decl_val;
1549 _ = explicit_alignment;
1550 _ = src_loc;
1551}1513}
15521514
1553pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1515pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1554 _ = wasm;1516 return wasm.zigObjectPtr().?.getAnonDeclVAddr(wasm, decl_val, reloc_info);
1555 _ = decl_val;
1556 _ = reloc_info;
1557}1517}
15581518
1559pub fn deleteDeclExport(1519pub fn deleteDeclExport(
...@@ -1561,9 +1521,9 @@ pub fn deleteDeclExport(...@@ -1561,9 +1521,9 @@ pub fn deleteDeclExport(
1561 decl_index: InternPool.DeclIndex,1521 decl_index: InternPool.DeclIndex,
1562 name: InternPool.NullTerminatedString,1522 name: InternPool.NullTerminatedString,
1563) void {1523) void {
1564 if (wasm.llvm_object) |_| return;
1565 _ = name;1524 _ = name;
1566 _ = decl_index;1525 if (wasm.llvm_object) |_| return;
1526 return wasm.zigObjectPtr().?.deleteDeclExport(wasm, decl_index);
1567}1527}
15681528
1569pub fn updateExports(1529pub fn updateExports(
...@@ -1576,10 +1536,12 @@ pub fn updateExports(...@@ -1576,10 +1536,12 @@ pub fn updateExports(
1576 @panic("Attempted to compile for object format that was disabled by build configuration");1536 @panic("Attempted to compile for object format that was disabled by build configuration");
1577 }1537 }
1578 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);1538 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
1539 return wasm.zigObjectPtr().?.updateExports(wasm, mod, exported, exports);
1579}1540}
15801541
1581pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {1542pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
1582 if (wasm.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);1543 if (wasm.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
1544 return wasm.zigObjectPtr().?.freeDecl(wasm, decl_index);
1583}1545}
15841546
1585/// Assigns indexes to all indirect functions.1547/// Assigns indexes to all indirect functions.
...@@ -1917,7 +1879,11 @@ pub fn createFunction(...@@ -1917,7 +1879,11 @@ pub fn createFunction(
1917 };1879 };
1918 try wasm.appendAtomAtIndex(section_index, atom_index);1880 try wasm.appendAtomAtIndex(section_index, atom_index);
1919 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);1881 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 );
1921 try wasm.synthetic_functions.append(gpa, atom_index);1887 try wasm.synthetic_functions.append(gpa, atom_index);
19221888
1923 return loc.index;1889 return loc.index;
...@@ -4285,22 +4251,43 @@ fn hasPassiveInitializationSegments(wasm: *const Wasm) bool {...@@ -4285,22 +4251,43 @@ fn hasPassiveInitializationSegments(wasm: *const Wasm) bool {
4285/// Searches for a matching function signature. When no matching signature is found,4251/// Searches for a matching function signature. When no matching signature is found,
4286/// a new entry will be made. The value returned is the index of the type within `wasm.func_types`.4252/// a new entry will be made. The value returned is the index of the type within `wasm.func_types`.
4287pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {4253pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
4288 _ = wasm;4254 if (wasm.getTypeIndex(func_type)) |index| {
4289 _ = func_type;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;
4290}4270}
42914271
4292/// For the given `decl_index`, stores the corresponding type representing the function signature.4272/// For the given `decl_index`, stores the corresponding type representing the function signature.
4293/// Asserts declaration has an associated `Atom`.4273/// Asserts declaration has an associated `Atom`.
4294/// Returns the index into the list of types.4274/// Returns the index into the list of types.
4295pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {4275pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
4296 _ = wasm;4276 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, decl_index, func_type);
4297 _ = decl_index;4277}
4298 _ = func_type;4278
4299 // const gpa = wasm.base.comp.gpa;4279/// Returns the symbol index of the error name table.
4300 // const atom_index = wasm.decls.get(decl_index).?;4280///
4301 // const index = try wasm.putOrGetFuncType(func_type);4281/// When the symbol does not yet exist, it will create a new one instead.
4302 // try wasm.atom_types.put(gpa, atom_index, index);4282pub fn getErrorTableSymbol(wasm_file: *Wasm) !u32 {
4303 // return index;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);
4304}4291}
43054292
4306/// Verifies all resolved symbols and checks whether itself needs to be marked alive,4293/// 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 {...@@ -85,11 +85,13 @@ pub fn init(zig_object: *ZigObject, wasm_file: *Wasm) !void {
8585
86fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {86fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {
87 const gpa = wasm_file.base.comp.gpa;87 const gpa = wasm_file.base.comp.gpa;
88 const sym_index = try zig_object.getGlobalSymbol(gpa, "__stack_pointer", .global);88 const sym_index = try zig_object.getGlobalSymbol(gpa, "__stack_pointer");
89 zig_object.symbols.items[sym_index].index = zig_object.imported_globals_count;89 const sym = zig_object.symbol(sym_index);
90 sym.index = zig_object.imported_globals_count;
91 sym.tag = .global;
90 const is_wasm32 = wasm_file.base.comp.root_mod.resolved_target.result.cpu.arch == .wasm32;92 const is_wasm32 = wasm_file.base.comp.root_mod.resolved_target.result.cpu.arch == .wasm32;
91 try zig_object.imports.putNoClobber(gpa, sym_index, .{93 try zig_object.imports.putNoClobber(gpa, sym_index, .{
92 .name = zig_object.symbols.items[sym_index].name,94 .name = sym.name,
93 .module_name = try zig_object.string_table.insert(gpa, wasm_file.host_name),95 .module_name = try zig_object.string_table.insert(gpa, wasm_file.host_name),
94 .kind = .{ .global = .{ .valtype = if (is_wasm32) .i32 else .i64, .mutable = true } },96 .kind = .{ .global = .{ .valtype = if (is_wasm32) .i32 else .i64, .mutable = true } },
95 });97 });
...@@ -97,6 +99,10 @@ fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -97,6 +99,10 @@ fn createStackPointer(zig_object: *ZigObject, wasm_file: *Wasm) !void {
97 zig_object.stack_pointer_sym = sym_index;99 zig_object.stack_pointer_sym = sym_index;
98}100}
99101
102fn symbol(zig_object: *const ZigObject, index: u32) *Symbol {
103 return &zig_object.symbols.items[index];
104}
105
100/// Frees and invalidates all memory of the incrementally compiled Zig module.106/// Frees and invalidates all memory of the incrementally compiled Zig module.
101/// It is illegal behavior to access the `ZigObject` after calling `deinit`.107/// It is illegal behavior to access the `ZigObject` after calling `deinit`.
102pub fn deinit(zig_object: *ZigObject, gpa: std.mem.Allocator) void {108pub 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 {...@@ -146,7 +152,7 @@ pub fn deinit(zig_object: *ZigObject, gpa: std.mem.Allocator) void {
146/// Will re-use slots when a symbol was freed at an earlier stage.152/// Will re-use slots when a symbol was freed at an earlier stage.
147pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {153pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
148 try zig_object.symbols.ensureUnusedCapacity(gpa, 1);154 try zig_object.symbols.ensureUnusedCapacity(gpa, 1);
149 const symbol: Symbol = .{155 const sym: Symbol = .{
150 .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls156 .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls
151 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),157 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
152 .tag = .undefined, // will be set after updateDecl158 .tag = .undefined, // will be set after updateDecl
...@@ -154,17 +160,22 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {...@@ -154,17 +160,22 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !u32 {
154 .virtual_address = std.math.maxInt(u32), // will be set during atom allocation160 .virtual_address = std.math.maxInt(u32), // will be set during atom allocation
155 };161 };
156 if (zig_object.symbols_free_list.popOrNull()) |index| {162 if (zig_object.symbols_free_list.popOrNull()) |index| {
157 zig_object.symbols.items[index] = symbol;163 zig_object.symbols.items[index] = sym;
158 return index;164 return index;
159 }165 }
160 const index = @as(u32, @intCast(zig_object.symbols.items.len));166 const index = @as(u32, @intCast(zig_object.symbols.items.len));
161 zig_object.symbols.appendAssumeCapacity(symbol);167 zig_object.symbols.appendAssumeCapacity(sym);
162 return index;168 return index;
163}169}
164170
165// Generate code for the Decl, storing it in memory to be later written to171// Generate code for the Decl, storing it in memory to be later written to
166// the file on flush().172// 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 {
168 const decl = mod.declPtr(decl_index);179 const decl = mod.declPtr(decl_index);
169 if (decl.val.getFunction(mod)) |_| {180 if (decl.val.getFunction(mod)) |_| {
170 return;181 return;
...@@ -173,7 +184,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i...@@ -173,7 +184,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
173 }184 }
174185
175 const gpa = wasm_file.base.comp.gpa;186 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);
177 const atom = wasm_file.getAtomPtr(atom_index);188 const atom = wasm_file.getAtomPtr(atom_index);
178 atom.clear();189 atom.clear();
179190
...@@ -181,7 +192,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i...@@ -181,7 +192,7 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
181 const variable = decl.getOwnedVariable(mod).?;192 const variable = decl.getOwnedVariable(mod).?;
182 const name = mod.intern_pool.stringToSlice(decl.name);193 const name = mod.intern_pool.stringToSlice(decl.name);
183 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);194 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);
185 }196 }
186 const val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;197 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...@@ -206,15 +217,22 @@ pub fn updateDecl(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, decl_i
206 },217 },
207 };218 };
208219
209 return wasm_file.finishUpdateDecl(decl_index, code, .data);220 return zig_object.finishUpdateDecl(wasm_file, decl_index, code, .data);
210}221}
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 {
213 const gpa = wasm_file.base.comp.gpa;231 const gpa = wasm_file.base.comp.gpa;
214 const func = mod.funcInfo(func_index);232 const func = mod.funcInfo(func_index);
215 const decl_index = func.owner_decl;233 const decl_index = func.owner_decl;
216 const decl = mod.declPtr(decl_index);234 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);
218 const atom = wasm_file.getAtomPtr(atom_index);236 const atom = wasm_file.getAtomPtr(atom_index);
219 atom.clear();237 atom.clear();
220238
...@@ -242,16 +260,22 @@ pub fn updateFunc(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, func_i...@@ -242,16 +260,22 @@ pub fn updateFunc(zig_object: *ZigObject, wasm_file: *Wasm, mod: *Module, func_i
242 return zig_object.finishUpdateDecl(wasm_file, decl_index, code, .function);260 return zig_object.finishUpdateDecl(wasm_file, decl_index, code, .function);
243}261}
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 {
246 const gpa = wasm_file.base.comp.gpa;270 const gpa = wasm_file.base.comp.gpa;
247 const mod = wasm_file.base.comp.module.?;271 const mod = wasm_file.base.comp.module.?;
248 const decl = mod.declPtr(decl_index);272 const decl = mod.declPtr(decl_index);
249 const atom_index = zig_object.decls.get(decl_index).?;273 const atom_index = zig_object.decls.get(decl_index).?;
250 const atom = wasm_file.getAtomPtr(atom_index);274 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().?);
252 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));276 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
253 symbol.name = try zig_object.string_table.insert(gpa, full_name);277 sym.name = try zig_object.string_table.insert(gpa, full_name);
254 symbol.tag = symbol_tag;278 sym.tag = symbol_tag;
255 try atom.code.appendSlice(gpa, code);279 try atom.code.appendSlice(gpa, code);
256 try wasm_file.resolved_symbols.put(gpa, atom.symbolLoc(), {});280 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...@@ -267,14 +291,13 @@ pub fn getOrCreateAtomForDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_ind
267 const gpa = wasm_file.base.comp.gpa;291 const gpa = wasm_file.base.comp.gpa;
268 const gop = try zig_object.decls.getOrPut(gpa, decl_index);292 const gop = try zig_object.decls.getOrPut(gpa, decl_index);
269 if (!gop.found_existing) {293 if (!gop.found_existing) {
270 const atom_index = try wasm_file.createAtom();294 const sym_index = try zig_object.allocateSymbol(gpa);
271 gop.value_ptr.* = atom_index;295 gop.value_ptr.* = try wasm_file.createAtom(sym_index);
272 const atom = wasm_file.getAtom(atom_index);
273 const symbol = atom.symbolLoc().getSymbol(wasm_file);
274 const mod = wasm_file.base.comp.module.?;296 const mod = wasm_file.base.comp.module.?;
275 const decl = mod.declPtr(decl_index);297 const decl = mod.declPtr(decl_index);
276 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));298 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);
278 }301 }
279 return gop.value_ptr.*;302 return gop.value_ptr.*;
280}303}
...@@ -297,7 +320,7 @@ pub fn lowerAnonDecl(...@@ -297,7 +320,7 @@ pub fn lowerAnonDecl(
297 @intFromEnum(decl_val),320 @intFromEnum(decl_val),
298 }) catch unreachable;321 }) 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)) {
301 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,324 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
302 .fail => |em| return .{ .fail = em },325 .fail => |em| return .{ .fail = em },
303 }326 }
...@@ -323,7 +346,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu...@@ -323,7 +346,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
323 std.debug.assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions346 std.debug.assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
324 const decl = mod.declPtr(decl_index);347 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);
327 const parent_atom = wasm_file.getAtom(parent_atom_index);350 const parent_atom = wasm_file.getAtom(parent_atom_index);
328 const local_index = parent_atom.locals.items.len;351 const local_index = parent_atom.locals.items.len;
329 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));352 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...@@ -332,7 +355,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu
332 });355 });
333 defer gpa.free(name);356 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))) {
336 .ok => |atom_index| {359 .ok => |atom_index| {
337 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);360 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
338 return wasm_file.getAtom(atom_index).getSymbolIndex().?;361 return wasm_file.getAtom(atom_index).getSymbolIndex().?;
...@@ -355,14 +378,15 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty...@@ -355,14 +378,15 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
355 const mod = wasm_file.base.comp.module.?;378 const mod = wasm_file.base.comp.module.?;
356379
357 // Create and initialize a new local symbol and atom380 // 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);
359 var value_bytes = std.ArrayList(u8).init(gpa);383 var value_bytes = std.ArrayList(u8).init(gpa);
360 defer value_bytes.deinit();384 defer value_bytes.deinit();
361385
362 const code = code: {386 const code = code: {
363 const atom = wasm_file.getAtomPtr(atom_index);387 const atom = wasm_file.getAtomPtr(atom_index);
364 atom.alignment = tv.ty.abiAlignment(mod);388 atom.alignment = tv.ty.abiAlignment(mod);
365 zig_object.symbols.items[atom.sym_index] = .{389 zig_object.symbols.items[sym_index] = .{
366 .name = try zig_object.string_table.insert(gpa, name),390 .name = try zig_object.string_table.insert(gpa, name),
367 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),391 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
368 .tag = .data,392 .tag = .data,
...@@ -399,14 +423,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty...@@ -399,14 +423,14 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty
399///423///
400/// When the symbol does not yet exist, it will create a new one instead.424/// When the symbol does not yet exist, it will create a new one instead.
401pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {425pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
402 if (zig_object.error_table_symbol) |symbol| {426 if (zig_object.error_table_symbol) |sym| {
403 return symbol;427 return sym;
404 }428 }
405429
406 // no error was referenced yet, so create a new symbol and atom for it430 // no error was referenced yet, so create a new symbol and atom for it
407 // and then return said symbol's index. The final table will be populated431 // and then return said symbol's index. The final table will be populated
408 // during `flush` when we know all possible error names.432 // during `flush` when we know all possible error names.
409 const gpa = wasm_file.base.gpa;433 const gpa = wasm_file.base.comp.gpa;
410 const sym_index = try zig_object.allocateSymbol(gpa);434 const sym_index = try zig_object.allocateSymbol(gpa);
411 const atom_index = try wasm_file.createAtom(sym_index);435 const atom_index = try wasm_file.createAtom(sym_index);
412 const atom = wasm_file.getAtomPtr(atom_index);436 const atom = wasm_file.getAtomPtr(atom_index);
...@@ -415,15 +439,16 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {...@@ -415,15 +439,16 @@ pub fn getErrorTableSymbol(zig_object: *ZigObject, wasm_file: *Wasm) !u32 {
415 atom.alignment = slice_ty.abiAlignment(mod);439 atom.alignment = slice_ty.abiAlignment(mod);
416440
417 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");441 const sym_name = try zig_object.string_table.insert(gpa, "__zig_err_name_table");
418 const symbol = &zig_object.symbols.items[sym_index];442 const sym = zig_object.symbol(sym_index);
419 symbol.* = .{443 sym.* = .{
420 .name = sym_name,444 .name = sym_name,
421 .tag = .data,445 .tag = .data,
422 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),446 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
423 .index = 0,447 .index = 0,
424 .virtual_address = undefined,448 .virtual_address = undefined,
425 };449 };
426 symbol.mark();450 // TODO: can we remove this?
451 // sym.mark();
427452
428 log.debug("Error name table was created with symbol index: ({d})", .{sym_index});453 log.debug("Error name table was created with symbol index: ({d})", .{sym_index});
429 zig_object.error_table_symbol = sym_index;454 zig_object.error_table_symbol = sym_index;
...@@ -528,13 +553,13 @@ pub fn addOrUpdateImport(...@@ -528,13 +553,13 @@ pub fn addOrUpdateImport(
528 defer if (mangle_name) gpa.free(full_name);553 defer if (mangle_name) gpa.free(full_name);
529554
530 const decl_name_index = try zig_object.string_table.insert(gpa, full_name);555 const decl_name_index = try zig_object.string_table.insert(gpa, full_name);
531 const symbol: *Symbol = &zig_object.symbols.items[symbol_index];556 const sym: *Symbol = &zig_object.symbols.items[symbol_index];
532 symbol.setUndefined(true);557 sym.setUndefined(true);
533 symbol.setGlobal(true);558 sym.setGlobal(true);
534 symbol.name = decl_name_index;559 sym.name = decl_name_index;
535 if (mangle_name) {560 if (mangle_name) {
536 // we specified a specific name for the symbol that does not match the import name561 // 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);
538 }563 }
539564
540 if (type_index) |ty_index| {565 if (type_index) |ty_index| {
...@@ -557,22 +582,22 @@ pub fn addOrUpdateImport(...@@ -557,22 +582,22 @@ pub fn addOrUpdateImport(
557/// such as an exported or imported symbol.582/// such as an exported or imported symbol.
558/// If the symbol does not yet exist, creates a new one symbol instead583/// If the symbol does not yet exist, creates a new one symbol instead
559/// and then returns the index to it.584/// 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 {
561 const name_index = try zig_object.string_table.insert(gpa, name);586 const name_index = try zig_object.string_table.insert(gpa, name);
562 const gop = try zig_object.global_syms.getOrPut(gpa, name_index);587 const gop = try zig_object.global_syms.getOrPut(gpa, name_index);
563 if (gop.found_existing) {588 if (gop.found_existing) {
564 return gop.value_ptr.*;589 return gop.value_ptr.*;
565 }590 }
566591
567 var symbol: Symbol = .{592 var sym: Symbol = .{
568 .name = name_index,593 .name = name_index,
569 .flags = 0,594 .flags = 0,
570 .index = undefined, // index to type will be set after merging symbols595 .index = undefined, // index to type will be set after merging symbols
571 .tag = tag,596 .tag = .function,
572 .virtual_address = std.math.maxInt(u32),597 .virtual_address = std.math.maxInt(u32),
573 };598 };
574 symbol.setGlobal(true);599 sym.setGlobal(true);
575 symbol.setUndefined(true);600 sym.setUndefined(true);
576601
577 const sym_index = if (zig_object.symbols_free_list.popOrNull()) |index| index else blk: {602 const sym_index = if (zig_object.symbols_free_list.popOrNull()) |index| index else blk: {
578 const index: u32 = @intCast(zig_object.symbols.items.len);603 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...@@ -580,7 +605,7 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
580 zig_object.symbols.items.len += 1;605 zig_object.symbols.items.len += 1;
581 break :blk index;606 break :blk index;
582 };607 };
583 zig_object.symbols.items[sym_index] = symbol;608 zig_object.symbols.items[sym_index] = sym;
584 gop.value_ptr.* = sym_index;609 gop.value_ptr.* = sym_index;
585 return sym_index;610 return sym_index;
586}611}
...@@ -675,8 +700,8 @@ pub fn deleteDeclExport(...@@ -675,8 +700,8 @@ pub fn deleteDeclExport(
675 const atom_index = zig_object.decls.get(decl_index) orelse return;700 const atom_index = zig_object.decls.get(decl_index) orelse return;
676 const sym_index = wasm_file.getAtom(atom_index).sym_index;701 const sym_index = wasm_file.getAtom(atom_index).sym_index;
677 const loc: Wasm.SymbolLoc = .{ .file = null, .index = sym_index };702 const loc: Wasm.SymbolLoc = .{ .file = null, .index = sym_index };
678 const symbol = loc.getSymbol(wasm_file);703 const sym = loc.getSymbol(wasm_file);
679 std.debug.assert(zig_object.global_syms.remove(symbol.name));704 std.debug.assert(zig_object.global_syms.remove(sym.name));
680}705}
681706
682pub fn updateExports(707pub fn updateExports(
...@@ -694,7 +719,7 @@ pub fn updateExports(...@@ -694,7 +719,7 @@ pub fn updateExports(
694 },719 },
695 };720 };
696 const decl = mod.declPtr(decl_index);721 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);
698 const atom = wasm_file.getAtom(atom_index);723 const atom = wasm_file.getAtom(atom_index);
699 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;724 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
700 const gpa = mod.gpa;725 const gpa = mod.gpa;
...@@ -722,24 +747,24 @@ pub fn updateExports(...@@ -722,24 +747,24 @@ pub fn updateExports(
722 },747 },
723 .decl_index => |i| i,748 .decl_index => |i| i,
724 };749 };
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);
726 const exported_atom = wasm_file.getAtom(exported_atom_index);751 const exported_atom = wasm_file.getAtom(exported_atom_index);
727 // const export_name = try zig_object.string_table.put(gpa, mod.intern_pool.stringToSlice(exp.opts.name));752 // const export_name = try zig_object.string_table.put(gpa, mod.intern_pool.stringToSlice(exp.opts.name));
728 const sym_loc = exported_atom.symbolLoc();753 const sym_loc = exported_atom.symbolLoc();
729 const symbol = sym_loc.getSymbol(wasm_file);754 const sym = sym_loc.getSymbol(wasm_file);
730 symbol.setGlobal(true);755 sym.setGlobal(true);
731 symbol.setUndefined(false);756 sym.setUndefined(false);
732 symbol.index = atom_sym.index;757 sym.index = atom_sym.index;
733 symbol.tag = atom_sym.tag;758 sym.tag = atom_sym.tag;
734 symbol.name = atom_sym.name;759 sym.name = atom_sym.name;
735760
736 switch (exp.opts.linkage) {761 switch (exp.opts.linkage) {
737 .Internal => {762 .Internal => {
738 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);763 sym.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
739 symbol.setFlag(.WASM_SYM_BINDING_WEAK);764 sym.setFlag(.WASM_SYM_BINDING_WEAK);
740 },765 },
741 .Weak => {766 .Weak => {
742 symbol.setFlag(.WASM_SYM_BINDING_WEAK);767 sym.setFlag(.WASM_SYM_BINDING_WEAK);
743 },768 },
744 .Strong => {}, // symbols are strong by default769 .Strong => {}, // symbols are strong by default
745 .LinkOnce => {770 .LinkOnce => {
...@@ -840,7 +865,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool...@@ -840,7 +865,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
840 }865 }
841}866}
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 {
844 var index: u32 = 0;869 var index: u32 = 0;
845 while (index < zig_object.func_types.items.len) : (index += 1) {870 while (index < zig_object.func_types.items.len) : (index += 1) {
846 if (zig_object.func_types.items[index].eql(func_type)) return index;871 if (zig_object.func_types.items[index].eql(func_type)) return index;
...@@ -1115,6 +1140,16 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {...@@ -1115,6 +1140,16 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {
1115 try allocAtom(zig_object, &zig_object.debug_pubtypes_index, zig_object.debug_pubtypes_atom.?);1140 try allocAtom(zig_object, &zig_object.debug_pubtypes_index, zig_object.debug_pubtypes_atom.?);
1116}1141}
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
1118const build_options = @import("build_options");1153const build_options = @import("build_options");
1119const builtin = @import("builtin");1154const builtin = @import("builtin");
1120const codegen = @import("../../codegen.zig");1155const codegen = @import("../../codegen.zig");