| 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,46 +1737,51 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link |
| 1737 | return 0; | 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 { | 1740 | pub fn lowerAnonDecl( |
| 1741 | // This is basically the same as lowerUnnamedConst. | 1741 | self: *Coff, |
| 1742 | // example: | 1742 | decl_val: InternPool.Index, |
| 1743 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); | 1743 | explicit_alignment: InternPool.Alignment, |
| 1744 | // const val = decl_val.toValue(); | 1744 | src_loc: Module.SrcLoc, |
| 1745 | // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`. | 1745 | ) !codegen.Result { |
| 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 | // ... | ||
| 1750 | const gpa = self.base.allocator; | 1746 | const gpa = self.base.allocator; |
| 1751 | const mod = self.base.options.module.?; | 1747 | const mod = self.base.options.module.?; |
| 1752 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | 1748 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 1753 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); | 1749 | const decl_alignment = switch (explicit_alignment) { |
| 1754 | const required_alignment = switch (decl_align) { | ||
| 1755 | .none => ty.abiAlignment(mod), | 1750 | .none => ty.abiAlignment(mod), |
| 1756 | else => decl_align, | 1751 | else => explicit_alignment, |
| 1757 | }; | 1752 | }; |
| 1758 | if (!gop.found_existing or | 1753 | if (self.anon_decls.get(decl_val)) |atom_index| { |
| 1759 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value)) | 1754 | const existing_addr = self.getAtom(atom_index).getSymbol(self).value; |
| 1760 | { | 1755 | if (decl_alignment.check(existing_addr)) |
| 1761 | const val = decl_val.toValue(); | 1756 | return .ok; |
| 1762 | const tv = TypedValue{ .ty = ty, .val = val }; | 1757 | } |
| 1763 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); | 1758 | |
| 1764 | defer gpa.free(name); | 1759 | const val = decl_val.toValue(); |
| 1765 | const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) { | 1760 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 1766 | else => { | 1761 | var name_buf: [32]u8 = undefined; |
| 1767 | // TODO improve error message | 1762 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 1768 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ | 1763 | @intFromEnum(decl_val), |
| 1769 | @errorName(err), | 1764 | }) catch unreachable; |
| 1770 | }); | 1765 | const res = self.lowerConst( |
| 1771 | return .{ .fail = em }; | 1766 | name, |
| 1772 | }, | 1767 | tv, |
| 1773 | }; | 1768 | decl_alignment, |
| 1774 | const atom_index = switch (res) { | 1769 | self.rdata_section_index.?, |
| 1775 | .ok => |atom_index| atom_index, | 1770 | src_loc, |
| 1776 | .fail => |em| return .{ .fail = em }, | 1771 | ) catch |err| switch (err) { |
| 1777 | }; | 1772 | error.OutOfMemory => return error.OutOfMemory, |
| 1778 | gop.value_ptr.* = atom_index; | 1773 | else => |e| return .{ .fail = try Module.ErrorMsg.create( |
| 1779 | } | 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 | return .ok; | 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,46 +2866,51 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2866 | return 0; | 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 { | 2869 | pub fn lowerAnonDecl( |
| 2870 | // This is basically the same as lowerUnnamedConst. | 2870 | self: *MachO, |
| 2871 | // example: | 2871 | decl_val: InternPool.Index, |
| 2872 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); | 2872 | explicit_alignment: InternPool.Alignment, |
| 2873 | // const val = decl_val.toValue(); | 2873 | src_loc: Module.SrcLoc, |
| 2874 | // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`. | 2874 | ) !codegen.Result { |
| 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 | // ... | ||
| 2879 | const gpa = self.base.allocator; | 2875 | const gpa = self.base.allocator; |
| 2880 | const mod = self.base.options.module.?; | 2876 | const mod = self.base.options.module.?; |
| 2881 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | 2877 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 2882 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); | 2878 | const decl_alignment = switch (explicit_alignment) { |
| 2883 | const required_alignment = switch (decl_align) { | ||
| 2884 | .none => ty.abiAlignment(mod), | 2879 | .none => ty.abiAlignment(mod), |
| 2885 | else => decl_align, | 2880 | else => explicit_alignment, |
| 2886 | }; | 2881 | }; |
| 2887 | if (!gop.found_existing or | 2882 | if (self.anon_decls.get(decl_val)) |atom_index| { |
| 2888 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value)) | 2883 | const existing_addr = self.getAtom(atom_index).getSymbol(self).n_value; |
| 2889 | { | 2884 | if (decl_alignment.check(existing_addr)) |
| 2890 | const val = decl_val.toValue(); | 2885 | return .ok; |
| 2891 | const tv = TypedValue{ .ty = ty, .val = val }; | 2886 | } |
| 2892 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); | 2887 | |
| 2893 | defer gpa.free(name); | 2888 | const val = decl_val.toValue(); |
| 2894 | const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) { | 2889 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 2895 | else => { | 2890 | var name_buf: [32]u8 = undefined; |
| 2896 | // TODO improve error message | 2891 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 2897 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ | 2892 | @intFromEnum(decl_val), |
| 2898 | @errorName(err), | 2893 | }) catch unreachable; |
| 2899 | }); | 2894 | const res = self.lowerConst( |
| 2900 | return .{ .fail = em }; | 2895 | name, |
| 2901 | }, | 2896 | tv, |
| 2902 | }; | 2897 | decl_alignment, |
| 2903 | const atom_index = switch (res) { | 2898 | self.data_const_section_index.?, |
| 2904 | .ok => |atom_index| atom_index, | 2899 | src_loc, |
| 2905 | .fail => |em| return .{ .fail = em }, | 2900 | ) catch |err| switch (err) { |
| 2906 | }; | 2901 | error.OutOfMemory => return error.OutOfMemory, |
| 2907 | gop.value_ptr.* = atom_index; | 2902 | else => |e| return .{ .fail = try Module.ErrorMsg.create( |
| 2908 | } | 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 | return .ok; | 2914 | return .ok; |
| 2910 | } | 2915 | } |
| 2911 | 2916 |
src/link/Wasm.zig+15-8| ... | @@ -1702,27 +1702,34 @@ pub fn getDeclVAddr( | ... | @@ -1702,27 +1702,34 @@ pub fn getDeclVAddr( |
| 1702 | return target_symbol_index; | 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 | const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val); | 1711 | const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val); |
| 1707 | if (!gop.found_existing) { | 1712 | if (!gop.found_existing) { |
| 1708 | const mod = wasm.base.options.module.?; | 1713 | const mod = wasm.base.options.module.?; |
| 1709 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | 1714 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 1710 | const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; | 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)}); | 1716 | var name_buf: [32]u8 = undefined; |
| 1712 | defer wasm.base.allocator.free(name); | 1717 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 1718 | @intFromEnum(decl_val), | ||
| 1719 | }) catch unreachable; | ||
| 1713 | 1720 | ||
| 1714 | switch (try wasm.lowerConst(name, tv, src_loc)) { | 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 | .fail => |em| return .{ .fail = em }, | 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 | atom.alignment = switch (atom.alignment) { | 1728 | atom.alignment = switch (atom.alignment) { |
| 1722 | .none => decl_align, | 1729 | .none => explicit_alignment, |
| 1723 | else => switch (decl_align) { | 1730 | else => switch (explicit_alignment) { |
| 1724 | .none => atom.alignment, | 1731 | .none => atom.alignment, |
| 1725 | else => atom.alignment.maxStrict(decl_align), | 1732 | else => atom.alignment.maxStrict(explicit_alignment), |
| 1726 | }, | 1733 | }, |
| 1727 | }; | 1734 | }; |
| 1728 | return .ok; | 1735 | return .ok; |