| author | |
| committer | |
| log | cf9735a5e06d302a29d70c737aefd505ca34e0fa |
| tree | 03ab9b4214484497990249099af9b41b292f350a |
| parent | 098a07dc45b678af22bb47379e75371767385cbf |
3 files changed, 95 insertions(+), 78 deletions(-)
src/link/Coff.zig+40-35| ... | ... | @@ -1737,46 +1737,51 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link |
| 1737 | 1737 | return 0; |
| 1738 | 1738 | } |
| 1739 | 1739 | |
| 1740 | pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1741 | // This is basically the same as lowerUnnamedConst. | |
| 1742 | // example: | |
| 1743 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 1744 | // const val = decl_val.toValue(); | |
| 1745 | // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`. | |
| 1746 | // It doesn't have an owner decl because it's just an unnamed constant that might | |
| 1747 | // be used by more than one function, however, its address is being used so we need | |
| 1748 | // to put it in some location. | |
| 1749 | // ... | |
| 1740 | pub fn lowerAnonDecl( | |
| 1741 | self: *Coff, | |
| 1742 | decl_val: InternPool.Index, | |
| 1743 | explicit_alignment: InternPool.Alignment, | |
| 1744 | src_loc: Module.SrcLoc, | |
| 1745 | ) !codegen.Result { | |
| 1750 | 1746 | const gpa = self.base.allocator; |
| 1751 | 1747 | const mod = self.base.options.module.?; |
| 1752 | 1748 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 1753 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); | |
| 1754 | const required_alignment = switch (decl_align) { | |
| 1749 | const decl_alignment = switch (explicit_alignment) { | |
| 1755 | 1750 | .none => ty.abiAlignment(mod), |
| 1756 | else => decl_align, | |
| 1751 | else => explicit_alignment, | |
| 1757 | 1752 | }; |
| 1758 | if (!gop.found_existing or | |
| 1759 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value)) | |
| 1760 | { | |
| 1761 | const val = decl_val.toValue(); | |
| 1762 | const tv = TypedValue{ .ty = ty, .val = val }; | |
| 1763 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); | |
| 1764 | defer gpa.free(name); | |
| 1765 | const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) { | |
| 1766 | else => { | |
| 1767 | // TODO improve error message | |
| 1768 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ | |
| 1769 | @errorName(err), | |
| 1770 | }); | |
| 1771 | return .{ .fail = em }; | |
| 1772 | }, | |
| 1773 | }; | |
| 1774 | const atom_index = switch (res) { | |
| 1775 | .ok => |atom_index| atom_index, | |
| 1776 | .fail => |em| return .{ .fail = em }, | |
| 1777 | }; | |
| 1778 | gop.value_ptr.* = atom_index; | |
| 1779 | } | |
| 1753 | if (self.anon_decls.get(decl_val)) |atom_index| { | |
| 1754 | const existing_addr = self.getAtom(atom_index).getSymbol(self).value; | |
| 1755 | if (decl_alignment.check(existing_addr)) | |
| 1756 | return .ok; | |
| 1757 | } | |
| 1758 | ||
| 1759 | const val = decl_val.toValue(); | |
| 1760 | const tv = TypedValue{ .ty = ty, .val = val }; | |
| 1761 | var name_buf: [32]u8 = undefined; | |
| 1762 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | |
| 1763 | @intFromEnum(decl_val), | |
| 1764 | }) catch unreachable; | |
| 1765 | const res = self.lowerConst( | |
| 1766 | name, | |
| 1767 | tv, | |
| 1768 | decl_alignment, | |
| 1769 | self.rdata_section_index.?, | |
| 1770 | src_loc, | |
| 1771 | ) catch |err| switch (err) { | |
| 1772 | error.OutOfMemory => return error.OutOfMemory, | |
| 1773 | else => |e| return .{ .fail = try Module.ErrorMsg.create( | |
| 1774 | gpa, | |
| 1775 | src_loc, | |
| 1776 | "lowerAnonDecl failed with error: {s}", | |
| 1777 | .{@errorName(e)}, | |
| 1778 | ) }, | |
| 1779 | }; | |
| 1780 | const atom_index = switch (res) { | |
| 1781 | .ok => |atom_index| atom_index, | |
| 1782 | .fail => |em| return .{ .fail = em }, | |
| 1783 | }; | |
| 1784 | try self.anon_decls.put(gpa, decl_val, atom_index); | |
| 1780 | 1785 | return .ok; |
| 1781 | 1786 | } |
| 1782 | 1787 |
src/link/MachO.zig+40-35| ... | ... | @@ -2866,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2866 | 2866 | return 0; |
| 2867 | 2867 | } |
| 2868 | 2868 | |
| 2869 | pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 2870 | // This is basically the same as lowerUnnamedConst. | |
| 2871 | // example: | |
| 2872 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 2873 | // const val = decl_val.toValue(); | |
| 2874 | // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`. | |
| 2875 | // It doesn't have an owner decl because it's just an unnamed constant that might | |
| 2876 | // be used by more than one function, however, its address is being used so we need | |
| 2877 | // to put it in some location. | |
| 2878 | // ... | |
| 2869 | pub fn lowerAnonDecl( | |
| 2870 | self: *MachO, | |
| 2871 | decl_val: InternPool.Index, | |
| 2872 | explicit_alignment: InternPool.Alignment, | |
| 2873 | src_loc: Module.SrcLoc, | |
| 2874 | ) !codegen.Result { | |
| 2879 | 2875 | const gpa = self.base.allocator; |
| 2880 | 2876 | const mod = self.base.options.module.?; |
| 2881 | 2877 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 2882 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); | |
| 2883 | const required_alignment = switch (decl_align) { | |
| 2878 | const decl_alignment = switch (explicit_alignment) { | |
| 2884 | 2879 | .none => ty.abiAlignment(mod), |
| 2885 | else => decl_align, | |
| 2880 | else => explicit_alignment, | |
| 2886 | 2881 | }; |
| 2887 | if (!gop.found_existing or | |
| 2888 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value)) | |
| 2889 | { | |
| 2890 | const val = decl_val.toValue(); | |
| 2891 | const tv = TypedValue{ .ty = ty, .val = val }; | |
| 2892 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); | |
| 2893 | defer gpa.free(name); | |
| 2894 | const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) { | |
| 2895 | else => { | |
| 2896 | // TODO improve error message | |
| 2897 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ | |
| 2898 | @errorName(err), | |
| 2899 | }); | |
| 2900 | return .{ .fail = em }; | |
| 2901 | }, | |
| 2902 | }; | |
| 2903 | const atom_index = switch (res) { | |
| 2904 | .ok => |atom_index| atom_index, | |
| 2905 | .fail => |em| return .{ .fail = em }, | |
| 2906 | }; | |
| 2907 | gop.value_ptr.* = atom_index; | |
| 2908 | } | |
| 2882 | if (self.anon_decls.get(decl_val)) |atom_index| { | |
| 2883 | const existing_addr = self.getAtom(atom_index).getSymbol(self).n_value; | |
| 2884 | if (decl_alignment.check(existing_addr)) | |
| 2885 | return .ok; | |
| 2886 | } | |
| 2887 | ||
| 2888 | const val = decl_val.toValue(); | |
| 2889 | const tv = TypedValue{ .ty = ty, .val = val }; | |
| 2890 | var name_buf: [32]u8 = undefined; | |
| 2891 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | |
| 2892 | @intFromEnum(decl_val), | |
| 2893 | }) catch unreachable; | |
| 2894 | const res = self.lowerConst( | |
| 2895 | name, | |
| 2896 | tv, | |
| 2897 | decl_alignment, | |
| 2898 | self.data_const_section_index.?, | |
| 2899 | src_loc, | |
| 2900 | ) catch |err| switch (err) { | |
| 2901 | error.OutOfMemory => return error.OutOfMemory, | |
| 2902 | else => |e| return .{ .fail = try Module.ErrorMsg.create( | |
| 2903 | gpa, | |
| 2904 | src_loc, | |
| 2905 | "unable to lower constant value: {s}", | |
| 2906 | .{@errorName(e)}, | |
| 2907 | ) }, | |
| 2908 | }; | |
| 2909 | const atom_index = switch (res) { | |
| 2910 | .ok => |atom_index| atom_index, | |
| 2911 | .fail => |em| return .{ .fail = em }, | |
| 2912 | }; | |
| 2913 | try self.anon_decls.put(gpa, decl_val, atom_index); | |
| 2909 | 2914 | return .ok; |
| 2910 | 2915 | } |
| 2911 | 2916 |
src/link/Wasm.zig+15-8| ... | ... | @@ -1702,27 +1702,34 @@ pub fn getDeclVAddr( |
| 1702 | 1702 | return target_symbol_index; |
| 1703 | 1703 | } |
| 1704 | 1704 | |
| 1705 | pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1705 | pub fn lowerAnonDecl( | |
| 1706 | wasm: *Wasm, | |
| 1707 | decl_val: InternPool.Index, | |
| 1708 | explicit_alignment: Alignment, | |
| 1709 | src_loc: Module.SrcLoc, | |
| 1710 | ) !codegen.Result { | |
| 1706 | 1711 | const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val); |
| 1707 | 1712 | if (!gop.found_existing) { |
| 1708 | 1713 | const mod = wasm.base.options.module.?; |
| 1709 | 1714 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 1710 | 1715 | const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; |
| 1711 | const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)}); | |
| 1712 | defer wasm.base.allocator.free(name); | |
| 1716 | var name_buf: [32]u8 = undefined; | |
| 1717 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | |
| 1718 | @intFromEnum(decl_val), | |
| 1719 | }) catch unreachable; | |
| 1713 | 1720 | |
| 1714 | 1721 | switch (try wasm.lowerConst(name, tv, src_loc)) { |
| 1715 | .ok => |atom_index| gop.value_ptr.* = atom_index, | |
| 1722 | .ok => |atom_index| wasm.anon_decls.values()[gop.index] = atom_index, | |
| 1716 | 1723 | .fail => |em| return .{ .fail = em }, |
| 1717 | 1724 | } |
| 1718 | 1725 | } |
| 1719 | 1726 | |
| 1720 | const atom = wasm.getAtomPtr(gop.value_ptr.*); | |
| 1727 | const atom = wasm.getAtomPtr(wasm.anon_decls.values()[gop.index]); | |
| 1721 | 1728 | atom.alignment = switch (atom.alignment) { |
| 1722 | .none => decl_align, | |
| 1723 | else => switch (decl_align) { | |
| 1729 | .none => explicit_alignment, | |
| 1730 | else => switch (explicit_alignment) { | |
| 1724 | 1731 | .none => atom.alignment, |
| 1725 | else => atom.alignment.maxStrict(decl_align), | |
| 1732 | else => atom.alignment.maxStrict(explicit_alignment), | |
| 1726 | 1733 | }, |
| 1727 | 1734 | }; |
| 1728 | 1735 | return .ok; |