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
.tmpBin
.d8_history
hs_err_pid*.log
/bin/
......@@ -2,11 +2,13 @@ Mu Reference Implementation version 2
=====================================
This project is the current reference implementation of Mu, the micro virtual
machine designed by [The Micro Virtual Machine Project](http://microvm.org). It
implements the [Mu Specification version
2](https://github.com/microvm/microvm-spec/wiki)
machine designed by [The Micro Virtual Machine Project](http://microvm.org).
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).
[microvm-refimpl](https://github.com/microvm-project/microvm-refimpl) is the
previous reference implementation.
......@@ -21,7 +23,7 @@ How to compile
`brew install scala`.
* Install [sbt](http://www.scala-sbt.org/) 0.13. If you use Mac and Homebrew,
`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).
* Clone this repository:
......@@ -32,9 +34,7 @@ git clone git@github.com:microvm/microvm-refimpl2.git
* In the directory `microvm-refimpl2`, do the following:
```bash
sbt update
sbt antlr4:antlr4Generate
sbt eclipse
sbt update genSrc eclipse
```
* 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).
To download all dependencies from the Maven central repository, invoke `sbt
update`.
To generate the Mu IR parser from its Antlr grammar, invoke `sbt
antlr4:antlr4Generate`. The generated sources will be in
`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 the Mu IR parser from the Antlr grammar, invoke `sbt genSrc`. The
generated sources will be in the `target/scala-2.11/src_managed` directory.
To generate an Eclipse project, install the [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`
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",
libraryDependencies := Seq(
"org.antlr" % "antlr4" % "4.5.1",
version := "2.1.0",
description := "The second reference implementation of Mu, the micro virtual machine",
licenses := Seq("CC BY-SA 4.0" -> url("https://creativecommons.org/licenses/by-sa/4.0/legalcode")),
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.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",
"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,
antlr4Settings
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen"),
antlr4PackageName in Antlr4 := Some("uvm.ir.textinput.gen")
antlr4GenListener in Antlr4 := false,
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
;
......@@ -11,7 +11,7 @@ topLevelDef
| globalDef
| funcDecl
| funcDef
| exposeDef
| funcExpDef
;
typeDef
......@@ -35,10 +35,10 @@ 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
;
......@@ -46,33 +46,32 @@ typeConstructor
: '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' '<' fieldTys+=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*) ')'
: '(' paramTys+=type* ')' '->' '(' retTys+=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,19 +99,32 @@ basicBlock
;
label
: name ':'
: name '(' bbParam* ')' excParam? ':'
;
bbParam
: '<' ty=type '>' name
;
excParam
: '[' name ']'
;
instResults
: results+=name
| '(' results+=name* ')'
;
inst
: (name '=')? instBody
: (instResults '=')? ('[' name ']')? instBody
;
instBody
// Integer/FP Arithmetic
: binop '<' type '>' op1=value op2=value excClause # InstBinOp
: binop '<' ty=type '>' op1=value op2=value excClause # InstBinOp
// Integer/FP Comparison
| cmpop '<' type '>' op1=value op2=value # InstCmp
| cmpop '<' ty=type '>' op1=value op2=value # InstCmp
// Conversions
| convop '<' fromTy=type toTy=type '>' opnd=value # InstConversion
......@@ -121,27 +133,23 @@ 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' '<' ty=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' retVals # 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
| '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
......@@ -155,7 +163,6 @@ instBody
| 'GETFIELDIREF' (ptr='PTR'?) '<' refTy=type index=intLiteral '>' opnd=value # InstGetFieldIRef
| 'GETELEMIREF' (ptr='PTR'?) '<' refTy=type indTy=type '>' opnd=value index=value # InstGetElemIRef
| 'SHIFTIREF' (ptr='PTR'?) '<' refTy=type offTy=type '>' opnd=value offset=value # InstShiftIRef
| 'GETFIXEDPARTIREF' (ptr='PTR'?) '<' refTy=type '>' opnd=value # InstGetFixedPartIRef
| 'GETVARPARTIREF' (ptr='PTR'?) '<' refTy=type '>' opnd=value # InstGetVarPartIRef
| 'LOAD' (ptr='PTR'?) memord? '<' type '>' loc=value excClause # InstLoad
......@@ -167,22 +174,32 @@ instBody
| 'FENCE' memord # InstFence
// Trap
| 'TRAP' '<' type '>' excClause keepAliveClause # InstTrap
| 'WATCHPOINT' wpid=intLiteral '<' type '>'
dis=bbName ena=bbName ('WPEXC' '(' wpExc=bbName ')')? keepAliveClause # InstWatchPoint
| 'TRAP' typeList excClause keepAliveClause # InstTrap
| 'WATCHPOINT' wpid=intLiteral typeList
dis=destClause ena=destClause ('WPEXC' '(' wpExc=destClause ')')? keepAliveClause # InstWatchPoint
| 'WPBRANCH' wpid=intLiteral dis=destClause ena=destClause # InstWPBranch
// Foreign Function Interface
| 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList keepAliveClause # InstCCall
| 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList excClause keepAliveClause # InstCCall
// Thread and Stack Operations
| 'NEWSTACK' funcCallBody excClause # InstNewStack
| 'NEWTHREAD' stack=value newStackClause excClause # InstNewThread
| 'SWAPSTACK' swappee=value curStackClause newStackClause excClause keepAliveClause # InstSwapStack
// Common Instructions
| 'COMMINST' nam=GLOBAL_NAME flagList? typeList? funcSigList? argList? excClause keepAliveClause # InstCommInst
;
bbName
retVals
: '(' vals+=value* ')'
| vals+=value
;
destClause
: bb argList
;
bb
: name
;
......@@ -195,7 +212,7 @@ funcCallBody
;
excClause
: ('EXC' '(' nor=bbName exc=bbName ')')?
: ('EXC' '(' nor=destClause exc=destClause ')')?
;
keepAliveClause
......@@ -219,13 +236,12 @@ argList
;
curStackClause
: 'RET_WITH' '<' type '>' # CurStackRetWith
: 'RET_WITH' typeList # CurStackRetWith
| 'KILL_OLD' # CurStackKillOld
;
newStackClause
: 'PASS_VALUE' '<' type '>' value # NewStackPassValue
| 'PASS_VOID' # NewStackPassVoid
: 'PASS_VALUES' typeList argList # NewStackPassValue
| 'THROW_EXC' exc=value # NewStackThrowExc
;
......
......@@ -2,12 +2,13 @@ package uvm
import uvm.types._
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.
*
* + allNs // All Identified entities
* + allNs // All globally Identified entities
* + typeNs // All types
* + funcSigNs // All function signatures
* + funcVerNs // All function versions
......@@ -17,90 +18,107 @@ class Bundle {
* + globalCellNs // Global cells
* + funcNs // Functions
* + expFuncNs // Exposed functions
* + localVarNs // Local variables (per function version)
* + localVarNs // Local variables (per basic block)
* + 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 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]()
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]()
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 = {
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 defFuncNs = new SimpleNamespace[Function]
}
/**
* 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]) {
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)
// def assertPresent[T <: Identified](ns: NestedNamespace[T], obj: T): Unit = {
// assert(ns.get(obj.id) == Some(obj))
// if (obj.id == 65731) {
// printf("Obj[65731] found in ns " + ns)
// }
// ns.maybeParent match {
// 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", e);
}
" global cell is not allowed: %s".format(cand.repr), 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 redefineFunctions(newNs: Namespace[FuncVer]) {
for (fv <- newNs.all) {
fv.func.versions = fv :: fv.func.versions
}
}
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
private def mergeLocalNamespaces(newBundle: TrantientBundle) {
for (fv <- newBundle.funcVerNs.all) {
fv.bbNs.reparent(allNs)
for (bb <- fv.bbs) {
bb.localVarNs.reparent(allNs)
bb.localInstNs.reparent(allNs)
}
}