Commit 4c11b17c authored by Adam R. Nelson's avatar Adam R. Nelson

Merge branch 'master' of https://github.com/microvm/microvm-refimpl2 into client-uir-writer

parents 2608dee4 607995f8
...@@ -9,3 +9,4 @@ target ...@@ -9,3 +9,4 @@ target
.tmpBin .tmpBin
.d8_history .d8_history
hs_err_pid*.log hs_err_pid*.log
/bin/
...@@ -2,11 +2,13 @@ Mu Reference Implementation version 2 ...@@ -2,11 +2,13 @@ Mu Reference Implementation version 2
===================================== =====================================
This project is the current reference implementation of Mu, the micro virtual This project is the current reference implementation of Mu, the micro virtual
machine designed by [The Micro Virtual Machine Project](http://microvm.org). It machine designed by [The Micro Virtual Machine Project](http://microvm.org).
implements the [Mu Specification version
2](https://github.com/microvm/microvm-spec/wiki)
This project is based on the Version 2.1.x implements the [master branch of the Mu
Specification](https://github.com/microvm/microvm-spec/tree/goto-with-values)
which uses the goto-with-values form.
This project is based on the previous works of
[simplest-microvm-project](https://github.com/microvm/simplest-microvm-project). [simplest-microvm-project](https://github.com/microvm/simplest-microvm-project).
[microvm-refimpl](https://github.com/microvm-project/microvm-refimpl) is the [microvm-refimpl](https://github.com/microvm-project/microvm-refimpl) is the
previous reference implementation. previous reference implementation.
...@@ -21,7 +23,7 @@ How to compile ...@@ -21,7 +23,7 @@ How to compile
`brew install scala`. `brew install scala`.
* Install [sbt](http://www.scala-sbt.org/) 0.13. If you use Mac and Homebrew, * Install [sbt](http://www.scala-sbt.org/) 0.13. If you use Mac and Homebrew,
`brew install sbt`. `brew install sbt`.
* Install [Scala IDE](http://scala-ide.org/) 4.0 (Eclipse with pre-installed * Install [Scala IDE](http://scala-ide.org/) 4.x (Eclipse with pre-installed
plugins for Scala). plugins for Scala).
* Clone this repository: * Clone this repository:
...@@ -32,9 +34,7 @@ git clone git@github.com:microvm/microvm-refimpl2.git ...@@ -32,9 +34,7 @@ git clone git@github.com:microvm/microvm-refimpl2.git
* In the directory `microvm-refimpl2`, do the following: * In the directory `microvm-refimpl2`, do the following:
```bash ```bash
sbt update sbt update genSrc eclipse
sbt antlr4:antlr4Generate
sbt eclipse
``` ```
* Open Scala IDE and import the generated project as "existing project into * Open Scala IDE and import the generated project as "existing project into
...@@ -50,15 +50,16 @@ yum, pacman, etc. for GNU/Linux distributions and Homebrew for Mac OS X). ...@@ -50,15 +50,16 @@ yum, pacman, etc. for GNU/Linux distributions and Homebrew for Mac OS X).
To download all dependencies from the Maven central repository, invoke `sbt To download all dependencies from the Maven central repository, invoke `sbt
update`. update`.
To generate the Mu IR parser from its Antlr grammar, invoke `sbt To generate the Mu IR parser from the Antlr grammar, invoke `sbt genSrc`. The
antlr4:antlr4Generate`. The generated sources will be in generated sources will be in the `target/scala-2.11/src_managed` directory.
`target/scala-2.11/src_managed`. Make sure your IDE can see those generated
sources.
To compile, invoke `sbt compile` or do this in your favourite IDE.
To generate an Eclipse project, install the [sbt-eclipse To generate an Eclipse project, install the [sbt-eclipse
plugin](https://github.com/typesafehub/sbteclipse) and invoke `sbt eclipse`. plugin](https://github.com/typesafehub/sbteclipse) and invoke `sbt eclipse`.
Make sure you generate the parser before creating the Eclipse project, so that
the generated sources will be on the Eclipse build path.
To compile, invoke `sbt compile`. This will also generate the Mu IR parser using
Antlr.
IntelliJ IDEA has plugins for Scala and SBT. Make sure you don't commit `.idea` IntelliJ IDEA has plugins for Scala and SBT. Make sure you don't commit `.idea`
or generated project files into the repository. or generated project files into the repository.
......
organization := "org.microvm"
name := "microvm-refimpl2" lazy val genSrc = taskKey[List[File]]("generate sources")
description := "The second reference implementation of Mu, the micro virtual machine" genSrc <<= (sourceGenerators in Compile) { _.join.map(_.flatten.toList) }
licenses := Seq("CC BY-SA 4.0" -> url("https://creativecommons.org/licenses/by-sa/4.0/legalcode")) lazy val root = (project in file(".")).settings(
organization := "org.microvm",
scalaVersion := "2.11.7" name := "microvm-refimpl2",
version := "2.1.0",
libraryDependencies := Seq( description := "The second reference implementation of Mu, the micro virtual machine",
"org.antlr" % "antlr4" % "4.5.1",
"com.typesafe.scala-logging" %% "scala-logging" % "3.1.0",
"ch.qos.logback" % "logback-classic" % "1.1.2",
"com.github.jnr" % "jnr-ffi" % "2.0.3",
"com.github.jnr" % "jffi" % "1.2.9",
"com.github.jnr" % "jnr-posix" % "3.0.17",
"org.scalatest" %% "scalatest" % "2.2.0" % "test",
"junit" % "junit" % "4.12" % "test"
)
antlr4Settings
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen") licenses := Seq("CC BY-SA 4.0" -> url("https://creativecommons.org/licenses/by-sa/4.0/legalcode")),
antlr4GenListener in Antlr4 := false scalaVersion := "2.11.7",
libraryDependencies ++= Seq(
"org.antlr" % "antlr4" % "4.5.1-1",
"com.typesafe.scala-logging" %% "scala-logging" % "3.1.0",
"ch.qos.logback" % "logback-classic" % "1.1.3",
"com.github.jnr" % "jnr-ffi" % "2.0.7",
"com.github.jnr" % "jffi" % "1.2.10",
"com.github.jnr" % "jnr-posix" % "3.0.23",
"org.scalatest" %% "scalatest" % "2.2.4" % "test",
"junit" % "junit" % "4.12" % "test"
),
testOptions in Test += Tests.Argument("-oF"), // print full stack trace when testing
antlr4Settings,
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen"),
antlr4GenListener in Antlr4 := false,
antlr4GenVisitor in Antlr4 := false
)
antlr4GenVisitor in Antlr4 := false
EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource + EclipseCreateSrc.Managed
This diff is collapsed.
FN=$1
if [ x$SED == x ]; then
SED=sed
fi
$SED -i 's/newClientAgent/newContext/g' $FN
$SED -i 's/ClientAgent/MuCtx/g' $FN
$SED -i 's/deleteHandle/deleteValue/g' $FN
$SED -i 's/\bca\b/ctx/g' $FN
$SED -i 's/ctx\.close()/ctx.closeContext()/g' $FN
$SED -i 's/Handle/MuValue/g' $FN
$SED -i 's/putInt("@i32",/handleFromInt32(/g' $FN
$SED -i 's/putInt("@i64",/handleFromInt64(/g' $FN
$SED -i 's/putInt("@i\(\d\+\)"\s*,\s*\([^)]*\))/handleFromInt(\2, \1)/g' $FN
$SED -i 's/putFloat("@float",/handleFromFloat(/g' $FN
$SED -i 's/putDouble("@double",/handleFromDouble(/g' $FN
$SED -i 's/putConstant/handleFromConst/g' $FN
$SED -i 's/putGlobal/handleFromGlobal/g' $FN
$SED -i 's/putFunction/handleFromFunc/g' $FN
$SED -i 's/putExpFunc/handleFromExpose/g' $FN
$SED -i 's/toInt(\(\w\+\),\s*\(signExt\s*=\s*\)\?true)/handleToSInt(\1.asInstanceOf[MuIntValue])/g' $FN
$SED -i 's/toInt(\(\w\+\))/handleToUInt(\1.asInstanceOf[MuIntValue])/g' $FN
$SED -i 's/toFloat/handleToFloat/g' $FN
$SED -i 's/toDouble/handleToDouble/g' $FN
$SED -i 's/toPointer/handleToPtr/g' $FN
$SED -i 's/refCast/refcast/g' $FN
$SED -i 's/currentInstruction/curInst/g' $FN
$SED -i 's/TrapRebindPassVoid/returnFromTrap/g' $FN
$SED -i 's/TrapRebindPassValue(\(\w\+\),\s*\(\w\+\)\s*)/Rebind(\1, PassValues(Seq(\2)))/g' $FN
FN=$1
if [ x$SED == x ]; then
SED=sed
fi
$SED -i 's/\(%\w\+\)\s*=\s*TRAP/[\1] TRAP/g' $FN
$SED -i 's/NEWSTACK\s*<\(@[0-9a-zA-Z._-]\+\)>\s*\(@\w\+\)/COMMINST @uvm.new_stack <[\1]> (\2)/g' $FN
$SED -i 's/COMMINST\s*@uvm\.new_thread\s*(\([@%]\w\+\))/NEWTHREAD \1 PASS_VALUES /g' $FN
$SED -i 's/TRAP\s*<@void>/TRAP <>/g' $FN
$SED -i 's/noparamsnoret/v_v/g' $FN
$SED -i 's/@funcdumb/@frv_v/g' $FN
$SED -i '/\.funcsig/ {s/@void\s*(\([^)]*\))/(\1) -> ()/g}' $FN
$SED -i '/\.funcsig/ {s/=\s*\(@\w\+\)\s*(\([^)]*\))/= (\2) -> (\1)/}' $FN
$SED -i 's/@i_ii/@ii_i/g' $FN
$SED -i 's/RET @VOID/RET ()/g' $FN
$SED -i 's/hybrid\s*<@void\s*/hybrid</g' $FN
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0") addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "4.0.0")
grammar HAIL;
hail
: topLevelDef*
;
topLevelDef
: fixedAlloc
| hybridAlloc
| memInit
;
fixedAlloc
: '.new' nam=HAIL_NAME '<' ty=type '>'
;
hybridAlloc
: '.newhybrid' nam=HAIL_NAME '<' ty=type '>' len=intExpr
;
memInit
: '.init' lv=lValue '=' rv=rValue
;
lValue
: nam=name (indices+=index)*
;
rValue
: GLOBAL_NAME # RVGlobal
| intLiteral # RVInt
| floatLiteral # RVFloat
| doubleLiteral # RVDouble
| 'NULL' # RVNull
| HAIL_NAME # RVHailRef
| '&' lValue # RVIRefOf
| '*' lValue # RVValueOf
| list # RVList
;
list
: '{' rv+=rValue* '}'
;
index
: '[' intExpr ']'
;
intExpr
: intLiteral # IntLit
| GLOBAL_NAME # IntGlobal
;
type
: GLOBAL_NAME
;
name
: GLOBAL_NAME
| HAIL_NAME
;
intLiteral
: INT_DEC
| INT_OCT
| INT_HEX
;
floatLiteral
: FP_NUM 'f' # FloatNumber
| INF 'f' # FloatInf
| NAN 'f' # FloatNan
| 'bitsf' '(' intLiteral ')' # FloatBits
;
doubleLiteral
: FP_NUM 'd' # DoubleNumber
| INF 'd' # DoubleInf
| NAN 'd' # DoubleNan
| 'bitsd' '(' intLiteral ')' # DoubleBits
;
// LEXER
INT_DEC
: ('+'|'-')? DIGIT_NON_ZERO DIGIT*
;
INT_OCT
: ('+'|'-')? '0' OCT_DIGIT*
;
INT_HEX
: ('+'|'-')? '0x' HEX_DIGIT+
;
FP_NUM
: ('+'|'-')? DIGIT+ '.' DIGIT+ ('e' ('+'|'-')? DIGIT+)?
;
INF
: ('+'|'-') 'inf'
;
NAN
: 'nan'
;
GLOBAL_NAME
: GLOBAL_NAME_PREFIX IDCHAR+
;
HAIL_NAME
: HAIL_NAME_PREFIX IDCHAR+
;
fragment
DIGIT
: [0-9]
;
fragment
DIGIT_NON_ZERO
: [1-9]
;
fragment
OCT_DIGIT
: [0-7]
;
fragment
HEX_DIGIT
: [0-9a-fA-F]
;
fragment
GLOBAL_NAME_PREFIX: '@';
fragment
HAIL_NAME_PREFIX: '$';
fragment
IDCHAR
: [a-z]
| [A-Z]
| [0-9]
| '-'
| '_'
| '.'
;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
LINE_COMMENT
: '//' ~[\r\n]* -> skip
;
This diff is collapsed.
...@@ -2,12 +2,13 @@ package uvm ...@@ -2,12 +2,13 @@ package uvm
import uvm.types._ import uvm.types._
import uvm.ssavariables._ import uvm.ssavariables._
import scala.collection.mutable.HashMap
class Bundle { abstract class Bundle {
/* /*
* There is a hierarchy of namespaces. A subnode is a subset of the parent. * 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 * + typeNs // All types
* + funcSigNs // All function signatures * + funcSigNs // All function signatures
* + funcVerNs // All function versions * + funcVerNs // All function versions
...@@ -17,90 +18,107 @@ class Bundle { ...@@ -17,90 +18,107 @@ class Bundle {
* + globalCellNs // Global cells * + globalCellNs // Global cells
* + funcNs // Functions * + funcNs // Functions
* + expFuncNs // Exposed functions * + expFuncNs // Exposed functions
* + localVarNs // Local variables (per function version) * + localVarNs // Local variables (per basic block)
* + bbNs // Basic blocks (per function version) * + bbNs // Basic blocks (per function version)
* + instNs // All instructions
* + localInstNs // Instructions in a basic block (per basic block)
* *
* TODO: Should there be a global "basic block ns for all function versions"? * bbNs and localVarNs are part of particular FuncVers and BBs.
*/ */
val allNs = new SimpleNamespace[Identified]() val allNs = new NestedNamespace[Identified](None)
val typeNs = new SimpleNamespace[Type]() val typeNs = allNs.makeSubSpace[Type]()
val funcSigNs = new SimpleNamespace[FuncSig]() val funcSigNs = allNs.makeSubSpace[FuncSig]()
val funcVerNs = new SimpleNamespace[FuncVer]() val funcVerNs = allNs.makeSubSpace[FuncVer]()
val varNs = allNs.makeSubSpace[SSAVariable]()
val varNs = new SimpleNamespace[SSAVariable]() val globalVarNs = varNs.makeSubSpace[GlobalVariable]()
val globalVarNs = new SimpleNamespace[GlobalVariable]() val constantNs = globalVarNs.makeSubSpace[Constant]()
val constantNs = new SimpleNamespace[Constant]() val globalCellNs = globalVarNs.makeSubSpace[GlobalCell]()
val globalCellNs = new SimpleNamespace[GlobalCell]() val funcNs = globalVarNs.makeSubSpace[Function]()
val funcNs = new SimpleNamespace[Function]() val expFuncNs = globalVarNs.makeSubSpace[ExposedFunc]()
val expFuncNs = new SimpleNamespace[ExposedFunc]()
val instNs = allNs.makeSubSpace[Instruction]()
}
/**
* This kind of bundle is generated when parsing a .UIR file.
* <p>
* In this kind of bundle, a Function does not have a FuncVer as its version.
* The funcNs only contains new functions declared in this bundle, not existing
* functions declared previously. When this bundle is merged with the global bundle,
* both funcNs and funcVerNs are simply merged, and new FuncVer objects become the
* newest version of the Function, whether the Function is newly declared or not.
*/
class TrantientBundle extends Bundle {
/** /**
* Add an identified entity to its appropriate global namespaces. * All functions (declared here or previously) that are defined in this bundle.
* <p>
* Mainly for debugging purpose.
*/ */
def add(obj: Identified): Unit = { //val defFuncNs = new SimpleNamespace[Function]
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])
}
/**
* This kind of bundle holds the global state. Functions and versions are fully merged.
*/
class GlobalBundle extends Bundle {
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) { private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) { for (cand <- newNs.all) {
if (!cand.isInstanceOf[Function] || oldNs.get(cand.id) == None) { try {
// Function merging happens separately. Only add a function if it does not redefine an old one. oldNs.add(cand)
try { // def assertPresent[T <: Identified](ns: NestedNamespace[T], obj: T): Unit = {
oldNs.add(cand) // assert(ns.get(obj.id) == Some(obj))
} catch { // if (obj.id == 65731) {
case e: NameConflictException => // printf("Obj[65731] found in ns " + ns)
throw new IllegalRedefinitionException( // }
"Redefinition of type, function signature, constant or" + // ns.maybeParent match {
" global cell is not allowed", e); // case None =>
} // case Some(ns2) =>
// assertPresent(ns2, obj)
// }
// }
// assertPresent(oldNs.asInstanceOf[NestedNamespace[T]], cand)
} catch {
case e: NameConflictException =>
throw new IllegalRedefinitionException(
"Redefinition of type, function signature, constant or" +
" global cell is not allowed: %s".format(cand.repr), e);
} }
} }
} }
private def mergeFunc(oldNs: Namespace[Function], newNs: Namespace[Function]) { private def redefineFunctions(newNs: Namespace[FuncVer]) {
for (cand <- newNs.all) { for (fv <- newNs.all) {
val id = cand.id fv.func.versions = fv :: fv.func.versions
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]) { private def mergeLocalNamespaces(newBundle: TrantientBundle) {
for (expFunc <- newNs.all) { for (fv <- newBundle.funcVerNs.all) {
val funcID = expFunc.func.id fv.bbNs.reparent(allNs)
oldNs.get(funcID) match { for (bb <- fv.bbs) {
case None => bb.localVarNs.reparent(allNs)
case Some(oldFunc) => expFunc.func = oldFunc bb.localInstNs.reparent(allNs)
} }
} }
} }
def merge(newBundle: Bundle) { def merge(newBundle: TrantientBundle) {
simpleMerge(allNs, newBundle.allNs) // Only merge leaves
simpleMerge(typeNs, newBundle.typeNs) simpleMerge(typeNs, newBundle.typeNs)
simpleMerge(funcSigNs, newBundle.funcSigNs) simpleMerge(funcSigNs, newBundle.funcSigNs)
simpleMerge(funcVerNs, newBundle.funcVerNs) simpleMerge(funcVerNs, newBundle.funcVerNs)
simpleMerge(varNs, newBundle.varNs)
simpleMerge(globalVarNs, newBundle.globalVarNs)
simpleMerge(constantNs, newBundle.constantNs) simpleMerge(constantNs, newBundle.constantNs)
simpleMerge(globalCellNs, newBundle.globalCellNs) simpleMerge(globalCellNs, newBundle.globalCellNs)
mergeFunc(funcNs, newBundle.funcNs) simpleMerge(funcNs, newBundle.funcNs)
simpleMerge(expFuncNs, newBundle.expFuncNs) simpleMerge(expFuncNs, newBundle.expFuncNs)
fixExpFuncs(funcNs, newBundle.expFuncNs) simpleMerge(instNs, newBundle.instNs)
redefineFunctions(newBundle.funcVerNs)
mergeLocalNamespaces(newBundle)
} }
}
}
\ No newline at end of file
...@@ -5,9 +5,31 @@ trait Identified { ...@@ -5,9 +5,31 @@ trait Identified {
def name: Option[String] def name: Option[String]
def repr: String = "[%d:%s]".format(id, name.getOrElse("_")) def repr: String = "[%d:%s]".format(id, name.getOrElse("_"))
// Identified objects should use reference equality rather than structural equality. (case classes use the latter)
override def hashCode(): Int = if (id != 0) id else System.identityHashCode(this)
override def equals(that: Any): Boolean = that match {
case v: AnyRef => this eq v
case _ => false
}
override def toString = "%s%s".format(this.getClass.getSimpleName, this.repr)
} }
trait IdentifiedSettable extends Identified { trait IdentifiedSettable extends Identified {
var id: Int = 0 var id: Int = 0
var name: Option[String] = None var name: Option[String] = None
} }
\ No newline at end of file
object RichIdentifiedSettable {
implicit class RichIdentifiedSettable[T <: IdentifiedSettable](val is: T) extends AnyVal {
def :=(p: Int): T = {
is.id = p
is
}
def :=(p: (Int, String)): T = {
is.id = p._1
is.name = Some(p._2)
is
}
}
}
...@@ -11,7 +11,7 @@ object CommInsts extends SimpleNamespace[CommInst] { ...@@ -11,7 +11,7 @@ object CommInsts extends SimpleNamespace[CommInst] {
add(ci) add(ci)
} }
commInst(0x201, "@uvm.new_thread") commInst(0x201, "@uvm.new_stack")
commInst(0x202, "@uvm.kill_stack") commInst(0x202, "@uvm.kill_stack")
commInst(0x203, "@uvm.thread_exit") commInst(0x203, "@uvm.thread_exit")
commInst(0x204, "@uvm.current_stack") commInst(0x204, "@uvm.current_stack")
...@@ -39,4 +39,28 @@ object CommInsts extends SimpleNamespace[CommInst] { ...@@ -39,4 +39,28 @@ object CommInsts extends SimpleNamespace[CommInst] {
commInst(0x242, "@uvm.native.expose") commInst(0x242, "@uvm.native.expose")
commInst(0x243, "@uvm.native.unexpose") commInst(0x243, "@uvm.native.unexpose")
commInst(0x244, "@uvm.native.get_cookie") commInst(0x244, "@uvm.native.get_cookie")
commInst(0x250, "@uvm.meta.id_of")
commInst(0x251, "@uvm.meta.name_of")
commInst(0x252, "@uvm.meta.load_bundle")
commInst(0x253, "@uvm.meta.load_hail")
commInst(0x254, "@uvm.meta.new_cursor")
commInst(0x255, "@uvm.meta.next_frame")
commInst(0x256, "@uvm.meta.copy_cursor")
commInst(0x257, "@uvm.meta.close_cursor")
commInst(0x258, "@uvm.meta.cur_func")
commInst(0x259, "@uvm.meta.cur_func_ver")
commInst(0x25a, "@uvm.meta.cur_inst")
commInst(0x25b, "@uvm.meta.dump_keepalives")
commInst(0x25c, "@uvm.meta.pop_frames_to")
commInst(0x25d, "@uvm.meta.push_frame")
commInst(0x25e, "@uvm.meta.enable_watchpoint")
commInst(0x25f, "@uvm.meta.disable_watchpoint")
commInst(0x260, "@uvm.meta.set_trap_handler")
} }
\ No newline at end of file
...@@ -3,11 +3,15 @@ package uvm ...@@ -3,11 +3,15 @@ package uvm
import uvm.types._ import uvm.types._
import uvm.ssavariables._ import uvm.ssavariables._
case class FuncSig(var retTy: Type, var paramTy: Seq[Type]) extends IdentifiedSettable case class FuncSig(var paramTys: Seq[Type], var retTys: Seq[Type]) extends IdentifiedSettable {
override final def toString: String = FuncSig.prettyPrint(this)
}
object FuncSig { object FuncSig {
def prettyPrint(sig: FuncSig): String = def prettyPrint(sig: FuncSig): String = {
"%s (%s)".format(sig.retTy.repr, sig.paramTy.map(_.repr).mkString(" ")) def mkReprList(is: Seq[Identified]): String = is.map(_.repr).mkString(" ")
"(%s) -> (%s)".format(mkReprList(sig.paramTys), mkReprList(sig.retTys))
}
} }
class Function extends GlobalVariable { class Function extends GlobalVariable {
...@@ -22,14 +26,17 @@ class FuncVer extends IdentifiedSettable { ...@@ -22,14 +26,17 @@ class FuncVer extends IdentifiedSettable {
var func: Function = null var func: Function = null
var bbs: Seq[BasicBlock] = null var bbs: Seq[BasicBlock] = null
var entry: BasicBlock = null var ent