Commit e05ae891 authored by Kunshan Wang's avatar Kunshan Wang

Fixed refimpl (not tested).

parent 918eeb4e
...@@ -27,12 +27,12 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -27,12 +27,12 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
val memoryManager = new MemoryManager(heapSize, globalSize, stackSize) val memoryManager = new MemoryManager(heapSize, globalSize, stackSize)
private implicit val memorySupport = memoryManager.memorySupport private implicit val memorySupport = memoryManager.memorySupport
implicit val nativeCallHelper = new NativeCallHelper() implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager() val threadStackManager = new ThreadStackManager()
val trapManager = new TrapManager() val trapManager = new TrapManager()
val clientAgents = new HashSet[ClientAgent]() val contexts = new HashSet[MuCtx]()
val irReader = new UIRTextReader(new IDFactory()) val irReader = new UIRTextReader(new IDFactory())
...@@ -63,24 +63,39 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -63,24 +63,39 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
} }
/** /**
* Create a new ClientAgent. * Create a new MuCtx. Part of the API.
*/ */
def newClientAgent(): ClientAgent = { def newContext(): MuCtx = {
val mutator = microVM.memoryManager.heap.makeMutator() // This may trigger GC val mutator = microVM.memoryManager.heap.makeMutator() // This may trigger GC
val ca = new ClientAgent(mutator) val ca = new MuCtx(mutator)
clientAgents.add(ca) contexts.add(ca)
ca ca
} }
/** /**
* Given a name, get the ID of an identified entity. * Given a name, get the ID of an identified entity.
*/ */
def idOf(name: String): Int = globalBundle.allNs(name).id def idOf(name: String): Int = try {
globalBundle.allNs(name).id
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has name %s.".format(name), e)
}
/** /**
* Given an ID, get the name of an identified entity. * Given an ID, get the name of an identified entity.
*/ */
def nameOf(id: Int): String = globalBundle.allNs(id).name.get def nameOf(id: Int): String = try {
globalBundle.allNs(id).name.get
} catch {
case e: NoSuchElementException => throw new UvmRefImplException("No Mu entity has ID %d.".format(id), e)
}
/**
* Set the trap handler.
*/
def setTrapHandler(trapHandler: TrapHandler): Unit = {
trapManager.trapHandler = trapHandler
}
/** /**
* Execute. This is the external pusher of the execution. * Execute. This is the external pusher of the execution.
*/ */
......
...@@ -425,7 +425,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -425,7 +425,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
} }
case i @ InstExtractValue(strTy, index, opnd) => { case i @ InstExtractValue(strTy, index, opnd) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct] val ob = boxOf(opnd).asInstanceOf[BoxSeq]
val fb = ob.values(index) val fb = ob.values(index)
val ib = resultBox(0) val ib = resultBox(0)
ib.copyFrom(fb) ib.copyFrom(fb)
...@@ -433,9 +433,9 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor { ...@@ -433,9 +433,9 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
} }
case i @ InstInsertValue(strTy, index, opnd, newVal) => { case i @ InstInsertValue(strTy, index, opnd, newVal) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct] val ob = boxOf(opnd).asInstanceOf[BoxSeq]
val nvb = boxOf(newVal) val nvb = boxOf(newVal)
val ib = resultBox(0).asInstanceOf[BoxStruct] val ib = resultBox(0).asInstanceOf[BoxSeq]
for (((ofb, ifb), ind) <- (ob.values zip ib.values).zipWithIndex) { for (((ofb, ifb), ind) <- (ob.values zip ib.values).zipWithIndex) {
if (ind == index) { if (ind == index) {
ifb.copyFrom(nvb) ifb.copyFrom(nvb)
......
...@@ -7,6 +7,7 @@ import com.typesafe.scalalogging.Logger ...@@ -7,6 +7,7 @@ import com.typesafe.scalalogging.Logger
import uvm._ import uvm._
import uvm.comminsts._ import uvm.comminsts._
import uvm.refimpl._ import uvm.refimpl._
import uvm.refimpl.{ HowToResume => ClientHowToResume }
import uvm.refimpl.mem._ import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._ import uvm.ssavariables._
...@@ -17,10 +18,16 @@ object InterpreterThread { ...@@ -17,10 +18,16 @@ object InterpreterThread {
val logger = Logger(LoggerFactory.getLogger(getClass.getName)) val logger = Logger(LoggerFactory.getLogger(getClass.getName))
} }
abstract class HowToResume
object HowToResume {
case class PassValues(values: Seq[ValueBox]) extends HowToResume
case class ThrowExc(exc: Word) extends HowToResume
}
/** /**
* A thread that interprets Mu instruction. * A thread that interprets Mu instruction.
*/ */
class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator: Mutator)( class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator: Mutator, htr: HowToResume)(
implicit protected val microVM: MicroVM) extends InstructionExecutor { implicit protected val microVM: MicroVM) extends InstructionExecutor {
import InterpreterThread._ import InterpreterThread._
...@@ -31,7 +38,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator ...@@ -31,7 +38,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
// Initialisation // Initialisation
rebindPassValues(initialStack, Seq()) htr match {
case HowToResume.PassValues(values) => rebindPassValues(initialStack, values)
case HowToResume.ThrowExc(exc) => catchException(exc)
}
} }
/** /**
...@@ -120,7 +130,7 @@ trait InterpreterActions extends InterpreterThreadState { ...@@ -120,7 +130,7 @@ trait InterpreterActions extends InterpreterThreadState {
* @see uvm.refimpl.itpr.InstructionExecutor * @see uvm.refimpl.itpr.InstructionExecutor
*/ */
protected def interpretCurrentInstruction(): Unit protected def interpretCurrentInstruction(): Unit
/** /**
* Specialised to interpet common instructions. * Specialised to interpet common instructions.
*/ */
...@@ -359,34 +369,36 @@ trait InterpreterActions extends InterpreterThreadState { ...@@ -359,34 +369,36 @@ trait InterpreterActions extends InterpreterThreadState {
protected def doTrap(retTys: Seq[Type], wpID: Int) = { protected def doTrap(retTys: Seq[Type], wpID: Int) = {
val curCtx = ctx // save the context string for debugging val curCtx = ctx // save the context string for debugging
val ca = microVM.newClientAgent() val c = microVM.newContext()
val hThread = ca.putThread(Some(curThread)) val hThread = c.handleFromInterpreterThread(Some(curThread))
val hStack = ca.putStack(Some(curStack)) val hStack = c.handleFromInterpreterStack(Some(curStack))
unbindRetWith(retTys) unbindRetWith(retTys)
val res = microVM.trapManager.trapHandler.handleTrap(ca, hThread, hStack, wpID) val res = microVM.trapManager.trapHandler.handleTrap(c, hThread, hStack, wpID)
def getStackNotNull(sh: Handle): InterpreterStack = sh.vb.asInstanceOf[BoxStack].stack.getOrElse {
throw new UvmRuntimeException(curCtx + "Attempt to rebind to NULL stack when returning from trap.")
}
res match { res match {
case TrapExit() => { case TrapHandlerResult.ThreadExit() => {
isRunning = false isRunning = false
} }
case TrapRebindPassValues(newStack, values) => { case TrapHandlerResult.Rebind(newStack, htr) => {
val ns = getStackNotNull(newStack) val ns = newStack.vb.stack.getOrElse {
rebindPassValues(ns, values.map(_.vb)) throw new UvmRuntimeException(curCtx + "Attempt to rebind to NULL stack when returning from trap.")
} }
case TrapRebindThrowExc(newStack, exc) => {
val ns = getStackNotNull(newStack) htr match {
rebindThrowExc(ns, exc.vb) case ClientHowToResume.PassValues(values) => {
rebindPassValues(ns, values.map(_.vb))
}
case ClientHowToResume.ThrowExc(exc) => {
rebindThrowExc(ns, exc.vb)
}
}
} }
} }
ca.close() c.closeContext()
} }
// Internal control structures (syntax sugars) // Internal control structures (syntax sugars)
......
...@@ -66,10 +66,10 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall ...@@ -66,10 +66,10 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
/** /**
* Create a new thread, bind to a given stack. * Create a new thread, bind to a given stack.
*/ */
def newThread(stack: InterpreterStack): InterpreterThread = { def newThread(stack: InterpreterStack, htr: HowToResume): InterpreterThread = {
val mutator = microVM.memoryManager.makeMutator() val mutator = microVM.memoryManager.makeMutator()
val id = makeThreadID() val id = makeThreadID()
val thr = new InterpreterThread(id, stack, mutator) val thr = new InterpreterThread(id, stack, mutator, htr)
threadRegistry.put(id, thr) threadRegistry.put(id, thr)
thr thr
} }
......
...@@ -5,7 +5,6 @@ import scala.collection.mutable.HashSet ...@@ -5,7 +5,6 @@ import scala.collection.mutable.HashSet
class TrapManager(implicit microVM: MicroVM) { class TrapManager(implicit microVM: MicroVM) {
var trapHandler: TrapHandler = DefaultTrapHandler var trapHandler: TrapHandler = DefaultTrapHandler
var undefinedFunctionHandler: UndefinedFunctionHandler = DefaultUndefinedFunctionHandler
private val enabledWatchPoints = new HashSet[Int]() private val enabledWatchPoints = new HashSet[Int]()
...@@ -16,22 +15,17 @@ class TrapManager(implicit microVM: MicroVM) { ...@@ -16,22 +15,17 @@ class TrapManager(implicit microVM: MicroVM) {
def disableWatchPoint(wpID: Int): Unit = enabledWatchPoints.remove(wpID) def disableWatchPoint(wpID: Int): Unit = enabledWatchPoints.remove(wpID)
object DefaultTrapHandler extends TrapHandler { object DefaultTrapHandler extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = { def handleTrap(ctx: MuCtx, thread: MuThreadRefValue, stack: MuStackRefValue, watchPointID: Int): TrapHandlerResult = {
val thr = thread.vb.asInstanceOf[BoxThread].thread.get val thrID = thread.vb.asInstanceOf[BoxThread].thread.get.id
val thrID = thr.id // val curFuncID = ctx.
val funcVerID = ca.currentFuncVer(stack, 0) // val funcVerID = ca.currentFuncVer(stack, 0)
val funcVer = microVM.globalBundle.funcVerNs(funcVerID) // val funcVer = microVM.globalBundle.funcVerNs(funcVerID)
val instID = ca.currentInstruction(stack, 0) // val instID = ca.currentInstruction(stack, 0)
val inst = microVM.globalBundle.varNs(instID) // val inst = microVM.globalBundle.varNs(instID)
throw new UvmRuntimeException("Unhandled trap. Thread %d, funcver %s, trap inst %s, watch point ID %d".format( // throw new UvmRuntimeException("Unhandled trap. Thread %d, funcver %s, trap inst %s, watch point ID %d".format(
thr.id, funcVer.repr, inst.repr, watchPointID)) // thr.id, funcVer.repr, inst.repr, watchPointID))
???
} }
} }
object DefaultUndefinedFunctionHandler extends UndefinedFunctionHandler {
def handleUndefinedFunction(functionID: Int): Unit = {
val func = microVM.globalBundle.funcNs(functionID)
throw new UvmRuntimeException("Unhandled undefined function. Function %s.".format(func.repr))
}
}
} }
...@@ -257,7 +257,14 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun ...@@ -257,7 +257,14 @@ class InterpreterStack(val id: Int, val stackMemory: StackMemory, stackBottomFun
/** Pop a frame. Part of the API. Also used by THROW */ /** Pop a frame. Part of the API. Also used by THROW */
def popFrame(): Unit = { def popFrame(): Unit = {
_popFrame() top match {
case f: NativeFrame => throw new UnimplementedOprationException("Popping native frames is not supported.")
case f: MuFrame => f.prev match {
case None => throw new UvmRuntimeException("Attempting to pop the last frame of a stack.")
case Some(prev) => popMuFrame()
}
}
} }
/** Push a Mu frame. Part of the API. */ /** Push a Mu frame. Part of the API. */
...@@ -352,7 +359,7 @@ class UndefinedMuFrame(func: Function, prev: Option[InterpreterFrame]) extends M ...@@ -352,7 +359,7 @@ class UndefinedMuFrame(func: Function, prev: Option[InterpreterFrame]) extends M
justCreated = false justCreated = false
state = FrameState.Running state = FrameState.Running
false false
} else { } else {
throw new UvmRefImplException("Undefined frame for function %s is already executed. Could be double binding.".format(func.repr)) throw new UvmRefImplException("Undefined frame for function %s is already executed. Could be double binding.".format(func.repr))
...@@ -486,10 +493,10 @@ class DefinedMuFrame(val savedStackPointer: Word, val funcVer: FuncVer, val cook ...@@ -486,10 +493,10 @@ class DefinedMuFrame(val savedStackPointer: Word, val funcVer: FuncVer, val cook
} }
val wasJustCreated = justCreated val wasJustCreated = justCreated
justCreated = false justCreated = false
state = FrameState.Running state = FrameState.Running
!wasJustCreated !wasJustCreated
} }
......
...@@ -31,7 +31,7 @@ class AllScanner(val handler: RefFieldHandler)( ...@@ -31,7 +31,7 @@ class AllScanner(val handler: RefFieldHandler)(
logger.debug("Tracing pin sets...") logger.debug("Tracing pin sets...")
tracePinSets() tracePinSets()
logger.debug("Tracing external roots...") logger.debug("Tracing external roots...")
traceClientAgents() traceClientContexts()
logger.debug("Tracing globals...") logger.debug("Tracing globals...")
traceGlobal() traceGlobal()
logger.debug("Tracing threads...") logger.debug("Tracing threads...")
...@@ -39,11 +39,11 @@ class AllScanner(val handler: RefFieldHandler)( ...@@ -39,11 +39,11 @@ class AllScanner(val handler: RefFieldHandler)(
} }
private def tracePinSets() { private def tracePinSets() {
logger.debug(s"Tracing client agents for pinned objects") logger.debug(s"Tracing client contexts for pinned objects")
for (ca <- microVM.clientAgents) { for (ctx <- microVM.contexts) {
assert(ca != null) assert(ctx != null)
assert(ca.pinSet != null) assert(ctx.pinSet != null)
for (addr <- ca.pinSet) { for (addr <- ctx.pinSet) {
this.pinSetToMem(addr) this.pinSetToMem(addr)
} }
} }
...@@ -55,8 +55,8 @@ class AllScanner(val handler: RefFieldHandler)( ...@@ -55,8 +55,8 @@ class AllScanner(val handler: RefFieldHandler)(
} }
} }
private def traceClientAgents() { private def traceClientContexts() {
for (ca <- microVM.clientAgents; h <- ca.handles) { for (ctx <- microVM.contexts; h <- ctx.handles) {
h.vb match { h.vb match {
case hor: HasObjRef => this.boxToHeap(hor) case hor: HasObjRef => this.boxToHeap(hor)
case bst: BoxStack => this.boxToStack(bst) case bst: BoxStack => this.boxToStack(bst)
......
...@@ -36,7 +36,7 @@ object NativeCallHelper { ...@@ -36,7 +36,7 @@ object NativeCallHelper {
case TypeFloat() => ptr.putFloat(off, vb.asInstanceOf[BoxFloat].value) case TypeFloat() => ptr.putFloat(off, vb.asInstanceOf[BoxFloat].value)
case TypeDouble() => ptr.putDouble(off, vb.asInstanceOf[BoxDouble].value) case TypeDouble() => ptr.putDouble(off, vb.asInstanceOf[BoxDouble].value)
case s @ TypeStruct(flds) => { case s @ TypeStruct(flds) => {
val fldvbs = vb.asInstanceOf[BoxStruct].values val fldvbs = vb.asInstanceOf[BoxSeq].values
for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) { for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) {
val off2 = TypeSizes.fieldOffsetOf(s, i) val off2 = TypeSizes.fieldOffsetOf(s, i)
storeBoxToPtr(ptr, off + off2.toInt, fty, fvb) storeBoxToPtr(ptr, off + off2.toInt, fty, fvb)
...@@ -55,7 +55,7 @@ object NativeCallHelper { ...@@ -55,7 +55,7 @@ object NativeCallHelper {
case TypeFloat() => vb.asInstanceOf[BoxFloat].value = ptr.getFloat(off) case TypeFloat() => vb.asInstanceOf[BoxFloat].value = ptr.getFloat(off)
case TypeDouble() => vb.asInstanceOf[BoxDouble].value = ptr.getDouble(off) case TypeDouble() => vb.asInstanceOf[BoxDouble].value = ptr.getDouble(off)
case s @ TypeStruct(flds) => { case s @ TypeStruct(flds) => {
val fldvbs = vb.asInstanceOf[BoxStruct].values val fldvbs = vb.asInstanceOf[BoxSeq].values
for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) { for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) {
val off2 = TypeSizes.fieldOffsetOf(s, i) val off2 = TypeSizes.fieldOffsetOf(s, i)
loadBoxFromPtr(ptr, off + off2, fty, fvb) loadBoxFromPtr(ptr, off + off2, fty, fvb)
...@@ -77,7 +77,7 @@ object NativeCallHelper { ...@@ -77,7 +77,7 @@ object NativeCallHelper {
val off2 = TypeSizes.fieldOffsetOf(s, i) val off2 = TypeSizes.fieldOffsetOf(s, i)
makeBoxFromPtr(ptr, off + off2, fty) makeBoxFromPtr(ptr, off + off2, fty)
} }
BoxStruct(fldvbs) BoxSeq(fldvbs)
} }
case _: AbstractPointerType => BoxPointer(ptr.getAddress(off)) case _: AbstractPointerType => BoxPointer(ptr.getAddress(off))
} }
...@@ -106,7 +106,6 @@ object NativeCallHelper { ...@@ -106,7 +106,6 @@ object NativeCallHelper {
} }
def makeBoxFromClosureBufParam(cbuf: Closure.Buffer, index: Int, mty: MType): ValueBox = mty match { def makeBoxFromClosureBufParam(cbuf: Closure.Buffer, index: Int, mty: MType): ValueBox = mty match {
case TypeVoid() => BoxVoid()
case TypeInt(8) => BoxInt(OpHelper.trunc(cbuf.getByte(index), 8)) case TypeInt(8) => BoxInt(OpHelper.trunc(cbuf.getByte(index), 8))
case TypeInt(16) => BoxInt(OpHelper.trunc(cbuf.getShort(index), 16)) case TypeInt(16) => BoxInt(OpHelper.trunc(cbuf.getShort(index), 16))
case TypeInt(32) => BoxInt(OpHelper.trunc(cbuf.getInt(index), 32)) case TypeInt(32) => BoxInt(OpHelper.trunc(cbuf.getInt(index), 32))
...@@ -372,6 +371,7 @@ class NativeCallHelper { ...@@ -372,6 +371,7 @@ class NativeCallHelper {
(maybeRetBox, maybeRvb) match { (maybeRetBox, maybeRvb) match {
case (None, None) => case (None, None) =>
case (Some(dst), Some(src)) => dst.copyFrom(src) case (Some(dst), Some(src)) => dst.copyFrom(src)
case _ => throw new Error("This is impossible")
} }
logger.debug("Back from nsk.slave. Returning to native...") logger.debug("Back from nsk.slave. Returning to native...")
......
...@@ -8,7 +8,9 @@ abstract class Type extends IdentifiedSettable { ...@@ -8,7 +8,9 @@ abstract class Type extends IdentifiedSettable {
abstract class FPType extends Type abstract class FPType extends Type
abstract class AbstractRefType extends Type { abstract class AbstractGenRefType extends Type
abstract class AbstractRefType extends AbstractGenRefType {
def ty: Type def ty: Type
} }
...@@ -33,9 +35,9 @@ case class TypeStruct(var fieldTys: Seq[Type]) extends AbstractStructType ...@@ -33,9 +35,9 @@ case class TypeStruct(var fieldTys: Seq[Type]) extends AbstractStructType
case class TypeArray(var elemTy: Type, var len: Long) extends AbstractSeqType case class TypeArray(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeHybrid(var fieldTys: Seq[Type], var varTy: Type) extends AbstractStructType case class TypeHybrid(var fieldTys: Seq[Type], var varTy: Type) extends AbstractStructType
case class TypeVoid() extends Type case class TypeVoid() extends Type
case class TypeFuncRef(var sig: FuncSig) extends Type case class TypeFuncRef(var sig: FuncSig) extends AbstractGenRefType
case class TypeThreadRef() extends Type case class TypeThreadRef() extends AbstractGenRefType
case class TypeStackRef() extends Type case class TypeStackRef() extends AbstractGenRefType
case class TypeTagRef64() extends Type case class TypeTagRef64() extends Type
case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeUPtr(var ty: Type) extends AbstractPointerType case class TypeUPtr(var ty: Type) extends AbstractPointerType
......
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