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
c589e5c8
Commit
c589e5c8
authored
Sep 15, 2015
by
Kunshan Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP: Callback
parent
a8ffa3e5
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
68 additions
and
29 deletions
+68
-29
src/main/scala/uvm/refimpl/MicroVM.scala
src/main/scala/uvm/refimpl/MicroVM.scala
+2
-2
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
+1
-1
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
+4
-3
src/main/scala/uvm/refimpl/nat/NativeCallHelper.scala
src/main/scala/uvm/refimpl/nat/NativeCallHelper.scala
+50
-23
src/main/scala/uvm/refimpl/nat/NativeSupport.scala
src/main/scala/uvm/refimpl/nat/NativeSupport.scala
+11
-0
No files found.
src/main/scala/uvm/refimpl/MicroVM.scala
View file @
c589e5c8
...
...
@@ -7,7 +7,7 @@ import uvm.refimpl.mem.TypeSizes.Word
import
scala.collection.mutable.HashSet
import
uvm.ir.textinput.UIRTextReader
import
uvm.ir.textinput.IDFactory
import
uvm.refimpl.nat.NativeHelper
import
uvm.refimpl.nat.Native
Call
Helper
object
MicroVM
{
val
DEFAULT_HEAP_SIZE
:
Word
=
4L
*
1024L
*
1024L
;
// 4MiB
...
...
@@ -28,7 +28,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
private
implicit
val
memorySupport
=
memoryManager
.
memorySupport
val
native
Helper
=
new
Native
Helper
()
val
native
CallHelper
=
new
NativeCall
Helper
()
val
threadStackManager
=
new
ThreadStackManager
()
val
trapManager
=
new
TrapManager
()
...
...
src/main/scala/uvm/refimpl/itpr/InterpreterThread.scala
View file @
c589e5c8
...
...
@@ -780,7 +780,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val
argBoxes
=
argList
.
map
(
boxOf
)
val
retBox
=
boxOf
(
i
)
microVM
.
nativeHelper
.
callNative
(
sig
,
addr
,
argBoxes
,
retBox
)
microVM
.
native
Call
Helper
.
callNative
(
sig
,
addr
,
argBoxes
,
retBox
)
continueNormally
()
}
...
...
src/main/scala/uvm/refimpl/mem/MemorySupport.scala
View file @
c589e5c8
...
...
@@ -6,11 +6,15 @@ import uvm.ssavariables.AtomicRMWOptr._
import
jnr.ffi.
{
Runtime
,
Memory
,
Pointer
}
import
uvm.refimpl.UvmRuntimeException
import
uvm.refimpl.UvmIllegalMemoryAccessException
import
uvm.refimpl.nat.NativeSupport
/**
* Support for native memory access. Backed by JNR-FFI.
*/
class
MemorySupport
(
val
muMemorySize
:
Word
)
{
val
jnrRuntime
=
NativeSupport
.
jnrRuntime
val
theMemory
=
NativeSupport
.
theMemory
val
SIZE_LIMIT
:
Word
=
Int
.
MaxValue
.
toLong
if
(
muMemorySize
>
SIZE_LIMIT
)
{
...
...
@@ -18,13 +22,10 @@ class MemorySupport(val muMemorySize: Word) {
" Due to the limitation of JNR-FFI, the maximum available memory size is %d bytes."
.
format
(
muMemorySize
,
SIZE_LIMIT
))
}
val
jnrRuntime
=
Runtime
.
getSystemRuntime
val
muMemory
=
Memory
.
allocateDirect
(
jnrRuntime
,
muMemorySize
.
toInt
,
true
)
val
muMemoryBegin
=
muMemory
.
address
()
val
muMemoryEnd
=
muMemoryBegin
+
muMemorySize
val
theMemory
=
Pointer
.
wrap
(
jnrRuntime
,
0L
)
def
isInMuMemory
(
addr
:
Word
)
:
Boolean
=
muMemoryBegin
<=
addr
&&
addr
<
muMemoryEnd
def
assertInMuMemory
(
inMu
:
Boolean
,
addr
:
Word
)
:
Unit
=
{
...
...
src/main/scala/uvm/refimpl/nat/
nativeHelpers
.scala
→
src/main/scala/uvm/refimpl/nat/
NativeCallHelper
.scala
View file @
c589e5c8
...
...
@@ -11,21 +11,25 @@ import uvm.refimpl.itpr._
import
uvm.refimpl.itpr.ValueBox
import
uvm.refimpl.mem.TypeSizes
import
uvm.refimpl.mem.TypeSizes.Word
import
uvm.
{
Function
=>
MFunc
}
import
uvm.types._
import
uvm.types.
{
Type
=>
MType
}
import
uvm.utils.LazyPool
import
uvm.utils.HexDump
import
scala.collection.mutable.HashMap
import
com.kenai.jffi.Closure
object
NativeHelper
{
object
Native
Call
Helper
{
val
logger
=
Logger
(
LoggerFactory
.
getLogger
(
getClass
.
getName
))
}
/**
* Helps calling native functions. Based on JFFI.
* Helps calling native functions
and supports callbacks from native
. Based on JFFI.
*/
class
NativeHelper
{
import
NativeHelper._
class
Native
Call
Helper
{
import
Native
Call
Helper._
/** A mapping of Mu types to JFFI types. Cached for struct types. */
val
jffiTypePool
:
LazyPool
[
MType
,
JType
]
=
LazyPool
{
case
TypeVoid
()
=>
JType
.
VOID
case
TypeInt
(
8
)
=>
JType
.
SINT8
...
...
@@ -44,6 +48,7 @@ class NativeHelper {
case
t
=>
throw
new
UvmRefImplException
(
"Type %s cannot be used in native calls."
.
format
(
t
.
repr
))
}
/** A mapping from referenced C functions (signature, function pointer) to JFFI functions. Cached. */
val
jffiFuncPool
=
LazyPool
[(
FuncSig
,
Word
)
,
JFunction
]
{
case
(
sig
,
funcAddr
)
=>
{
val
jParamTypes
=
sig
.
paramTy
.
map
(
jffiTypePool
.
apply
)
...
...
@@ -51,7 +56,26 @@ class NativeHelper {
new
JFunction
(
funcAddr
,
jRetTy
,
jParamTypes
:
_
*
)
}
}
/**
* A dynamically-exposed Mu function. A Mu function may be exposed many times. Each DynExpFunc corresponds to one
* such callable instance.
* <p>
* A ".expose" definition will permanently create an instance.
* <p>
* The "@uvm.native.expose" instruction will also create one such instance. Such instances can be removed later by
* "@uvm.native.unexpose". The equivalent API calls do the same.
*/
class
DynExpFunc
(
val
muFunc
:
MFunc
,
val
closureHandle
:
Closure.Handle
)
{
val
addr
=
closureHandle
.
getAddress
()
}
val
exposedFuncs
=
new
HashMap
[
Word
,
DynExpFunc
]()
def
exposeFunc
(
muFunc
:
MFunc
,
cookie
:
Word
)
:
Word
=
{
???
}
private
def
putArgToBuf
(
buf
:
ByteBuffer
,
off
:
Int
,
mty
:
MType
,
vb
:
ValueBox
)
:
Unit
=
{
mty
match
{
case
TypeInt
(
8
)
=>
buf
.
put
(
off
,
vb
.
asInstanceOf
[
BoxInt
].
value
.
toByte
)
...
...
@@ -82,6 +106,7 @@ class NativeHelper {
case
TypeFloat
()
=>
hib
.
putFloat
(
vb
.
asInstanceOf
[
BoxFloat
].
value
)
case
TypeDouble
()
=>
hib
.
putDouble
(
vb
.
asInstanceOf
[
BoxDouble
].
value
)
case
TypeStruct
(
flds
)
=>
{
// Always allocate more space so that C may access the word that contains the byte instead of just the byte.
val
buf
=
ByteBuffer
.
allocate
(
TypeSizes
.
alignUp
(
TypeSizes
.
sizeOf
(
mty
),
FORCE_ALIGN_UP
).
intValue
())
buf
.
order
(
ByteOrder
.
LITTLE_ENDIAN
)
putArgToBuf
(
buf
,
0
,
mty
,
vb
)
...
...
@@ -92,6 +117,26 @@ class NativeHelper {
}
}
private
def
getArgFromBuf
(
buf
:
ByteBuffer
,
off
:
Int
,
mty
:
MType
,
vb
:
ValueBox
)
:
Unit
=
{
mty
match
{
case
TypeInt
(
8
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
get
(
off
),
8
)
case
TypeInt
(
16
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getShort
(
off
),
16
)
case
TypeInt
(
32
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getInt
(
off
),
32
)
case
TypeInt
(
64
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getLong
(
off
),
64
)
case
TypeFloat
()
=>
vb
.
asInstanceOf
[
BoxFloat
].
value
=
buf
.
getFloat
(
off
)
case
TypeDouble
()
=>
vb
.
asInstanceOf
[
BoxDouble
].
value
=
buf
.
getDouble
(
off
)
case
s
@
TypeStruct
(
flds
)
=>
{
val
fldvbs
=
vb
.
asInstanceOf
[
BoxStruct
].
values
for
(((
fty
,
fvb
),
i
)
<-
(
flds
zip
fldvbs
).
zipWithIndex
)
{
val
off2
=
TypeSizes
.
fieldOffsetOf
(
s
,
i
)
getArgFromBuf
(
buf
,
off
+
off2
.
toInt
,
fty
,
fvb
)
}
}
case
_:
AbstractPointerType
=>
vb
.
asInstanceOf
[
BoxPointer
].
addr
=
buf
.
getLong
(
off
)
}
}
/** Call a native (C) function. */
def
callNative
(
sig
:
FuncSig
,
func
:
Word
,
args
:
Seq
[
ValueBox
],
retBox
:
ValueBox
)
:
Unit
=
{
val
jFunc
=
jffiFuncPool
((
sig
,
func
))
...
...
@@ -144,22 +189,4 @@ class NativeHelper {
}
}
private
def
getArgFromBuf
(
buf
:
ByteBuffer
,
off
:
Int
,
mty
:
MType
,
vb
:
ValueBox
)
:
Unit
=
{
mty
match
{
case
TypeInt
(
8
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
get
(
off
),
8
)
case
TypeInt
(
16
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getShort
(
off
),
16
)
case
TypeInt
(
32
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getInt
(
off
),
32
)
case
TypeInt
(
64
)
=>
vb
.
asInstanceOf
[
BoxInt
].
value
=
OpHelper
.
trunc
(
buf
.
getLong
(
off
),
64
)
case
TypeFloat
()
=>
vb
.
asInstanceOf
[
BoxFloat
].
value
=
buf
.
getFloat
(
off
)
case
TypeDouble
()
=>
vb
.
asInstanceOf
[
BoxDouble
].
value
=
buf
.
getDouble
(
off
)
case
s
@
TypeStruct
(
flds
)
=>
{
val
fldvbs
=
vb
.
asInstanceOf
[
BoxStruct
].
values
for
(((
fty
,
fvb
),
i
)
<-
(
flds
zip
fldvbs
).
zipWithIndex
)
{
val
off2
=
TypeSizes
.
fieldOffsetOf
(
s
,
i
)
getArgFromBuf
(
buf
,
off
+
off2
.
toInt
,
fty
,
fvb
)
}
}
case
_:
AbstractPointerType
=>
vb
.
asInstanceOf
[
BoxPointer
].
addr
=
buf
.
getLong
(
off
)
}
}
}
\ No newline at end of file
src/main/scala/uvm/refimpl/nat/NativeSupport.scala
0 → 100644
View file @
c589e5c8
package
uvm.refimpl.nat
import
jnr.ffi.
{
Runtime
,
Memory
,
Pointer
}
/**
* Holder of JNR-specific resources.
*/
object
NativeSupport
{
val
jnrRuntime
=
Runtime
.
getSystemRuntime
val
theMemory
=
Pointer
.
wrap
(
jnrRuntime
,
0L
)
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment