| ... | ... | @@ -1143,9 +1143,29 @@ pub fn addOrUpdateImport( |
| 1143 | 1143 | } else @panic("TODO: Implement undefined symbols for non-function declarations"); |
| 1144 | 1144 | } |
| 1145 | 1145 | |
| 1146 | /// Kind represents the type of an Atom, which is only |
| 1147 | /// used to parse a decl into an Atom to define in which section |
| 1148 | /// or segment it should be placed. |
| 1146 | 1149 | const Kind = union(enum) { |
| 1147 | | data: void, |
| 1150 | /// Represents the segment the data symbol should |
| 1151 | /// be inserted into. |
| 1152 | /// TODO: Add TLS segments |
| 1153 | data: enum { |
| 1154 | read_only, |
| 1155 | uninitialized, |
| 1156 | initialized, |
| 1157 | }, |
| 1148 | 1158 | function: FnData, |
| 1159 | |
| 1160 | /// Returns the segment name the data kind represents. |
| 1161 | /// Asserts `kind` has its active tag set to `data`. |
| 1162 | fn segmentName(kind: Kind) []const u8 { |
| 1163 | switch (kind.data) { |
| 1164 | .read_only => return ".rodata.", |
| 1165 | .uninitialized => return ".bss.", |
| 1166 | .initialized => return ".data.", |
| 1167 | } |
| 1168 | } |
| 1149 | 1169 | }; |
| 1150 | 1170 | |
| 1151 | 1171 | /// Parses an Atom and inserts its metadata into the corresponding sections. |
| ... | ... | @@ -1174,9 +1194,8 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void { |
| 1174 | 1194 | break :result self.code_section_index.?; |
| 1175 | 1195 | }, |
| 1176 | 1196 | .data => result: { |
| 1177 | | // TODO: Add mutables global decls to .bss section instead |
| 1178 | 1197 | const segment_name = try std.mem.concat(self.base.allocator, u8, &.{ |
| 1179 | | ".rodata.", |
| 1198 | kind.segmentName(), |
| 1180 | 1199 | self.string_table.get(symbol.name), |
| 1181 | 1200 | }); |
| 1182 | 1201 | errdefer self.base.allocator.free(segment_name); |
| ... | ... | @@ -1722,8 +1741,8 @@ fn populateErrorNameTable(self: *Wasm) !void { |
| 1722 | 1741 | |
| 1723 | 1742 | // link the atoms with the rest of the binary so they can be allocated |
| 1724 | 1743 | // and relocations will be performed. |
| 1725 | | try self.parseAtom(atom, .data); |
| 1726 | | try self.parseAtom(names_atom, .data); |
| 1744 | try self.parseAtom(atom, .{ .data = .read_only }); |
| 1745 | try self.parseAtom(names_atom, .{ .data = .read_only }); |
| 1727 | 1746 | } |
| 1728 | 1747 | |
| 1729 | 1748 | pub fn getDebugInfoIndex(self: *Wasm) !u32 { |
| ... | ... | @@ -1866,13 +1885,21 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1866 | 1885 | const atom = &decl.*.link.wasm; |
| 1867 | 1886 | if (decl.ty.zigTypeTag() == .Fn) { |
| 1868 | 1887 | try self.parseAtom(atom, .{ .function = decl.fn_link.wasm }); |
| 1888 | } else if (decl.getVariable()) |variable| { |
| 1889 | if (!variable.is_mutable) { |
| 1890 | try self.parseAtom(atom, .{ .data = .read_only }); |
| 1891 | } else if (variable.init.isUndefDeep()) { |
| 1892 | try self.parseAtom(atom, .{ .data = .uninitialized }); |
| 1893 | } else { |
| 1894 | try self.parseAtom(atom, .{ .data = .initialized }); |
| 1895 | } |
| 1869 | 1896 | } else { |
| 1870 | | try self.parseAtom(atom, .data); |
| 1897 | try self.parseAtom(atom, .{ .data = .read_only }); |
| 1871 | 1898 | } |
| 1872 | 1899 | |
| 1873 | 1900 | // also parse atoms for a decl's locals |
| 1874 | 1901 | for (atom.locals.items) |*local_atom| { |
| 1875 | | try self.parseAtom(local_atom, .data); |
| 1902 | try self.parseAtom(local_atom, .{ .data = .read_only }); |
| 1876 | 1903 | } |
| 1877 | 1904 | } |
| 1878 | 1905 | |
| ... | ... | @@ -2167,7 +2194,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2167 | 2194 | while (it.next()) |entry| { |
| 2168 | 2195 | // do not output 'bss' section unless we import memory and therefore |
| 2169 | 2196 | // want to guarantee the data is zero initialized |
| 2170 | | if (std.mem.eql(u8, entry.key_ptr.*, ".bss") and !import_memory) continue; |
| 2197 | if (!import_memory and std.mem.eql(u8, entry.key_ptr.*, ".bss")) continue; |
| 2171 | 2198 | segment_count += 1; |
| 2172 | 2199 | const atom_index = entry.value_ptr.*; |
| 2173 | 2200 | var atom: *Atom = self.atoms.getPtr(atom_index).?.*.getFirst(); |