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.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.2% of users enabled 2FA.

Commit e05ae891 authored by Kunshan Wang's avatar Kunshan Wang
Browse files

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