Skip to content

Commit

Permalink
[v3] Refactor loads and stores in V3Interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Dec 16, 2024
1 parent 297cd39 commit 8f39b2b
Showing 1 changed file with 50 additions and 58 deletions.
108 changes: 50 additions & 58 deletions src/engine/v3/V3Interpreter.v3
Original file line number Diff line number Diff line change
Expand Up @@ -441,29 +441,29 @@ class V3Interpreter extends WasmStack {
Runtime.TABLE_SET(this, frame.func.instance, table_index);
}

I32_LOAD => doLoad(4, DataReaders.read_range_u32, Value.I32);
I64_LOAD => doLoad(8, DataReaders.read_range_u64, Value.I64);
F32_LOAD => doLoad(4, DataReaders.read_range_u32, Value.F32);
F64_LOAD => doLoad(8, DataReaders.read_range_u64, Value.F64);
I32_LOAD8_S => doLoad(1, DataReaders.read_range_u32_i8, Value.I32);
I32_LOAD8_U => doLoad(1, DataReaders.read_range_u32_u8, Value.I32);
I32_LOAD16_S => doLoad(2, DataReaders.read_range_u32_i16, Value.I32);
I32_LOAD16_U => doLoad(2, DataReaders.read_range_u32_u16, Value.I32);
I64_LOAD8_S => doLoad(1, DataReaders.read_range_u64_i8, Value.I64);
I64_LOAD8_U => doLoad(1, DataReaders.read_range_u64_u8, Value.I64);
I64_LOAD16_S => doLoad(2, DataReaders.read_range_u64_i16, Value.I64);
I64_LOAD16_U => doLoad(2, DataReaders.read_range_u64_u16, Value.I64);
I64_LOAD32_S => doLoad(4, DataReaders.read_range_u64_i32, Value.I64);
I64_LOAD32_U => doLoad(4, DataReaders.read_range_u64_u32, Value.I64);
I32_STORE => doStore(4, DataWriters.write_range_u32, Values.unbox_u);
I64_STORE => doStore(8, DataWriters.write_range_u64, Values.unbox_w);
F32_STORE => doStore(4, DataWriters.write_range_u32, Values.unbox_fu32);
F64_STORE => doStore(8, DataWriters.write_range_u64, Values.unbox_du64);
I32_STORE8 => doStore(1, DataWriters.write_range_u8, Values.unbox_u8);
I32_STORE16 => doStore(2, DataWriters.write_range_u16, Values.unbox_u16);
I64_STORE8 => doStore(1, DataWriters.write_range_u8, Values.unbox_w8);
I64_STORE16 => doStore(2, DataWriters.write_range_u16, Values.unbox_w16);
I64_STORE32 => doStore(4, DataWriters.write_range_u32, Values.unbox_w32);
I32_LOAD => doLoad(4, DataReaders.read_range_u32, pushu);
I64_LOAD => doLoad(8, DataReaders.read_range_u64, pushw);
F32_LOAD => doLoad(4, DataReaders.read_range_float, pushf);
F64_LOAD => doLoad(8, DataReaders.read_range_double, pushd);
I32_LOAD8_S => doLoad(1, DataReaders.read_range_u32_i8, pushu);
I32_LOAD8_U => doLoad(1, DataReaders.read_range_u32_u8, pushu);
I32_LOAD16_S => doLoad(2, DataReaders.read_range_u32_i16, pushu);
I32_LOAD16_U => doLoad(2, DataReaders.read_range_u32_u16, pushu);
I64_LOAD8_S => doLoad(1, DataReaders.read_range_u64_i8, pushw);
I64_LOAD8_U => doLoad(1, DataReaders.read_range_u64_u8, pushw);
I64_LOAD16_S => doLoad(2, DataReaders.read_range_u64_i16, pushw);
I64_LOAD16_U => doLoad(2, DataReaders.read_range_u64_u16, pushw);
I64_LOAD32_S => doLoad(4, DataReaders.read_range_u64_i32, pushw);
I64_LOAD32_U => doLoad(4, DataReaders.read_range_u64_u32, pushw);
I32_STORE => doStore(4, DataWriters.write_range_u32, popu());
I64_STORE => doStore(8, DataWriters.write_range_u64, popw());
F32_STORE => doStore(4, DataWriters.write_range_float, popf());
F64_STORE => doStore(8, DataWriters.write_range_double, popd());
I32_STORE8 => doStore(1, DataWriters.write_range_u8, u8.view(popu()));
I32_STORE16 => doStore(2, DataWriters.write_range_u16, u16.view(popu()));
I64_STORE8 => doStore(1, DataWriters.write_range_u8, u8.view(popw()));
I64_STORE16 => doStore(2, DataWriters.write_range_u16, u16.view(popw()));
I64_STORE32 => doStore(4, DataWriters.write_range_u32, u32.view(popw()));

// Atomic operations
MEMORY_ATOMIC_NOTIFY => {
Expand All @@ -478,13 +478,13 @@ class V3Interpreter extends WasmStack {
var imm = codeptr.read_MemArg();
Runtime.MEMORY_ATOMIC_WAIT64(this, frame.func.instance, imm.memory_index, imm.offset);
}
I32_ATOMIC_LOAD => doAtomicLoad(4, DataReaders.read_range_u32, Value.I32);
I64_ATOMIC_LOAD => doAtomicLoad(8, DataReaders.read_range_u64, Value.I64);
I32_ATOMIC_LOAD8_U => doAtomicLoad(1, DataReaders.read_range_u32_u8, Value.I32);
I32_ATOMIC_LOAD16_U => doAtomicLoad(2, DataReaders.read_range_u32_u16, Value.I32);
I64_ATOMIC_LOAD8_U => doAtomicLoad(1, DataReaders.read_range_u64_u8, Value.I64);
I64_ATOMIC_LOAD16_U => doAtomicLoad(2, DataReaders.read_range_u64_u16, Value.I64);
I64_ATOMIC_LOAD32_U => doAtomicLoad(4, DataReaders.read_range_u64_u32, Value.I64);
I32_ATOMIC_LOAD => doAtomicLoad(4, DataReaders.read_range_u32, pushu);
I64_ATOMIC_LOAD => doAtomicLoad(8, DataReaders.read_range_u64, pushw);
I32_ATOMIC_LOAD8_U => doAtomicLoad(1, DataReaders.read_range_u32_u8, pushu);
I32_ATOMIC_LOAD16_U => doAtomicLoad(2, DataReaders.read_range_u32_u16, pushu);
I64_ATOMIC_LOAD8_U => doAtomicLoad(1, DataReaders.read_range_u64_u8, pushw);
I64_ATOMIC_LOAD16_U => doAtomicLoad(2, DataReaders.read_range_u64_u16, pushw);
I64_ATOMIC_LOAD32_U => doAtomicLoad(4, DataReaders.read_range_u64_u32, pushw);

MEMORY_SIZE => {
var index = codeptr.read_uleb32();
Expand Down Expand Up @@ -878,7 +878,7 @@ class V3Interpreter extends WasmStack {
var table_index = codeptr.read_uleb31();
Runtime.TABLE_FILL(this, frame.func.instance, table_index);
}
V128_LOAD => doLoad(16, DataReaders.read_range_u128, Value.V128);
V128_LOAD => doLoad(16, DataReaders.read_range_u128, pushs);
V128_LOAD_64_LANE => doLoadLane(8, 3, DataReaders.read_range_u64);
V128_LOAD_32_LANE => doLoadLane(4, 2, DataReaders.read_range_u32);
V128_LOAD_16_LANE => doLoadLane(2, 1, DataReaders.read_range_u32_u16);
Expand All @@ -895,7 +895,7 @@ class V3Interpreter extends WasmStack {
V128_LOAD_16X4_U => doLoadExtend(2, u16.view<u64>, u32.view<u16>, u32.view<u32>);
V128_LOAD_32X2_S => doLoadExtend(4, i32.view<u64>, i64.view<i32>, u64.view<i64>);
V128_LOAD_32X2_U => doLoadExtend(4, u32.view<u64>, u64.view<u32>, u64.view<u64>);
V128_STORE => doStore(16, DataWriters.write_range_u128, Values.unbox_s);
V128_STORE => doStore(16, DataWriters.write_range_u128, pops());
V128_STORE_8_LANE => doStoreLane(1, 0, u8.view<u64>, DataWriters.write_range_u8);
V128_STORE_16_LANE => doStoreLane(2, 1, u16.view<u64>, DataWriters.write_range_u16);
V128_STORE_32_LANE => doStoreLane(4, 2, u32.view<u64>, DataWriters.write_range_u32);
Expand Down Expand Up @@ -1188,16 +1188,16 @@ class V3Interpreter extends WasmStack {
}
if (frame != null) frame.pc = codeptr.pos;
}
def doLoadReg<T>(size: byte) -> MaybeTrap<Range<byte>> {
def decodeMemArgAndGetMemoryRange(size: byte) -> MaybeTrap<Range<byte>> {
var memarg = codeptr.read_MemArg();
var memory = frame.func.instance.memories[memarg.memory_index];
var index = popa(memory.decl.size);
return memory.range_oil_64(memarg.offset, index, size);
}
def doLoad<T>(size: byte, read: Range<byte> -> T, box: T -> Value) {
var t = doLoadReg(size);
def doLoad<T>(size: byte, read: Range<byte> -> T, push: T -> void) {
var t = decodeMemArgAndGetMemoryRange(size);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
else push(box(read(t.result)));
push(read(t.result));
}
// Atomic load
def doAtomicLoadReg<T>(size: byte) -> MaybeTrap<Range<byte>> {
Expand All @@ -1206,14 +1206,14 @@ class V3Interpreter extends WasmStack {
var index = popa(memory.decl.size);
return memory.range_oil_64(memarg.offset, index, size);
}
def doAtomicLoad<T>(size: byte, read: Range<byte> -> T, box: T -> Value) {
def doAtomicLoad<T>(size: byte, read: Range<byte> -> T, push: T -> void) {
var t = doAtomicLoadReg(size);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
else push(box(read(t.result))); // Suppose "read" function is atomic in Virgil.
push(read(t.result)); // XXX: assumes "read" function is atomic
}
def doLoadLane<T>(size: byte, log2_size: u3, read: Range<byte> -> T) {
var v = pops();
var t = doLoadReg(size);
var t = decodeMemArgAndGetMemoryRange(size);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
var val = u64.!(read(t.result));
var idx = codeptr.read1();
Expand All @@ -1231,15 +1231,15 @@ class V3Interpreter extends WasmStack {
push(Value.V128(low, high));
}
def doLoadZero<T>(size: byte, read: Range<byte> -> T) {
var t = doLoadReg(size);
var t = decodeMemArgAndGetMemoryRange(size);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
var val = u64.!(read(t.result));
var high = 0ul;
push(Value.V128(val, high));
}
// Tn: narrow source type, Sw: (signed) wide type, Uw: corresponding unsigned wide type
def doLoadExtend<Tn, Sw, Uw>(size: byte, view: u64 -> Tn, extend: Tn -> Sw, convert: Sw -> Uw) {
var t = doLoadReg(8);
var t = decodeMemArgAndGetMemoryRange(8);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
var val = DataReaders.read_range_u64(t.result);
var low = 0ul, high = 0ul;
Expand Down Expand Up @@ -1337,7 +1337,7 @@ class V3Interpreter extends WasmStack {
return res;
}
def doLoadSplat<T>(size: byte, log2_size: byte, read: Range<byte> -> T) {
var t = doLoadReg(size);
var t = decodeMemArgAndGetMemoryRange(size);
if (t.reason != TrapReason.NONE) return void(trap(t.reason));
var val = u64.!(read(t.result));
doSplatV(size, log2_size, val);
Expand All @@ -1358,23 +1358,16 @@ class V3Interpreter extends WasmStack {
}
push(Value.V128(low, high));
}
def doStore<T>(size: byte, write: (Range<byte>, T) -> void, unbox: Value -> T) {
var memarg = codeptr.read_MemArg();
var memory = frame.func.instance.memories[memarg.memory_index];
var val = pop();
var index = popa(memory.decl.size);
var t = memory.range_oil_64(memarg.offset, index, size);
def doStore<T>(size: byte, write: (Range<byte>, T) -> void, val: T) {
var t = decodeMemArgAndGetMemoryRange(size);
if (t.reason != TrapReason.NONE) trap(t.reason);
else write(t.result, unbox(val));
else write(t.result, val);
}
def doStoreLane<T>(size: byte, log2_size: u3, view: u64 -> T, write: (Range<byte>, T) -> void) {
var v = pops();
// Decode memarg
var memarg = codeptr.read_MemArg();
var memory = frame.func.instance.memories[memarg.memory_index];
var index = popa(memory.decl.size);
// Decode immediate
var idx = codeptr.read1();
var t = decodeMemArgAndGetMemoryRange(size);
var idx = codeptr.read1(); // get lane immediate
if (t.reason != TrapReason.NONE) trap(t.reason);
// Extract lane
var low = v.0, high = v.1;
var val: T;
Expand All @@ -1387,9 +1380,7 @@ class V3Interpreter extends WasmStack {
val = view(high >> shift);
}
// Write to memory
var t = memory.range_oil_64(memarg.offset, index, size);
if (t.reason != TrapReason.NONE) trap(t.reason);
else write(t.result, val);
write(t.result, val);
}
def doFallthru() {
frame.stp += 4;
Expand Down Expand Up @@ -1564,6 +1555,7 @@ class V3Interpreter extends WasmStack {
def pushf(val: float) { values.push(Value.F32(u32.view(val))); }
def pushd(val: double) { values.push(Value.F64(u64.view(val))); }
def pushz(val: bool) { values.push(if(val, Values.I32_1, Values.I32_0)); }
def pushs(low: u64, high: u64) { values.push(Value.V128(low, high)); }
def popN(t: Range<ValueType>) -> Array<Value> {
var result = Array<Value>.new(t.length);
var sp = values.top - t.length;
Expand Down

0 comments on commit 8f39b2b

Please sign in to comment.