authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-03-08 06:27:03+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-03-18 16:12:42+01:00
logbddf138e7285eefb86ef880e1200a929193da40b
tree7f5fa11e597ff892801968de310e3b2b95b50c7f
parentc31007bb47a4d1d62917324a33e9a9a6cd1df5a6
signaturelock-open Commit is signed but in an unrecognized format.

wasm-link: fix storing decls in the right segment

When a decl is `undefined` is must be stored in the data segment when the build mode is safe. For unsafe optimize modes, it must be stored in the bss segment instead. For mutable decls where the atom contains all zeroes, it must always be stored in the bss segment. All other values will result in the atom being stored in the data segment.

1 files changed, 12 insertions(+), 3 deletions(-)

src/link/Wasm.zig+12-3
......@@ -2828,22 +2828,31 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
28282828 const decl = mod.declPtr(entry.key_ptr.*);
28292829 if (decl.isExtern()) continue;
28302830 const atom_index = entry.value_ptr.*;
2831 const atom = wasm.getAtomPtr(atom_index);
28312832 if (decl.ty.zigTypeTag() == .Fn) {
28322833 try wasm.parseAtom(atom_index, .function);
28332834 } else if (decl.getVariable()) |variable| {
28342835 if (!variable.is_mutable) {
28352836 try wasm.parseAtom(atom_index, .{ .data = .read_only });
28362837 } else if (variable.init.isUndefDeep()) {
2837 try wasm.parseAtom(atom_index, .{ .data = .uninitialized });
2838 // for safe build modes, we store the atom in the data segment,
2839 // whereas for unsafe build modes we store it in bss.
2840 const is_initialized = wasm.base.options.optimize_mode == .Debug or
2841 wasm.base.options.optimize_mode == .ReleaseSafe;
2842 try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized });
28382843 } else {
2839 try wasm.parseAtom(atom_index, .{ .data = .initialized });
2844 // when the decl is all zeroes, we store the atom in the bss segment,
2845 // in all other cases it will be in the data segment.
2846 const is_zeroes = for (atom.code.items) |byte| {
2847 if (byte != 0) break false;
2848 } else true;
2849 try wasm.parseAtom(atom_index, .{ .data = if (is_zeroes) .uninitialized else .initialized });
28402850 }
28412851 } else {
28422852 try wasm.parseAtom(atom_index, .{ .data = .read_only });
28432853 }
28442854
28452855 // also parse atoms for a decl's locals
2846 const atom = wasm.getAtomPtr(atom_index);
28472856 for (atom.locals.items) |local_atom_index| {
28482857 try wasm.parseAtom(local_atom_index, .{ .data = .read_only });
28492858 }