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