Commit 3323a4b7 authored by Kunshan Wang's avatar Kunshan Wang

WIP: Testing parser...

parent e8612f5f
......@@ -11,7 +11,7 @@ topLevelDef
| globalDef
| funcDecl
| funcDef
| exposeDef
| funcExpDef
;
typeDef
......@@ -35,44 +35,43 @@ funcDecl
;
funcDef
: '.funcdef' nam=GLOBAL_NAME 'VERSION' ver=GLOBAL_NAME '<' sig=funcSig '>' params=paramList body=funcBody
: '.funcdef' nam=GLOBAL_NAME 'VERSION' ver=name '<' sig=funcSig '>' body=funcBody
;
exposeDef
funcExpDef
: '.expose' nam=GLOBAL_NAME '=' funcName=GLOBAL_NAME callConv=flag cookie=GLOBAL_NAME
;
typeConstructor
: 'int' '<' length=intLiteral '>' # TypeInt
: 'int' '<' length=intLiteral '>' # TypeInt
| 'float' # TypeFloat
| 'double' # TypeDouble
| 'ref' '<' type '>' # TypeRef
| 'iref' '<' type '>' # TypeIRef
| 'weakref' '<' type '>' # TypeWeakRef
| 'struct' '<' type+ '>' # TypeStruct
| 'array' '<' type length=intLiteral '>' # TypeArray
| 'hybrid' '<' fixedTy=type varTy=type '>' # TypeHybrid
| 'ref' '<' ty=type '>' # TypeRef
| 'iref' '<' ty=type '>' # TypeIRef
| 'weakref' '<' ty=type '>' # TypeWeakRef
| 'struct' '<' fieldTys+=type+ '>' # TypeStruct
| 'array' '<' ty=type length=intLiteral '>' # TypeArray
| 'hybrid' '<' fixedTy=type varTy=type '>' # TypeHybrid
| 'void' # TypeVoid
| 'func' '<' funcSig '>' # TypeFunc
| 'thread' # TypeThread
| 'stack' # TypeStack
| 'funcref' '<' funcSig '>' # TypeFuncRef
| 'threadref' # TypeThreadRef
| 'stackref' # TypeStackRef
| 'tagref64' # TypeTagRef64
| 'vector' '<' type length=intLiteral '>' # TypeVector
| 'ptr' '<' type '>' # TypePtr
| 'funcptr' '<' funcSig '>' # TypeFuncPtr
| 'vector' '<' ty=type length=intLiteral '>' # TypeVector
| 'uptr' '<' ty=type '>' # TypeUPtr
| 'ufuncptr' '<' funcSig '>' # TypeUFuncPtr
;
funcSigConstructor
: retTy=type '(' (paramTy+=type*) ')'
: retTy=type '(' (paramTys+=type*) ')'
;
constConstructor
: intLiteral # ConstInt
| floatLiteral # ConstFloat
| doubleLiteral # ConstDouble
| '{' GLOBAL_NAME* '}' # ConstStruct
| 'NULL' # ConstNull
| 'VEC' '{' constant* '}' # ConstVector
: intLiteral # CtorInt
| floatLiteral # CtorFloat
| doubleLiteral # CtorDouble
| '{' GLOBAL_NAME* '}' # CtorList
| 'NULL' # CtorNull
;
type
......@@ -100,8 +99,16 @@ basicBlock
;
label
: name ':'
: name '(' bbParam* ')' excParam? ':'
;
bbParam
: '<' type '>' name
;
excParam
: '[' name ']'
;
inst
: (name '=')? instBody
......@@ -121,28 +128,24 @@ instBody
| 'SELECT' '<' condTy=type resTy=type '>' cond=value ifTrue=value ifFalse=value # InstSelect
// Intra-function Control Flow
| 'BRANCH' bbName # InstBranch
| 'BRANCH2' cond=value ifTrue=bbName ifFalse=bbName # InstBranch2
| 'SWITCH' '<' type '>' opnd=value defDest=bbName '{'
(caseVal+=value ':' caseDest+=bbName ';')* '}' # InstSwitch
| 'PHI' '<' type '>' '{'
(caseSrc+=bbName ':' caseVal+=value ';')* '}' # InstPhi
| 'BRANCH' dest=destClause # InstBranch
| 'BRANCH2' cond=value ifTrue=destClause ifFalse=destClause # InstBranch2
| 'SWITCH' '<' type '>' opnd=value defDest=destClause '{'
(caseVal+=value caseDest+=destClause )* '}' # InstSwitch
// Inter-function Control Flow
| 'CALL' funcCallBody excClause keepAliveClause # InstCall
| 'TAILCALL' funcCallBody # InstTailCall
| 'RET' '<' type '>' retVal=value # InstRet
| 'RETVOID' # InstRetVoid
| 'RET' retVal=value # InstRet
| 'THROW' exc=value # InstThrow
| 'LANDINGPAD' # InstLandingPad
// Aggregate Operations
| 'EXTRACTVALUE' '<' type intLiteral '>' opnd=value # InstExtractValue
| 'INSERTVALUE' '<' type intLiteral '>' opnd=value newVal=value # InstInsertValue
| 'EXTRACTELEMENT' '<' vecTy=type indTy=type '>' opnd=value index=value # InstExtractElement
| 'INSERTELEMENT' '<' vecTy=type indTy=type '>' opnd=value index=value newVal=value # InstInsertElement
| 'SHUFFLEVECTOR' '<' vecTy=type maskTy=type '>' vec1=value vec2=value mask=value # InstShuffleVector
| 'EXTRACTVALUE' '<' ty=type intLiteral '>' opnd=value # InstExtractValue
| 'INSERTVALUE' '<' ty=type intLiteral '>' opnd=value newVal=value # InstInsertValue
| 'EXTRACTELEMENT' '<' seqTy=type indTy=type '>' opnd=value index=value # InstExtractElement
| 'INSERTELEMENT' '<' seqTy=type indTy=type '>' opnd=value index=value newVal=value # InstInsertElement
| 'SHUFFLEVECTOR' '<' vecTy=type maskTy=type '>' vec1=value vec2=value mask=value # InstShuffleVector
// Memory Operations
| 'NEW' '<' allocTy=type '>' excClause # InstNew
......@@ -169,7 +172,7 @@ instBody
// Trap
| 'TRAP' '<' type '>' excClause keepAliveClause # InstTrap
| 'WATCHPOINT' wpid=intLiteral '<' type '>'
dis=bbName ena=bbName ('WPEXC' '(' wpExc=bbName ')')? keepAliveClause # InstWatchPoint
dis=destClause ena=destClause ('WPEXC' '(' wpExc=destClause ')')? keepAliveClause # InstWatchPoint
// Foreign Function Interface
| 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList keepAliveClause # InstCCall
......@@ -182,9 +185,13 @@ instBody
| 'COMMINST' nam=GLOBAL_NAME flagList? typeList? funcSigList? argList? excClause keepAliveClause # InstCommInst
;
bbName
: name
destClause
: bb argList
;
bb
: name
;
value
: name
......@@ -195,7 +202,7 @@ funcCallBody
;
excClause
: ('EXC' '(' nor=bbName exc=bbName ')')?
: ('EXC' '(' nor=destClause exc=destClause ')')?
;
keepAliveClause
......@@ -225,7 +232,6 @@ curStackClause
newStackClause
: 'PASS_VALUE' '<' type '>' value # NewStackPassValue
| 'PASS_VOID' # NewStackPassVoid
| 'THROW_EXC' exc=value # NewStackThrowExc
;
......
......@@ -7,7 +7,7 @@ class Bundle {
/*
* There is a hierarchy of namespaces. A subnode is a subset of the parent.
*
* + allNs // All Identified entities
* + allNs // All globally Identified entities
* + typeNs // All types
* + funcSigNs // All function signatures
* + funcVerNs // All function versions
......@@ -17,90 +17,46 @@ class Bundle {
* + globalCellNs // Global cells
* + funcNs // Functions
* + expFuncNs // Exposed functions
* + localVarNs // Local variables (per function version)
* + bbNs // Basic blocks (per function version)
*
* TODO: Should there be a global "basic block ns for all function versions"?
* These namespaces are local, i.e. they cannot be directly looked up from a bundle:
* + bbNs // Basic blocks (per function version)
* + localVarNs // Local variables (per basic block)
*/
val allNs = new SimpleNamespace[Identified]()
val allNs = new NestedNamespace[Identified](None)
val typeNs = new SimpleNamespace[Type]()
val funcSigNs = new SimpleNamespace[FuncSig]()
val funcVerNs = new SimpleNamespace[FuncVer]()
val typeNs = allNs.makeSubSpace[Type]()
val funcSigNs = allNs.makeSubSpace[FuncSig]()
val funcVerNs = allNs.makeSubSpace[FuncVer]()
val varNs = allNs.makeSubSpace[SSAVariable]()
val varNs = new SimpleNamespace[SSAVariable]()
val globalVarNs = new SimpleNamespace[GlobalVariable]()
val constantNs = new SimpleNamespace[Constant]()
val globalCellNs = new SimpleNamespace[GlobalCell]()
val funcNs = new SimpleNamespace[Function]()
val expFuncNs = new SimpleNamespace[ExposedFunc]()
/**
* 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])
if (obj.isInstanceOf[ExposedFunc]) expFuncNs.add(obj.asInstanceOf[ExposedFunc])
}
val globalVarNs = varNs.makeSubSpace[GlobalVariable]()
val constantNs = globalVarNs.makeSubSpace[Constant]()
val globalCellNs = globalVarNs.makeSubSpace[GlobalCell]()
val funcNs = globalVarNs.makeSubSpace[Function]()
val expFuncNs = globalVarNs.makeSubSpace[ExposedFunc]()
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) {
// Function merging happens separately. Only add a function if it does not redefine an old one.
try {
oldNs.add(cand)
} catch {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
"Redefinition of type, function signature, constant or" +
" global cell is not allowed", e);
}
}
}
}
private def mergeFunc(oldNs: Namespace[Function], newNs: Namespace[Function]) {
for (cand <- newNs.all) {
val id = cand.id
oldNs.get(id) match {
case None => oldNs.add(cand)
case Some(oldObj) =>
oldObj.versions = cand.versions.head :: oldObj.versions
cand.versions.head.func = oldObj
}
}
}
private def fixExpFuncs(oldNs: Namespace[Function], newNs: Namespace[ExposedFunc]) {
for (expFunc <- newNs.all) {
val funcID = expFunc.func.id
oldNs.get(funcID) match {
case None =>
case Some(oldFunc) => expFunc.func = oldFunc
try {
oldNs.add(cand)
} catch {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
"Redefinition of type, function signature, constant or" +
" global cell is not allowed", e);
}
}
}
def merge(newBundle: Bundle) {
simpleMerge(allNs, newBundle.allNs)
// Only merge leaves
simpleMerge(typeNs, newBundle.typeNs)
simpleMerge(funcSigNs, newBundle.funcSigNs)
simpleMerge(funcVerNs, newBundle.funcVerNs)
simpleMerge(varNs, newBundle.varNs)
simpleMerge(globalVarNs, newBundle.globalVarNs)
simpleMerge(constantNs, newBundle.constantNs)
simpleMerge(globalCellNs, newBundle.globalCellNs)
mergeFunc(funcNs, newBundle.funcNs)
simpleMerge(funcNs, newBundle.funcNs)
simpleMerge(expFuncNs, newBundle.expFuncNs)
fixExpFuncs(funcNs, newBundle.expFuncNs)
}
}
......@@ -10,4 +10,18 @@ trait Identified {
trait IdentifiedSettable extends Identified {
var id: Int = 0
var name: Option[String] = None
}
\ No newline at end of file
}
object RichIdentifiedSettable {
implicit class RichIdentifiedSettable[T <: IdentifiedSettable](val is: T) {
def :=(p: Int): T = {
is.id = p
is
}
def :=(p: (Int, String)): T = {
is.id = p._1
is.name = Some(p._2)
is
}
}
}
......@@ -3,7 +3,14 @@ package uvm
import uvm.types._
import uvm.ssavariables._
case class FuncSig(var retTy: Type, var paramTy: Seq[Type]) extends IdentifiedSettable
case class FuncSig(var retTy: Type, var paramTy: Seq[Type]) extends IdentifiedSettable {
override final def toString: String = FuncSig.prettyPrint(this)
override def hashCode(): Int = System.identityHashCode(this)
override def equals(that: Any): Boolean = that match {
case v: AnyRef => this eq v
case _ => false
}
}
object FuncSig {
def prettyPrint(sig: FuncSig): String =
......@@ -22,14 +29,16 @@ class FuncVer extends IdentifiedSettable {
var func: Function = null
var bbs: Seq[BasicBlock] = null
var entry: BasicBlock = null
var params: Seq[Parameter] = null
val bbNs: Namespace[BasicBlock] = new SimpleNamespace[BasicBlock]()
val localVarNs: Namespace[LocalVariable] = new SimpleNamespace[LocalVariable]()
def sig: FuncSig = func.sig
val bbNs = new SimpleNamespace[BasicBlock]
}
class BasicBlock extends IdentifiedSettable {
var norParams: Seq[NorParam] = null
var excParam: Option[ExcParam] = null
var insts: Seq[Instruction] = null
val localVarNs = new SimpleNamespace[LocalVariable]
}
......@@ -44,3 +44,14 @@ class SimpleNamespace[T <: Identified] extends Namespace[T] {
def all = idMap.values
}
class NestedNamespace[T <: Identified](val maybeParent: Option[NestedNamespace[_ >: T]]) extends SimpleNamespace[T] {
override def add(obj: T): Unit = {
super.add(obj)
maybeParent.foreach(_.add(obj))
}
def makeSubSpace[U <: T](): NestedNamespace[U] = {
new NestedNamespace[U](Some(this))
}
}
......@@ -178,7 +178,7 @@ class ClientAgent(mutator: Mutator)(
def extractValue(str: Handle, index: Int): Handle = {
val st = str.ty.asInstanceOf[TypeStruct]
val sb = str.vb.asInstanceOf[BoxStruct]
val et = st.fieldTy(index)
val et = st.fieldTys(index)
val eb = sb.values(index)
newHandle(et, eb)
}
......@@ -223,7 +223,7 @@ class ClientAgent(mutator: Mutator)(
def getFieldIRef(handle: Handle, index: Int): Handle = {
val t = handle.ty.asInstanceOf[TypeIRef]
val st = t.ty.asInstanceOf[TypeStruct]
val ft = st.fieldTy(index)
val ft = st.fieldTys(index)
val nt = InternalTypePool.irefOf(ft)
val ob = handle.vb.asInstanceOf[BoxIRef]
val nb = BoxIRef(ob.objRef, ob.offset + TypeSizes.fieldOffsetOf(st, index))
......@@ -275,7 +275,7 @@ class ClientAgent(mutator: Mutator)(
def load(ord: MemoryOrder, loc: Handle): Handle = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypePtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -289,7 +289,7 @@ class ClientAgent(mutator: Mutator)(
def store(ord: MemoryOrder, loc: Handle, newVal: Handle): Unit = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypePtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -302,7 +302,7 @@ class ClientAgent(mutator: Mutator)(
def cmpXchg(ordSucc: MemoryOrder, ordFail: MemoryOrder, weak: Boolean, loc: Handle, expected: Handle, desired: Handle): (Boolean, Handle) = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypePtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -316,7 +316,7 @@ class ClientAgent(mutator: Mutator)(
def atomicRMW(ord: MemoryOrder, op: AtomicRMWOptr, loc: Handle, opnd: Handle): Handle = {
val (ptr, ty) = loc.ty match {
case TypeIRef(t) => (false, t)
case TypePtr(t) => (true, t)
case TypeUPtr(t) => (true, t)
}
val uty = InternalTypePool.unmarkedOf(ty)
val addr = MemoryOperations.addressOf(ptr, loc.vb)
......@@ -558,7 +558,7 @@ class ClientAgent(mutator: Mutator)(
}
def expose(func: Handle, callConv: Flag, cookie: Handle): Handle = {
val TypeFunc(sig) = func.ty
val TypeFuncRef(sig) = func.ty
val f = func.vb.asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException("Attempt to expose NULL Mu function")
}
......
......@@ -35,17 +35,17 @@ object InternalTypes {
val REF_VOID = TypeRef(VOID) := internal("ref_void")
val STACK = TypeStack() := internal("stack")
val THREAD = TypeThread() := internal("thread")
val STACK = TypeStackRef() := internal("stack")
val THREAD = TypeThreadRef() := internal("thread")
val TAGREF64 = TypeTagRef64() := internal("tagref64")
}
object InternalTypePool {
val refOf = LazyPool(TypeRef)
val irefOf = LazyPool(TypeIRef)
val ptrOf = LazyPool(TypePtr)
val funcOf = LazyPool(TypeFunc)
val funcPtrOf = LazyPool(TypeFuncPtr)
val ptrOf = LazyPool(TypeUPtr)
val funcOf = LazyPool(TypeFuncRef)
val funcPtrOf = LazyPool(TypeUFuncPtr)
val vecOf = LazyPool[(Type, Long), TypeVector] { case (t, l) => TypeVector(t, l) }
def unmarkedOf(t: Type): Type = t match {
case TypeWeakRef(r) => refOf(r)
......@@ -83,7 +83,7 @@ object TypeInferer {
case i: InstRetVoid => VOID
case i: InstThrow => VOID
case i: InstLandingPad => REF_VOID
case i: InstExtractValue => i.strTy.fieldTy(i.index)
case i: InstExtractValue => i.strTy.fieldTys(i.index)
case i: InstInsertValue => i.strTy
case i: InstExtractElement => i.vecTy.elemTy
case i: InstInsertElement => i.vecTy
......@@ -93,7 +93,7 @@ object TypeInferer {
case i: InstAlloca => irefOf(i.allocTy)
case i: InstAllocaHybrid => irefOf(i.allocTy)
case i: InstGetIRef => irefOf(i.referentTy)
case i: InstGetFieldIRef => ptrOrIRefOf(i.ptr, i.referentTy.fieldTy(i.index))
case i: InstGetFieldIRef => ptrOrIRefOf(i.ptr, i.referentTy.fieldTys(i.index))
case i: InstGetElemIRef => ptrOrIRefOf(i.ptr, i.referentTy.elemTy)
case i: InstShiftIRef => ptrOrIRefOf(i.ptr, i.referentTy)
case i: InstGetFixedPartIRef => ptrOrIRefOf(i.ptr, i.referentTy.fixedTy)
......
......@@ -27,9 +27,9 @@ class ConstantPool(implicit microVM: MicroVM) {
case ConstNull(ty) => ty match {
case _:TypeRef => BoxRef(0L)
case _:TypeIRef => BoxIRef(0L, 0L)
case _:TypeFunc => BoxFunc(None)
case _:TypeThread => BoxThread(None)
case _:TypeStack => BoxStack(None)
case _:TypeFuncRef => BoxFunc(None)
case _:TypeThreadRef => BoxThread(None)
case _:TypeStackRef => BoxStack(None)
}
case ConstVector(ty, elems) => BoxVector(elems.map(maybeMakeBox))
case ConstPointer(ty, addr) => BoxPointer(addr)
......
......@@ -272,14 +272,14 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
def doScalar(scalarTy: Type, b1: ValueBox, b2: ValueBox, br: ValueBox): Unit = {
scalarTy match {
case TypeInt(l) => doInt(l, b1, b2, br)
case TypeFloat() => doFloat(b1, b2, br)
case TypeDouble() => doDouble(b1, b2, br)
case TypeRef(_) => doRef(b1, b2, br)
case TypeIRef(_) => doIRef(b1, b2, br)
case TypeFunc(_) => doFunc(b1, b2, br)
case TypeStack() => doStack(b1, b2, br)
case _ => throw new UvmRuntimeException(ctx + "Comparison not suitable for type %s".format(opndTy))
case TypeInt(l) => doInt(l, b1, b2, br)
case TypeFloat() => doFloat(b1, b2, br)
case TypeDouble() => doDouble(b1, b2, br)
case TypeRef(_) => doRef(b1, b2, br)
case TypeIRef(_) => doIRef(b1, b2, br)
case TypeFuncRef(_) => doFunc(b1, b2, br)
case TypeStackRef() => doStack(b1, b2, br)
case _ => throw new UvmRuntimeException(ctx + "Comparison not suitable for type %s".format(opndTy))
}
}
......@@ -369,9 +369,9 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
}
def refcast(): Unit = (scalarFromTy, scalarToTy) match {
case (TypeRef(_), TypeRef(_)) => br.copyFrom(bOpnd)
case (TypeIRef(_), TypeIRef(_)) => br.copyFrom(bOpnd)
case (TypeFunc(_), TypeFunc(_)) => br.copyFrom(bOpnd)
case (TypeRef(_), TypeRef(_)) => br.copyFrom(bOpnd)
case (TypeIRef(_), TypeIRef(_)) => br.copyFrom(bOpnd)
case (TypeFuncRef(_), TypeFuncRef(_)) => br.copyFrom(bOpnd)
case _ => throw new UvmRuntimeException(ctx +
"REFCAST can only convert between two types both of which are ref, iref, or func. Found %s and %s.".format(scalarFromTy, scalarToTy))
}
......@@ -1134,26 +1134,26 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val Seq(callConv) = flagList
val Seq(sig) = sigList
val Seq(func, cookie) = argList
val f = boxOf(func).asInstanceOf[BoxFunc].func.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to expose NULL Mu function")
}
val c = boxOf(cookie).asInstanceOf[BoxInt].value.toLong
val addr = microVM.nativeCallHelper.exposeFuncDynamic(f, c)
val addr = microVM.nativeCallHelper.exposeFuncDynamic(f, c)
boxOf(i).asInstanceOf[BoxPointer].addr = addr
continueNormally()
}
case "@uvm.native.unexpose" => {
val Seq(callConv) = flagList
val Seq(addr) = argList
val a = boxOf(addr).asInstanceOf[BoxPointer].addr
microVM.nativeCallHelper.unexposeFunc(a)
continueNormally()
......
......@@ -101,12 +101,12 @@ object ValueBox {
case _: TypeArray => throw new UvmRefImplException("array cannot be an SSA variable type")
case _: TypeHybrid => throw new UvmRefImplException("hybrid cannot be an SSA variable type")
case _: TypeVoid => BoxVoid()
case _: TypeFunc => BoxFunc(None)
case _: TypeStack => BoxStack(None)
case _: TypeThread => BoxThread(None)
case _: TypeFuncRef => BoxFunc(None)
case _: TypeStackRef => BoxStack(None)
case _: TypeThreadRef => BoxThread(None)
case _: TypeTagRef64 => BoxTagRef64(0L)
case _: TypePtr => BoxPointer(0L)
case _: TypeFuncPtr => BoxPointer(0L)
case _: TypeUPtr => BoxPointer(0L)
case _: TypeUFuncPtr => BoxPointer(0L)
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ abstract class SSAVariable extends IdentifiedSettable {
case v: AnyRef => this eq v
case _ => false
}
override def toString = "%s%s".format(this.getClass.getSimpleName, this.repr)
}
// Global variables: Constants, Global Cells and Functions (Function is defined in controlFlow.scala)
......@@ -28,6 +29,8 @@ case class ConstDouble(var constTy: Type, var num: Double) extends Constant
case class ConstStruct(var constTy: Type, var fields: Seq[GlobalVariable]) extends Constant
case class ConstArray(var constTy: Type, var elems: Seq[GlobalVariable]) extends Constant
case class ConstNull(var constTy: Type) extends Constant
case class ConstVector(var constTy: Type, var elems: Seq[Constant]) extends Constant
......@@ -42,7 +45,9 @@ case class ExposedFunc(var func: Function, var callConv: Flag, var cookie: Const
abstract class LocalVariable extends SSAVariable
case class Parameter(var funcVer: FuncVer, var index: Int) extends LocalVariable
abstract class Parameter extends LocalVariable
case class NorParam(ty: Type) extends Parameter
case class ExcParam() extends Parameter
// Instructions
......@@ -103,7 +108,9 @@ trait CallLike extends HasArgList {
var callee: SSAVariable
}
case class ExcClause(val nor: BasicBlock, val exc: BasicBlock)
case class DestClause(val bb: BasicBlock, val args: Seq[SSAVariable])
case class ExcClause(val nor: DestClause, val exc: DestClause)
trait HasExcClause extends Instruction {
var excClause: Option[ExcClause]
......@@ -149,12 +156,6 @@ case class PassValue(var argTy: Type, var arg: SSAVariable) extends NewStackActi
case class PassVoid() extends NewStackAction
case class ThrowExc(var exc: SSAVariable) extends NewStackAction
/**
* An EdgeAssigned instruction is evaluated at control flow edges rather than sequentially when the PC
* reaches that instruction. Currently PHI and LANDINGPAD are the only two such instructions.
*/
trait EdgeAssigned extends Instruction
/**
* Flags are used in common instructions.
*/
......@@ -171,36 +172,32 @@ case class InstConv(var op: ConvOptr, var fromTy: Type, var toTy: Type, var opnd
case class InstSelect(var condTy: Type, var opndTy: Type,
var cond: SSAVariable, var ifTrue: SSAVariable, var ifFalse: SSAVariable) extends Instruction
case class InstBranch(var dest: BasicBlock) extends Instruction
case class InstBranch2(var cond: SSAVariable, var ifTrue: BasicBlock, var ifFalse: BasicBlock) extends Instruction
case class InstBranch(var dest: DestClause) extends Instruction
case class InstSwitch(var opndTy: Type, var opnd: SSAVariable, var defDest: BasicBlock,
var cases: Seq[(SSAVariable, BasicBlock)]) extends Instruction
case class InstBranch2(var cond: SSAVariable, var ifTrue: DestClause, var ifFalse: DestClause) extends Instruction
case class InstPhi(var opndTy: Type, var cases: Seq[(BasicBlock, SSAVariable)]) extends Instruction with EdgeAssigned
case class InstSwitch(var opndTy: Type, var opnd: SSAVariable, var defDest: DestClause,
var cases: Seq[(SSAVariable, DestClause)]) extends Instruction
case class InstCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable],
var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends AbstractCall with HasExcClause with HasKeepAliveClause
case class InstTailCall(var sig: FuncSig, var callee: SSAVariable, var argList: Seq[SSAVariable]) extends AbstractCall
case class InstRet(var retTy: Type, var retVal: SSAVariable) extends AbstractRet
case class InstRet(val funcVer: FuncVer, var retVal: SSAVariable) extends AbstractRet
case class InstRetVoid() extends AbstractRet
case class InstThrow(var excVal: SSAVariable) extends Instruction
case class InstLandingPad() extends Instruction with EdgeAssigned
case class InstExtractValue(var strTy: TypeStruct, var index: Int, var opnd: SSAVariable) extends Instruction
case class InstInsertValue(var strTy: TypeStruct, var index: Int, var opnd: SSAVariable, var newVal: SSAVariable) extends Instruction
case class InstExtractElement(var vecTy: TypeVector, var indTy: TypeInt,
case class InstExtractElement(var seqTy: AbstractSeqType, var indTy: TypeInt,
var opnd: SSAVariable, var index: SSAVariable) extends Instruction
case class InstInsertElement(var vecTy: TypeVector, var indTy: TypeInt,
case class InstInsertElement(var seqTy: AbstractSeqType, var indTy: TypeInt,
var opnd: SSAVariable, var index: SSAVariable, var newVal: SSAVariable) extends Instruction
case class InstShuffleVector(var vecTy: TypeVector, var maskTy: TypeVector,
......@@ -243,7 +240,7 @@ case class InstFence(var ord: MemoryOrder) extends Instruction
case class InstTrap(var retTy: Type, var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends AbstractTrap with HasExcClause
case class InstWatchPoint(var wpID: Int, var retTy: Type,
var dis: BasicBlock, var ena: BasicBlock, var exc: Option[BasicBlock],
var dis: DestClause, var ena: DestClause, var exc: Option[DestClause],
var keepAlives: Seq[LocalVariable]) extends AbstractTrap
case class InstCCall(var callConv: Flag, var funcTy: Type,
......
......@@ -30,17 +30,17 @@ case class TypeDouble() extends FPType
case class TypeRef(var ty: Type) extends AbstractRefType
case class TypeIRef(var ty: Type) extends AbstractRefType
case class TypeWeakRef(var ty: Type) extends AbstractRefType
case class TypeStruct(var fieldTy: Seq[Type]) extends Type
case class TypeStruct(var fieldTys: Seq[Type]) extends Type
case class TypeArray(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypeHybrid(var fixedTy: Type, var varTy: Type) extends Type
case class TypeVoid() extends Type
case class TypeFunc(var sig: FuncSig) extends Type
case class TypeThread() extends Type
case class TypeStack() extends Type
case class TypeFuncRef(var sig: FuncSig) extends Type
case class TypeThreadRef() extends Type
case class TypeStackRef() extends Type
case class TypeTagRef64() extends Type
case class TypeVector(var elemTy: Type, var len: Long) extends AbstractSeqType
case class TypePtr(var ty: Type) extends AbstractPointerType
case class TypeFuncPtr(var sig: FuncSig) extends AbstractPointerType
case class TypeUPtr(var ty: Type) extends AbstractPointerType
case class TypeUFuncPtr(var sig: FuncSig) extends AbstractPointerType