| ... | @@ -54,7 +54,7 @@ entry_addr: ?u32 = null, | ... | @@ -54,7 +54,7 @@ entry_addr: ?u32 = null, |
| 54 | lazy_syms: LazySymbolTable = .{}, | 54 | lazy_syms: LazySymbolTable = .{}, |
| 55 | | 55 | |
| 56 | /// Table of tracked Decls. | 56 | /// Table of tracked Decls. |
| 57 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, | 57 | decls: DeclTable = .{}, |
| 58 | | 58 | |
| 59 | /// List of atoms that are either synthetic or map directly to the Zig source program. | 59 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 60 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 60 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| ... | @@ -108,7 +108,8 @@ const HotUpdateState = struct { | ... | @@ -108,7 +108,8 @@ const HotUpdateState = struct { |
| 108 | loaded_base_address: ?std.os.windows.HMODULE = null, | 108 | loaded_base_address: ?std.os.windows.HMODULE = null, |
| 109 | }; | 109 | }; |
| 110 | | 110 | |
| 111 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index); | 111 | const DeclTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata); |
| | 112 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); |
| 112 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); | 113 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 113 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 114 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 114 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); | 115 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| ... | @@ -325,7 +326,14 @@ pub fn deinit(self: *Coff) void { | ... | @@ -325,7 +326,14 @@ pub fn deinit(self: *Coff) void { |
| 325 | atoms.deinit(gpa); | 326 | atoms.deinit(gpa); |
| 326 | } | 327 | } |
| 327 | self.unnamed_const_atoms.deinit(gpa); | 328 | self.unnamed_const_atoms.deinit(gpa); |
| 328 | self.anon_decls.deinit(gpa); | 329 | |
| | 330 | { |
| | 331 | var it = self.anon_decls.iterator(); |
| | 332 | while (it.next()) |entry| { |
| | 333 | entry.value_ptr.exports.deinit(gpa); |
| | 334 | } |
| | 335 | self.anon_decls.deinit(gpa); |
| | 336 | } |
| 329 | | 337 | |
| 330 | for (self.relocs.values()) |*relocs| { | 338 | for (self.relocs.values()) |*relocs| { |
| 331 | relocs.deinit(gpa); | 339 | relocs.deinit(gpa); |
| ... | @@ -1462,62 +1470,66 @@ pub fn updateExports( | ... | @@ -1462,62 +1470,66 @@ pub fn updateExports( |
| 1462 | | 1470 | |
| 1463 | const gpa = self.base.allocator; | 1471 | const gpa = self.base.allocator; |
| 1464 | | 1472 | |
| 1465 | const decl_index = switch (exported) { | 1473 | const metadata = switch (exported) { |
| 1466 | .decl_index => |i| i, | 1474 | .decl_index => |decl_index| blk: { |
| 1467 | .value => |val| { | 1475 | _ = try self.getOrCreateAtomForDecl(decl_index); |
| 1468 | _ = val; | 1476 | break :blk self.decls.getPtr(decl_index).?; |
| 1469 | @panic("TODO: implement COFF linker code for exporting a constant value"); | 1477 | }, |
| | 1478 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { |
| | 1479 | const first_exp = exports[0]; |
| | 1480 | const res = try self.lowerAnonDecl(value, .none, first_exp.getSrcLoc(mod)); |
| | 1481 | switch (res) { |
| | 1482 | .ok => {}, |
| | 1483 | .fail => |em| { |
| | 1484 | // TODO maybe it's enough to return an error here and let Module.processExportsInner |
| | 1485 | // handle the error? |
| | 1486 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); |
| | 1487 | mod.failed_exports.putAssumeCapacityNoClobber(first_exp, em); |
| | 1488 | return; |
| | 1489 | }, |
| | 1490 | } |
| | 1491 | break :blk self.anon_decls.getPtr(value).?; |
| 1470 | }, | 1492 | }, |
| 1471 | }; | 1493 | }; |
| 1472 | const decl = mod.declPtr(decl_index); | 1494 | const atom_index = metadata.atom; |
| 1473 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); | | |
| 1474 | const atom = self.getAtom(atom_index); | 1495 | const atom = self.getAtom(atom_index); |
| 1475 | const decl_metadata = self.decls.getPtr(decl_index).?; | | |
| 1476 | | 1496 | |
| 1477 | for (exports) |exp| { | 1497 | for (exports) |exp| { |
| 1478 | log.debug("adding new export '{}'", .{exp.opts.name.fmt(&mod.intern_pool)}); | 1498 | log.debug("adding new export '{}'", .{exp.opts.name.fmt(&mod.intern_pool)}); |
| 1479 | | 1499 | |
| 1480 | if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section_name| { | 1500 | if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section_name| { |
| 1481 | if (!mem.eql(u8, section_name, ".text")) { | 1501 | if (!mem.eql(u8, section_name, ".text")) { |
| 1482 | try mod.failed_exports.putNoClobber( | 1502 | try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create( |
| 1483 | gpa, | 1503 | gpa, |
| 1484 | exp, | 1504 | exp.getSrcLoc(mod), |
| 1485 | try Module.ErrorMsg.create( | 1505 | "Unimplemented: ExportOptions.section", |
| 1486 | gpa, | 1506 | .{}, |
| 1487 | decl.srcLoc(mod), | 1507 | )); |
| 1488 | "Unimplemented: ExportOptions.section", | | |
| 1489 | .{}, | | |
| 1490 | ), | | |
| 1491 | ); | | |
| 1492 | continue; | 1508 | continue; |
| 1493 | } | 1509 | } |
| 1494 | } | 1510 | } |
| 1495 | | 1511 | |
| 1496 | if (exp.opts.linkage == .LinkOnce) { | 1512 | if (exp.opts.linkage == .LinkOnce) { |
| 1497 | try mod.failed_exports.putNoClobber( | 1513 | try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create( |
| 1498 | gpa, | 1514 | gpa, |
| 1499 | exp, | 1515 | exp.getSrcLoc(mod), |
| 1500 | try Module.ErrorMsg.create( | 1516 | "Unimplemented: GlobalLinkage.LinkOnce", |
| 1501 | gpa, | 1517 | .{}, |
| 1502 | decl.srcLoc(mod), | 1518 | )); |
| 1503 | "Unimplemented: GlobalLinkage.LinkOnce", | | |
| 1504 | .{}, | | |
| 1505 | ), | | |
| 1506 | ); | | |
| 1507 | continue; | 1519 | continue; |
| 1508 | } | 1520 | } |
| 1509 | | 1521 | |
| 1510 | const sym_index = decl_metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { | 1522 | const sym_index = metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { |
| 1511 | const sym_index = try self.allocateSymbol(); | 1523 | const sym_index = try self.allocateSymbol(); |
| 1512 | try decl_metadata.exports.append(gpa, sym_index); | 1524 | try metadata.exports.append(gpa, sym_index); |
| 1513 | break :blk sym_index; | 1525 | break :blk sym_index; |
| 1514 | }; | 1526 | }; |
| 1515 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1527 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1516 | const sym = self.getSymbolPtr(sym_loc); | 1528 | const sym = self.getSymbolPtr(sym_loc); |
| 1517 | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); | 1529 | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); |
| 1518 | sym.value = atom.getSymbol(self).value; | 1530 | sym.value = atom.getSymbol(self).value; |
| 1519 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(self.text_section_index.? + 1)); | 1531 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(metadata.section + 1)); |
| 1520 | sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL }; | 1532 | sym.type = atom.getSymbol(self).type; |
| 1521 | | 1533 | |
| 1522 | switch (exp.opts.linkage) { | 1534 | switch (exp.opts.linkage) { |
| 1523 | .Strong => { | 1535 | .Strong => { |
| ... | @@ -1761,8 +1773,8 @@ pub fn lowerAnonDecl( | ... | @@ -1761,8 +1773,8 @@ pub fn lowerAnonDecl( |
| 1761 | .none => ty.abiAlignment(mod), | 1773 | .none => ty.abiAlignment(mod), |
| 1762 | else => explicit_alignment, | 1774 | else => explicit_alignment, |
| 1763 | }; | 1775 | }; |
| 1764 | if (self.anon_decls.get(decl_val)) |atom_index| { | 1776 | if (self.anon_decls.get(decl_val)) |metadata| { |
| 1765 | const existing_addr = self.getAtom(atom_index).getSymbol(self).value; | 1777 | const existing_addr = self.getAtom(metadata.atom).getSymbol(self).value; |
| 1766 | if (decl_alignment.check(existing_addr)) | 1778 | if (decl_alignment.check(existing_addr)) |
| 1767 | return .ok; | 1779 | return .ok; |
| 1768 | } | 1780 | } |
| ... | @@ -1792,14 +1804,14 @@ pub fn lowerAnonDecl( | ... | @@ -1792,14 +1804,14 @@ pub fn lowerAnonDecl( |
| 1792 | .ok => |atom_index| atom_index, | 1804 | .ok => |atom_index| atom_index, |
| 1793 | .fail => |em| return .{ .fail = em }, | 1805 | .fail => |em| return .{ .fail = em }, |
| 1794 | }; | 1806 | }; |
| 1795 | try self.anon_decls.put(gpa, decl_val, atom_index); | 1807 | try self.anon_decls.put(gpa, decl_val, .{ .atom = atom_index, .section = self.rdata_section_index.? }); |
| 1796 | return .ok; | 1808 | return .ok; |
| 1797 | } | 1809 | } |
| 1798 | | 1810 | |
| 1799 | pub fn getAnonDeclVAddr(self: *Coff, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1811 | pub fn getAnonDeclVAddr(self: *Coff, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 1800 | assert(self.llvm_object == null); | 1812 | assert(self.llvm_object == null); |
| 1801 | | 1813 | |
| 1802 | const this_atom_index = self.anon_decls.get(decl_val).?; | 1814 | const this_atom_index = self.anon_decls.get(decl_val).?.atom; |
| 1803 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; | 1815 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; |
| 1804 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; | 1816 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; |
| 1805 | const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1817 | const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |