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 0787369e authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Fixed interpreter and impl details.

parent 559c72dc
......@@ -22,7 +22,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
// implicitly injected resources
private implicit val microVM = this
val globalBundle = new Bundle()
val globalBundle = new GlobalBundle()
val constantPool = new ConstantPool()
val memoryManager = new MemoryManager(heapSize, globalSize, stackSize)
......@@ -50,7 +50,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
/**
* Add things from a bundle to the Micro VM.
*/
def addBundle(bundle: Bundle) {
def addBundle(bundle: TrantientBundle) {
globalBundle.merge(bundle);
for (gc <- bundle.globalCellNs.all) {
......
......@@ -65,7 +65,8 @@ object TypeInferer {
case c: Constant => c.constTy
case g: GlobalCell => irefOf(g.cellTy)
case f: Function => funcOf(f.sig)
case p: Parameter => p.funcVer.sig.paramTy(p.index)
case p: NorParam => p.ty
case p: ExcParam => REF_VOID
case i: InstBinOp => i.opndTy
case i: InstCmp => i.opndTy match {
case TypeVector(_, l) => vecOf(I1, l)
......@@ -76,17 +77,14 @@ object TypeInferer {
case i: InstBranch => VOID
case i: InstBranch2 => VOID
case i: InstSwitch => VOID
case i: InstPhi => i.opndTy
case i: InstCall => i.sig.retTy
case i: InstTailCall => VOID
case i: InstRet => VOID
case i: InstRetVoid => VOID
case i: InstThrow => VOID
case i: InstLandingPad => REF_VOID
case i: InstExtractValue => i.strTy.fieldTys(i.index)
case i: InstInsertValue => i.strTy
case i: InstExtractElement => i.vecTy.elemTy
case i: InstInsertElement => i.vecTy
case i: InstExtractElement => i.seqTy.elemTy
case i: InstInsertElement => i.seqTy
case i: InstShuffleVector => vecOf((i.vecTy.elemTy, i.maskTy.len))
case i: InstNew => refOf(i.allocTy)
case i: InstNewHybrid => refOf(i.allocTy)
......
......@@ -100,10 +100,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
private def boxOf(v: SSAVariable): ValueBox = boxOf(curStack, v)
/** Get the edge-assigned value box of an edge-assigned instruction in a stack. */
private def edgeAssignedBoxOf(s: InterpreterStack, ea: EdgeAssigned): ValueBox = topMu.edgeAssignedBoxes(ea)
private def edgeAssignedBoxOf(s: InterpreterStack, p: Parameter): ValueBox = topMu.edgeAssignedBoxes(p)
/** Get the edge-assigned value box of an edge-assigned instruction in the current stack. */
private def edgeAssignedBoxOf(ea: EdgeAssigned): ValueBox = edgeAssignedBoxOf(curStack, ea)
private def edgeAssignedBoxOf(p: Parameter): ValueBox = edgeAssignedBoxOf(curStack, p)
// Context printing for debugging
......@@ -191,7 +191,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
case e: UvmDivisionByZeroException => excClause match {
case None => throw e
case Some(ec) => {
branchAndMovePC(ec.exc)
branchAndAssignParameters(ec.exc)
}
}
}
......@@ -465,13 +465,13 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
}
case i @ InstBranch(dest) => {
branchAndMovePC(dest)
branchAndAssignParameters(dest)
}
case i @ InstBranch2(cond, ifTrue, ifFalse) => {
val cv = boxOf(cond).asInstanceOf[BoxInt].value
val dest = if (cv == 1) ifTrue else ifFalse
branchAndMovePC(dest)
branchAndAssignParameters(dest)
}
case i @ InstSwitch(opndTy, opnd, defDest, cases) => {
......@@ -479,15 +479,12 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
case TypeInt(l) => {
val ov = boxOf(opnd).asInstanceOf[BoxInt].value
val dest = cases.find(pair => boxOf(pair._1).asInstanceOf[BoxInt].value == ov).map(_._2).getOrElse(defDest)
branchAndMovePC(dest)
branchAndAssignParameters(dest)
}
case _ => throw new UvmRefImplException(ctx + "Operand type must be integer. %s found.".format(opndTy))
}
}
case i @ InstPhi(_, _) => throw new UvmRefImplException(ctx + "PHI instructions reached in normal execution, " +
"but PHI must only appear in the beginning of basic blocks and not in the entry block.")
case i @ InstCall(sig, callee, argList, excClause, keepAlives) => {
val calleeFunc = boxOf(callee).asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException(ctx + "Callee must not be NULL")
......@@ -534,32 +531,12 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
}
}
case i @ InstRetVoid() => {
curStack.popFrame()
top match {
case f: MuFrame => {
finishHalfExecutedInst()
}
case f: NativeFrame => {
// Now the top is a native frame, and it must be calling back to Mu.
// Since Mu returns void, we don't need to assign the return value.
// Return to native, and keep an eye on the result, in case it calls back again.
val result = curStack.returnToNativeOnStack()
// Handle the control flow according to how the native function respond
handleNativeCallResult(result)
}
}
}
case i @ InstThrow(excVal) => {
val exc = boxOf(excVal).asInstanceOf[BoxRef].objRef
curStack.popFrame()
catchException(exc)
}
case i @ InstLandingPad() => throw new UvmRefImplException(ctx + "LANDINGPAD instructions reached in normal execution, " +
"but LANDINGPAD must only appear in the beginning of basic blocks and not in the entry block.")
case i @ InstExtractValue(strTy, index, opnd) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct]
val fb = ob.values(index)
......@@ -801,7 +778,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
if (isEnabled) {
doTrap(retTy, wpID)
} else {
branchAndMovePC(dis)
branchAndAssignParameters(dis)
}
}
......@@ -861,9 +838,6 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val argBox = boxOf(oldStack, arg)
rebindPassValue(newStack, argBox)
}
case PassVoid() => {
rebindPassVoid(newStack)
}
case ThrowExc(exc) => {
val excBox = boxOf(oldStack, exc)
rebindThrowExc(newStack, excBox)
......@@ -1188,49 +1162,51 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
// Control flow helpers
/** Branch to a basic block and execute starter instructions (PHI and LANDINGPAD). */
private def branchAndMovePC(dest: BasicBlock, excAddr: Word = 0L): Unit = {
private def branchAndAssignParameters(destClause: DestClause, maybeExcAddr: Option[Word] = None): Unit = {
val curBB = this.curBB
var cont = true
var i = 0
// Determine the value of edge-assigned instructions (phis and landingpads), but keep them in their temporary boxes.
while (cont) {
dest.insts(i) match {
case phi @ InstPhi(opndTy, cases) => {
val caseVal = cases.find(_._1 == curBB).map(_._2).getOrElse {
throw new UvmRuntimeException(s"Phi node ${phi.repr} does not include the case for source basic block ${curBB.repr}")
}
val vb = boxOf(caseVal)
val db = edgeAssignedBoxOf(phi)
db.copyFrom(vb)
i += 1
}
case lp: InstLandingPad => {
val db = edgeAssignedBoxOf(lp).asInstanceOf[BoxRef]
db.objRef = excAddr
i += 1
val dest = destClause.bb
val norArgs = destClause.args
// Copy to edge-assigned boxes, first.
assert(norArgs.length == dest.norParams.length)
for ((arg, np) <- norArgs zip dest.norParams) {
val argBox = boxOf(arg)
val npEdgeBox = edgeAssignedBoxOf(np)
npEdgeBox.copyFrom(argBox)
}
for (ep <- dest.excParam) {
maybeExcAddr match {
case None => throw new UvmRefImplException(ctx + "Branching normally to a basic block with ExcParam: %s".format(dest.repr))
case Some(excAddr) => {
val epEdgeBox = edgeAssignedBoxOf(ep).asInstanceOf[BoxRef]
epEdgeBox.setObjRef(excAddr)
}
case _ => cont = false
}
}
// Copy the values of edge-assigned instructions (phis and landingpads) to their canonical boxes.
for (j <- 0 until i) {
val destInst = dest.insts(j)
val sb = edgeAssignedBoxOf(destInst.asInstanceOf[EdgeAssigned])
val db = boxOf(destInst)
db.copyFrom(sb)
// Copy from edge-assigned boxes to their canonical boxes.
for (np <- dest.norParams) {
val npEdgeBox = edgeAssignedBoxOf(np)
val npBox = boxOf(np)
npBox.copyFrom(npEdgeBox)
}
for (ep <- dest.excParam) {
val epEdgeBox = edgeAssignedBoxOf(ep)
val epBox = boxOf(ep)
epBox.copyFrom(epEdgeBox)
}
// Continue execution
jump(dest, i)
jump(dest, 0)
}
/** Continue normally. Work for all instructions. */
private def continueNormally(): Unit = {
curInst match {
case wp: InstWatchPoint => {
branchAndMovePC(wp.ena)
branchAndAssignParameters(wp.ena)
// NOTE: WatchPoint only "continue normally" when the current stack is rebound with value or void.
// This includes executing a watch point. In any case, this watch point must have been enabled. If the watch
// point is disabled during the course the stack is unbound, this watch point should still continue from the
......@@ -1239,7 +1215,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
case h: HasExcClause => h.excClause match {
case None => incPC()
case Some(ec) => {
branchAndMovePC(ec.nor)
branchAndAssignParameters(ec.nor)
}
}
case _ => incPC()
......@@ -1264,9 +1240,9 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
*/
private def catchException(exc: Word): Unit = {
@tailrec
def unwindUntilCatchable(frame: InterpreterFrame): (InterpreterFrame, BasicBlock) = frame match {
def unwindUntilCatchable(frame: InterpreterFrame): (InterpreterFrame, DestClause) = frame match {
case f: MuFrame => maybeFindExceptionHandler(f.curInst) match {
case Some(bb) => (f, bb)
case Some(dc) => (f, dc)
case None => f.prev match {
case None => throw new UvmRuntimeException(ctx + "Exception is thrown out of the bottom frame.")
case Some(prev) => unwindUntilCatchable(prev)
......@@ -1280,30 +1256,30 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val s = curStack
val f = s.top
val (newFrame, newBB) = unwindUntilCatchable(f)
val (newFrame, dc) = unwindUntilCatchable(f)
s.unwindTo(newFrame)
branchAndMovePC(newBB, exc)
branchAndAssignParameters(dc, Some(exc))
curInstHalfExecuted = false
}
/**
* Test if the current frame with i as the current instruction can catch an exception that unwinds the stack.
*
* @return Return Some(h) if i can catch the exception and h is the basic block for the exception. Return None if i
* @return Return Some(dc) if i can catch the exception and d is the destination clause for the exception. Return None if i
* cannot catch exceptions.
*
* @throw Throw UvmRefimplException if a frame stops at an unexpected instruction. Normally the top frame can be
* executing TRAP, WATCHPOINT, SWAPSTACK or CALL and all other frames must be executing CALL.
*/
private def maybeFindExceptionHandler(inst: Instruction): Option[BasicBlock] = {
private def maybeFindExceptionHandler(inst: Instruction): Option[DestClause] = {
inst match {
case i: InstCall => i.excClause.map(_.exc)
case i: InstTrap => i.excClause.map(_.exc)
case i: InstWatchPoint => i.exc
case i: InstSwapStack => i.excClause.map(_.exc)
case _ => {
throw new UvmRefImplException(ctx + "Instruction %s (%s) is in a stack frame when an exception is thrown.".format(inst.repr, inst.getClass.getName))
throw new UvmRefImplException(ctx + "Non-OSR point instruction %s (%s) is in a stack frame when an exception is thrown.".format(inst.repr, inst.getClass.getName))
}
}
}
......@@ -1351,9 +1327,6 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
MemoryOperations.addressOf(ptr, boxOf(v))
}
def incrementBoxPointer(src: BoxPointer, dst: BoxPointer, addrIncr: Word): Unit = {
}
// Thread termination
/** Terminate the thread. Please only let the thread terminate itself. */
......@@ -1486,7 +1459,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
private def branchToExcDestOr(excClause: Option[ExcClause])(f: => Unit): Unit = {
excClause match {
case None => f
case Some(ExcClause(_, excBB)) => branchAndMovePC(excBB, 0L)
case Some(ExcClause(_, excBB)) => branchAndAssignParameters(excBB)
}
}
......
......@@ -292,7 +292,7 @@ object MemoryOperations {
lb.objRef + lb.offset
}
}
def noAccessViaPointer(ptr: Boolean, ty: Type) {
if (ptr) {
throw new UvmIllegalMemoryAccessException("Cannot access type %s via pointer".format(ty.repr))
......@@ -325,17 +325,17 @@ object MemoryOperations {
val base = memorySupport.loadLong(loc)
val offset = memorySupport.loadLong(loc + WORD_SIZE_BYTES)
br.asInstanceOf[BoxIRef].oo = (base, offset)
case _: TypeFunc =>
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val fid = memorySupport.loadLong(loc).toInt
val func = microVM.globalBundle.funcNs.get(fid)
br.asInstanceOf[BoxFunc].func = func
case _: TypeThread =>
case _: TypeThreadRef =>
noAccessViaPointer(ptr, ty)
val tid = memorySupport.loadLong(loc).toInt
val thr = microVM.threadStackManager.getThreadByID(tid)
br.asInstanceOf[BoxThread].thread = thr
case _: TypeStack =>
case _: TypeStackRef =>
noAccessViaPointer(ptr, ty)
val sid = memorySupport.loadLong(loc).toInt
val sta = microVM.threadStackManager.getStackByID(sid)
......@@ -344,7 +344,7 @@ object MemoryOperations {
noAccessViaPointer(ptr, ty)
val raw = memorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _: TypePtr | _: TypeFuncPtr =>
case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr
case _ => throw new UnimplementedOprationException("Loading of type %s is not supporing".format(ty.getClass.getName))
......@@ -387,15 +387,15 @@ object MemoryOperations {
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
memorySupport.storeLong(loc, base)
memorySupport.storeLong(loc + WORD_SIZE_BYTES, offset)
case _: TypeFunc =>
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val fid = nvb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0)
memorySupport.storeLong(loc, fid.toLong & 0xFFFFFFFFL)
case _: TypeThread =>
case _: TypeThreadRef =>
noAccessViaPointer(ptr, ty)
val tid = nvb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0)
memorySupport.storeLong(loc, tid.toLong & 0xFFFFFFFFL)
case _: TypeStack =>
case _: TypeStackRef =>
noAccessViaPointer(ptr, ty)
val sid = nvb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0)
memorySupport.storeLong(loc, sid.toLong & 0xFFFFFFFFL)
......@@ -403,7 +403,7 @@ object MemoryOperations {
noAccessViaPointer(ptr, ty)
val raw = nvb.asInstanceOf[BoxTagRef64].raw
memorySupport.storeLong(loc, raw)
case _: TypePtr | _: TypeFuncPtr =>
case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr)
case _ => throw new UnimplementedOprationException("Storing of type %s is not supporing".format(ty.getClass.getName))
......@@ -456,7 +456,7 @@ object MemoryOperations {
val (succ, (rl, rh)) = memorySupport.cmpXchgI128(loc, (el, eh), (dl, dh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
succ
case _: TypeFunc =>
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val el = eb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
......@@ -464,7 +464,7 @@ object MemoryOperations {
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
br.asInstanceOf[BoxFunc].func = rf
succ
case _: TypeThread =>
case _: TypeThreadRef =>
noAccessViaPointer(ptr, ty)
val el = eb.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
......@@ -472,7 +472,7 @@ object MemoryOperations {
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
br.asInstanceOf[BoxThread].thread = rt
succ
case _: TypeStack =>
case _: TypeStackRef =>
noAccessViaPointer(ptr, ty)
val el = eb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val dl = db.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
......@@ -480,7 +480,7 @@ object MemoryOperations {
val rs = microVM.threadStackManager.getStackByID(rl.toInt)
br.asInstanceOf[BoxStack].stack = rs
succ
case _: TypePtr | _: TypeFuncPtr =>
case _: TypeUPtr | _: TypeUFuncPtr =>
val el = eb.asInstanceOf[BoxPointer].addr
val dl = db.asInstanceOf[BoxPointer].addr
val (succ, rl) = memorySupport.cmpXchgLong(loc, el, dl, !ptr)
......@@ -515,19 +515,19 @@ object MemoryOperations {
val BoxIRef(ol, oh) = ob.asInstanceOf[BoxIRef]
val (rl, rh) = memorySupport.xchgI128(loc, (ol, oh))
br.asInstanceOf[BoxIRef].oo = (rl, rh)
case _: TypeFunc =>
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val ol = ob.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0).toLong
val rl = memorySupport.atomicRMWLong(op, loc, ol)
val rf = microVM.globalBundle.funcNs.get(rl.toInt)
br.asInstanceOf[BoxFunc].func = rf
case _: TypeThread =>
case _: TypeThreadRef =>
noAccessViaPointer(ptr, ty)
val ol = ob.asInstanceOf[BoxThread].thread.map(_.id).getOrElse(0).toLong
val rl = memorySupport.atomicRMWLong(op, loc, ol)
val rt = microVM.threadStackManager.getThreadByID(rl.toInt)
br.asInstanceOf[BoxThread].thread = rt
case _: TypeStack =>
case _: TypeStackRef =>
noAccessViaPointer(ptr, ty)
val ol = ob.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0).toLong
val rl = memorySupport.atomicRMWLong(op, loc, ol)
......@@ -538,7 +538,7 @@ object MemoryOperations {
val ol = ob.asInstanceOf[BoxTagRef64].raw
val rl = memorySupport.atomicRMWLong(op, loc, ol)
br.asInstanceOf[BoxTagRef64].raw = rl
case _: TypePtr | _: TypeFuncPtr =>
case _: TypeUPtr | _: TypeUFuncPtr =>
val ol = ob.asInstanceOf[BoxPointer].addr
val rl = memorySupport.atomicRMWLong(op, loc, ol, !ptr)
br.asInstanceOf[BoxPointer].addr = rl
......
......@@ -58,7 +58,7 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun
top = newFrame
top.savedStackPointer = stackMemory.top
}
def pushMuFrameForCallBack(funcVer: FuncVer, cookie: Long, args: Seq[ValueBox]): Unit = {
val newFrame = InterpreterFrame.forMuFunc(funcVer, cookie, args, Some(top))
top = newFrame
......@@ -146,7 +146,7 @@ object InterpreterFrame {
def forMuFunc(funcVer: FuncVer, cookie: Long, args: Seq[ValueBox], prev: Option[InterpreterFrame]): MuFrame = {
val frm = new MuFrame(funcVer, cookie, prev) // Bottom frame
for ((p, a) <- (funcVer.params zip args)) {
for ((p, a) <- (funcVer.entry.norParams zip args)) {
frm.boxes(p).copyFrom(a)
}
......@@ -161,14 +161,14 @@ object InterpreterFrame {
/**
* A Mu frame
*
*
* @param cookie: The cookie in the native interface. When called by another Mu function, cookie can be any value.
*/
class MuFrame(val funcVer: FuncVer, val cookie: Long, prev: Option[InterpreterFrame]) extends InterpreterFrame(prev) {
val boxes = new HashMap[LocalVariable, ValueBox]()
/** Edge-assigned instructions take values determined at look backedges */
val edgeAssignedBoxes = new HashMap[EdgeAssigned, ValueBox]()
val edgeAssignedBoxes = new HashMap[Parameter, ValueBox]()
/** Current basic block */
var curBB: BasicBlock = funcVer.entry
......@@ -201,19 +201,25 @@ class MuFrame(val funcVer: FuncVer, val cookie: Long, prev: Option[InterpreterFr
makeBoxes()
private def makeBoxes() {
for (param <- funcVer.params) {
putBox(param)
}
for (bb <- funcVer.bbs; inst <- bb.insts) {
putBox(inst)
for (bb <- funcVer.bbs) {
for (p <- bb.norParams) {
putBox(p)
}
for (p <- bb.excParam) {
putBox(p)
}
for (inst <- bb.insts) {
putBox(inst)
}
}
}
private def putBox(lv: LocalVariable) {
val ty = TypeInferer.inferType(lv)
boxes.put(lv, ValueBox.makeBoxForType(ty))
if (lv.isInstanceOf[EdgeAssigned]) {
edgeAssignedBoxes.put(lv.asInstanceOf[EdgeAssigned], ValueBox.makeBoxForType(ty))
if (lv.isInstanceOf[Parameter]) {
edgeAssignedBoxes.put(lv.asInstanceOf[Parameter], ValueBox.makeBoxForType(ty))
}
}
......
......@@ -68,17 +68,17 @@ object TypeSizes {
case _: TypeRef => WORD_SIZE_BYTES
case _: TypeIRef => 2L * WORD_SIZE_BYTES
case _: TypeWeakRef => WORD_SIZE_BYTES
case t @ TypeStruct(ftys) => structPrefixSizeOf(t, ftys.size)
case t @ TypeStruct(ftys) => structPrefixSizeOf(t, ftys.size)
case t @ TypeArray(et, l) => seqPrefixSizeOf(t, l)
case _: TypeHybrid => throw new IllegalArgumentException("Hybrid should use hybridSizeOf to probe size")
case _: TypeVoid => 0L
case _: TypeFunc => WORD_SIZE_BYTES
case _: TypeThread => WORD_SIZE_BYTES
case _: TypeStack => WORD_SIZE_BYTES
case _: TypeFuncRef => WORD_SIZE_BYTES
case _: TypeThreadRef => WORD_SIZE_BYTES
case _: TypeStackRef => WORD_SIZE_BYTES
case _: TypeTagRef64 => 8L
case t @ TypeVector(et, l) => seqPrefixSizeOf(t, l)
case _: TypePtr => WORD_SIZE_BYTES
case _: TypeFuncPtr => WORD_SIZE_BYTES
case _: TypeUPtr => WORD_SIZE_BYTES
case _: TypeUFuncPtr => WORD_SIZE_BYTES
}
def alignOf(ty: Type): Word = ty match {
......@@ -105,9 +105,9 @@ object TypeSizes {
}
def fieldOffsetOf(ty: TypeStruct, index: Int): Word = {
val fieldType = ty.fieldTy(index)
val fieldType = ty.fieldTys(index)
val fieldAlign = alignOf(fieldType)
val prefixSize = structPrefixSizeOf(ty, index)
val prefixSize = structPrefixSizeOf(ty, index)
val offset = alignUp(prefixSize, fieldAlign)
return offset
}
......@@ -126,8 +126,8 @@ object TypeSizes {
return alignUp(sizeOf(ty.fixedTy), alignOf(ty.varTy))
}
def structPrefixSizeOf(ty: TypeStruct, prefixLen: Int): Word = {
val sz = ty.fieldTy.take(prefixLen).foldLeft(0L) { (oldSz, nextTy) =>
def structPrefixSizeOf(ty: TypeStruct, prefixLen: Int): Word = {
val sz = ty.fieldTys.take(prefixLen).foldLeft(0L) { (oldSz, nextTy) =>
alignUp(oldSz, alignOf(nextTy)) + sizeOf(nextTy)
}
return sz
......
......@@ -62,7 +62,7 @@ object MemoryDataScanner extends StrictLogging {
}
case t: TypeStruct => {
var fieldAddr = iRef
for (fieldTy <- t.fieldTy) {
for (fieldTy <- t.fieldTys) {
val fieldAlign = TypeSizes.alignOf(fieldTy)
fieldAddr = TypeSizes.alignUp(fieldAddr, fieldAlign)
scanField(fieldTy, objRef, fieldAddr, handler)
......@@ -96,7 +96,7 @@ object MemoryDataScanner extends StrictLogging {
curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign)
}
}
case t: TypeStack => {
case t: TypeStackRef => {
val toStackID = memorySupport.loadLong(iRef)
val maybeToStack = if (toStackID == 0) {
None
......
......@@ -185,8 +185,6 @@ case class InstTailCall(var sig: FuncSig, var callee: SSAVariable, var argList:
case class InstRet(val funcVer: FuncVer, var retVal: SSAVariable) extends AbstractRet
case class InstRetVoid() extends AbstractRet
<