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,
val memoryManager = new MemoryManager(heapSize, globalSize, stackSize)
private implicit val memorySupport = memoryManager.memorySupport
implicit val nativeCallHelper = new NativeCallHelper()
val threadStackManager = new ThreadStackManager()
val trapManager = new TrapManager()
val clientAgents = new HashSet[ClientAgent]()
val contexts = new HashSet[MuCtx]()
val irReader = new UIRTextReader(new IDFactory())
......@@ -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 ca = new ClientAgent(mutator)
clientAgents.add(ca)
val ca = new MuCtx(mutator)
contexts.add(ca)
ca
}
/**
* 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.
*/
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.
*/
......
......@@ -425,7 +425,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstExtractValue(strTy, index, opnd) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct]
val ob = boxOf(opnd).asInstanceOf[BoxSeq]
val fb = ob.values(index)
val ib = resultBox(0)
ib.copyFrom(fb)
......@@ -433,9 +433,9 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
case i @ InstInsertValue(strTy, index, opnd, newVal) => {
val ob = boxOf(opnd).asInstanceOf[BoxStruct]
val ob = boxOf(opnd).asInstanceOf[BoxSeq]
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) {
if (ind == index) {
ifb.copyFrom(nvb)
......
......@@ -7,6 +7,7 @@ import com.typesafe.scalalogging.Logger
import uvm._
import uvm.comminsts._
import uvm.refimpl._
import uvm.refimpl.{ HowToResume => ClientHowToResume }
import uvm.refimpl.mem._
import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._
......@@ -17,10 +18,16 @@ object InterpreterThread {
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.
*/
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 {
import InterpreterThread._
......@@ -31,7 +38,10 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
// 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 {
* @see uvm.refimpl.itpr.InstructionExecutor
*/
protected def interpretCurrentInstruction(): Unit
/**
* Specialised to interpet common instructions.
*/
......@@ -359,34 +369,36 @@ trait InterpreterActions extends InterpreterThreadState {
protected def doTrap(retTys: Seq[Type], wpID: Int) = {
val curCtx = ctx // save the context string for debugging
val ca = microVM.newClientAgent()
val c = microVM.newContext()
val hThread = ca.putThread(Some(curThread))
val hStack = ca.putStack(Some(curStack))
val hThread = c.handleFromInterpreterThread(Some(curThread))
val hStack = c.handleFromInterpreterStack(Some(curStack))
unbindRetWith(retTys)
val res = microVM.trapManager.trapHandler.handleTrap(ca, 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.")
}
val res = microVM.trapManager.trapHandler.handleTrap(c, hThread, hStack, wpID)
res match {
case TrapExit() => {
case TrapHandlerResult.ThreadExit() => {
isRunning = false
}
case TrapRebindPassValues(newStack, values) => {
val ns = getStackNotNull(newStack)
rebindPassValues(ns, values.map(_.vb))
}
case TrapRebindThrowExc(newStack, exc) => {
val ns = getStackNotNull(newStack)
rebindThrowExc(ns, exc.vb)
case TrapHandlerResult.Rebind(newStack, htr) => {
val ns = newStack.vb.stack.getOrElse {
throw new UvmRuntimeException(curCtx + "Attempt to rebind to NULL stack when returning from trap.")
}
htr match {
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)
......
......@@ -66,10 +66,10 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
/**
* 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 id = makeThreadID()
val thr = new InterpreterThread(id, stack, mutator)
val thr = new InterpreterThread(id, stack, mutator, htr)
threadRegistry.put(id, thr)
thr
}
......
......@@ -5,7 +5,6 @@ import scala.collection.mutable.HashSet
class TrapManager(implicit microVM: MicroVM) {
var trapHandler: TrapHandler = DefaultTrapHandler
var undefinedFunctionHandler: UndefinedFunctionHandler = DefaultUndefinedFunctionHandler
private val enabledWatchPoints = new HashSet[Int]()
......@@ -16,22 +15,17 @@ class TrapManager(implicit microVM: MicroVM) {
def disableWatchPoint(wpID: Int): Unit = enabledWatchPoints.remove(wpID)
object DefaultTrapHandler extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = {
val thr = thread.vb.asInstanceOf[BoxThread].thread.get
val thrID = thr.id
val funcVerID = ca.currentFuncVer(stack, 0)
val funcVer = microVM.globalBundle.funcVerNs(funcVerID)
val instID = ca.currentInstruction(stack, 0)
val inst = microVM.globalBundle.varNs(instID)
throw new UvmRuntimeException("Unhandled trap. Thread %d, funcver %s, trap inst %s, watch point ID %d".format(
thr.id, funcVer.repr, inst.repr, watchPointID))
def handleTrap(ctx: MuCtx, thread: MuThreadRefValue, stack: MuStackRefValue, watchPointID: Int): TrapHandlerResult = {
val thrID = thread.vb.asInstanceOf[BoxThread].thread.get.id
// val curFuncID = ctx.
// val funcVerID = ca.currentFuncVer(stack, 0)
// val funcVer = microVM.globalBundle.funcVerNs(funcVerID)
// val instID = ca.currentInstruction(stack, 0)
// val inst = microVM.globalBundle.varNs(instID)
// throw new UvmRuntimeException("Unhandled trap. Thread %d, funcver %s, trap inst %s, watch point ID %d".format(
// 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
/** Pop a frame. Part of the API. Also used by THROW */
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. */
......@@ -352,7 +359,7 @@ class UndefinedMuFrame(func: Function, prev: Option[InterpreterFrame]) extends M
justCreated = false
state = FrameState.Running
false
} else {
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
}
val wasJustCreated = justCreated
justCreated = false
state = FrameState.Running
!wasJustCreated
}
......
......@@ -31,7 +31,7 @@ class AllScanner(val handler: RefFieldHandler)(
logger.debug("Tracing pin sets...")
tracePinSets()
logger.debug("Tracing external roots...")
traceClientAgents()
traceClientContexts()
logger.debug("Tracing globals...")
traceGlobal()
logger.debug("Tracing threads...")
......@@ -39,11 +39,11 @@ class AllScanner(val handler: RefFieldHandler)(
}
private def tracePinSets() {
logger.debug(s"Tracing client agents for pinned objects")
for (ca <- microVM.clientAgents) {
assert(ca != null)
assert(ca.pinSet != null)
for (addr <- ca.pinSet) {
logger.debug(s"Tracing client contexts for pinned objects")
for (ctx <- microVM.contexts) {
assert(ctx != null)
assert(ctx.pinSet != null)
for (addr <- ctx.pinSet) {
this.pinSetToMem(addr)
}
}
......@@ -55,8 +55,8 @@ class AllScanner(val handler: RefFieldHandler)(
}
}
private def traceClientAgents() {
for (ca <- microVM.clientAgents; h <- ca.handles) {
private def traceClientContexts() {
for (ctx <- microVM.contexts; h <- ctx.handles) {
h.vb match {
case hor: HasObjRef => this.boxToHeap(hor)
case bst: BoxStack => this.boxToStack(bst)
......
......@@ -36,7 +36,7 @@ object NativeCallHelper {
case TypeFloat() => ptr.putFloat(off, vb.asInstanceOf[BoxFloat].value)
case TypeDouble() => ptr.putDouble(off, vb.asInstanceOf[BoxDouble].value)
case s @ TypeStruct(flds) => {
val fldvbs = vb.asInstanceOf[BoxStruct].values
val fldvbs = vb.asInstanceOf[BoxSeq].values
for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) {
val off2 = TypeSizes.fieldOffsetOf(s, i)
storeBoxToPtr(ptr, off + off2.toInt, fty, fvb)
......@@ -55,7 +55,7 @@ object NativeCallHelper {
case TypeFloat() => vb.asInstanceOf[BoxFloat].value = ptr.getFloat(off)
case TypeDouble() => vb.asInstanceOf[BoxDouble].value = ptr.getDouble(off)
case s @ TypeStruct(flds) => {
val fldvbs = vb.asInstanceOf[BoxStruct].values
val fldvbs = vb.asInstanceOf[BoxSeq].values
for (((fty, fvb), i) <- (flds zip fldvbs).zipWithIndex) {
val off2 = TypeSizes.fieldOffsetOf(s, i)
loadBoxFromPtr(ptr, off + off2, fty, fvb)
......@@ -77,7 +77,7 @@ object NativeCallHelper {
val off2 = TypeSizes.fieldOffsetOf(s, i)
makeBoxFromPtr(ptr, off + off2, fty)
}
BoxStruct(fldvbs)
BoxSeq(fldvbs)
}
case _: AbstractPointerType => BoxPointer(ptr.getAddress(off))
}
......@@ -106,7 +106,6 @@ object NativeCallHelper {
}
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(16) => BoxInt(OpHelper.trunc(cbuf.getShort(index), 16))
case TypeInt(32) => BoxInt(OpHelper.trunc(cbuf.getInt(index), 32))
......@@ -372,6 +371,7 @@ class NativeCallHelper {
(maybeRetBox, maybeRvb) match {
case (None, None) =>
case (Some(dst), Some(src)) => dst.copyFrom(src)
case _ => throw new Error("This is impossible")
}
logger.debug("Back from nsk.slave. Returning to native...")
......
......@@ -8,7 +8,9 @@ abstract class Type extends IdentifiedSettable {
abstract class FPType extends Type
abstract class AbstractRefType extends Type {
abstract class AbstractGenRefType extends Type
abstract class AbstractRefType extends AbstractGenRefType {
def ty: Type
}
......@@ -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 TypeHybrid(var fieldTys: Seq[Type], var varTy: Type) extends AbstractStructType
case class TypeVoid() extends Type
case class TypeFuncRef(var sig: FuncSig) extends Type
case class TypeThreadRef() extends Type
case class TypeStackRef() extends Type
case class TypeFuncRef(var sig: FuncSig) extends AbstractGenRefType
case class TypeThreadRef() extends AbstractGenRefType
case class TypeStackRef() extends AbstractGenRefType
case class TypeTagRef64() extends Type
case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType
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