aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-03-02 22:18:45 +0100
committerAndrew Kelley <andrew@ziglang.org>2022-03-03 16:33:46 -0700
commitec4c30ae483e6700a1fd1d5edaadbb042790c52e (patch)
tree72a0cc5ffcf656a1654cd3adbf7fd3d6f06aa525 /src/arch/wasm
parent0ea51f7f494cd84a48fd997b60196d6c4254ccac (diff)
downloadzig-ec4c30ae483e6700a1fd1d5edaadbb042790c52e.tar.gz
zig-ec4c30ae483e6700a1fd1d5edaadbb042790c52e.zip
wasm: Implement `@wasmMemorySize()` builtin
This implements the `wasmMemorySize` builtin, in Sema and the Wasm backend. The Stage2 implementation differs from stage1 in the way that `index` must be a comptime value. The stage1 variant is incorrect, as the index is part of the instruction encoding, and therefore, cannot be a runtime value.
Diffstat (limited to 'src/arch/wasm')
-rw-r--r--src/arch/wasm/CodeGen.zig12
-rw-r--r--src/arch/wasm/Emit.zig2
-rw-r--r--src/arch/wasm/Mir.zig4
3 files changed, 15 insertions, 3 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 4f19aeca6b..0ea0418d7f 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1671,6 +1671,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
.wrap_errunion_payload => self.airWrapErrUnionPayload(inst),
.wrap_errunion_err => self.airWrapErrUnionErr(inst),
+ .wasm_memory_size => self.airWasmMemorySize(inst),
+
.add_sat,
.sub_sat,
.mul_sat,
@@ -3426,6 +3428,16 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
return WValue{ .none = {} };
}
+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);
+ try self.addLabel(.local_set, result.local);
+ return result;
+}
+
fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
assert(operand_ty.hasRuntimeBits());
assert(op == .eq or op == .neq);
diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig
index d787c46774..4432e19638 100644
--- a/src/arch/wasm/Emit.zig
+++ b/src/arch/wasm/Emit.zig
@@ -89,10 +89,10 @@ pub fn emitMir(emit: *Emit) InnerError!void {
.local_set => try emit.emitLabel(tag, inst),
.local_tee => try emit.emitLabel(tag, inst),
.memory_grow => try emit.emitLabel(tag, inst),
+ .memory_size => try emit.emitLabel(tag, inst),
// no-ops
.end => try emit.emitTag(tag),
- .memory_size => try emit.emitTag(tag),
.@"return" => try emit.emitTag(tag),
.@"unreachable" => try emit.emitTag(tag),
diff --git a/src/arch/wasm/Mir.zig b/src/arch/wasm/Mir.zig
index ed0867e583..04edb09dca 100644
--- a/src/arch/wasm/Mir.zig
+++ b/src/arch/wasm/Mir.zig
@@ -226,9 +226,9 @@ pub const Inst = struct {
i64_store32 = 0x3E,
/// Returns the memory size in amount of pages.
///
- /// Uses `nop`
+ /// Uses `label`
memory_size = 0x3F,
- /// Increases the memory at by given number of pages.
+ /// Increases the memory by given number of pages.
///
/// Uses `label`
memory_grow = 0x40,