Commit 97e8b94f authored by Kunshan Wang's avatar Kunshan Wang

Fixed basic tests.

parent e05ae891
......@@ -77,7 +77,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
def idOf(name: String): Int = try {
globalBundle.allNs(name).id
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s.".format(name), e)
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s".format(name), e)
}
/**
......@@ -86,7 +86,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
def nameOf(id: Int): String = try {
globalBundle.allNs(id).name.get
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d.".format(id), e)
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d".format(id), e)
}
/**
......
......@@ -22,6 +22,7 @@ object MuValue {
case (t: TypeIRef, v: BoxIRef) => MuIRefValue(t, v)
case (t: TypeStruct, v: BoxSeq) => MuStructValue(t, v)
case (t: TypeArray, v: BoxSeq) => MuArrayValue(t, v)
case (t: TypeVector, v: BoxSeq) => MuVectorValue(t, v)
case (t: TypeFuncRef, v: BoxFunc) => MuFuncRefValue(t, v)
case (t: TypeThreadRef, v: BoxThread) => MuThreadRefValue(t, v)
case (t: TypeStackRef, v: BoxStack) => MuStackRefValue(t, v)
......
......@@ -74,7 +74,7 @@ object TypeInferer {
try {
resTys(r.index)
} catch {
case e: ArrayIndexOutOfBoundsException => throw new UvmRefImplException(
case e: IndexOutOfBoundsException => throw new UvmRefImplException(
s"Instruction ${r.inst} produces only ${resTys.size} results, but result index ${r.index} is requested")
}
}
......
......@@ -20,21 +20,24 @@ class ConstantPool(implicit microVM: MicroVM) {
}
def makeBox(g: GlobalVariable): ValueBox = g match {
case ConstInt(ty, num) => BoxInt(OpHelper.unprepare(num, ty.asInstanceOf[TypeInt].length))
case ConstFloat(ty, num) => BoxFloat(num)
case ConstInt(ty, num) => ty match {
case TypeInt(l) => BoxInt(OpHelper.unprepare(num, l))
case _: AbstractPointerType => BoxPointer(num.toLong)
}
case ConstFloat(ty, num) => BoxFloat(num)
case ConstDouble(ty, num) => BoxDouble(num)
case ConstSeq(ty, elems) => BoxSeq(elems.map(maybeMakeBox))
case ConstSeq(ty, elems) => BoxSeq(elems.map(maybeMakeBox))
case ConstNull(ty) => ty match {
case _:TypeRef => BoxRef(0L)
case _:TypeIRef => BoxIRef(0L, 0L)
case _:TypeFuncRef => BoxFunc(None)
case _:TypeThreadRef => BoxThread(None)
case _:TypeStackRef => BoxStack(None)
case _: TypeRef => BoxRef(0L)
case _: TypeIRef => BoxIRef(0L, 0L)
case _: TypeFuncRef => BoxFunc(None)
case _: TypeThreadRef => BoxThread(None)
case _: TypeStackRef => BoxStack(None)
}
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f:Function => BoxFunc(Some(f))
case ef:ExposedFunc => BoxPointer(microVM.nativeCallHelper.getStaticExpFuncAddr(ef))
case gc: GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f: Function => BoxFunc(Some(f))
case ef: ExposedFunc => BoxPointer(microVM.nativeCallHelper.getStaticExpFuncAddr(ef))
}
def getGlobalVarBox(g: GlobalVariable): ValueBox = globalVarBoxes(g)
}
\ No newline at end of file
......@@ -45,31 +45,33 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
implicit def nameOf(id: Int): String = microVM.nameOf(id)
def preloadBundles(fileNames: String*): Unit = {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
for (fn <- fileNames) {
val r = new FileReader(fn)
ca.loadBundle(r)
ctx.loadBundle(r)
r.close()
}
ca.close()
ctx.closeContext()
}
type TrapHandlerFunction = (ClientAgent, Handle, Handle, Int) => TrapHandlerResult
type TrapHandlerFunction = (MuCtx, MuThreadRefValue, MuStackRefValue, Int) => TrapHandlerResult
class MockTrapHandler(thf: TrapHandlerFunction) extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = {
thf(ca, thread, stack, watchPointID)
def handleTrap(ctx: MuCtx, thread: MuThreadRefValue, stack: MuStackRefValue, watchPointID: Int): TrapHandlerResult = {
thf(ctx, thread, stack, watchPointID)
}
}
def testFunc(ca: ClientAgent, func: Handle, args: Seq[Handle])(handler: TrapHandlerFunction): Unit = {
def testFunc(ctx: MuCtx, func: MuFuncRefValue, args: Seq[MuValue])(handler: TrapHandlerFunction): Unit = {
microVM.trapManager.trapHandler = new MockTrapHandler(handler)
val hStack = ca.newStack(func)
val hThread = ca.newThread(hStack)
val hStack = ctx.newStack(func)
val hThread = ctx.newThread(hStack, HowToResume.PassValues(args))
microVM.execute()
}
implicit def magicalMuValue(mv: MuValue): MagicalBox = MagicalBox(mv.vb)
implicit class MagicalBox(vb: ValueBox) {
def asInt: BigInt = vb.asInstanceOf[BoxInt].value
......@@ -80,7 +82,7 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
def asRef: Word = vb.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = { val b = vb.asInstanceOf[BoxIRef]; (b.objRef, b.offset) }
def asIRefAddr: Word = { val b = vb.asInstanceOf[BoxIRef]; b.objRef + b.offset }
def asStruct: Seq[ValueBox] = vb.asInstanceOf[BoxStruct].values
def asStruct: Seq[ValueBox] = vb.asInstanceOf[BoxSeq].values
def asFunc: Option[Function] = vb.asInstanceOf[BoxFunc].func
def asThread: Option[InterpreterThread] = vb.asInstanceOf[BoxThread].thread
def asStack: Option[InterpreterStack] = vb.asInstanceOf[BoxStack].stack
......@@ -90,4 +92,10 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxSeq].values
def asPointer: Word = vb.asInstanceOf[BoxPointer].addr
}
implicit class RichMuCtx(ctx: MuCtx) {
def i32(num: BigInt) = ctx.handleFromInt(num, 32)
def i64(num: BigInt) = ctx.handleFromInt(num, 64)
def func(id: Int) = ctx.handleFromFunc(id)
}
}
\ No newline at end of file
......@@ -11,6 +11,8 @@ import uvm.refimpl.mem._
import MemoryOrder._
import AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.TrapHandlerResult.{ ThreadExit, Rebind }
import uvm.refimpl.HowToResume.{ PassValues, ThrowExc }
import ch.qos.logback.classic.Level._
......@@ -23,7 +25,8 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
override def makeMicroVM = new MicroVM(heapSize = 8L * 1024L * 1024L)
preloadBundles("tests/uvm-refimpl-test/basic-tests.uir")
preloadBundles("tests/uvm-refimpl-test/primitives.uir",
"tests/uvm-refimpl-test/basic-tests.uir")
"The constant pool" should "contain appropriate constant values" in {
def gvb(name: String) = microVM.constantPool.getGlobalVarBox(microVM.globalBundle.globalVarNs(name))
......@@ -39,14 +42,14 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
}
"Binary operations" should "work on int<32>" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops32")
val arg0 = ca.putInt("@i32", 42)
val arg1 = ca.putInt("@i32", 3)
val func = ctx.func("@binops32")
val arg0 = ctx.i32(42)
val arg1 = ctx.i32(3)
testFunc(ca, func, Seq(arg0, arg1)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg1)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
add.vb.asSInt(32) shouldEqual 45
sub.vb.asSInt(32) shouldEqual 39
......@@ -62,45 +65,45 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
or.vb.asSInt(32) shouldEqual 43
xor.vb.asSInt(32) shouldEqual 41
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg2 = ca.putInt("@i32", -100)
val arg3 = ca.putInt("@i32", 6)
val arg2 = ctx.handleFromInt(-100, 32)
val arg3 = ctx.handleFromInt(6, 32)
testFunc(ca, func, Seq(arg2, arg3)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg2, arg3)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
sdiv.vb.asSInt(32) shouldEqual -16
srem.vb.asSInt(32) shouldEqual -4
lshr.vb.asUInt(32) shouldEqual 67108862
ashr.vb.asSInt(32) shouldEqual -2
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg4 = ca.putInt("@i32", 42)
val arg5 = ca.putInt("@i32", -15)
val arg4 = ctx.handleFromInt(42, 32)
val arg5 = ctx.handleFromInt(-15, 32)
testFunc(ca, func, Seq(arg4, arg5)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg4, arg5)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
sdiv.vb.asSInt(32) shouldEqual -2
srem.vb.asSInt(32) shouldEqual 12
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Binary operations" should "work on int<64>" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops64")
val arg0 = ca.putInt("@i64", 42)
val arg1 = ca.putInt("@i64", 3)
val func = ctx.func("@binops64")
val arg0 = ctx.i64(42)
val arg1 = ctx.i64(3)
testFunc(ca, func, Seq(arg0, arg1)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg1)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
add.vb.asSInt(64) shouldEqual 45
sub.vb.asSInt(64) shouldEqual 39
......@@ -116,96 +119,96 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
or.vb.asSInt(64) shouldEqual 43
xor.vb.asSInt(64) shouldEqual 41
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg2 = ca.putInt("@i64", -0x8000000000000000L)
val arg3 = ca.putInt("@i64", -1L)
val arg2 = ctx.i64(-0x8000000000000000L)
val arg3 = ctx.i64(-1L)
testFunc(ca, func, Seq(arg2, arg3)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg2, arg3)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
sdiv.vb.asSInt(64) shouldEqual -0x8000000000000000L
srem.vb.asSInt(64) shouldEqual 0
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg4 = ca.putInt("@i64", 13)
val arg5 = ca.putInt("@i64", 63)
val arg6 = ca.putInt("@i64", 64)
val arg7 = ca.putInt("@i64", 65)
val arg4 = ctx.i64(13)
val arg5 = ctx.i64(63)
val arg6 = ctx.i64(64)
val arg7 = ctx.i64(65)
testFunc(ca, func, Seq(arg4, arg5)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg4, arg5)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
shl.vb.asUInt(64) shouldEqual BigInt("8000000000000000", 16)
lshr.vb.asUInt(64) shouldEqual 0
ashr.vb.asSInt(64) shouldEqual 0
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(arg4, arg6)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg4, arg6)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
shl.vb.asUInt(64) shouldEqual 13
lshr.vb.asUInt(64) shouldEqual 13
ashr.vb.asSInt(64) shouldEqual 13
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(arg4, arg7)) { (ca, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg4, arg7)) { (ctx, th, st, wp) =>
val Seq(add, sub, mul, udiv, sdiv, urem, srem, shl, lshr, ashr, and, or, xor) = ctx.dumpKeepalives(st, 0)
shl.vb.asUInt(64) shouldEqual 26
lshr.vb.asUInt(64) shouldEqual 6
ashr.vb.asSInt(64) shouldEqual 6
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Binary operations" should "safely handle integer division by zero" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops64_div0")
val a = ca.putInt("@i64", 42)
val one = ca.putInt("@i64", 1)
val zero = ca.putInt("@i64", 0)
val func = ctx.func("@binops64_div0")
val a = ctx.i64(42)
val one = ctx.i64(1)
val zero = ctx.i64(0)
testFunc(ca, func, Seq(a, zero, one, one, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
testFunc(ctx, func, Seq(a, zero, one, one, one)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) shouldBe "@binops64_div0.v1.exc.trapexc"
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(a, one, zero, one, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
testFunc(ctx, func, Seq(a, one, zero, one, one)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) shouldBe "@binops64_div0.v1.exc.trapexc"
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(a, one, one, zero, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
testFunc(ctx, func, Seq(a, one, one, zero, one)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) shouldBe "@binops64_div0.v1.exc.trapexc"
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(a, one, one, one, zero)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
testFunc(ctx, func, Seq(a, one, one, one, zero)) { (ctx, th, st, wp) =>
nameOf(ctx.curInst(st, 0)) shouldBe "@binops64_div0.v1.exc.trapexc"
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Binary operations" should "work on float" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops_f")
val arg0 = ca.putFloat("@float", 45.0f)
val arg1 = ca.putFloat("@float", 4.0f)
val func = ctx.func("@binops_f")
val arg0 = ctx.handleFromFloat(45.0f)
val arg1 = ctx.handleFromFloat(4.0f)
testFunc(ca, func, Seq(arg0, arg1)) { (ca, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg1)) { (ctx, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ctx.dumpKeepalives(st, 0)
fadd.vb.asFloat shouldEqual 49.0f
fsub.vb.asFloat shouldEqual 41.0f
......@@ -213,13 +216,13 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fdiv.vb.asFloat shouldEqual 11.25f
frem.vb.asFloat shouldEqual 1.0f
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg2 = ca.putFloat("@float", Float.NaN)
val arg2 = ctx.handleFromFloat(Float.NaN)
testFunc(ca, func, Seq(arg0, arg2)) { (ca, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg2)) { (ctx, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ctx.dumpKeepalives(st, 0)
fadd.vb.asFloat.isNaN shouldEqual true
fsub.vb.asFloat.isNaN shouldEqual true
......@@ -227,21 +230,21 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fdiv.vb.asFloat.isNaN shouldEqual true
frem.vb.asFloat.isNaN shouldEqual true
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Binary operations" should "work on double" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops_d")
val arg0 = ca.putDouble("@double", 45.0d)
val arg1 = ca.putDouble("@double", 4.0d)
val func = ctx.func("@binops_d")
val arg0 = ctx.handleFromDouble(45.0d)
val arg1 = ctx.handleFromDouble(4.0d)
testFunc(ca, func, Seq(arg0, arg1)) { (ca, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg1)) { (ctx, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ctx.dumpKeepalives(st, 0)
fadd.vb.asDouble shouldEqual 49.0d
fsub.vb.asDouble shouldEqual 41.0d
......@@ -249,13 +252,13 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fdiv.vb.asDouble shouldEqual 11.25d
frem.vb.asDouble shouldEqual 1.0d
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val arg2 = ca.putDouble("@double", Double.NaN)
val arg2 = ctx.handleFromDouble(Double.NaN)
testFunc(ca, func, Seq(arg0, arg2)) { (ca, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(arg0, arg2)) { (ctx, th, st, wp) =>
val Seq(fadd, fsub, fmul, fdiv, frem) = ctx.dumpKeepalives(st, 0)
fadd.vb.asDouble.isNaN shouldEqual true
fsub.vb.asDouble.isNaN shouldEqual true
......@@ -263,26 +266,26 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fdiv.vb.asDouble.isNaN shouldEqual true
frem.vb.asDouble.isNaN shouldEqual true
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Binary operations" should "work on vector types" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@binops_vec")
val func = ctx.func("@binops_vec")
val a0 = ca.putIntVec("@4xi32", Seq(1, 2, 3, 4))
val a1 = ca.putIntVec("@4xi32", Seq(10, 20, 30, 40))
val a2 = ca.putFloatVec("@4xfloat", Seq(1.0f, 2.0f, 3.0f, 4.0f))
val a3 = ca.putFloatVec("@4xfloat", Seq(10.0f, 20.0f, 30.0f, 40.0f))
val a4 = ca.putDoubleVec("@2xdouble", Seq(1.0d, 2.0d))
val a5 = ca.putDoubleVec("@2xdouble", Seq(10.0d, 20.0d))
val a0 = ctx.handleFromConst("@4xI32_V3")
val a1 = ctx.handleFromConst("@4xI32_V4")
val a2 = ctx.handleFromConst("@4xF_V3")
val a3 = ctx.handleFromConst("@4xF_V4")
val a4 = ctx.handleFromConst("@2xD_V3")
val a5 = ctx.handleFromConst("@2xD_V4")
testFunc(ca, func, Seq(a0, a1, a2, a3, a4, a5)) { (ca, th, st, wp) =>
val Seq(addi, subi, addf, subf, addd, subd) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a1, a2, a3, a4, a5)) { (ctx, th, st, wp) =>
val Seq(addi, subi, addf, subf, addd, subd) = ctx.dumpKeepalives(st, 0)
addi.vb.asVec.map(_.asSInt(32)) shouldEqual Seq(11, 22, 33, 44)
subi.vb.asVec.map(_.asSInt(32)) shouldEqual Seq(-9, -18, -27, -36)
......@@ -291,22 +294,22 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
addd.vb.asVec.map(_.asDouble) shouldEqual Seq(11.0d, 22.0d)
subd.vb.asVec.map(_.asDouble) shouldEqual Seq(-9.0d, -18.0d)
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Comparing operations" should "work on int<64>" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@cmp64")
val func = ctx.func("@cmp64")
val a0 = ca.putInt("@i64", 1)
val a1 = ca.putInt("@i64", 2)
val a0 = ctx.i64(1)
val a1 = ctx.i64(2)
testFunc(ca, func, Seq(a0, a1)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a1)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
......@@ -319,11 +322,11 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(a0, a0)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a0)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 1
ne.vb.asUInt(1) shouldEqual 0
......@@ -336,13 +339,13 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
sgt.vb.asUInt(1) shouldEqual 0
sge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val a2 = ca.putInt("@i64", -3)
val a2 = ctx.i64(-3)
testFunc(ca, func, Seq(a0, a2)) { (ca, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a2)) { (ctx, th, st, wp) =>
val Seq(eq, ne, ult, ule, ugt, uge, slt, sle, sgt, sge) = ctx.dumpKeepalives(st, 0)
eq.vb.asUInt(1) shouldEqual 0
ne.vb.asUInt(1) shouldEqual 1
......@@ -351,22 +354,22 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
sgt.vb.asUInt(1) shouldEqual 1
sge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
ca.close()
ctx.closeContext()
}
"Comparing operations" should "work on float" in {
val ca = microVM.newClientAgent()
val ctx = microVM.newContext()
val func = ca.putFunction("@cmp_f")
val func = ctx.func("@cmp_f")
val a0 = ca.putFloat("@float", 1.0f)
val a1 = ca.putFloat("@float", 2.0f)
val a0 = ctx.handleFromFloat(1.0f)
val a1 = ctx.handleFromFloat(2.0f)
testFunc(ca, func, Seq(a0, a1)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a1)) { (ctx, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ctx.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
......@@ -385,11 +388,11 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
testFunc(ca, func, Seq(a0, a0)) { (ca, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ca.dumpKeepalives(st, 0)
testFunc(ctx, func, Seq(a0, a0)) { (ctx, th, st, wp) =>
val Seq(ftrue, ffalse, ford, foeq, fone, folt, fole, fogt, foge, funo, fueq, fune, fult, fule, fugt, fuge) = ctx.dumpKeepalives(st, 0)
ftrue.vb.asUInt(1) shouldEqual 1
ffalse.vb.asUInt(1) shouldEqual 0
......@@ -408,13 +411,13 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
fugt.vb.asUInt(1) shouldEqual 0
fuge.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
Rebind(st, PassValues(Seq()))
}
val a2 = ca.putFloat("@float", Float.NaN)