diff --git a/src/engine/v3/V3Interpreter.v3 b/src/engine/v3/V3Interpreter.v3 index a723ed2f..29aac8b1 100644 --- a/src/engine/v3/V3Interpreter.v3 +++ b/src/engine/v3/V3Interpreter.v3 @@ -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 => { @@ -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(); @@ -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); @@ -895,7 +895,7 @@ class V3Interpreter extends WasmStack { V128_LOAD_16X4_U => doLoadExtend(2, u16.view, u32.view, u32.view); V128_LOAD_32X2_S => doLoadExtend(4, i32.view, i64.view, u64.view); V128_LOAD_32X2_U => doLoadExtend(4, u32.view, u64.view, u64.view); - 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, DataWriters.write_range_u8); V128_STORE_16_LANE => doStoreLane(2, 1, u16.view, DataWriters.write_range_u16); V128_STORE_32_LANE => doStoreLane(4, 2, u32.view, DataWriters.write_range_u32); @@ -1188,16 +1188,16 @@ class V3Interpreter extends WasmStack { } if (frame != null) frame.pc = codeptr.pos; } - def doLoadReg(size: byte) -> MaybeTrap> { + def decodeMemArgAndGetMemoryRange(size: byte) -> MaybeTrap> { 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(size: byte, read: Range -> T, box: T -> Value) { - var t = doLoadReg(size); + def doLoad(size: byte, read: Range -> 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(size: byte) -> MaybeTrap> { @@ -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(size: byte, read: Range -> T, box: T -> Value) { + def doAtomicLoad(size: byte, read: Range -> 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(size: byte, log2_size: u3, read: Range -> 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(); @@ -1231,7 +1231,7 @@ class V3Interpreter extends WasmStack { push(Value.V128(low, high)); } def doLoadZero(size: byte, read: Range -> 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; @@ -1239,7 +1239,7 @@ class V3Interpreter extends WasmStack { } // Tn: narrow source type, Sw: (signed) wide type, Uw: corresponding unsigned wide type def doLoadExtend(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; @@ -1337,7 +1337,7 @@ class V3Interpreter extends WasmStack { return res; } def doLoadSplat(size: byte, log2_size: byte, read: Range -> 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); @@ -1358,23 +1358,16 @@ class V3Interpreter extends WasmStack { } push(Value.V128(low, high)); } - def doStore(size: byte, write: (Range, 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(size: byte, write: (Range, 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(size: byte, log2_size: u3, view: u64 -> T, write: (Range, 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; @@ -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; @@ -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) -> Array { var result = Array.new(t.length); var sp = values.top - t.length;