| ... | @@ -1209,9 +1209,10 @@ fn resolveLazySymbols(wasm: *Wasm) !void { | ... | @@ -1209,9 +1209,10 @@ fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1209 | try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); | 1209 | try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); |
| 1210 | } | 1210 | } |
| 1211 | } | 1211 | } |
| 1212 | if (wasm.undefs.fetchSwapRemove("__zig_lt_errors_len")) |kv| { | 1212 | if (wasm.undefs.fetchSwapRemove("__zig_errors_len")) |kv| { |
| 1213 | const loc = try wasm.createSyntheticSymbol("__zig_lt_errors_len", .function); | 1213 | const loc = try wasm.createSyntheticSymbol("__zig_errors_len", .data); |
| 1214 | try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); | 1214 | try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc); |
| | 1215 | _ = wasm.resolved_symbols.swapRemove(kv.value); |
| 1215 | } | 1216 | } |
| 1216 | } | 1217 | } |
| 1217 | | 1218 | |
| ... | @@ -2189,44 +2190,41 @@ fn setupInitFunctions(wasm: *Wasm) !void { | ... | @@ -2189,44 +2190,41 @@ fn setupInitFunctions(wasm: *Wasm) !void { |
| 2189 | std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan); | 2190 | std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan); |
| 2190 | } | 2191 | } |
| 2191 | | 2192 | |
| 2192 | /// Generates the function which verifies if an integer value is less than the | 2193 | /// Generates an atom containing the global error set' size. |
| 2193 | /// amount of error values. This will only be generated if the symbol exists. | 2194 | /// This will only be generated if the symbol exists. |
| 2194 | fn setupLtErrorsLenFunction(wasm: *Wasm) !void { | 2195 | fn setupErrorsLen(wasm: *Wasm) !void { |
| 2195 | if (wasm.findGlobalSymbol("__zig_lt_errors_len") == null) return; | 2196 | const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return; |
| 2196 | const errors_len = wasm.base.options.module.?.global_error_set.count(); | | |
| 2197 | | | |
| 2198 | var body_list = std.ArrayList(u8).init(wasm.base.allocator); | | |
| 2199 | defer body_list.deinit(); | | |
| 2200 | const writer = body_list.writer(); | | |
| 2201 | | | |
| 2202 | { | | |
| 2203 | // generates bytecode for the following function: | | |
| 2204 | // fn (index: u16) bool { | | |
| 2205 | // return index < errors_len; | | |
| 2206 | // } | | |
| 2207 | | | |
| 2208 | // no locals | | |
| 2209 | try leb.writeULEB128(writer, @as(u32, 0)); | | |
| 2210 | | | |
| 2211 | // get argument | | |
| 2212 | try writer.writeByte(std.wasm.opcode(.local_get)); | | |
| 2213 | try leb.writeULEB128(writer, @as(u32, 0)); | | |
| 2214 | | | |
| 2215 | // get error length | | |
| 2216 | try writer.writeByte(std.wasm.opcode(.i32_const)); | | |
| 2217 | try leb.writeULEB128(writer, @intCast(u32, errors_len)); | | |
| 2218 | | | |
| 2219 | try writer.writeByte(std.wasm.opcode(.i32_lt_u)); | | |
| 2220 | | | |
| 2221 | // stack values are implicit return values so keep the value | | |
| 2222 | // on the stack and end the function. | | |
| 2223 | | 2197 | |
| 2224 | // end function | 2198 | const errors_len = wasm.base.options.module.?.global_error_set.count(); |
| 2225 | try writer.writeByte(std.wasm.opcode(.end)); | 2199 | // overwrite existing atom if it already exists (maybe the error set has increased) |
| 2226 | } | 2200 | // if not, allcoate a new atom. |
| | 2201 | const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: { |
| | 2202 | const atom = wasm.getAtomPtr(index); |
| | 2203 | if (atom.next) |next_atom_index| { |
| | 2204 | const next_atom = wasm.getAtomPtr(next_atom_index); |
| | 2205 | next_atom.prev = atom.prev; |
| | 2206 | atom.next = null; |
| | 2207 | } |
| | 2208 | if (atom.prev) |prev_index| { |
| | 2209 | const prev_atom = wasm.getAtomPtr(prev_index); |
| | 2210 | prev_atom.next = atom.next; |
| | 2211 | atom.prev = null; |
| | 2212 | } |
| | 2213 | atom.deinit(wasm); |
| | 2214 | break :blk index; |
| | 2215 | } else new_atom: { |
| | 2216 | const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len); |
| | 2217 | try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index); |
| | 2218 | try wasm.managed_atoms.append(wasm.base.allocator, undefined); |
| | 2219 | break :new_atom atom_index; |
| | 2220 | }; |
| | 2221 | const atom = wasm.getAtomPtr(atom_index); |
| | 2222 | atom.* = Atom.empty; |
| | 2223 | atom.sym_index = loc.index; |
| | 2224 | atom.size = 2; |
| | 2225 | try atom.code.writer(wasm.base.allocator).writeIntLittle(u16, @intCast(u16, errors_len)); |
| 2227 | | 2226 | |
| 2228 | const func_type: std.wasm.Type = .{ .params = &.{std.wasm.Valtype.i32}, .returns = &.{std.wasm.Valtype.i32} }; | 2227 | try wasm.parseAtom(atom_index, .{ .data = .read_only }); |
| 2229 | try wasm.createSyntheticFunction("__zig_lt_errors_len", func_type, &body_list); | | |
| 2230 | } | 2228 | } |
| 2231 | | 2229 | |
| 2232 | /// Creates a function body for the `__wasm_call_ctors` symbol. | 2230 | /// Creates a function body for the `__wasm_call_ctors` symbol. |
| ... | @@ -3361,6 +3359,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3361,6 +3359,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3361 | // So we can rebuild the binary file on each incremental update | 3359 | // So we can rebuild the binary file on each incremental update |
| 3362 | defer wasm.resetState(); | 3360 | defer wasm.resetState(); |
| 3363 | try wasm.setupInitFunctions(); | 3361 | try wasm.setupInitFunctions(); |
| | 3362 | try wasm.setupErrorsLen(); |
| 3364 | try wasm.setupStart(); | 3363 | try wasm.setupStart(); |
| 3365 | try wasm.setupImports(); | 3364 | try wasm.setupImports(); |
| 3366 | if (wasm.base.options.module) |mod| { | 3365 | if (wasm.base.options.module) |mod| { |
| ... | @@ -3423,7 +3422,6 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -3423,7 +3422,6 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3423 | try wasm.setupInitMemoryFunction(); | 3422 | try wasm.setupInitMemoryFunction(); |
| 3424 | try wasm.setupTLSRelocationsFunction(); | 3423 | try wasm.setupTLSRelocationsFunction(); |
| 3425 | try wasm.initializeTLSFunction(); | 3424 | try wasm.initializeTLSFunction(); |
| 3426 | try wasm.setupLtErrorsLenFunction(); | | |
| 3427 | try wasm.setupExports(); | 3425 | try wasm.setupExports(); |
| 3428 | try wasm.writeToFile(enabled_features, emit_features_count, arena); | 3426 | try wasm.writeToFile(enabled_features, emit_features_count, arena); |
| 3429 | } | 3427 | } |