diff --git a/src/Air.zig b/src/Air.zig index e00720f534..874af09b71 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -584,11 +584,11 @@ pub const Inst = struct { field_parent_ptr, /// Implements @wasmMemorySize builtin. - /// Uses the `ty_pl` field, payload is `WasmMemoryIndex`. + /// Uses the `ty_pl` field, payload represents the index of the target memory. wasm_memory_size, /// Implements @wasmMemoryGrow builtin. - /// Uses the `pl_op` field, payload is `WasmMemoryIndex`. + /// Uses the `pl_op` field, payload represents the index of the target memory. wasm_memory_grow, pub fn fromCmpOp(op: std.math.CompareOperator) Tag { @@ -725,12 +725,6 @@ pub const FieldParentPtr = struct { field_index: u32, }; -/// Wasm's memory instructions require a comptime-known index -/// which represents the memory it operates on. -pub const WasmMemoryIndex = struct { - index: u32, -}; - /// Trailing: /// 0. `Inst.Ref` for every outputs_len /// 1. `Inst.Ref` for every inputs_len diff --git a/src/Sema.zig b/src/Sema.zig index a8dc872a99..65536cdbde 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -14034,7 +14034,7 @@ fn zirWasmMemorySize( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - if (!sema.mod.getTarget().isWasm()) { + if (!sema.mod.getTarget().isWasm() and sema.mod.comp.bin_file.options.object_format != .c) { return sema.fail(block, src, "builtin '@wasmMemorySize' is a wasm feature only", .{}); } @@ -14045,7 +14045,7 @@ fn zirWasmMemorySize( .tag = .wasm_memory_size, .data = .{ .ty_pl = .{ .ty = try sema.addType(Type.u32), - .payload = try sema.addExtra(Air.WasmMemoryIndex{ .index = index }), + .payload = index, } }, }); } @@ -14057,7 +14057,7 @@ fn zirWasmMemoryGrow( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - if (!sema.mod.getTarget().isWasm()) { + if (!sema.mod.getTarget().isWasm() and sema.mod.comp.bin_file.options.object_format != .c) { return sema.fail(block, src, "builtin '@wasmMemoryGrow' is a wasm feature only", .{}); } @@ -14070,7 +14070,7 @@ fn zirWasmMemoryGrow( .tag = .wasm_memory_grow, .data = .{ .pl_op = .{ .operand = delta_arg, - .payload = try sema.addExtra(Air.WasmMemoryIndex{ .index = index }), + .payload = index, } }, }); } diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index b4917738dd..b1c4be9fef 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3431,22 +3431,20 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) InnerError!WValue { fn airWasmMemorySize(self: *Self, inst: Air.Inst.Index) !WValue { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - const extra = self.air.extraData(Air.WasmMemoryIndex, ty_pl.payload).data; - const result = try self.allocLocal(Type.usize); - try self.addLabel(.memory_size, extra.index); + const result = try self.allocLocal(self.air.typeOfIndex(inst)); + try self.addLabel(.memory_size, ty_pl.payload); try self.addLabel(.local_set, result.local); return result; } fn airWasmMemoryGrow(self: *Self, inst: Air.Inst.Index) !WValue { const pl_op = self.air.instructions.items(.data)[inst].pl_op; - const extra = self.air.extraData(Air.WasmMemoryIndex, pl_op.payload).data; const operand = try self.resolveInst(pl_op.operand); - const result = try self.allocLocal(Type.usize); + const result = try self.allocLocal(self.air.typeOfIndex(inst)); try self.emitWValue(operand); - try self.addLabel(.memory_grow, extra.index); + try self.addLabel(.memory_grow, pl_op.payload); try self.addLabel(.local_set, result.local); return result; } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 988576a6f1..a36b58041c 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1759,8 +1759,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .wrap_errunion_err => try airWrapErrUnionErr(f, inst), .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst), - .wasm_memory_size => unreachable, - .wasm_memory_grow => unreachable, + .wasm_memory_size => try airWasmMemorySize(f, inst), + .wasm_memory_grow => try airWasmMemoryGrow(f, inst), // zig fmt: on }; switch (result_value) { @@ -3591,6 +3591,34 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { return CValue.none; } +fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue { + const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; + + const writer = f.object.writer(); + const inst_ty = f.air.typeOfIndex(inst); + const local = try f.allocLocal(inst_ty, .Const); + + try writer.writeAll(" = "); + try writer.print("zig_wasm_memory_size({d});\n", .{ty_pl.payload}); + + return local; +} + +fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { + const pl_op = f.air.instructions.items(.data)[inst].pl_op; + + const writer = f.object.writer(); + const inst_ty = f.air.typeOfIndex(inst); + const operand = try f.resolveInst(pl_op.operand); + const local = try f.allocLocal(inst_ty, .Const); + + try writer.writeAll(" = "); + try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload}); + try f.writeCValue(writer, operand); + try writer.writeAll(");\n"); + return local; +} + fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { return switch (order) { .Unordered => "memory_order_relaxed", diff --git a/src/link/C/zig.h b/src/link/C/zig.h index 4a725ca678..bf94f44c8f 100644 --- a/src/link/C/zig.h +++ b/src/link/C/zig.h @@ -89,6 +89,18 @@ #define zig_prefetch(addr, rw, locality) #endif +#if defined(__clang__) +#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index) +#else +#define zig_wasm_memory_size(index) 0 +#endif + +#if defined(__clang__) +#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta) +#else +#define zig_wasm_memory_grow(index, delta) 0 +#endif + #if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) #include #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail) diff --git a/src/print_air.zig b/src/print_air.zig index 3dd1decf53..3158daee6d 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -627,16 +627,12 @@ const Writer = struct { fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; - const extra = w.air.extraData(Air.WasmMemoryIndex, ty_pl.payload).data; - - try s.print("{d}", .{extra.index}); + try s.print("{d}", .{ty_pl.payload}); } fn writeWasmMemoryGrow(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { const pl_op = w.air.instructions.items(.data)[inst].pl_op; - const extra = w.air.extraData(Air.WasmMemoryIndex, pl_op.payload).data; - - try s.print("{d}, ", .{extra.index}); + try s.print("{d}, ", .{pl_op.payload}); try w.writeOperand(s, inst, 0, pl_op.operand); }