Commit f6d369d9 authored by Kunshan Wang's avatar Kunshan Wang

Implemented IR builder CommInsts.

parent d502900b
......@@ -609,7 +609,7 @@ struct MuCtx {
MuInstNode (*new_ccall )(MuCtx *ctx, MuBBNode bb, MuCallConv callconv, MuTypeNode callee_ty, MuFuncSigNode sig, MuVarNode callee, MuVarNode *args, MuArraySize nargs); /// MUAPIPARSER args:array:nargs
MuInstNode (*new_newthread )(MuCtx *ctx, MuBBNode bb, MuVarNode stack, MuVarNode threadlocal);
MuInstNode (*new_newthread )(MuCtx *ctx, MuBBNode bb, MuVarNode stack, MuVarNode threadlocal); /// MUAPIPARSER threadlocal:optional
MuInstNode (*new_swapstack_ret )(MuCtx *ctx, MuBBNode bb, MuVarNode swappee, MuTypeNode *ret_tys, MuArraySize nret_tys); /// MUAPIPARSER ret_tys:array:nret_tys
MuInstNode (*new_swapstack_kill)(MuCtx *ctx, MuBBNode bb, MuVarNode swappee);
......
......@@ -25,7 +25,7 @@ CommInstDesc = namedtuple("CommInstDesc", """
pragmas
arrays
sizes
bools
optionals
""".split())
_type_map = {
......@@ -90,7 +90,7 @@ def get_comminsts(ast):
pragmas = meth["pragmas"]
arrays = {}
sizes = set()
bools = set()
optionals = set()
paramnames = []
cparamtys = []
......@@ -111,8 +111,8 @@ def get_comminsts(ast):
sz = pragma[2]
arrays[pn] = sz
sizes.add(sz)
elif pragma[1] == "bool":
bools.add(pn)
elif pragma[1] == "optional":
optionals.add(pn)
muretty = to_mu_ty(cretty)
......@@ -128,7 +128,7 @@ def get_comminsts(ast):
muretty = muretty,
arrays = arrays,
sizes = sizes,
bools = bools,
optionals = optionals,
)
comminsts.append(comminst)
......@@ -171,11 +171,177 @@ def gen_comminsts_retvals(comminsts):
return "\n".join(lines)
_get_arg_meths = {
"int<64>": "asInt64.toLong",
"int<32>": "asInt32.toInt",
"float": "asFloat",
"double": "asDouble",
}
def get_arg_meth(mty, cty, cname):
if mty in _get_arg_meths:
return _get_arg_meths[mty]
elif mty.startswith("iref<"):
return "asIRef"
raise Exception("I don't know how to get arg: {}, {}, {}".format(mty, cty, cname))
def get_arg(ind, mty, cty, cname, is_optional):
if cty == "MuBundleNode":
meth = 'asIRNode.getOrElse(throw new UvmNullGenRefException("CommInst arg %{} must not be null")).asInstanceOf[BundleNode]'.format(cname)
elif mty == "irnoderef":
if is_optional:
meth = 'asIRNode'
else:
meth = 'asIRNode.getOrElse(throw new UvmNullGenRefException("CommInst arg %{} must not be null"))'.format(cname)
else:
meth = get_arg_meth(mty, cty, cname)
return " val {} = argList({}).{}".format(cname, ind, meth)
_set_arg_meths = {
"int<32>": "asInt32",
}
def set_arg_meth(mty, cty):
if mty in _set_arg_meths:
return _set_arg_meths[mty]
elif mty.startswith("iref<"):
return "asIRef"
raise Exception("I don't know how to set return value: {}, {}".format(mty, cty))
def set_ret(ind, mty, cty, value):
if mty == "irnoderef":
meth = 'asIRNode'
return " results({}).{} = Some({})".format(ind, meth, value)
else:
meth = set_arg_meth(mty, cty)
return " results({}).{} = {}".format(ind, meth, value)
_special_cases = {
"id": "ID",
"sint8": "SInt8",
"uint8": "UInt8",
"sint16": "SInt16",
"uint16": "UInt16",
"sint32": "SInt32",
"uint32": "UInt32",
"sint64": "SInt64",
"uint64": "UInt64",
"uint64s": "UInt64s",
"fp": "FP",
"uptr": "UPtr",
"ufuncptr": "UFuncPtr",
"iref": "IRef",
"weakref": "WeakRef",
"funcref": "FuncRef",
"tagref64": "TagRef64",
"threadref": "ThreadRef",
"stackref": "StackRef",
"framecursorref": "FrameCursorRef",
"irnoderef": "IRNodeRef",
"funcsig": "FuncSig",
"bb": "BB",
"binop": "BinOp",
"tailcall": "TailCall",
"extractvalue": "ExtractValue",
"insertvalue": "InsertValue",
"extractelement": "ExtractElement",
"insertelement": "InsertElement",
"shufflevector": "ShuffleVector",
"newhybrid": "NewHybrid",
"allocahybrid": "AllocaHybrid",
"getiref": "GetIRef",
"getfieldiref": "GetFieldIRef",
"getelemiref": "GetElemIRef",
"shiftiref": "ShiftIRef",
"getvarpartiref": "GetVarPartIRef",
"cmpxchg": "CmpXchg",
"atomicrmw": "AtomicRMW",
"watchpoint": "WatchPoint",
"wpbranch": "WPBranch",
"ccall": "CCall",
"newthread": "NewThread",
"newstack": "NewStack",
"swapstack": "SwapStack",
"comminst": "CommInst",
}
def toCamelCase(name):
ins = name.split("_")
outs = [ins[0]]
for inn in ins[1:]:
if inn in _special_cases:
outs.append(_special_cases[inn])
else:
outs.append(inn[0].upper()+inn[1:])
return "".join(outs)
def gen_comminst_impl(comminst):
lines = []
lines.append(' case "{}" => {{'.format(comminst.muname))
for ind, (cty, mty, cname) in enumerate(zip(
comminst.cparamtys, comminst.muparamtys, comminst.paramnames)):
lines.append(get_arg(ind, mty, cty, cname,
is_optional=(cname in comminst.optionals)))
ir_builder_args = []
for cty, mty, cname in zip(
comminst.cparamtys, comminst.muparamtys, comminst.paramnames):
if cname in comminst.arrays:
sz = comminst.arrays[cname]
loaded_array_name = "_ary_" + cname
if mty == "iref<irnoderef>":
loader_func = "loadIRNodeArray"
elif mty == "iref<int<64>>":
loader_func = "loadInt64Array"
elif cty == "MuFlag*":
loader_func = "loadFlagArray"
else:
raise Exception("I don't know how to load array: {}, {}, {}".format(
cty, mty, cname))
lines.append(' val {} = {}({}, {})'.format(
loaded_array_name, loader_func, cname, sz))
ir_builder_args.append(loaded_array_name)
elif cname in comminst.sizes:
pass # skip array sizes
elif cty == "MuBool":
bool_name = "_bool_" + cname
lines.append(' val {} = {} != 0'.format(bool_name, cname))
ir_builder_args.append(bool_name)
else:
ir_builder_args.append(cname)
ir_builder_meth_name = toCamelCase(comminst.funcname)
lines.append(' val _rv = irBuilder.{}({})'.format(
ir_builder_meth_name, ", ".join(ir_builder_args)))
if comminst.cretty != "void":
lines.append(set_ret(0, comminst.muretty, comminst.cretty, "_rv"))
lines.append(" continueNormally()")
lines.append(" }")
return "\n".join(lines)
# These functions are too speical. Implemented manually in Scala.
_blacklist = [
"load_bundle_from_node",
"abort_bundle_node",
"set_name",
"new_const_int_ex",
]
def gen_comminsts_impls(comminsts):
lines = []
for comminst in comminsts:
lines.append(' case "{}" => ???'.format(comminst.muname))
if comminst.funcname not in _blacklist:
lines.append(gen_comminst_impl(comminst))
return "\n".join(lines)
......
......@@ -13,6 +13,7 @@ import uvm.refimpl.nat.NativeCallHelper
import uvm.staticanalysis.StaticAnalyzer
import uvm.utils.IDFactory
import uvm.ir.irbuilder.IRBuilder
import uvm.ir.irbuilder.IRNode
object MicroVM {
val DEFAULT_SOS_SIZE: Word = 2L * 1024L * 1024L; // 2MiB
......@@ -52,6 +53,7 @@ class MicroVM(vmConf: VMConf) {
val idFactory = new IDFactory(MicroVM.FIRST_CLIENT_USABLE_ID)
val irBuilder = new IRBuilder(globalBundle, idFactory)
val irNodeRegistry = new SequentialObjectKeeper[IRNode]()
val irReader = new UIRTextReader(idFactory, recordSourceInfo=vmConf.sourceInfo)
val hailScriptLoader = new HailScriptLoader(recordSourceInfo=vmConf.sourceInfo)
val staticAnalyzer = new StaticAnalyzer()
......
......@@ -27,6 +27,9 @@ class UvmUndefinedBehaviorException(message: String = null, cause: Throwable = n
/** Thrown when a division by zero is executed and the exception clause is not present. */
class UvmDivisionByZeroException(message: String = null, cause: Throwable = null) extends UvmUndefinedBehaviorException(message, cause)
/** Thrown when a general reference value is null when it must not be. */
class UvmNullGenRefException(message: String = null, cause: Throwable = null) extends UvmUndefinedBehaviorException(message, cause)
/** Thrown when accessing Mu memory but the address is outside the allocated region. */
class UvmIllegalMemoryAccessException(message: String = null, cause: Throwable = null) extends UvmRuntimeException(message, cause)
......
......@@ -34,7 +34,7 @@ trait CommInstExecutor extends InterpreterActions with ObjectPinner with IRBuild
val Seq(sig) = sigList
val Seq(func) = argList
val funcVal = func.asFunc.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to create new thread for NULL Mu function.")
throw new UvmNullGenRefException(ctx + "Attempt to create new thread for NULL Mu function.")
}
val sta = microVM.threadStackManager.newStack(funcVal, mutator)
......@@ -45,7 +45,7 @@ trait CommInstExecutor extends InterpreterActions with ObjectPinner with IRBuild
case "@uvm.kill_stack" => {
val Seq(s) = argList
val sta = s.asStack.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to kill NULL stack.")
throw new UvmNullGenRefException(ctx + "Attempt to kill NULL stack.")
}
sta.kill()
continueNormally()
......@@ -281,7 +281,7 @@ trait CommInstExecutor extends InterpreterActions with ObjectPinner with IRBuild
val Seq(func, cookie) = argList
val f = func.asFunc.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to expose NULL Mu function")
throw new UvmNullGenRefException(ctx + "Attempt to expose NULL Mu function")
}
val c = boxOf(cookie).asSInt64.longValue
......
......@@ -242,7 +242,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstCall(sig, callee, argList, excClause, keepalives) => {
val calleeFunc = callee.asFunc.getOrElse {
throw new UvmRuntimeException(ctx + "Callee must not be NULL")
throw new UvmNullGenRefException(ctx + "Callee must not be NULL")
}
val argBoxes = argList.map(boxOf)
......@@ -255,7 +255,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstTailCall(sig, callee, argList) => {
val calleeFunc = callee.asFunc.getOrElse {
throw new UvmRuntimeException(ctx + "Callee must not be NULL")
throw new UvmNullGenRefException(ctx + "Callee must not be NULL")
}
val argBoxes = argList.map(boxOf)
......@@ -386,7 +386,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstGetIRef(referentTy, opnd) => {
val baseAddr = opnd.asRef
if (baseAddr == 0L) {
throw new UvmUndefinedBehaviorException(ctx + "Attempted to use GETIREF on a NULL reference")
throw new UvmNullGenRefException(ctx + "Attempted to use GETIREF on a NULL reference")
}
results(0).asIRef = (baseAddr, 0L)
continueNormally()
......@@ -524,7 +524,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstNewThread(stack, threadLocal, newStackAction, excClause) => {
val newStack = stack.asStack.getOrElse {
throw new UvmUndefinedBehaviorException(ctx + "Attempt to bind a new thread to a NULL stack.")
throw new UvmNullGenRefException(ctx + "Attempt to bind a new thread to a NULL stack.")
}
val threadLocalAddr = threadLocal.map(tl => tl.asRef).getOrElse(0L)
......@@ -547,7 +547,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
case i @ InstSwapStack(swappee, curStackAction, newStackAction, excClause, keepalives) => {
val oldStack = curStack
val newStack = swappee.asStack.getOrElse {
throw new UvmUndefinedBehaviorException(ctx + "Swappee must not be NULL.")
throw new UvmNullGenRefException(ctx + "Swappee must not be NULL.")
}
def handleOldStack() = curStackAction match {
......
......@@ -13,6 +13,7 @@ import uvm.refimpl.mem.TypeSizes.Word
import uvm.ssavariables._
import uvm.types._
import uvm.refimpl.nat.NativeCallResult
import uvm.ir.irbuilder.IRNode
object InterpreterThread {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -421,7 +422,7 @@ trait InterpreterActions extends InterpreterThreadState {
}
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.")
throw new UvmNullGenRefException(curCtx + "Attempt to rebind to NULL stack when returning from trap.")
}
htr match {
......@@ -510,14 +511,16 @@ object MagicalBox {
def asBoolean: Boolean = OpHelper.prepareUnsigned(box.asIntRaw, 1) == 1
def asFloat: Float = box.asInstanceOf[BoxFloat].value
def asDouble: Double = box.asInstanceOf[BoxDouble].value
def asPtr: Word = box.asInstanceOf[BoxPointer].addr
def asSeq: Seq[ValueBox] = box.asInstanceOf[BoxSeq].values
def asRef: Word = box.asInstanceOf[BoxRef].objRef
def asIRef: (Word, Word) = box.asInstanceOf[BoxIRef].oo
def asTR64Raw: Long = box.asInstanceOf[BoxTagRef64].raw
def asFunc: Option[Function] = box.asInstanceOf[BoxFunc].func
def asThread: Option[InterpreterThread] = box.asInstanceOf[BoxThread].thread
def asStack: Option[InterpreterStack] = box.asInstanceOf[BoxStack].stack
def asTR64Raw: Long = box.asInstanceOf[BoxTagRef64].raw
def asPtr: Word = box.asInstanceOf[BoxPointer].addr
def asSeq: Seq[ValueBox] = box.asInstanceOf[BoxSeq].values
def asFrameCursor: Option[FrameCursor] = box.asInstanceOf[BoxFrameCursor].cursor
def asIRNode: Option[IRNode] = box.asInstanceOf[BoxIRNode].node
def asIntRaw_=(v: BigInt): Unit = box.asInstanceOf[BoxInt].value = v
def asInt1_=(v: BigInt): Unit = box.setInt(v, 1)
......@@ -530,18 +533,16 @@ object MagicalBox {
def asBoolean_=(v: Boolean): Unit = box.setInt(if (v) 1 else 0, 1)
def asFloat_=(v: Float): Unit = box.asInstanceOf[BoxFloat].value = v
def asDouble_=(v: Double): Unit = box.asInstanceOf[BoxDouble].value = v
def asPtr_=(v: Word): Unit = box.asInstanceOf[BoxPointer].addr = v
def asSeq_=(vs: Seq[ValueBox]): Unit = { for ((dst, src) <- box.asSeq zip vs) { dst copyFrom src } }
def asRef_=(v: Word): Unit = box.asInstanceOf[BoxRef].objRef = v
def asIRef_=(oo: (Word, Word)): Unit = box.asInstanceOf[BoxIRef].oo = oo
def asTR64Raw_=(v: Long): Unit = box.asInstanceOf[BoxTagRef64].raw = v
def asFunc_=(v: Option[Function]): Unit = box.asInstanceOf[BoxFunc].func = v
def asThread_=(v: Option[InterpreterThread]): Unit = box.asInstanceOf[BoxThread].thread = v
def asStack_=(v: Option[InterpreterStack]): Unit = box.asInstanceOf[BoxStack].stack = v
def asTR64Raw_=(v: Long): Unit = box.asInstanceOf[BoxTagRef64].raw = v
def asPtr_=(v: Word): Unit = box.asInstanceOf[BoxPointer].addr = v
def asSeq_=(vs: Seq[ValueBox]): Unit = {
for ((dst, src) <- box.asSeq zip vs) {
dst copyFrom src
}
}
def asFrameCursor_=(v: Option[FrameCursor]): Unit = box.asInstanceOf[BoxFrameCursor].cursor = v
def asIRNode_=(v: Option[IRNode]): Unit = box.asInstanceOf[BoxIRNode].node = v
def getSInt(len: Int): BigInt = OpHelper.prepareSigned(box.asIntRaw, len)
def getUInt(len: Int): BigInt = OpHelper.prepareUnsigned(box.asIntRaw, len)
......
......@@ -10,6 +10,7 @@ import uvm.refimpl.mem.TypeSizes
import uvm.ssavariables._
import uvm.ssavariables.AtomicRMWOptr._
import uvm.types._
import uvm.ir.irbuilder.IRNode
object OpHelper {
......@@ -365,6 +366,9 @@ object MemoryOperations {
case _: TypeDouble =>
val dv = memorySupport.loadDouble(loc, !ptr)
br.asInstanceOf[BoxDouble].value = dv
case _: AbstractPointerType =>
val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = memorySupport.loadLong(loc)
......@@ -374,6 +378,10 @@ object MemoryOperations {
val base = memorySupport.loadLong(loc)
val offset = memorySupport.loadLong(loc + WORD_SIZE_BYTES)
br.asInstanceOf[BoxIRef].oo = (base, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = memorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val fid = memorySupport.loadLong(loc).toInt
......@@ -389,13 +397,10 @@ object MemoryOperations {
val sid = memorySupport.loadLong(loc).toInt
val sta = microVM.threadStackManager.stackRegistry.get(sid)
br.asInstanceOf[BoxStack].stack = sta
case _: TypeTagRef64 =>
case _: TypeIRNodeRef =>
noAccessViaPointer(ptr, ty)
val raw = memorySupport.loadLong(loc)
br.asInstanceOf[BoxTagRef64].raw = raw
case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = memorySupport.loadLong(loc, !ptr)
br.asInstanceOf[BoxPointer].addr = addr
val maybeIRNode = loadIRNode(loc)
br.asInstanceOf[BoxIRNode].node = maybeIRNode
case _ => throw new UvmUnimplementedOperationException("Loading of type %s is not supporing".format(ty.getClass.getName))
}
......@@ -410,7 +415,7 @@ object MemoryOperations {
}
}
def store(ptr: Boolean, ty: Type, loc: Word, nvb: ValueBox)(implicit memorySupport: MemorySupport): Unit = {
def store(ptr: Boolean, ty: Type, loc: Word, nvb: ValueBox)(implicit microVM: MicroVM, memorySupport: MemorySupport): Unit = {
def storeScalar(ty: Type, loc: Word, nvb: ValueBox): Unit = ty match {
case TypeInt(l) =>
val bi = nvb.asInstanceOf[BoxInt].value
......@@ -431,6 +436,9 @@ object MemoryOperations {
case _: TypeDouble =>
val dv = nvb.asInstanceOf[BoxDouble].value
memorySupport.storeDouble(loc, dv, !ptr)
case _: AbstractPointerType =>
val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr)
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val addr = nvb.asInstanceOf[BoxRef].objRef
......@@ -440,6 +448,10 @@ object MemoryOperations {
val BoxIRef(base, offset) = nvb.asInstanceOf[BoxIRef]
memorySupport.storeLong(loc, base)
memorySupport.storeLong(loc + WORD_SIZE_BYTES, offset)
case _: TypeTagRef64 =>
noAccessViaPointer(ptr, ty)
val raw = nvb.asInstanceOf[BoxTagRef64].raw
memorySupport.storeLong(loc, raw)
case _: TypeFuncRef =>
noAccessViaPointer(ptr, ty)
val fid = nvb.asInstanceOf[BoxFunc].func.map(_.id).getOrElse(0)
......@@ -452,13 +464,10 @@ object MemoryOperations {
noAccessViaPointer(ptr, ty)
val sid = nvb.asInstanceOf[BoxStack].stack.map(_.id).getOrElse(0)
memorySupport.storeLong(loc, sid.toLong & 0xFFFFFFFFL)
case _: TypeTagRef64 =>
case _: TypeIRNodeRef =>
noAccessViaPointer(ptr, ty)
val raw = nvb.asInstanceOf[BoxTagRef64].raw
memorySupport.storeLong(loc, raw)
case _: TypeUPtr | _: TypeUFuncPtr =>
val addr = nvb.asInstanceOf[BoxPointer].addr
memorySupport.storeLong(loc, addr, !ptr)
val maybeIRNode = nvb.asInstanceOf[BoxIRNode].node
storeIRNode(loc, maybeIRNode)
case _ => throw new UvmUnimplementedOperationException("Storing of type %s is not supporing".format(ty.getClass.getName))
}
......@@ -494,6 +503,12 @@ object MemoryOperations {
}
br.asInstanceOf[BoxInt].value = OpHelper.unprepare(rbi, l)
succ
case _: AbstractPointerType =>
val el = eb.asInstanceOf[BoxPointer].addr
val dl = db.asInstanceOf[BoxPointer].addr
val (succ, rl) = memorySupport.cmpXchgLong(loc, el, dl, !ptr)
br.asInstanceOf[BoxPointer].addr = rl
succ
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val el = eb.asInstanceOf[BoxRef].objRef
......@@ -532,12 +547,6 @@ object MemoryOperations {
val rs = microVM.threadStackManager.stackRegistry.get(rl.toInt)
br.asInstanceOf[BoxStack].stack = rs
succ
case _: TypeUPtr | _: TypeUFuncPtr =>
val el = eb.asInstanceOf[BoxPointer].addr
val dl = db.asInstanceOf[BoxPointer].addr
val (succ, rl) = memorySupport.cmpXchgLong(loc, el, dl, !ptr)
br.asInstanceOf[BoxPointer].addr = rl
succ
case _ => throw new UvmUnimplementedOperationException("CmpXchg of type %s is not supporing".format(ty.getClass.getName))
}
}
......@@ -557,6 +566,10 @@ object MemoryOperations {
throw new UvmUnimplementedOperationException("AtomicRMW operation other than XCHG only supports int. %s found.".format(ty.getClass.getName))
} else {
ty match {
case _: AbstractPointerType =>
val ol = ob.asInstanceOf[BoxPointer].addr
val rl = memorySupport.atomicRMWLong(op, loc, ol, !ptr)
br.asInstanceOf[BoxPointer].addr = rl
case _: TypeRef =>
noAccessViaPointer(ptr, ty)
val ol = ob.asInstanceOf[BoxRef].objRef
......@@ -590,10 +603,6 @@ object MemoryOperations {
val ol = ob.asInstanceOf[BoxTagRef64].raw
val rl = memorySupport.atomicRMWLong(op, loc, ol)
br.asInstanceOf[BoxTagRef64].raw = rl
case _: TypeUPtr | _: TypeUFuncPtr =>
val ol = ob.asInstanceOf[BoxPointer].addr
val rl = memorySupport.atomicRMWLong(op, loc, ol, !ptr)
br.asInstanceOf[BoxPointer].addr = rl
case _ =>
throw new UvmUnimplementedOperationException("AtomicRMW XCHG of type %s is not supporing".format(ty.getClass.getName))
}
......@@ -651,5 +660,57 @@ object MemoryOperations {
loc
}
/**
* Load irnoderef value from the memory. Use fake value from microVM.irNodeRegistry
*/
def loadIRNode(loc: Word)(implicit microVM: MicroVM, memorySupport: MemorySupport): Option[IRNode] = {
val irNodeLong = memorySupport.loadLong(loc).toInt
val maybeIRNode = microVM.irNodeRegistry.longToObj(irNodeLong)
maybeIRNode
}
/**
* Store irnoderef value into the memory. Use fake value from microVM.irNodeRegistry
*/
def storeIRNode(loc: Word, maybeIRNode: Option[IRNode])(implicit microVM: MicroVM, memorySupport: MemorySupport): Unit = {
val irNodeLong = microVM.irNodeRegistry.objGetLong(maybeIRNode)
memorySupport.storeLong(loc, irNodeLong)
}
def loadInt32Array(base: Word, len: Word)(implicit memorySupport: MemorySupport): IndexedSeq[Int] = {
if (base == 0L) {
IndexedSeq[Int]()
} else {
for (i <- 0L until len) yield {
val addr = base + i * 4L
val v = memorySupport.loadInt(addr)
v
}
}
}
def loadInt64Array(base: Word, len: Word)(implicit memorySupport: MemorySupport): IndexedSeq[Long] = {
if (base == 0L) {
IndexedSeq[Long]()
} else {
for (i <- 0L until len) yield {
val addr = base + i * WORD_SIZE_BYTES
val v = memorySupport.loadLong(addr)
v
}
}
}
def loadIRNodeArray(base: Word, sz: Word)(implicit microVM: MicroVM, memorySupport: MemorySupport): IndexedSeq[IRNode] = {
if (base == 0L) {
IndexedSeq[IRNode]()
} else {
for (i <- 0L until sz) yield {
val loc = base + i * WORD_SIZE_BYTES
loadIRNode(loc).get
}
}
}
}
package uvm.refimpl.mem
import scala.collection.mutable.HashMap
/**
* This class keeps a map between Long and arbitrary Scala objects. In this way,
* references to arbitrary Scala objects can be stored in the Mu memory.
* <p>
* Similar to JFFI's object exposer.
*/
class SequentialObjectKeeper[T] {
private val longToObj = new HashMap[Long, T]()
private val objToLong = new HashMap[T, Long]()
var nextLong = 1L
def objGetLong(maybeObj: Option[T]): Long = {
maybeObj match {
case None => 0L
case Some(obj) =>
objToLong.getOrElseUpdate(obj, {
val myLong = nextLong
nextLong += 1
longToObj(myLong) = obj
myLong
})
}
}
def longToObj(l: Long): Option[T] = longToObj.get(l)
def maybeRemoveObj(obj: T): Unit = {
objToLong.remove(obj).foreach { l =>
longToObj.remove(l)
}
}
}
\ No newline at end of file
......@@ -32,20 +32,20 @@ abstract class AbstractPointerType extends Type
case class TypeInt(var length: Int) extends Type
case class TypeFloat() extends FPType
case class TypeDouble() extends FPType
case class TypeRef(var ty: Type) extends AbstractObjRefType
case class TypeIRef(var ty: Type) extends AbstractRefType
case class TypeWeakRef(var ty: Type) extends AbstractObjRefType
case class TypeUPtr(var ty: Type) extends AbstractPointerType
case class TypeUFuncPtr(var sig: FuncSig) extends AbstractPointerType
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 TypeArray(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeVoid() extends Type
case class TypeRef(var ty: Type) extends AbstractObjRefType
case class TypeIRef(var ty: Type) extends AbstractRefType
case class TypeWeakRef(var ty: Type) extends AbstractObjRefType
case class TypeTagRef64() 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
case class TypeUFuncPtr(var sig: FuncSig) extends AbstractPointerType
case class TypeFrameCursorRef() extends AbstractGenRefType
case class TypeIRNodeRef() extends AbstractGenRefType
......
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