Commit 6c1ab376dd
Changed files (2)
src
arch
wasm
link
src/arch/wasm/CodeGen.zig
@@ -3339,13 +3339,14 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const operand = try func.resolveInst(un_op);
- const sym_index = try func.bin_file.getGlobalSymbol("__zig_lt_errors_len", null);
+ const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
+ const errors_len = WValue{ .memory = sym_index };
try func.emitWValue(operand);
- try func.addLabel(.call, sym_index);
- const result = try func.allocLocal(Type.bool);
- try func.addLabel(.local_set, result.local.value);
- return func.finishAir(inst, result, &.{un_op});
+ const errors_len_val = try func.load(errors_len, Type.err_int, 0);
+ const result = try func.cmp(.stack, errors_len_val, Type.err_int, .lt);
+
+ return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
}
fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6518,7 +6519,6 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
- if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ty_op.operand});
const operand = try func.resolveInst(ty_op.operand);
const error_set_ty = func.air.getRefType(ty_op.ty);
src/link/Wasm.zig
@@ -1209,9 +1209,10 @@ fn resolveLazySymbols(wasm: *Wasm) !void {
try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
}
}
- if (wasm.undefs.fetchSwapRemove("__zig_lt_errors_len")) |kv| {
- const loc = try wasm.createSyntheticSymbol("__zig_lt_errors_len", .function);
+ if (wasm.undefs.fetchSwapRemove("__zig_errors_len")) |kv| {
+ const loc = try wasm.createSyntheticSymbol("__zig_errors_len", .data);
try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
+ _ = wasm.resolved_symbols.swapRemove(kv.value);
}
}
@@ -2189,44 +2190,41 @@ fn setupInitFunctions(wasm: *Wasm) !void {
std.sort.sort(InitFuncLoc, wasm.init_funcs.items, {}, InitFuncLoc.lessThan);
}
-/// Generates the function which verifies if an integer value is less than the
-/// amount of error values. This will only be generated if the symbol exists.
-fn setupLtErrorsLenFunction(wasm: *Wasm) !void {
- if (wasm.findGlobalSymbol("__zig_lt_errors_len") == null) return;
- const errors_len = wasm.base.options.module.?.global_error_set.count();
-
- var body_list = std.ArrayList(u8).init(wasm.base.allocator);
- defer body_list.deinit();
- const writer = body_list.writer();
-
- {
- // generates bytecode for the following function:
- // fn (index: u16) bool {
- // return index < errors_len;
- // }
-
- // no locals
- try leb.writeULEB128(writer, @as(u32, 0));
-
- // get argument
- try writer.writeByte(std.wasm.opcode(.local_get));
- try leb.writeULEB128(writer, @as(u32, 0));
-
- // get error length
- try writer.writeByte(std.wasm.opcode(.i32_const));
- try leb.writeULEB128(writer, @intCast(u32, errors_len));
-
- try writer.writeByte(std.wasm.opcode(.i32_lt_u));
-
- // stack values are implicit return values so keep the value
- // on the stack and end the function.
+/// Generates an atom containing the global error set' size.
+/// This will only be generated if the symbol exists.
+fn setupErrorsLen(wasm: *Wasm) !void {
+ const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return;
- // end function
- try writer.writeByte(std.wasm.opcode(.end));
- }
+ const errors_len = wasm.base.options.module.?.global_error_set.count();
+ // overwrite existing atom if it already exists (maybe the error set has increased)
+ // if not, allcoate a new atom.
+ const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
+ const atom = wasm.getAtomPtr(index);
+ if (atom.next) |next_atom_index| {
+ const next_atom = wasm.getAtomPtr(next_atom_index);
+ next_atom.prev = atom.prev;
+ atom.next = null;
+ }
+ if (atom.prev) |prev_index| {
+ const prev_atom = wasm.getAtomPtr(prev_index);
+ prev_atom.next = atom.next;
+ atom.prev = null;
+ }
+ atom.deinit(wasm);
+ break :blk index;
+ } else new_atom: {
+ const atom_index = @intCast(Atom.Index, wasm.managed_atoms.items.len);
+ try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index);
+ try wasm.managed_atoms.append(wasm.base.allocator, undefined);
+ break :new_atom atom_index;
+ };
+ const atom = wasm.getAtomPtr(atom_index);
+ atom.* = Atom.empty;
+ atom.sym_index = loc.index;
+ atom.size = 2;
+ try atom.code.writer(wasm.base.allocator).writeIntLittle(u16, @intCast(u16, errors_len));
- const func_type: std.wasm.Type = .{ .params = &.{std.wasm.Valtype.i32}, .returns = &.{std.wasm.Valtype.i32} };
- try wasm.createSyntheticFunction("__zig_lt_errors_len", func_type, &body_list);
+ try wasm.parseAtom(atom_index, .{ .data = .read_only });
}
/// 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
// So we can rebuild the binary file on each incremental update
defer wasm.resetState();
try wasm.setupInitFunctions();
+ try wasm.setupErrorsLen();
try wasm.setupStart();
try wasm.setupImports();
if (wasm.base.options.module) |mod| {
@@ -3423,7 +3422,6 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
try wasm.setupInitMemoryFunction();
try wasm.setupTLSRelocationsFunction();
try wasm.initializeTLSFunction();
- try wasm.setupLtErrorsLenFunction();
try wasm.setupExports();
try wasm.writeToFile(enabled_features, emit_features_count, arena);
}