To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

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

Refactor. Make idOf and nameOf methods of MicroVM.

Also updated testing class structures.
parent 13ddfc19
......@@ -34,6 +34,21 @@ class Bundle {
val globalCellNs = new SimpleNamespace[GlobalCell]()
val funcNs = new SimpleNamespace[Function]()
/**
* Add an identified entity to its appropriate global namespaces.
*/
def add(obj: Identified): Unit = {
allNs.add(obj)
if (obj.isInstanceOf[Type]) typeNs.add(obj.asInstanceOf[Type])
if (obj.isInstanceOf[FuncSig]) funcSigNs.add(obj.asInstanceOf[FuncSig])
if (obj.isInstanceOf[FuncVer]) funcVerNs.add(obj.asInstanceOf[FuncVer])
if (obj.isInstanceOf[SSAVariable]) varNs.add(obj.asInstanceOf[SSAVariable])
if (obj.isInstanceOf[GlobalVariable]) globalVarNs.add(obj.asInstanceOf[GlobalVariable])
if (obj.isInstanceOf[Constant]) constantNs.add(obj.asInstanceOf[Constant])
if (obj.isInstanceOf[GlobalCell]) globalCellNs.add(obj.asInstanceOf[GlobalCell])
if (obj.isInstanceOf[Function]) funcNs.add(obj.asInstanceOf[Function])
}
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) {
......
......@@ -45,7 +45,7 @@ class UIRTextReader(val idFactory: IDFactory) {
parser.addErrorListener(ea)
val ast = parser.ir()
if (ea.hasError) {
throw new TextIRParsingException("Syntax error:\n"+ea.getMessages)
throw new TextIRParsingException("Syntax error:\n" + ea.getMessages)
}
read(ast, globalBundle)
......@@ -69,7 +69,7 @@ class UIRTextReader(val idFactory: IDFactory) {
}
val abs = prefix match {
case "0x" => BigInt(nums, 16)
case "0" => if(nums=="") BigInt(0) else BigInt(nums, 8)
case "0" => if (nums == "") BigInt(0) else BigInt(nums, 8)
case "" => BigInt(nums, 10)
}
return if (neg) -abs else abs
......@@ -139,39 +139,26 @@ class UIRTextReader(val idFactory: IDFactory) {
// Add entities to namespaces.
def addTy(obj: Type): Unit = {
bundle.allNs.add(obj)
bundle.typeNs.add(obj)
bundle.add(obj)
}
def addSig(obj: FuncSig): Unit = {
bundle.allNs.add(obj)
bundle.funcSigNs.add(obj)
bundle.add(obj)
}
def addConst(obj: Constant): Unit = {
bundle.allNs.add(obj)
bundle.constantNs.add(obj)
bundle.globalVarNs.add(obj)
bundle.varNs.add(obj)
bundle.add(obj)
}
def addGlobalCell(obj: GlobalCell): Unit = {
bundle.allNs.add(obj)
bundle.globalCellNs.add(obj)
bundle.globalVarNs.add(obj)
bundle.varNs.add(obj)
bundle.add(obj)
}
def addFunc(obj: Function): Unit = {
bundle.allNs.add(obj)
bundle.funcNs.add(obj)
bundle.globalVarNs.add(obj)
bundle.varNs.add(obj)
bundle.add(obj)
}
def addLocalVar(obj: LocalVariable, localNs: Namespace[LocalVariable]) = {
localNs.add(obj)
bundle.varNs.add(obj)
bundle.allNs.add(obj)
bundle.add(obj)
}
def addFuncVer(obj: FuncVer): Unit = {
bundle.allNs.add(obj)
bundle.funcVerNs.add(obj)
bundle.add(obj)
}
// Resolve types, with parse-time checking.
......@@ -341,7 +328,7 @@ class UIRTextReader(val idFactory: IDFactory) {
bb.id = idFactory.getID()
bb.name = Some(globalize(bbCtx.label().name()))
ver.bbNs.add(bb)
bundle.allNs.add(bb)
bundle.add(bb)
bb.insts = bbCtx.inst.map(mkInst)
......@@ -588,7 +575,7 @@ class UIRTextReader(val idFactory: IDFactory) {
}
inst.id = idFactory.getID()
inst.name = Option(instDef.name).map(n=>globalize(n.getText))
inst.name = Option(instDef.name).map(n => globalize(n.getText))
addLocalVar(inst, ver.localVarNs)
......
......@@ -52,6 +52,18 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
}
}
/**
* Create a new ClientAgent.
*/
def newClientAgent(): ClientAgent = new ClientAgent(this)
/**
* Given a name, get the ID of an identified entity.
*/
def idOf(name: String): Int = globalBundle.allNs(name).id
/**
* Given an ID, get the name of an identified entity.
*/
def nameOf(id: Int): String = globalBundle.allNs(id).name.get
}
\ No newline at end of file
......@@ -5,10 +5,11 @@ import uvm.refimpl._
object FactorialFromRPython extends App {
val microVM = new MicroVM()
val r = new java.io.FileReader("tests/extra-progs/factorial.uir")
val ca = microVM.newClientAgent()
val r = new java.io.FileReader("tests/extra-progs/factorial.uir")
ca.loadBundle(r)
r.close()
// Magical trick. Theoretically the client would publish bundles as binary and knows all the IDs. But in this version
// only the text form is supported and IDs are automatically generated. So we look into the globalBundle itself.
......
package uvm.refimpl
import org.scalatest._
import java.io.FileReader
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.refimpl._
import uvm.refimpl.itpr._
import uvm.ssavariables.MemoryOrder._
import uvm.ssavariables.AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
import ch.qos.logback.classic.{ Logger => LLogger }
import ch.qos.logback.classic.Level
object UvmBundleTesterBase {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}
abstract class UvmBundleTesterBase extends FlatSpec with Matchers {
val ROOT_LOGGER_NAME = org.slf4j.Logger.ROOT_LOGGER_NAME
def setLogLevels(settings: (String, Level)*): Unit = { // Configure logger
import org.slf4j.LoggerFactory
import org.slf4j.{ Logger => SLogger }
import ch.qos.logback.classic.{ Logger => LLogger, Level }
import ch.qos.logback.classic.Level._
def setLevel(name: String, level: Level): Unit = {
LoggerFactory.getLogger(name).asInstanceOf[LLogger].setLevel(level)
}
for ((name, lvl) <- settings) {
setLevel(name, lvl)
}
}
def makeMicroVM(): MicroVM = new MicroVM()
val microVM = makeMicroVM()
implicit def idOf(name: String): Int = microVM.idOf(name)
implicit def nameOf(id: Int): String = microVM.nameOf(id)
def preloadBundles(fileNames: String*): Unit = {
val ca = microVM.newClientAgent()
for (fn <- fileNames) {
val r = new FileReader(fn)
ca.loadBundle(r)
r.close()
}
ca.close()
}
type TrapHandlerFunction = (ClientAgent, Handle, Handle, Int) => TrapHandlerResult
class MockTrapHandler(thf: TrapHandlerFunction) extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = {
thf(ca, thread, stack, watchPointID)
}
}
def testFunc(ca: ClientAgent, func: Handle, args: Seq[Handle])(handler: TrapHandlerFunction): Unit = {
microVM.trapManager.trapHandler = new MockTrapHandler(handler)
val hStack = ca.newStack(func, args)
val hThread = ca.newThread(hStack)
microVM.threadStackManager.joinAll()
}
implicit class MagicalBox(vb: ValueBox) {
def asInt: BigInt = vb.asInstanceOf[BoxInt].value
def asSInt(l: Int): BigInt = OpHelper.prepareSigned(vb.asInstanceOf[BoxInt].value, l)
def asUInt(l: Int): BigInt = OpHelper.prepareUnsigned(vb.asInstanceOf[BoxInt].value, l)
def asFloat: Float = vb.asInstanceOf[BoxFloat].value
def asDouble: Double = vb.asInstanceOf[BoxDouble].value
def asRef: Word = vb.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = { val b = vb.asInstanceOf[BoxIRef]; (b.objRef, b.offset) }
def asIRefAddr: Word = { val b = vb.asInstanceOf[BoxIRef]; b.objRef + b.offset }
def asStruct: Seq[ValueBox] = vb.asInstanceOf[BoxStruct].values
def asFunc: Option[Function] = vb.asInstanceOf[BoxFunc].func
def asThread: Option[InterpreterThread] = vb.asInstanceOf[BoxThread].thread
def asStack: Option[InterpreterStack] = vb.asInstanceOf[BoxStack].stack
def asTR64Box: BoxTagRef64 = vb.asInstanceOf[BoxTagRef64]
def asTR64Raw: Long = vb.asInstanceOf[BoxTagRef64].raw
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxVector].values
}
}
\ No newline at end of file
......@@ -10,74 +10,16 @@ import uvm.refimpl.itpr._
import MemoryOrder._
import AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word
import ch.qos.logback.classic.Level._
import uvm.refimpl.UvmBundleTesterBase
class UvmInterpreterSimpleTests extends FlatSpec with Matchers {
class UvmInterpreterSimpleTests extends UvmBundleTesterBase {
setLogLevels(
ROOT_LOGGER_NAME -> INFO,
"uvm.refimpl.itpr" -> DEBUG)
{ // Configure logger
import org.slf4j.LoggerFactory
import org.slf4j.{ Logger => SLogger }
import ch.qos.logback.classic.{ Logger => LLogger, Level }
import ch.qos.logback.classic.Level._
def setLevel(name: String, level: Level): Unit = {
LoggerFactory.getLogger(name).asInstanceOf[LLogger].setLevel(level)
}
setLevel(SLogger.ROOT_LOGGER_NAME, INFO)
setLevel("uvm.refimpl.itpr", DEBUG)
}
val microVM = new MicroVM();
implicit def idOf(name: String): Int = microVM.globalBundle.allNs(name).id
implicit def nameOf(id: Int): String = microVM.globalBundle.allNs(id).name.get
{
val ca = microVM.newClientAgent()
val r = new FileReader("tests/uvm-refimpl-test/primitives.uir")
ca.loadBundle(r)
r.close()
val r2 = new FileReader("tests/uvm-refimpl-test/simple-tests.uir")
ca.loadBundle(r2)
r2.close()
ca.close()
}
type TrapHandlerFunction = (ClientAgent, Handle, Handle, Int) => TrapHandlerResult
class MockTrapHandler(thf: TrapHandlerFunction) extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = {
thf(ca, thread, stack, watchPointID)
}
}
def testFunc(ca: ClientAgent, func: Handle, args: Seq[Handle])(handler: TrapHandlerFunction): Unit = {
microVM.trapManager.trapHandler = new MockTrapHandler(handler)
val hStack = ca.newStack(func, args)
val hThread = ca.newThread(hStack)
microVM.threadStackManager.joinAll()
}
implicit class MagicalBox(vb: ValueBox) {
def asInt: BigInt = vb.asInstanceOf[BoxInt].value
def asSInt(l: Int): BigInt = OpHelper.prepareSigned(vb.asInstanceOf[BoxInt].value, l)
def asUInt(l: Int): BigInt = OpHelper.prepareUnsigned(vb.asInstanceOf[BoxInt].value, l)
def asFloat: Float = vb.asInstanceOf[BoxFloat].value
def asDouble: Double = vb.asInstanceOf[BoxDouble].value
def asRef: Word = vb.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = { val b = vb.asInstanceOf[BoxIRef]; (b.objRef, b.offset) }
def asIRefAddr: Word = { val b = vb.asInstanceOf[BoxIRef]; b.objRef + b.offset }
def asStruct: Seq[ValueBox] = vb.asInstanceOf[BoxStruct].values
def asFunc: Option[Function] = vb.asInstanceOf[BoxFunc].func
def asThread: Option[InterpreterThread] = vb.asInstanceOf[BoxThread].thread
def asStack: Option[InterpreterStack] = vb.asInstanceOf[BoxStack].stack
def asTR64Box: BoxTagRef64 = vb.asInstanceOf[BoxTagRef64]
def asTR64Raw: Long = vb.asInstanceOf[BoxTagRef64].raw
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxVector].values
}
preloadBundles("tests/uvm-refimpl-test/primitives.uir",
"tests/uvm-refimpl-test/simple-tests.uir")
"Factorial functions" should "work" in {
val ca = microVM.newClientAgent()
......
......@@ -11,69 +11,15 @@ import MemoryOrder._
import AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word
class UvmInterpreterSpec extends FlatSpec with Matchers {
import ch.qos.logback.classic.Level._
{ // Configure logger
import org.slf4j.LoggerFactory
import org.slf4j.{ Logger => SLogger }
import ch.qos.logback.classic.{ Logger => LLogger, Level }
import ch.qos.logback.classic.Level._
class UvmInterpreterSpec extends UvmBundleTesterBase {
def setLevel(name: String, level: Level): Unit = {
LoggerFactory.getLogger(name).asInstanceOf[LLogger].setLevel(level)
}
setLevel(SLogger.ROOT_LOGGER_NAME, INFO)
setLevel("uvm.refimpl.itpr", DEBUG)
}
val microVM = new MicroVM();
implicit def idOf(name: String): Int = microVM.globalBundle.allNs(name).id
implicit def nameOf(id: Int): String = microVM.globalBundle.allNs(id).name.get
{
val ca = microVM.newClientAgent()
val r = new FileReader("tests/uvm-refimpl-test/basic-tests.uir")
ca.loadBundle(r)
r.close()
ca.close()
}
type TrapHandlerFunction = (ClientAgent, Handle, Handle, Int) => TrapHandlerResult
setLogLevels(
ROOT_LOGGER_NAME -> INFO,
"uvm.refimpl.itpr" -> DEBUG)
class MockTrapHandler(thf: TrapHandlerFunction) extends TrapHandler {
def handleTrap(ca: ClientAgent, thread: Handle, stack: Handle, watchPointID: Int): TrapHandlerResult = {
thf(ca, thread, stack, watchPointID)
}
}
def testFunc(ca: ClientAgent, func: Handle, args: Seq[Handle])(handler: TrapHandlerFunction): Unit = {
microVM.trapManager.trapHandler = new MockTrapHandler(handler)
val hStack = ca.newStack(func, args)
val hThread = ca.newThread(hStack)
microVM.threadStackManager.joinAll()
}
implicit class MagicalBox(vb: ValueBox) {
def asInt: BigInt = vb.asInstanceOf[BoxInt].value
def asSInt(l: Int): BigInt = OpHelper.prepareSigned(vb.asInstanceOf[BoxInt].value, l)
def asUInt(l: Int): BigInt = OpHelper.prepareUnsigned(vb.asInstanceOf[BoxInt].value, l)
def asFloat: Float = vb.asInstanceOf[BoxFloat].value
def asDouble: Double = vb.asInstanceOf[BoxDouble].value
def asRef: Word = vb.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = { val b = vb.asInstanceOf[BoxIRef]; (b.objRef, b.offset) }
def asIRefAddr: Word = { val b = vb.asInstanceOf[BoxIRef]; b.objRef + b.offset }
def asStruct: Seq[ValueBox] = vb.asInstanceOf[BoxStruct].values
def asFunc: Option[Function] = vb.asInstanceOf[BoxFunc].func
def asThread: Option[InterpreterThread] = vb.asInstanceOf[BoxThread].thread
def asStack: Option[InterpreterStack] = vb.asInstanceOf[BoxStack].stack
def asTR64Box: BoxTagRef64 = vb.asInstanceOf[BoxTagRef64]
def asTR64Raw: Long = vb.asInstanceOf[BoxTagRef64].raw
def asVec: Seq[ValueBox] = vb.asInstanceOf[BoxVector].values
}
preloadBundles("tests/uvm-refimpl-test/basic-tests.uir")
"The constant pool" should "contain appropriate constant values" in {
def gvb(name: String) = microVM.constantPool.getGlobalVarBox(microVM.globalBundle.globalVarNs(name))
......
......@@ -10,28 +10,18 @@ import uvm.refimpl.itpr._
import MemoryOrder._
import AtomicRMWOptr._
class UvmMemOperationsSpec extends FlatSpec with Matchers with BeforeAndAfter {
class UvmMemOperationsSpec extends UvmBundleTesterBase {
// The heap size is intentionally reduced to make GC more often
// The heap is divided in two halves. There is a 256KiB small object space (with 8 32KiB blocks) and a 256KiB large
// object space.
val microVM = new MicroVM(heapSize = 512L * 1024L);
override def makeMicroVM() = new MicroVM(heapSize = 512L * 1024L)
implicit def idOf(name: String): Int = microVM.globalBundle.allNs(name).id
{
microVM.memoryManager.heap.space.debugLogBlockStates()
val ca = microVM.newClientAgent()
val r = new FileReader("tests/uvm-refimpl-test/uvm-mem-test-bundle.uir")
ca.loadBundle(r)
r.close()
ca.close()
preloadBundles("tests/uvm-refimpl-test/uvm-mem-test-bundle.uir")
microVM.memoryManager.heap.space.debugLogBlockStates()
}
behavior of "UVM memory manager"
......
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