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...@@ -2828,22 +2828,31 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
2828 const decl = mod.declPtr(entry.key_ptr.*);2828 const decl = mod.declPtr(entry.key_ptr.*);
2829 if (decl.isExtern()) continue;2829 if (decl.isExtern()) continue;
2830 const atom_index = entry.value_ptr.*;2830 const atom_index = entry.value_ptr.*;
2831 const atom = wasm.getAtomPtr(atom_index);
2831 if (decl.ty.zigTypeTag() == .Fn) {2832 if (decl.ty.zigTypeTag() == .Fn) {
2832 try wasm.parseAtom(atom_index, .function);2833 try wasm.parseAtom(atom_index, .function);
2833 } else if (decl.getVariable()) |variable| {2834 } else if (decl.getVariable()) |variable| {
2834 if (!variable.is_mutable) {2835 if (!variable.is_mutable) {
2835 try wasm.parseAtom(atom_index, .{ .data = .read_only });2836 try wasm.parseAtom(atom_index, .{ .data = .read_only });
2836 } else if (variable.init.isUndefDeep()) {2837 } 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 });
2838 } else {2843 } 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 });
2840 }2850 }
2841 } else {2851 } else {
2842 try wasm.parseAtom(atom_index, .{ .data = .read_only });2852 try wasm.parseAtom(atom_index, .{ .data = .read_only });
2843 }2853 }
28442854
2845 // also parse atoms for a decl's locals2855 // also parse atoms for a decl's locals
2846 const atom = wasm.getAtomPtr(atom_index);
2847 for (atom.locals.items) |local_atom_index| {2856 for (atom.locals.items) |local_atom_index| {
2848 try wasm.parseAtom(local_atom_index, .{ .data = .read_only });2857 try wasm.parseAtom(local_atom_index, .{ .data = .read_only });
2849 }2858 }