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.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit bcb40c0c authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Implement comparison of general reference types.

Including ref, iref, func and stack. There is currently no way to get
Thread values.
parent c932ca84
...@@ -201,11 +201,63 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter ...@@ -201,11 +201,63 @@ class InterpreterThread(val id: Int, microVM: MicroVM, initialStack: Interpreter
writeBooleanResult(result, br) writeBooleanResult(result, br)
} }
def doRef(b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
val op1v = b1.asInstanceOf[BoxRef].objRef
val op2v = b2.asInstanceOf[BoxRef].objRef
val result = op match {
case CmpOptr.EQ => op1v == op2v
case CmpOptr.NE => op1v != op2v
case _ => throw new UvmRuntimeException(ctx + "Comparison %s not suitable for reference type %s".format(op, opndTy))
}
writeBooleanResult(result, br)
}
def doIRef(b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
val op1v = b1.asInstanceOf[BoxIRef].oo
val op2v = b2.asInstanceOf[BoxIRef].oo
val result = op match {
case CmpOptr.EQ => op1v == op2v
case CmpOptr.NE => op1v != op2v
case _ => throw new UvmRuntimeException(ctx + "Comparison %s not suitable for internal reference type %s".format(op, opndTy))
}
writeBooleanResult(result, br)
}
def doFunc(b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
val op1v = b1.asInstanceOf[BoxFunc].func
val op2v = b2.asInstanceOf[BoxFunc].func
val result = op match {
case CmpOptr.EQ => op1v == op2v
case CmpOptr.NE => op1v != op2v
case _ => throw new UvmRuntimeException(ctx + "Comparison %s not suitable for function type %s".format(op, opndTy))
}
writeBooleanResult(result, br)
}
def doStack(b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
val op1v = b1.asInstanceOf[BoxStack].stack
val op2v = b2.asInstanceOf[BoxStack].stack
val result = op match {
case CmpOptr.EQ => op1v == op2v
case CmpOptr.NE => op1v != op2v
case _ => throw new UvmRuntimeException(ctx + "Comparison %s not suitable for stack type %s".format(op, opndTy))
}
writeBooleanResult(result, br)
}
def doScalar(scalarTy: Type, b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = { def doScalar(scalarTy: Type, b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
scalarTy match { scalarTy match {
case TypeInt(l) => doInt(l, b1, b2, br) case TypeInt(l) => doInt(l, b1, b2, br)
case TypeFloat() => doFloat(b1, b2, br) case TypeFloat() => doFloat(b1, b2, br)
case TypeDouble() => doDouble(b1, b2, br) case TypeDouble() => doDouble(b1, b2, br)
case TypeRef(_) => doRef(b1, b2, br)
case TypeIRef(_) => doIRef(b1, b2, br)
case TypeFunc(_) => doFunc(b1, b2, br)
case TypeStack() => doStack(b1, b2, br)
case _ => throw new UvmRuntimeException(ctx + "Comparison not suitable for type %s".format(opndTy)) case _ => throw new UvmRuntimeException(ctx + "Comparison not suitable for type %s".format(opndTy))
} }
} }
......
...@@ -557,7 +557,89 @@ class UvmInterpreterSpec extends UvmBundleTesterBase { ...@@ -557,7 +557,89 @@ class UvmInterpreterSpec extends UvmBundleTesterBase {
} }
ca.close() ca.close()
} }
"Comparing operations" should "work on general reference types" in {
val ca = microVM.newClientAgent()
val func = ca.putFunction("@cmp_ref")
val a0 = ca.newFixed("@i64")
val a1 = ca.newFixed("@i64")
val a2 = ca.putGlobal("@dummy_global1")
val a3 = ca.putGlobal("@dummy_global2")
val a4 = ca.putFunction("@dummy_func1")
val a5 = ca.putFunction("@dummy_func2")
val a6 = ca.newStack(a5, Seq())
val a7 = ca.newStack(a5, Seq())
testFunc(ca, func, Seq(a0, a0, a2, a2, a4, a4, a6, a6)) { (ca, th, st, wp) =>
val Seq(req, rne,ieq, ine, feq, fne, seq, sne) = ca.dumpKeepalives(st, 0)
req.vb.asUInt(1) shouldEqual 1
rne.vb.asUInt(1) shouldEqual 0
ieq.vb.asUInt(1) shouldEqual 1
ine.vb.asUInt(1) shouldEqual 0
feq.vb.asUInt(1) shouldEqual 1
fne.vb.asUInt(1) shouldEqual 0
seq.vb.asUInt(1) shouldEqual 1
sne.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0, a1, a2, a3, a4, a5, a6, a7)) { (ca, th, st, wp) =>
val Seq(req, rne,ieq, ine, feq, fne, seq, sne) = ca.dumpKeepalives(st, 0)
req.vb.asUInt(1) shouldEqual 0
rne.vb.asUInt(1) shouldEqual 1
ieq.vb.asUInt(1) shouldEqual 0
ine.vb.asUInt(1) shouldEqual 1
feq.vb.asUInt(1) shouldEqual 0
fne.vb.asUInt(1) shouldEqual 1
seq.vb.asUInt(1) shouldEqual 0
sne.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
val nr = ca.putConstant("@NULLREF_I64")
val ni = ca.putConstant("@NULLIREF_I64")
val nf = ca.putConstant("@NULLFUNC")
val ns = ca.putConstant("@NULLSTACK")
testFunc(ca, func, Seq(nr, nr, ni, ni, nf, nf, ns, ns)) { (ca, th, st, wp) =>
val Seq(req, rne,ieq, ine, feq, fne, seq, sne) = ca.dumpKeepalives(st, 0)
req.vb.asUInt(1) shouldEqual 1
rne.vb.asUInt(1) shouldEqual 0
ieq.vb.asUInt(1) shouldEqual 1
ine.vb.asUInt(1) shouldEqual 0
feq.vb.asUInt(1) shouldEqual 1
fne.vb.asUInt(1) shouldEqual 0
seq.vb.asUInt(1) shouldEqual 1
sne.vb.asUInt(1) shouldEqual 0
TrapRebindPassVoid(st)
}
testFunc(ca, func, Seq(a0, nr, a2, ni, a4, nf, a6, ns)) { (ca, th, st, wp) =>
val Seq(req, rne,ieq, ine, feq, fne, seq, sne) = ca.dumpKeepalives(st, 0)
req.vb.asUInt(1) shouldEqual 0
rne.vb.asUInt(1) shouldEqual 1
ieq.vb.asUInt(1) shouldEqual 0
ine.vb.asUInt(1) shouldEqual 1
feq.vb.asUInt(1) shouldEqual 0
fne.vb.asUInt(1) shouldEqual 1
seq.vb.asUInt(1) shouldEqual 0
sne.vb.asUInt(1) shouldEqual 1
TrapRebindPassVoid(st)
}
ca.close()
}
"Conversions" should "work on scalar types" in { "Conversions" should "work on scalar types" in {
val ca = microVM.newClientAgent() val ca = microVM.newClientAgent()
......
...@@ -76,7 +76,13 @@ ...@@ -76,7 +76,13 @@
.typedef @refvoid = ref<@void> .typedef @refvoid = ref<@void>
.typedef @irefvoid = iref<@void> .typedef @irefvoid = iref<@void>
.typedef @weakrefvoid = weakref<@void> .typedef @weakrefvoid = weakref<@void>
.const @NULLREF <@refvoid> = NULL .const @NULLREF <@refvoid> = NULL
.const @NULLIREF <@irefvoid> = NULL
.const @NULLFUNC <@funcdumb> = NULL
.const @NULLSTACK <@stack> = NULL
.const @NULLREF_I64 <@refi64> = NULL
.const @NULLIREF_I64 <@irefi64> = NULL
.funcsig @binops32_sig = @void (@i32 @i32) .funcsig @binops32_sig = @void (@i32 @i32)
.funcdef @binops32 VERSION @binops32_v1 <@binops32_sig> (%p0 %p1) { .funcdef @binops32 VERSION @binops32_v1 <@binops32_sig> (%p0 %p1) {
...@@ -285,6 +291,33 @@ ...@@ -285,6 +291,33 @@
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
.global @dummy_global1 <@i64>
.global @dummy_global2 <@i64>
.funcdecl @dummy_func1 <@noparamsnoret>
.funcdef @dummy_func2 VERSION @dummy_func2.v1 <@noparamsnoret> () {
%entry:
RETVOID
}
.funcsig @cmp_ref_sig = @void (@refi64 @refi64 @irefi64 @irefi64 @funcdumb @funcdumb @stack @stack)
.funcdef @cmp_ref VERSION @cmp_ref_v1 <@cmp_ref_sig> (%p0 %p1 %p2 %p3 %p4 %p5 %p6 %p7) {
%entry:
%req = EQ <@refi64> %p0 %p1
%rne = NE <@refi64> %p0 %p1
%ieq = EQ <@irefi64> %p2 %p3
%ine = NE <@irefi64> %p2 %p3
%feq = EQ <@funcdumb> %p4 %p5
%fne = NE <@funcdumb> %p4 %p5
%seq = EQ <@stack> %p6 %p7
%sne = NE <@stack> %p6 %p7
%trap = TRAP <@void> KEEPALIVE (
%req %rne %ieq %ine %feq %fne %seq %sne
)
COMMINST @uvm.thread_exit
}
.funcsig @conv_sig = @void (@i32 @i64 @float @double) .funcsig @conv_sig = @void (@i32 @i64 @float @double)
.funcdef @conv VERSION @conv_v1 <@conv_sig> (%p0 %p1 %p2 %p3) { .funcdef @conv VERSION @conv_v1 <@conv_sig> (%p0 %p1 %p2 %p3) {
%entry: %entry:
...@@ -662,8 +695,6 @@ ...@@ -662,8 +695,6 @@
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
.const @NULLIREF_I64 <@irefi64> = NULL
.funcdef @memAccessingNull VERSION @memAccessingNull_v1 <@noparamsnoret> () { .funcdef @memAccessingNull VERSION @memAccessingNull_v1 <@noparamsnoret> () {
%entry: %entry:
%l = LOAD <@i64> @NULLIREF_I64 EXC(%unreachable %bb2) %l = LOAD <@i64> @NULLIREF_I64 EXC(%unreachable %bb2)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment