WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit 87c9ebdc authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Passes main test.

parent 0787369e
......@@ -18,10 +18,10 @@ abstract class Bundle {
* + globalCellNs // Global cells
* + funcNs // Functions
* + expFuncNs // Exposed functions
*
* These namespaces are local, i.e. they cannot be directly looked up from a bundle:
* + bbNs // Basic blocks (per function version)
* + localVarNs // Local variables (per basic block)
* + bbNs // Basic blocks (per function version)
*
* bbNs and localVarNs are part of particular FuncVers and BBs.
*/
val allNs = new NestedNamespace[Identified](None)
......@@ -64,6 +64,18 @@ class GlobalBundle extends Bundle {
for (cand <- newNs.all) {
try {
oldNs.add(cand)
def assertPresent[T <: Identified](ns: NestedNamespace[T], obj: T): Unit = {
assert(ns.get(obj.id) == Some(obj))
if (obj.id == 65731) {
printf("Obj[65731] found in ns " + ns)
}
ns.maybeParent match {
case None =>
case Some(ns2) =>
assertPresent(ns2, obj)
}
}
assertPresent(oldNs.asInstanceOf[NestedNamespace[T]], cand)
} catch {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
......@@ -79,6 +91,15 @@ class GlobalBundle extends Bundle {
}
}
private def mergeLocalNamespaces(newBundle: TrantientBundle) {
for (fv <- newBundle.funcVerNs.all) {
fv.bbNs.reparent(allNs)
for (bb <- fv.bbs) {
bb.localVarNs.reparent(allNs)
}
}
}
def merge(newBundle: TrantientBundle) {
// Only merge leaves
simpleMerge(typeNs, newBundle.typeNs)
......@@ -90,6 +111,8 @@ class GlobalBundle extends Bundle {
simpleMerge(expFuncNs, newBundle.expFuncNs)
redefineFunctions(newBundle.funcVerNs)
mergeLocalNamespaces(newBundle)
}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ class FuncVer extends IdentifiedSettable {
def sig: FuncSig = func.sig
val bbNs = new SimpleNamespace[BasicBlock]
var bbNs: NestedNamespace[BasicBlock] = null // sub-namespace of allNs
}
class BasicBlock extends IdentifiedSettable {
......@@ -40,5 +40,5 @@ class BasicBlock extends IdentifiedSettable {
var excParam: Option[ExcParam] = null
var insts: Seq[Instruction] = null
val localVarNs = new SimpleNamespace[LocalVariable]
var localVarNs: NestedNamespace[LocalVariable] = null // sub-namespace of allNs
}
......@@ -239,7 +239,7 @@ class UIRTextReader(val idFactory: IDFactory) {
case t: TypeRefContext => TypeRef(null).later(phase1) { _.ty = t.ty }
case t: TypeIRefContext => TypeIRef(null).later(phase1) { _.ty = t.ty }
case t: TypeWeakRefContext => TypeWeakRef(null).later(phase1) { _.ty = t.ty }
case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy)}
case t: TypeStructContext => TypeStruct(null).later(phase1) { _.fieldTys = t.fieldTys.map(resTy) }
case t: TypeArrayContext => TypeArray(null, t.length.longValue()).later(phase1) { _.elemTy = t.ty }
case t: TypeHybridContext => TypeHybrid(null, null).later(phase1) { tt => tt.fixedTy = t.fixedTy; tt.varTy = t.varTy }
case t: TypeVoidContext => TypeVoid()
......@@ -295,12 +295,9 @@ class UIRTextReader(val idFactory: IDFactory) {
case _: TypeStruct => ConstStruct(t, null).later(phase2) {
_.fields = for (gn <- cc.GLOBAL_NAME()) yield resGlobalVar(gn)
}
case _: TypeArray => ConstArray(t, null).later(phase2) {
case _: TypeArray | _: TypeVector => ConstSeq(t, null).later(phase2) {
_.elems = for (gn <- cc.GLOBAL_NAME()) yield resGlobalVar(gn)
}
case _: TypeVector => ConstVector(t, null).later(phase2) {
_.elems = for (c <- cc.GLOBAL_NAME()) yield resConstByName(c)
}
}
case _: CtorNullContext => ConstNull(t)
}
......@@ -388,8 +385,9 @@ class UIRTextReader(val idFactory: IDFactory) {
ver.func = func
//func.versions = ver :: func.versions // Don't override here. Let the MicroVM redefine functions.
def globalizeBB(name: String): String = globalize(name, verName)
ver.bbNs = bundle.allNs.makeSubSpace[BasicBlock]
def globalizeBB(name: String): String = globalize(name, verName)
// Resolve function version local entities
......@@ -411,6 +409,8 @@ class UIRTextReader(val idFactory: IDFactory) {
bb.name = Some(bbName)
ver.bbNs.add(bb)
bb.localVarNs = bundle.allNs.makeSubSpace[LocalVariable]
def mkNorParam(ty: Type, name: String): NorParam = {
val param = NorParam(ty)
param.id = idFactory.getID()
......
......@@ -45,7 +45,7 @@ class SimpleNamespace[T <: Identified] extends Namespace[T] {
def all = idMap.values
}
class NestedNamespace[T <: Identified](val maybeParent: Option[NestedNamespace[_ >: T]]) extends SimpleNamespace[T] {
class NestedNamespace[T <: Identified](var maybeParent: Option[NestedNamespace[_ >: T <: Identified]]) extends SimpleNamespace[T] {
override def add(obj: T): Unit = {
super.add(obj)
maybeParent.foreach(_.add(obj))
......@@ -54,4 +54,11 @@ class NestedNamespace[T <: Identified](val maybeParent: Option[NestedNamespace[_
def makeSubSpace[U <: T](): NestedNamespace[U] = {
new NestedNamespace[U](Some(this))
}
def reparent[U >: T <: Identified](newParent: NestedNamespace[U]) = {
maybeParent = Some(newParent)
for (obj <- all) {
newParent.add(obj)
}
}
}
......@@ -39,11 +39,8 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
{
// The micro VM allocates stacks on the heap in the large object space. It is represented as a bug chunk of byte array.
// So the GC must know about this type because the GC looks up the globalBundle for types.
globalBundle.allNs.add(InternalTypes.VOID)
globalBundle.typeNs.add(InternalTypes.VOID)
globalBundle.allNs.add(InternalTypes.BYTE)
globalBundle.typeNs.add(InternalTypes.BYTE)
globalBundle.allNs.add(InternalTypes.BYTE_ARRAY)
globalBundle.typeNs.add(InternalTypes.BYTE_ARRAY)
}
......
......@@ -86,19 +86,19 @@ class ClientAgent(mutator: Mutator)(
val t = microVM.globalBundle.typeNs(typeID).asInstanceOf[TypeVector]
val et = t.elemTy.asInstanceOf[TypeInt]
val preparedVs = for (v <- vs) yield OpHelper.trunc(v, et.length)
newHandle(t, BoxVector(preparedVs.map(BoxInt)))
newHandle(t, BoxSeq(preparedVs.map(BoxInt)))
}
def putFloatVec(typeID: Int, vs: Seq[Float]): Handle = {
val t = microVM.globalBundle.typeNs(typeID).asInstanceOf[TypeVector]
val et = t.elemTy.asInstanceOf[TypeFloat]
newHandle(t, BoxVector(vs.map(BoxFloat)))
newHandle(t, BoxSeq(vs.map(BoxFloat)))
}
def putDoubleVec(typeID: Int, vs: Seq[Double]): Handle = {
val t = microVM.globalBundle.typeNs(typeID).asInstanceOf[TypeVector]
val et = t.elemTy.asInstanceOf[TypeDouble]
newHandle(t, BoxVector(vs.map(BoxDouble)))
newHandle(t, BoxSeq(vs.map(BoxDouble)))
}
def putPointer(typeID: Int, v: Word): Handle = {
......@@ -156,7 +156,7 @@ class ClientAgent(mutator: Mutator)(
def toIntVec(h: Handle, signExt: Boolean = false): Seq[BigInt] = {
val t = h.ty.asInstanceOf[TypeVector]
val et = t.elemTy.asInstanceOf[TypeInt]
val bv = h.vb.asInstanceOf[BoxVector]
val bv = h.vb.asInstanceOf[BoxSeq]
for (b <- bv.values) yield {
val ib = b.asInstanceOf[BoxInt]
if (signExt) OpHelper.prepareSigned(ib.value, et.length) else OpHelper.prepareUnsigned(ib.value, et.length)
......@@ -164,11 +164,11 @@ class ClientAgent(mutator: Mutator)(
}
def toFloatVec(h: Handle): Seq[Float] = {
h.vb.asInstanceOf[BoxVector].values.map(b => b.asInstanceOf[BoxFloat].value)
h.vb.asInstanceOf[BoxSeq].values.map(b => b.asInstanceOf[BoxFloat].value)
}
def toDoubleVec(h: Handle): Seq[Double] = {
h.vb.asInstanceOf[BoxVector].values.map(b => b.asInstanceOf[BoxDouble].value)
h.vb.asInstanceOf[BoxSeq].values.map(b => b.asInstanceOf[BoxDouble].value)
}
def toPointer(h: Handle): Word = {
......
......@@ -25,13 +25,14 @@ class ConstantPool(implicit microVM: MicroVM) {
case ConstDouble(ty, num) => BoxDouble(num)
case ConstStruct(ty, flds) => BoxStruct(flds.map(maybeMakeBox))
case ConstNull(ty) => ty match {
case _:TypeVoid => BoxVoid()
case _:TypeRef => BoxRef(0L)
case _:TypeIRef => BoxIRef(0L, 0L)
case _:TypeFuncRef => BoxFunc(None)
case _:TypeThreadRef => BoxThread(None)
case _:TypeStackRef => BoxStack(None)
}
case ConstVector(ty, elems) => BoxVector(elems.map(maybeMakeBox))
case ConstSeq(ty, elems) => BoxSeq(elems.map(maybeMakeBox))
case ConstPointer(ty, addr) => BoxPointer(addr)
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f:Function => BoxFunc(Some(f))
......
......@@ -176,9 +176,9 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
try {
opndTy match {
case TypeVector(scalarTy, sz) => {
val op1Bs = boxOf(op1).asInstanceOf[BoxVector].values
val op2Bs = boxOf(op2).asInstanceOf[BoxVector].values
val rBs = boxOf(i).asInstanceOf[BoxVector].values
val op1Bs = boxOf(op1).asInstanceOf[BoxSeq].values
val op2Bs = boxOf(op2).asInstanceOf[BoxSeq].values
val rBs = boxOf(i).asInstanceOf[BoxSeq].values
for (((b1, b2), br) <- ((op1Bs zip op2Bs) zip rBs)) {
doScalar(scalarTy, b1, b2, br)
......@@ -285,9 +285,9 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
opndTy match {
case TypeVector(scalarTy, sz) => {
val op1Bs = boxOf(op1).asInstanceOf[BoxVector].values
val op2Bs = boxOf(op2).asInstanceOf[BoxVector].values
val rBs = boxOf(i).asInstanceOf[BoxVector].values
val op1Bs = boxOf(op1).asInstanceOf[BoxSeq].values
val op2Bs = boxOf(op2).asInstanceOf[BoxSeq].values
val rBs = boxOf(i).asInstanceOf[BoxSeq].values
for (((b1, b2), br) <- ((op1Bs zip op2Bs) zip rBs)) {
doScalar(scalarTy, b1, b2, br)
......@@ -420,8 +420,8 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
case (TypeVector(scalarFromTy, sz), TypeVector(scalarToTy, sz2)) => {
if (sz != sz2) throw new UvmRefImplException(ctx + "The source and dest vector types must have the same length")
val bOpnds = boxOf(opnd).asInstanceOf[BoxVector].values
val rBs = boxOf(i).asInstanceOf[BoxVector].values
val bOpnds = boxOf(opnd).asInstanceOf[BoxSeq].values
val rBs = boxOf(i).asInstanceOf[BoxSeq].values
for ((bOpnd, br) <- (bOpnds zip rBs)) {
doScalar(scalarFromTy, scalarToTy, bOpnd, br)
......@@ -446,10 +446,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
condTy match {
case TypeVector(TypeInt(1), sz) => {
val bConds = boxOf(cond).asInstanceOf[BoxVector].values
val bTrues = boxOf(ifTrue).asInstanceOf[BoxVector].values
val bFalses = boxOf(ifFalse).asInstanceOf[BoxVector].values
val bResults = boxOf(i).asInstanceOf[BoxVector].values
val bConds = boxOf(cond).asInstanceOf[BoxSeq].values
val bTrues = boxOf(ifTrue).asInstanceOf[BoxSeq].values
val bFalses = boxOf(ifFalse).asInstanceOf[BoxSeq].values
val bResults = boxOf(i).asInstanceOf[BoxSeq].values
for ((((bCond, bTrue), bFalse), br) <- bConds.zip(bTrues).zip(bFalses).zip(bResults)) {
doScalar(bCond, bTrue, bFalse, br)
......@@ -560,7 +560,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
}
case i @ InstExtractElement(vecTy, indTy, opnd, index) => {
val ob = boxOf(opnd).asInstanceOf[BoxVector]
val ob = boxOf(opnd).asInstanceOf[BoxSeq]
val indb = boxOf(index).asInstanceOf[BoxInt]
val ind = OpHelper.prepareUnsigned(indb.value, indTy.length)
......@@ -575,7 +575,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
}
case i @ InstInsertElement(vecTy, indTy, opnd, index, newVal) => {
val ob = boxOf(opnd).asInstanceOf[BoxVector]
val ob = boxOf(opnd).asInstanceOf[BoxSeq]
val indb = boxOf(index).asInstanceOf[BoxInt]
val ind = OpHelper.prepareUnsigned(indb.value, indTy.length)
......@@ -587,7 +587,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val indInt = ind.intValue
val nvb = boxOf(newVal)
val ib = boxOf(i).asInstanceOf[BoxVector]
val ib = boxOf(i).asInstanceOf[BoxSeq]
for (((oeb, ieb), ind2) <- (ob.values zip ib.values).zipWithIndex) {
if (ind2 == indInt) {
......@@ -602,10 +602,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
case i @ InstShuffleVector(vecTy, maskTy, vec1, vec2, mask) => {
val vecLen = vecTy.len.toInt
val maskIntLen = maskTy.elemTy.asInstanceOf[TypeInt].length
val vb1 = boxOf(vec1).asInstanceOf[BoxVector]
val vb2 = boxOf(vec2).asInstanceOf[BoxVector]
val mb = boxOf(mask).asInstanceOf[BoxVector]
val ib = boxOf(i).asInstanceOf[BoxVector]
val vb1 = boxOf(vec1).asInstanceOf[BoxSeq]
val vb2 = boxOf(vec2).asInstanceOf[BoxSeq]
val mb = boxOf(mask).asInstanceOf[BoxSeq]
val ib = boxOf(i).asInstanceOf[BoxSeq]
for (((meb, ieb), ind) <- (mb.values zip ib.values).zipWithIndex) {
val me = OpHelper.prepareUnsigned(meb.asInstanceOf[BoxInt].value, maskIntLen)
......@@ -1168,7 +1168,11 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val norArgs = destClause.args
// Copy to edge-assigned boxes, first.
assert(norArgs.length == dest.norParams.length)
if(norArgs.length != dest.norParams.length) {
throw new UvmRefImplException(ctx + "Wrong number of arguments. Basic block: %s, expected: %d, actual: %d".format(
dest.repr, dest.norParams.length, norArgs.length))
}
for ((arg, np) <- norArgs zip dest.norParams) {
val argBox = boxOf(arg)
val npEdgeBox = edgeAssignedBoxOf(np)
......
......@@ -31,8 +31,8 @@ case class BoxFloat(var value: Float) extends ValueBox {
case class BoxDouble(var value: Double) extends ValueBox {
def copyFrom(other: ValueBox): Unit = { this.value = other.asInstanceOf[BoxDouble].value }
}
case class BoxVector(var values: Seq[ValueBox]) extends ValueBox {
def copyFrom(other: ValueBox): Unit = { for ((t, o) <- this.values.zip(other.asInstanceOf[BoxVector].values)) t.copyFrom(o) }
case class BoxSeq(var values: Seq[ValueBox]) extends ValueBox {
def copyFrom(other: ValueBox): Unit = { for ((t, o) <- this.values.zip(other.asInstanceOf[BoxSeq].values)) t.copyFrom(o) }
}
case class BoxRef(var objRef: Word) extends HasObjRef {
def copyFrom(other: ValueBox): Unit = { this.objRef = other.asInstanceOf[BoxRef].objRef }
......@@ -93,12 +93,12 @@ object ValueBox {
case _: TypeInt => BoxInt(0)
case _: TypeFloat => BoxFloat(0.0f)
case _: TypeDouble => BoxDouble(0.0d)
case TypeVector(elemTy, len) => BoxVector(Seq.fill(len.toInt)(makeBoxForType(elemTy)))
case TypeVector(elemTy, len) => BoxSeq(Seq.fill(len.toInt)(makeBoxForType(elemTy)))
case _: TypeRef => BoxRef(0L)
case _: TypeIRef => BoxIRef(0L, 0L)
case _: TypeWeakRef => throw new UvmRefImplException("weakref cannot be an SSA variable type")
case TypeStruct(fieldTys) => BoxStruct(fieldTys.map(makeBoxForType))
case _: TypeArray => throw new UvmRefImplException("array cannot be an SSA variable type")
case TypeArray(elemTy, len) => BoxSeq(Seq.fill(len.toInt)(makeBoxForType(elemTy)))
case _: TypeHybrid => throw new UvmRefImplException("hybrid cannot be an SSA variable type")
case _: TypeVoid => BoxVoid()
case _: TypeFuncRef => BoxFunc(None)
......
......@@ -352,7 +352,7 @@ object MemoryOperations {
ty match {
case TypeVector(ety, len) =>
val brs = br.asInstanceOf[BoxVector].values
val brs = br.asInstanceOf[BoxSeq].values
val elemSkip = alignUp(sizeOf(ety), alignOf(ety))
for ((brElem, i) <- brs.zipWithIndex) {
loadScalar(ety, loc + elemSkip * i, brElem)
......@@ -411,8 +411,8 @@ object MemoryOperations {
ty match {
case TypeVector(ety, len) =>
val nvbs = nvb.asInstanceOf[BoxVector].values
val brs = br.asInstanceOf[BoxVector].values
val nvbs = nvb.asInstanceOf[BoxSeq].values
val brs = br.asInstanceOf[BoxSeq].values
val elemSkip = alignUp(sizeOf(ety), alignOf(ety))
for (((brElem, nvbElem), i) <- (brs zip nvbs).zipWithIndex) {
storeScalar(ety, loc + elemSkip * i, nvbElem, brElem)
......
......@@ -29,11 +29,9 @@ case class ConstDouble(var constTy: Type, var num: Double) extends Constant
case class ConstStruct(var constTy: Type, var fields: Seq[GlobalVariable]) extends Constant
case class ConstArray(var constTy: Type, var elems: Seq[GlobalVariable]) extends Constant
case class ConstNull(var constTy: Type) extends Constant
case class ConstVector(var constTy: Type, var elems: Seq[Constant]) extends Constant
case class ConstSeq(var constTy: Type, var elems: Seq[GlobalVariable]) extends Constant
case class ConstPointer(var constTy: Type, var addr: Long) extends Constant
......
......@@ -201,7 +201,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
our const "@cth" shouldBeA[ConstNull] { _.constTy shouldBe (our ty "@thread") }
our const "@cst" shouldBeA[ConstNull] { _.constTy shouldBe (our ty "@stack") }
our const "@cv4f" shouldBeA[ConstVector] { its =>
our const "@cv4f" shouldBeA[ConstSeq] { its =>
its.constTy shouldBe (our ty "@4xfloat")
its elems 0 shouldBe (our const "@F_1")
its elems 1 shouldBe (our const "@F_2")
......@@ -209,7 +209,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its elems 3 shouldBe (our const "@F_4")
}
our const "@cv4i" shouldBeA[ConstVector] { its =>
our const "@cv4i" shouldBeA[ConstSeq] { its =>
its.constTy shouldBe (our ty "@4xi32")
its elems 0 shouldBe (our const "@I32_1")
its elems 1 shouldBe (our const "@I32_2")
......@@ -217,7 +217,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its elems 3 shouldBe (our const "@I32_4")
}
our const "@cv4d" shouldBeA[ConstVector] { its =>
our const "@cv4d" shouldBeA[ConstSeq] { its =>
its.constTy shouldBe (our ty "@2xdouble")
its elems 0 shouldBe (our const "@D_1")
its elems 1 shouldBe (our const "@D_2")
......@@ -243,7 +243,7 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
its.addr shouldBe 0xfedcba9876543210L
}
our const "@ary1" shouldBeA[ConstArray] { its =>
our const "@ary1" shouldBeA[ConstSeq] { its =>
its.constTy shouldBe (our ty "@i32_3_ary")
its elems 0 shouldBe (our const "@I32_1")
its elems 1 shouldBe (our const "@I32_2")
......
......@@ -86,7 +86,8 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
def asStack: Option[InterpreterStack] = vb.asInstanceOf[BoxStack].stack
def asTR64Box: BoxTagRef64 = vb.asInstanceOf[BoxTagRef64]
def asTR64Raw: Long = vb.asInstanceOf[BoxTagRef64].raw
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxVector].values
def asSeq: Seq[ValueBox] = vb.asInstanceOf[BoxSeq].values
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxSeq].values
def asPointer: Word = vb.asInstanceOf[BoxPointer].addr
}
}
\ No newline at end of file
......@@ -178,19 +178,19 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
val zero = ca.putInt("@i64", 0)
testFunc(ca, func, Seq(a, zero, one, one, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.trapexc"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a, one, zero, one, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.trapexc"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a, one, one, zero, one)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.trapexc"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a, one, one, one, zero)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.trapexc"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@binops64_div0_v1.exc.trapexc"
TrapRebindPassVoid(st)
}
......@@ -763,22 +763,22 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
val a1 = ca.putInt("@i64", 1)
testFunc(ca, func, Seq(a0)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@branch_v1.traptrue"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@branch_v1.iftrue.traptrue"
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a1)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) shouldBe "@branch_v1.trapfalse"
nameOf(ca.currentInstruction(st, 0)) shouldBe "@branch_v1.iffalse.trapfalse"
TrapRebindPassVoid(st)
}
ca.close()
}
"SWTICH and PHI" should "work" in {
"SWTICH" should "work" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@switch_phi")
val func = ca.putFunction("@switch")
val a0 = ca.putInt("@i64", 0)
val a1 = ca.putInt("@i64", 1)
......@@ -789,27 +789,27 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
val M = midTrapName
nameOf(ca.currentInstruction(st, 0)) match {
case M => {}
case "@switch_phi_v1.trapend" => {
val Seq(phi) = ca.dumpKeepalives(st, 0)
phi.vb.asSInt(64) shouldBe phiValue
case "@switch.v1.exit.trapend" => {
val Seq(v) = ca.dumpKeepalives(st, 0)
v.vb.asSInt(64) shouldBe phiValue
}
case trapName => fail("Trap %s should not be reached. Should reach %s.".format(trapName))
}
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0))(expectFlow("@switch_phi_v1.trapdef", 4))
testFunc(ca, func, Seq(a1))(expectFlow("@switch_phi_v1.trapone", 5))
testFunc(ca, func, Seq(a2))(expectFlow("@switch_phi_v1.traptwo", 6))
testFunc(ca, func, Seq(a3))(expectFlow("@switch_phi_v1.trapthree", 7))
testFunc(ca, func, Seq(a0))(expectFlow("@switch.v1.def.trapdef", 4))
testFunc(ca, func, Seq(a1))(expectFlow("@switch.v1.one.trapone", 5))
testFunc(ca, func, Seq(a2))(expectFlow("@switch.v1.two.traptwo", 6))
testFunc(ca, func, Seq(a3))(expectFlow("@switch.v1.three.trapthree", 7))
ca.close()
}
"PHI instructions in a basic block" should "be assigned at the same time in CFG edges" in {
"Parameters of a basic block" should "be assigned at the same time in CFG edges" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@phi_cyclic_dep_test")
val func = ca.putFunction("@edge_asgn_test")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val Seq(x, y) = ca.dumpKeepalives(st, 0)
......@@ -841,7 +841,7 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
ca.close()
}
"CALL, THROW and LANDINGPAD" should "handle exceptions" in {
"CALL, THROW and the exception parameter" should "handle exceptions" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@call_throw")
......@@ -850,11 +850,11 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
testFunc(ca, func, Seq(a0)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
case "@call_throw_v1.trapnor" => {
case "@call_throw_v1.nor.trapnor" => {
val Seq(rv) = ca.dumpKeepalives(st, 0)
rv.vb.asInt shouldEqual 3
}
case "@call_throw_v1.trapexc" => {
case "@call_throw_v1.exctrapexc" => {
fail("Should not receive exception")
}
}
......@@ -866,12 +866,12 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
testFunc(ca, func, Seq(a1)) { (ca, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match {
case "@call_throw_v1.trapnor" => {
case "@call_throw_v1.nor.trapnor" => {
fail("Should not return normally")
}
case "@call_throw_v1.trapexc" => {
val Seq(lp) = ca.dumpKeepalives(st, 0)
lp.vb.asRef shouldEqual 0L
case "@call_throw_v1.exc.trapexc" => {
val Seq(theExc) = ca.dumpKeepalives(st, 0)
theExc.vb.asRef shouldEqual 0L
}
}
......@@ -897,17 +897,19 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
ca.close()
}
"EXTRACTELEMENT and INSERTELEMENT" should "work on vectors" in {
"EXTRACTELEMENT and INSERTELEMENT" should "work on vectors and arrays" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@aggregate_vector")
val func = ca.putFunction("@aggregate_seq")
testFunc(ca, func, Seq()) { (ca, th, st, wp) =>
val Seq(ee0, ie0, sv0) = ca.dumpKeepalives(st, 0)