Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mu-impl-ref2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mu
mu-impl-ref2
Commits
3323a4b7
Commit
3323a4b7
authored
Oct 10, 2015
by
Kunshan Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: Testing parser...
parent
e8612f5f
Changes
21
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1289 additions
and
1165 deletions
+1289
-1165
src/main/antlr4/UIR.g4
src/main/antlr4/UIR.g4
+49
-43
src/main/scala/uvm/Bundle.scala
src/main/scala/uvm/Bundle.scala
+23
-67
src/main/scala/uvm/Identified.scala
src/main/scala/uvm/Identified.scala
+15
-1
src/main/scala/uvm/controlFlow.scala
src/main/scala/uvm/controlFlow.scala
+14
-5
src/main/scala/uvm/ir/textinput/UIRTextReader.scala
src/main/scala/uvm/ir/textinput/UIRTextReader.scala
+319
-303
src/main/scala/uvm/namespaces.scala
src/main/scala/uvm/namespaces.scala
+11
-0
src/main/scala/uvm/refimpl/clientInterface.scala
src/main/scala/uvm/refimpl/clientInterface.scala
+7
-7
src/main/scala/uvm/refimpl/internals.scala
src/main/scala/uvm/refimpl/internals.scala
+7
-7
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
+3
-3
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
+19
-19
src/main/scala/uvm/refimpl/itpr/boxes.scala
src/main/scala/uvm/refimpl/itpr/boxes.scala
+5
-5
src/main/scala/uvm/ssavariables/ssavariables.scala
src/main/scala/uvm/ssavariables/ssavariables.scala
+17
-20
src/main/scala/uvm/types/types.scala
src/main/scala/uvm/types/types.scala
+11
-25
src/main/scala/uvm/utils/HexDump.scala
src/main/scala/uvm/utils/HexDump.scala
+8
-1
src/test/scala/uvm/NameSpaceSpec.scala
src/test/scala/uvm/NameSpaceSpec.scala
+54
-0
src/test/scala/uvm/ir/textinput/TestingBundlesValidators.scala
...est/scala/uvm/ir/textinput/TestingBundlesValidators.scala
+399
-338
src/test/scala/uvm/ir/textinput/UIRTextReaderSpec.scala
src/test/scala/uvm/ir/textinput/UIRTextReaderSpec.scala
+2
-0
tests/uvm-parsing-test/constants.uir
tests/uvm-parsing-test/constants.uir
+12
-8
tests/uvm-parsing-test/functions.uir
tests/uvm-parsing-test/functions.uir
+4
-4
tests/uvm-parsing-test/instructions.uir
tests/uvm-parsing-test/instructions.uir
+302
-301
tests/uvm-parsing-test/types.uir
tests/uvm-parsing-test/types.uir
+8
-8
No files found.
src/main/antlr4/UIR.g4
View file @
3323a4b7
...
...
@@ -11,7 +11,7 @@ topLevelDef
| globalDef
| funcDecl
| funcDef
|
expose
Def
|
funcExp
Def
;
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
;
expose
Def
funcExp
Def
: '.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
| 'func
ref' '<' funcSig '>' # TypeFuncRef
| 'thread
ref' # TypeThreadRef
| 'stack
ref' # TypeStackRef
| 'tagref64' # TypeTagRef64
| 'vector'
'<' type length=intLiteral '>'
# TypeVector
| '
ptr' '<' type '>' # Type
Ptr
| '
funcptr' '<' funcSig '>' # Type
FuncPtr
| 'vector'
'<' ty=type length=intLiteral '>'
# TypeVector
| '
uptr' '<' ty=type '>' # TypeU
Ptr
| '
ufuncptr' '<' funcSig '>' # TypeU
FuncPtr
;
funcSigConstructor
: retTy=type '(' (paramTy+=type*) ')'
: retTy=type '(' (paramTy
s
+=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
;
bbNam
e
:
name
destClaus
e
:
bb argList
;
bb
: name
;
value
: name
...
...
@@ -195,7 +202,7 @@ funcCallBody
;
excClause
: ('EXC' '(' nor=
bbName exc=bbNam
e ')')?
: ('EXC' '(' nor=
destClause exc=destClaus
e ')')?
;
keepAliveClause
...
...
@@ -225,7 +232,6 @@ curStackClause
newStackClause
: 'PASS_VALUE' '<' type '>' value # NewStackPassValue
| 'PASS_VOID' # NewStackPassVoid
| 'THROW_EXC' exc=value # NewStackThrowExc
;
...
...
src/main/scala/uvm/Bundle.scala
View file @
3323a4b7
...
...
@@ -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
)
}
}
src/main/scala/uvm/Identified.scala
View file @
3323a4b7
...
...
@@ -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
}
}
}
src/main/scala/uvm/controlFlow.scala
View file @
3323a4b7
...
...
@@ -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
]
}
src/main/scala/uvm/ir/textinput/UIRTextReader.scala
View file @
3323a4b7
This diff is collapsed.
Click to expand it.
src/main/scala/uvm/namespaces.scala
View file @
3323a4b7
...
...
@@ -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
))
}
}
src/main/scala/uvm/refimpl/clientInterface.scala
View file @
3323a4b7
...
...
@@ -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
.
fieldTy
s
(
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
.
fieldTy
s
(
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
Type
U
Ptr
(
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
Type
U
Ptr
(
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
Type
U
Ptr
(
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
Type
U
Ptr
(
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
TypeFunc
Ref
(
sig
)
=
func
.
ty
val
f
=
func
.
vb
.
asInstanceOf
[
BoxFunc
].
func
.
getOrElse
{
throw
new
UvmRuntimeException
(
"Attempt to expose NULL Mu function"
)
}
...
...
src/main/scala/uvm/refimpl/internals.scala
View file @
3323a4b7
...
...
@@ -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
=
TypeStack
Ref
()
:=
internal
(
"stack"
)
val
THREAD
=
TypeThread
Ref
()
:=
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
(
Type
U
Ptr
)
val
funcOf
=
LazyPool
(
TypeFunc
Ref
)
val
funcPtrOf
=
LazyPool
(
Type
U
FuncPtr
)
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
.
fieldTy
s
(
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
.
fieldTy
s
(
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
)
...
...
src/main/scala/uvm/refimpl/itpr/ConstantPool.scala
View file @
3323a4b7
...
...
@@ -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
_:
TypeFunc
Ref
=>
BoxFunc
(
None
)
case
_:
TypeThread
Ref
=>
BoxThread
(
None
)
case
_:
TypeStack
Ref
=>
BoxStack
(
None
)
}
case
ConstVector
(
ty
,
elems
)
=>
BoxVector
(
elems
.
map
(
maybeMakeBox
))
case
ConstPointer
(
ty
,
addr
)
=>
BoxPointer
(
addr
)
...
...
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
View file @
3323a4b7
...
...
@@ -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
TypeFunc
Ref
(
_
)
=>
doFunc
(
b1
,
b2
,
br
)
case
TypeStack
Ref
()
=>
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
(
TypeFunc
Ref
(
_
),
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
()
...
...
src/main/scala/uvm/refimpl/itpr/boxes.scala
View file @
3323a4b7
...
...
@@ -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
_:
TypeFunc
Ref
=>
BoxFunc
(
None
)
case
_:
TypeStack
Ref
=>
BoxStack
(
None
)
case
_:
TypeThread
Ref
=>
BoxThread
(
None
)
case
_:
TypeTagRef64
=>
BoxTagRef64
(
0L
)
case
_:
TypePtr
=>
BoxPointer
(
0L
)
case
_:
TypeFuncPtr
=>
BoxPointer
(
0L
)
case
_:
Type
U
Ptr
=>
BoxPointer
(
0L
)
case
_:
Type
U
FuncPtr
=>
BoxPointer
(
0L
)
}
}
\ No newline at end of file
src/main/scala/uvm/ssavariables/ssavariables.scala
View file @
3323a4b7
...
...
@@ -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
(
va
r
retTy
:
Type
,
var
retVal
:
SSAVariable
)
extends
AbstractRet
case
class
InstRet
(
va
l
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
,
...
...
src/main/scala/uvm/types/types.scala
View file @
3323a4b7
...
...
@@ -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
fieldTy
s
:
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