Commit ffdc3604 authored by Kunshan Wang's avatar Kunshan Wang

Fixed memory layout and memory op tests

parent ebe76f0d
FN=$1
sed -i 's/newClientAgent/newContext/g' $FN
sed -i 's/\bca\b/ctx/g' $FN
sed -i 's/ctx\.close()/ctx.closeContext()/g' $FN
sed -i 's/putInt("@i32",/i32(/g' $FN
sed -i 's/putInt("@i64",/i64(/g' $FN
sed -i 's/putConstant/handleFromConst/g' $FN
sed -i 's/putGlobal/handleFromGlobal/g' $FN
sed -i 's/putFunction/handleFromFunc/g' $FN
sed -i 's/toInt(\(\w\+\),\s*signExt\s*=\s*true)/handleToSInt(\1.asInstanceOf[MuIntValue])/g' $FN
sed -i 's/currentInstruction/curInst/g' $FN
sed -i 's/TrapRebindPassVoid/returnFromTrap/g' $FN
sed -i 's/TrapRebindPassValue(\(\w\+\),\s*\(\w\+\)\s*)/Rebind(\1, PassValues(Seq(\2)))/g' $FN
if [ x$SED == x ]; then
SED=sed
fi
$SED -i 's/newClientAgent/newContext/g' $FN
$SED -i 's/deleteHandle/deleteValue/g' $FN
$SED -i 's/\bca\b/ctx/g' $FN
$SED -i 's/ctx\.close()/ctx.closeContext()/g' $FN
$SED -i 's/putInt("@i32",/handleFromInt32(/g' $FN
$SED -i 's/putInt("@i64",/handleFromInt64(/g' $FN
$SED -i 's/putInt("@i\(\d\+\)"\s*,\s*\([^)]*\))/handleFromInt(\2, \1)/g' $FN
$SED -i 's/putFloat("@float",/handleFromFloat(/g' $FN
$SED -i 's/putDouble("@double",/handleFromDouble(/g' $FN
$SED -i 's/putConstant/handleFromConst/g' $FN
$SED -i 's/putGlobal/handleFromGlobal/g' $FN
$SED -i 's/putFunction/handleFromFunc/g' $FN
$SED -i 's/toInt(\(\w\+\),\s*\(signExt\s*=\s*\)\?true)/handleToSInt(\1.asInstanceOf[MuIntValue])/g' $FN
$SED -i 's/toFloat/handleToFloat/g' $FN
$SED -i 's/toDouble/handleToDouble/g' $FN
$SED -i 's/refCast/refcast/g' $FN
$SED -i 's/currentInstruction/curInst/g' $FN
$SED -i 's/TrapRebindPassVoid/returnFromTrap/g' $FN
$SED -i 's/TrapRebindPassValue(\(\w\+\),\s*\(\w\+\)\s*)/Rebind(\1, PassValues(Seq(\2)))/g' $FN
......@@ -12,6 +12,7 @@ import uvm.ssavariables.HasKeepAliveClause
import scala.collection.mutable.ArrayBuffer
import uvm.ssavariables.Flag
import uvm.refimpl.itpr.{ HowToResume => ItprHowToResume }
import scala.collection.mutable.Buffer
object MuValue {
def apply(ty: Type, vb: ValueBox): MuValue = (ty, vb) match {
......@@ -90,6 +91,10 @@ trait UndefinedFunctionHandler {
def handleUndefinedFunction(functionID: Int): Unit
}
/**
* A client context. The main part of the API. It keeps thread-local states, including a set of handles. It provides
* operations on the Mu VM.
*/
class MuCtx(mutator: Mutator)(
implicit microVM: MicroVM, memorySupport: MemorySupport) extends ObjectPinner {
val handles = new HashSet[MuValue]()
......@@ -317,7 +322,7 @@ class MuCtx(mutator: Mutator)(
}
/** Cast between two refs, two irefs or two funcrefs */
def refcast(opnd: MuValue, newType: Int): MuValue = {
def refcast[T <: MuGenRefValue](opnd: T, newType: Int): T = {
val nt = microVM.globalBundle.typeNs(newType)
val nh = (opnd, nt) match {
......@@ -330,7 +335,7 @@ class MuCtx(mutator: Mutator)(
}
}
addHandle(nh)
addHandle(nh.asInstanceOf[T])
}
/** Convert ref to iref */
......@@ -424,7 +429,7 @@ class MuCtx(mutator: Mutator)(
MemoryOperations.store(ptr, uty, addr, nvb)
}
/** Perform compare exchange on a location. */
/** Perform compare exchange on a location. */
def cmpXchg(ordSucc: MemoryOrder, ordFail: MemoryOrder, weak: Boolean,
loc: MuIRefValue, expected: MuValue, desired: MuValue): (MuValue, Boolean) = {
val (ptr, ty) = loc.ty match {
......@@ -522,8 +527,10 @@ class MuCtx(mutator: Mutator)(
}
}
/** Get the ID of the current function version of a frame. Return 0 for native frames
* or Mu frames of undefined functions*/
/**
* Get the ID of the current function version of a frame. Return 0 for native frames
* or Mu frames of undefined functions
*/
def curFuncVer(stack: MuStackRefValue, frame: Int): Int = {
val sv = getStackNotNull(stack)
val fr = nthFrame(sv, frame)
......@@ -534,8 +541,10 @@ class MuCtx(mutator: Mutator)(
}
}
/** Get the ID of the current instruction of a frame. Return 0 for native frames, Mu frames for undefined
* functions, or if the frame is just created by newStack or pushFrame. */
/**
* Get the ID of the current instruction of a frame. Return 0 for native frames, Mu frames for undefined
* functions, or if the frame is just created by newStack or pushFrame.
*/
def curInst(stack: MuStackRefValue, frame: Int): Int = {
val sv = getStackNotNull(stack)
val fr = nthFrame(sv, frame)
......@@ -655,7 +664,7 @@ class MuCtx(mutator: Mutator)(
/** Convert an object ref and a tag to a tagref64. */
def tr64FromRef(ref: MuRefValue, tag: MuIntValue): MuTagRef64Value = {
if (tag.ty.length != 52) throw new IllegalArgumentException("Expect int<6> tag, found %s".format(tag.ty.repr))
if (tag.ty.length != 6) throw new IllegalArgumentException("Expect int<6> tag, found %s".format(tag.ty.repr))
val refv = ref.vb.objRef
val tagv = tag.vb.value
val box = new BoxTagRef64(OpHelper.refToTr64(refv, tagv.longValue))
......@@ -725,5 +734,56 @@ class MuCtx(mutator: Mutator)(
val box = BoxStack(sta)
addHandle(MuStackRefValue(s, box))
}
}
object RichMuCtx {
/** Extensions to the MuCtx interface. Not officially part of the client API. */
implicit class RichMuCtx(ctx: MuCtx) {
def handleFromBoolean(b: Boolean) = ctx.handleFromInt(if (b) 1 else 0, 1)
def handleFromInt1(num: BigInt) = ctx.handleFromInt(num, 1)
def handleFromInt6(num: BigInt) = ctx.handleFromInt(num, 6)
def handleFromInt8(num: BigInt) = ctx.handleFromInt(num, 8)
def handleFromInt16(num: BigInt) = ctx.handleFromInt(num, 16)
def handleFromInt32(num: BigInt) = ctx.handleFromInt(num, 32)
def handleFromInt52(num: BigInt) = ctx.handleFromInt(num, 52)
def handleFromInt64(num: BigInt) = ctx.handleFromInt(num, 64)
def deleteValue(vs: MuValue*) = vs.foreach(ctx.deleteValue)
class DelayedDisposer(garbageList: Buffer[MuValue]) {
def apply[T<:MuValue](v: T): T = {
garbageList += v
v
}
}
def autoDispose[T](f: DelayedDisposer => T) = {
val garbages = ArrayBuffer[MuValue]()
val dd = new DelayedDisposer(garbages)
val rv = f(dd)
garbages.foreach(ctx.deleteValue)
rv
}
def loadInt(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuIntValue]
def loadFloat(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuFloatValue]
def loadDouble(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuDoubleValue]
def loadRef(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuRefValue]
def loadIRef(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuIRefValue]
def loadFuncRef(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuFuncRefValue]
def loadThreadRef(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuThreadRefValue]
def loadStackRef(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuStackRefValue]
def loadTagRef64(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuTagRef64Value]
def loadVector(ord: MemoryOrder, loc: MuIRefValue) = ctx.load(ord, loc).asInstanceOf[MuVectorValue]
def storeInt(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuIntValue]
def storeFloat(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuFloatValue]
def storeDouble(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuDoubleValue]
def storeRef(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuRefValue]
def storeIRef(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuIRefValue]
def storeFuncRef(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuFuncRefValue]
def storeThreadRef(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuThreadRefValue]
def storeStackRef(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuStackRefValue]
def storeTagRef64(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuTagRef64Value]
def storeVector(ord: MemoryOrder, loc: MuIRefValue, newval: MuValue) = ctx.store(ord, loc, newval).asInstanceOf[MuVectorValue]
}
}
\ No newline at end of file
......@@ -95,11 +95,7 @@ abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
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)
}
implicit def richMuCtx(ctx: MuCtx) = RichMuCtx.RichMuCtx(ctx)
def returnFromTrap(st: MuStackRefValue) = Rebind(st, PassValues(Seq()))
}
\ No newline at end of file
......@@ -146,10 +146,10 @@ class UvmInterpreterFutexTests extends UvmBundleTesterBase {
val nthr2 = nt2.vb.asThread.get
if (nthr.isFutexWaiting && nthr2.isFutexWaiting) {
val one = ctx.i32(1)
val one = ctx.handleFromInt32(1)
Rebind(st, PassValues(Seq(one)))
} else {
val zero = ctx.i32(0)
val zero = ctx.handleFromInt32(0)
Rebind(st, PassValues(Seq(zero)))
}
}
......@@ -215,10 +215,10 @@ class UvmInterpreterFutexTests extends UvmBundleTesterBase {
val nthr = nt.vb.asThread.get
if (nthr.isFutexWaiting) {
val one = ctx.i32(1)
val one = ctx.handleFromInt32(1)
Rebind(st, PassValues(Seq(one)))
} else {
val zero = ctx.i32(0)
val zero = ctx.handleFromInt32(0)
Rebind(st, PassValues(Seq(zero)))
}
}
......
......@@ -19,7 +19,7 @@ class UvmMemLayoutSpec extends FlatSpec with Matchers with BeforeAndAfter {
sizeOf(TypeIRef(TypeVoid())) shouldBe 16
sizeOf(TypeWeakRef(TypeVoid())) shouldBe 8
sizeOf(TypeVoid()) shouldBe 0
sizeOf(TypeFuncRef(FuncSig(TypeVoid(), Seq()))) shouldBe 8
sizeOf(TypeFuncRef(FuncSig(Seq(), Seq()))) shouldBe 8
sizeOf(TypeThreadRef()) shouldBe 8
sizeOf(TypeStackRef()) shouldBe 8
sizeOf(TypeTagRef64()) shouldBe 8
......@@ -36,7 +36,7 @@ class UvmMemLayoutSpec extends FlatSpec with Matchers with BeforeAndAfter {
alignOf(TypeIRef(TypeVoid())) shouldBe 16
alignOf(TypeWeakRef(TypeVoid())) shouldBe 8
alignOf(TypeVoid()) shouldBe 1
alignOf(TypeFuncRef(FuncSig(TypeVoid(), Seq()))) shouldBe 8
alignOf(TypeFuncRef(FuncSig(Seq(), Seq()))) shouldBe 8
alignOf(TypeThreadRef()) shouldBe 8
alignOf(TypeStackRef()) shouldBe 8
alignOf(TypeTagRef64()) shouldBe 8
......@@ -75,10 +75,20 @@ class UvmMemLayoutSpec extends FlatSpec with Matchers with BeforeAndAfter {
}
"In a hybrid, fields" should "be laid out in the fixed-then-var fasion" in {
val ty = TypeHybrid(TypeInt(16), TypeDouble())
hybridSizeOf(ty, 10) shouldBe 88
val ty = TypeHybrid(Seq(TypeInt(8), TypeInt(16), TypeInt(32), TypeInt(64)), TypeDouble())
hybridSizeOf(ty, 10) shouldBe 96
hybridAlignOf(ty, 10) shouldBe 8
fixedPartOffsetOf(ty) shouldBe 0
varPartOffsetOf(ty) shouldBe 8
fieldOffsetOf(ty, 0) shouldBe 0
fieldOffsetOf(ty, 1) shouldBe 2
fieldOffsetOf(ty, 2) shouldBe 4
fieldOffsetOf(ty, 3) shouldBe 8
varPartOffsetOf(ty) shouldBe 16
}
"In a hybrid with no fixed parts, the variable part" should "have offset 0" in {
val ty = TypeHybrid(Seq(), TypeFloat())
hybridSizeOf(ty, 10) shouldBe 40
hybridAlignOf(ty, 10) shouldBe 4
varPartOffsetOf(ty) shouldBe 0
}
}
\ No newline at end of file
.typedef @i1 = int<1>
.typedef @i8 = int<8>
.typedef @i16 = int<16>
.typedef @i32 = int<32>
.typedef @i64 = int<64>
.typedef @float = float
.typedef @double = double
.typedef @rv = ref<@void>
.typedef @irv = iref<@void>
.typedef @wrv = weakref<@void>
.const @NULLRV <@rv> = NULL
.const @NULLIRV <@irv> = NULL
// require 'primitives.uir'
.typedef @ri16 = ref<@i16>
.typedef @s1 = struct<@i8 @i16 @i32 @i64 @float @double @rv @irv @wrv @ri16>
.typedef @s1 = struct<@i8 @i16 @i32 @i64 @float @double @refvoid @irefvoid @weakrefvoid @ri16>
.typedef @Cons = struct<@i64 @RefCons>
.typedef @RefCons = ref<@Cons>
......@@ -27,33 +13,20 @@
.typedef @a1 = array<@foo 10>
.typedef @a2 = array<@a1 10>
.typedef @h0 = hybrid <@void @i8>
.typedef @h0 = hybrid <@i8>
.typedef @h1 = hybrid <@foo @i64>
.typedef @void = void
.funcsig @sig0 = @void ()
.funcsig @sig0 = () -> ()
.typedef @ii8 = iref<@i8>
.typedef @iii8 = iref<@ii8>
.funcsig @sig1 = @i32 (@i32 @iii8)
.funcsig @sig1 = (@i32 @iii8) -> (@i32)
.typedef @f0 = funcref<@sig0>
.typedef @f1 = funcref<@sig1>
.typedef @th = threadref
.typedef @st = stackref
.typedef @tr64 = tagref64
.typedef @i6 = int<6>
.typedef @i52 = int<52>
.typedef @s2 = struct<@f0 @th @st @tr64>
.typedef @4xfloat = vector <@float 4>
.typedef @4xi32 = vector <@i32 4>
.typedef @2xdouble = vector <@double 2>
.typedef @s2 = struct<@f0 @thread @stack @tagref64>
.funcdecl @fun <@sig0>
.funcdecl @fun <@sig0>
.funcdecl @fun2 <@sig0>
.const @NULLF0 <@f0> = NULL
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