@@ -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 ();
0 commit comments