Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
djinni
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
djinni
Commits
4b803ef0
Commit
4b803ef0
authored
Mar 01, 2015
by
Miro Knejp
Committed by
Jacob Potter
Apr 17, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce marshalling object for JNI code generator
parent
b2e75f1a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
104 additions
and
76 deletions
+104
-76
src/source/JNIGenerator.scala
src/source/JNIGenerator.scala
+49
-76
src/source/JNIMarshal.scala
src/source/JNIMarshal.scala
+55
-0
No files found.
src/source/JNIGenerator.scala
View file @
4b803ef0
...
@@ -25,6 +25,9 @@ import scala.collection.mutable
...
@@ -25,6 +25,9 @@ import scala.collection.mutable
class
JNIGenerator
(
spec
:
Spec
)
extends
Generator
(
spec
)
{
class
JNIGenerator
(
spec
:
Spec
)
extends
Generator
(
spec
)
{
val
jniMarshal
=
new
JNIMarshal
(
spec
)
val
cppMarshal
=
new
CppMarshal
(
spec
)
val
javaMarshal
=
new
JavaMarshal
(
spec
)
val
jniBaseLibClassIdentStyle
=
IdentStyle
.
prefix
(
"H"
,
IdentStyle
.
camelUpper
)
val
jniBaseLibClassIdentStyle
=
IdentStyle
.
prefix
(
"H"
,
IdentStyle
.
camelUpper
)
val
jniBaseLibFileIdentStyle
=
jniBaseLibClassIdentStyle
val
jniBaseLibFileIdentStyle
=
jniBaseLibClassIdentStyle
...
@@ -55,23 +58,22 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -55,23 +58,22 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
override
def
generateEnum
(
origin
:
String
,
ident
:
Ident
,
doc
:
Doc
,
e
:
Enum
)
{
override
def
generateEnum
(
origin
:
String
,
ident
:
Ident
,
doc
:
Doc
,
e
:
Enum
)
{
val
refs
=
new
JNIRefs
(
ident
.
name
)
val
refs
=
new
JNIRefs
(
ident
.
name
)
val
self
=
idCpp
.
enumType
(
ident
)
val
jniHelper
=
jniMarshal
.
helperClass
(
ident
)
val
selfQ
=
withNs
(
spec
.
cppNamespace
,
self
)
val
cppSelf
=
cppMarshal
.
fqTypename
(
ident
,
e
)
val
jniClassName
=
spec
.
jniClassIdentStyle
(
ident
)
writeJniHppFile
(
ident
,
origin
,
Iterable
.
concat
(
refs
.
jniHpp
,
refs
.
jniCpp
),
Nil
,
w
=>
{
writeJniHppFile
(
ident
,
origin
,
Iterable
.
concat
(
refs
.
jniHpp
,
refs
.
jniCpp
),
Nil
,
w
=>
{
w
.
w
(
s
"class $jni
ClassName
final : djinni::JniEnum"
).
bracedSemi
{
w
.
w
(
s
"class $jni
Helper
final : djinni::JniEnum"
).
bracedSemi
{
w
.
wlOutdent
(
"public:"
)
w
.
wlOutdent
(
"public:"
)
w
.
wl
(
s
"using CppType = $
selfQ
;"
)
w
.
wl
(
s
"using CppType = $
cppSelf
;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
w
.
wl
w
.
wl
(
s
"static jobject toJava(JNIEnv* jniEnv, $
selfQ c) { return djinni::JniClass<$jniClassName
>::get().create(jniEnv, static_cast<int>(c)).release(); }"
)
w
.
wl
(
s
"static jobject toJava(JNIEnv* jniEnv, $
cppSelf c) { return djinni::JniClass<$jniHelper
>::get().create(jniEnv, static_cast<int>(c)).release(); }"
)
w
.
wl
(
s
"static $
selfQ fromJava(JNIEnv* jniEnv, jobject j) { return static_cast<$selfQ>(djinni::JniClass<$jniClassName
>::get().ordinal(jniEnv, j)); }"
)
w
.
wl
(
s
"static $
cppSelf fromJava(JNIEnv* jniEnv, jobject j) { return static_cast<$cppSelf>(djinni::JniClass<$jniHelper
>::get().ordinal(jniEnv, j)); }"
)
w
.
wl
w
.
wl
w
.
wlOutdent
(
"private:"
)
w
.
wlOutdent
(
"private:"
)
val
classLookup
=
q
(
toJavaClassLookup
(
ident
,
spec
.
javaPackag
e
))
val
classLookup
=
q
(
jniMarshal
.
undecoratedTypename
(
ident
,
e
))
w
.
wl
(
s
"$jni
ClassName
() : JniEnum($classLookup) {}"
)
w
.
wl
(
s
"$jni
Helper
() : JniEnum($classLookup) {}"
)
w
.
wl
(
s
"friend class djinni::JniClass<$jni
ClassName
>;"
)
w
.
wl
(
s
"friend class djinni::JniClass<$jni
Helper
>;"
)
}
}
})
})
}
}
...
@@ -79,35 +81,34 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -79,35 +81,34 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
override
def
generateRecord
(
origin
:
String
,
ident
:
Ident
,
doc
:
Doc
,
params
:
Seq
[
TypeParam
],
r
:
Record
)
{
override
def
generateRecord
(
origin
:
String
,
ident
:
Ident
,
doc
:
Doc
,
params
:
Seq
[
TypeParam
],
r
:
Record
)
{
val
refs
=
new
JNIRefs
(
ident
.
name
)
val
refs
=
new
JNIRefs
(
ident
.
name
)
r
.
fields
.
foreach
(
f
=>
refs
.
find
(
f
.
ty
))
r
.
fields
.
foreach
(
f
=>
refs
.
find
(
f
.
ty
))
val
jniClassName
=
spec
.
jniClassIdentStyle
(
ident
)
val
fqJniClassName
=
withNs
(
Some
(
spec
.
jniNamespace
),
jniClassName
)
val
self
=
idCpp
.
ty
(
ident
)
val
jniHelper
=
jniMarshal
.
helperClass
(
ident
)
val
selfQ
=
withNs
(
spec
.
cppNamespace
,
self
)
+
cppTypeArgs
(
params
)
// Qualified "self"
val
cppSelf
=
cppMarshal
.
fqTypename
(
ident
,
r
)
+
cppTypeArgs
(
params
)
val
fqJniHelper
=
jniMarshal
.
fqHelperClass
(
ident
)
def
writeJniPrototype
(
w
:
IndentWriter
)
{
def
writeJniPrototype
(
w
:
IndentWriter
)
{
writeJniTypeParams
(
w
,
params
)
writeJniTypeParams
(
w
,
params
)
w
.
w
(
s
"class $jni
ClassName
final"
).
bracedSemi
{
w
.
w
(
s
"class $jni
Helper
final"
).
bracedSemi
{
w
.
wlOutdent
(
"public:"
)
w
.
wlOutdent
(
"public:"
)
w
.
wl
(
s
"using CppType = $
selfQ
;"
)
w
.
wl
(
s
"using CppType = $
cppSelf
;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
w
.
wl
w
.
wl
(
s
"static jobject toJava(JNIEnv*, $
selfQ
);"
)
w
.
wl
(
s
"static jobject toJava(JNIEnv*, $
cppSelf
);"
)
w
.
wl
(
s
"static $
selfQ
fromJava(JNIEnv*, jobject);"
)
w
.
wl
(
s
"static $
cppSelf
fromJava(JNIEnv*, jobject);"
)
w
.
wl
w
.
wl
val
classLookup
=
q
(
toJavaClassLookup
(
ident
,
spec
.
javaPackage
))
val
classLookup
=
q
(
jniMarshal
.
undecoratedTypename
(
ident
,
r
))
w
.
wl
(
s
"const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass($classLookup) };"
)
w
.
wl
(
s
"const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass($classLookup) };"
)
val
constructorSig
=
q
(
toJavaMethodSig
(
spec
.
javaPackage
,
r
.
fields
,
None
))
val
constructorSig
=
q
(
toJavaMethodSig
(
spec
.
javaPackage
,
r
.
fields
,
None
))
w
.
wl
(
s
"const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), ${q("
<
init
>
")}, $constructorSig) };"
)
w
.
wl
(
s
"const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), ${q("
<
init
>
")}, $constructorSig) };"
)
for
(
f
<-
r
.
fields
)
{
for
(
f
<-
r
.
fields
)
{
val
javaFieldName
=
idJava
.
field
(
f
.
ident
)
val
javaFieldName
=
idJava
.
field
(
f
.
ident
)
val
javaSig
=
q
(
toJavaTypeSig
(
f
.
ty
,
spec
.
javaPackage
))
val
javaSig
=
q
(
jniMarshal
.
typename
(
f
.
ty
))
w
.
wl
(
s
"const jfieldID field_$javaFieldName { djinni::jniGetFieldID(clazz.get(), ${q(javaFieldName)}, $javaSig) };"
)
w
.
wl
(
s
"const jfieldID field_$javaFieldName { djinni::jniGetFieldID(clazz.get(), ${q(javaFieldName)}, $javaSig) };"
)
}
}
w
.
wl
w
.
wl
w
.
wlOutdent
(
"private:"
)
w
.
wlOutdent
(
"private:"
)
w
.
wl
(
s
"$jni
ClassName
() {}"
)
w
.
wl
(
s
"$jni
Helper
() {}"
)
w
.
wl
(
s
"friend class djinni::JniClass<$fqJni
ClassName
>;"
)
w
.
wl
(
s
"friend class djinni::JniClass<$fqJni
Helper
>;"
)
}
}
}
}
...
@@ -115,7 +116,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -115,7 +116,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
writeJniTypeParams
(
w
,
params
)
writeJniTypeParams
(
w
,
params
)
val
dataVar
=
if
(
r
.
fields
.
nonEmpty
)
" c"
else
""
val
dataVar
=
if
(
r
.
fields
.
nonEmpty
)
" c"
else
""
w
.
w
(
s
"jobject $jni
ClassName::toJava(JNIEnv* jniEnv, $selfQ
$dataVar)"
).
braced
{
w
.
w
(
s
"jobject $jni
Helper::toJava(JNIEnv* jniEnv, $cppSelf
$dataVar)"
).
braced
{
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
val
jniArgs
=
mutable
.
ListBuffer
[
String
]()
val
jniArgs
=
mutable
.
ListBuffer
[
String
]()
for
(
f
<-
r
.
fields
)
{
for
(
f
<-
r
.
fields
)
{
...
@@ -125,7 +126,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -125,7 +126,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
val
jniLocalRead
=
storeLocal
(
w
,
jniLocal
,
f
.
ty
,
s
"$jniHelperClass::toJava(jniEnv, c.$cppFieldName)"
)
val
jniLocalRead
=
storeLocal
(
w
,
jniLocal
,
f
.
ty
,
s
"$jniHelperClass::toJava(jniEnv, c.$cppFieldName)"
)
jniArgs
.
append
(
jniLocalRead
)
jniArgs
.
append
(
jniLocalRead
)
}
}
w
.
wl
(
s
"const auto & data = djinni::JniClass<$fqJni
ClassName
>::get();"
)
w
.
wl
(
s
"const auto & data = djinni::JniClass<$fqJni
Helper
>::get();"
)
val
argList
=
jniArgs
.
map
(
", "
+
_
).
mkString
(
""
)
val
argList
=
jniArgs
.
map
(
", "
+
_
).
mkString
(
""
)
w
.
wl
(
s
"jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor$argList);"
)
w
.
wl
(
s
"jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor$argList);"
)
w
.
wl
(
s
"djinni::jniExceptionCheck(jniEnv);"
)
w
.
wl
(
s
"djinni::jniExceptionCheck(jniEnv);"
)
...
@@ -134,11 +135,11 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -134,11 +135,11 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w
.
wl
w
.
wl
writeJniTypeParams
(
w
,
params
)
writeJniTypeParams
(
w
,
params
)
if
(
r
.
fields
.
nonEmpty
)
{
if
(
r
.
fields
.
nonEmpty
)
{
w
.
w
(
s
"$
selfQ $jniClassName
::fromJava(JNIEnv* jniEnv, jobject j)"
).
braced
{
w
.
w
(
s
"$
cppSelf $jniHelper
::fromJava(JNIEnv* jniEnv, jobject j)"
).
braced
{
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
w
.
wl
(
s
"assert(j != nullptr);"
)
w
.
wl
(
s
"assert(j != nullptr);"
)
w
.
wl
(
s
"const auto & data = djinni::JniClass<$fqJni
ClassName
>::get();"
)
w
.
wl
(
s
"const auto & data = djinni::JniClass<$fqJni
Helper
>::get();"
)
w
.
wl
(
s
"return $
selfQ
("
).
nested
{
w
.
wl
(
s
"return $
cppSelf
("
).
nested
{
val
skipFirst
=
SkipFirst
()
val
skipFirst
=
SkipFirst
()
for
(
f
<-
r
.
fields
)
{
for
(
f
<-
r
.
fields
)
{
skipFirst
{
w
.
wl
(
","
)
}
skipFirst
{
w
.
wl
(
","
)
}
...
@@ -155,10 +156,10 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -155,10 +156,10 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
}
}
}
}
}
else
{
}
else
{
w
.
w
(
s
"$
selfQ $jniClassName
::fromJava(JNIEnv*, jobject j)"
).
braced
{
w
.
w
(
s
"$
cppSelf $jniHelper
::fromJava(JNIEnv*, jobject j)"
).
braced
{
w
.
wl
(
"assert(j != nullptr);"
)
w
.
wl
(
"assert(j != nullptr);"
)
w
.
wl
(
"(void) j; // Suppress unused error in release build"
)
w
.
wl
(
"(void) j; // Suppress unused error in release build"
)
w
.
wl
(
s
"return $
selfQ
();"
)
w
.
wl
(
s
"return $
cppSelf
();"
)
}
}
}
}
...
@@ -177,23 +178,22 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -177,23 +178,22 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
refs
.
find
(
c
.
ty
)
refs
.
find
(
c
.
ty
)
})
})
val
self
=
idCpp
.
ty
(
ident
)
val
jniSelf
=
jniMarshal
.
helperClass
(
ident
)
val
selfQ
=
withNs
(
spec
.
cppNamespace
,
self
)
+
cppTypeArgs
(
typeParams
)
// Qualified "self"
val
cppSelf
=
cppMarshal
.
fqTypename
(
ident
,
i
)
+
cppTypeArgs
(
typeParams
)
val
fqJniClassName
=
jniMarshal
.
fqHelperClass
(
ident
)
val
jniClassName
=
spec
.
jniClassIdentStyle
(
ident
)
val
classLookup
=
jniMarshal
.
undecoratedTypename
(
ident
,
i
)
val
fqJniClassName
=
withNs
(
Some
(
spec
.
jniNamespace
),
jniClassName
)
val
baseType
=
s
"djinni::JniInterface<$cppSelf, $jniSelf>"
val
classLookup
=
toJavaClassLookup
(
ident
,
spec
.
javaPackage
)
val
baseType
=
s
"djinni::JniInterface<$selfQ, $jniClassName>"
def
writeJniPrototype
(
w
:
IndentWriter
)
{
def
writeJniPrototype
(
w
:
IndentWriter
)
{
writeJniTypeParams
(
w
,
typeParams
)
writeJniTypeParams
(
w
,
typeParams
)
w
.
w
(
s
"class $jni
ClassName
final : $baseType"
).
bracedSemi
{
w
.
w
(
s
"class $jni
Self
final : $baseType"
).
bracedSemi
{
w
.
wlOutdent
(
s
"public:"
)
w
.
wlOutdent
(
s
"public:"
)
w
.
wl
(
s
"using CppType = std::shared_ptr<$
selfQ
>;"
)
w
.
wl
(
s
"using CppType = std::shared_ptr<$
cppSelf
>;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
(
s
"using JniType = jobject;"
)
w
.
wl
w
.
wl
w
.
wl
(
s
"static jobject toJava(JNIEnv* jniEnv, std::shared_ptr<$
selfQ
> c) { return djinni::JniClass<$fqJniClassName>::get()._toJava(jniEnv, c); }"
)
w
.
wl
(
s
"static jobject toJava(JNIEnv* jniEnv, std::shared_ptr<$
cppSelf
> c) { return djinni::JniClass<$fqJniClassName>::get()._toJava(jniEnv, c); }"
)
w
.
wl
(
s
"static std::shared_ptr<$
selfQ
> fromJava(JNIEnv* jniEnv, jobject j) { return djinni::JniClass<$fqJniClassName>::get()._fromJava(jniEnv, j); }"
)
w
.
wl
(
s
"static std::shared_ptr<$
cppSelf
> fromJava(JNIEnv* jniEnv, jobject j) { return djinni::JniClass<$fqJniClassName>::get()._fromJava(jniEnv, j); }"
)
w
.
wl
w
.
wl
if
(
i
.
ext
.
java
)
{
if
(
i
.
ext
.
java
)
{
w
.
wl
(
s
"const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass(${q(classLookup)}) };"
)
w
.
wl
(
s
"const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass(${q(classLookup)}) };"
)
...
@@ -216,13 +216,13 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -216,13 +216,13 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w
.
wl
w
.
wl
w
.
wlOutdent
(
s
"private:"
)
w
.
wlOutdent
(
s
"private:"
)
w
.
wl
(
s
"using djinni::JavaProxyCacheEntry::getGlobalRef;"
)
w
.
wl
(
s
"using djinni::JavaProxyCacheEntry::getGlobalRef;"
)
w
.
wl
(
s
"friend class djinni::JniInterface<$
selfQ
, $fqJniClassName>;"
)
w
.
wl
(
s
"friend class djinni::JniInterface<$
cppSelf
, $fqJniClassName>;"
)
w
.
wl
(
s
"friend class djinni::JavaProxyCache<JavaProxy>;"
)
w
.
wl
(
s
"friend class djinni::JavaProxyCache<JavaProxy>;"
)
}
}
}
}
w
.
wl
w
.
wl
w
.
wlOutdent
(
"private:"
)
w
.
wlOutdent
(
"private:"
)
w
.
wl
(
s
"$jni
ClassName
();"
)
w
.
wl
(
s
"$jni
Self
();"
)
w
.
wl
(
s
"friend class djinni::JniClass<$fqJniClassName>;"
)
w
.
wl
(
s
"friend class djinni::JniClass<$fqJniClassName>;"
)
}
}
}
}
...
@@ -230,18 +230,18 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -230,18 +230,18 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
def
writeJniBody
(
w
:
IndentWriter
)
{
def
writeJniBody
(
w
:
IndentWriter
)
{
val
baseClassParam
=
if
(
i
.
ext
.
cpp
)
q
(
classLookup
+
"$CppProxy"
)
else
""
val
baseClassParam
=
if
(
i
.
ext
.
cpp
)
q
(
classLookup
+
"$CppProxy"
)
else
""
writeJniTypeParams
(
w
,
typeParams
)
writeJniTypeParams
(
w
,
typeParams
)
w
.
wl
(
s
"$jni
ClassName::$jniClassName
() : $baseType($baseClassParam) {}"
)
w
.
wl
(
s
"$jni
Self::$jniSelf
() : $baseType($baseClassParam) {}"
)
w
.
wl
w
.
wl
if
(
i
.
ext
.
java
)
{
if
(
i
.
ext
.
java
)
{
writeJniTypeParams
(
w
,
typeParams
)
writeJniTypeParams
(
w
,
typeParams
)
w
.
wl
(
s
"$jni
ClassName
::JavaProxy::JavaProxy(jobject obj) : JavaProxyCacheEntry(obj) {}"
)
w
.
wl
(
s
"$jni
Self
::JavaProxy::JavaProxy(jobject obj) : JavaProxyCacheEntry(obj) {}"
)
for
(
m
<-
i
.
methods
)
{
for
(
m
<-
i
.
methods
)
{
w
.
wl
w
.
wl
val
ret
=
m
.
ret
.
fold
(
"void"
)(
toCppType
(
_
,
spec
.
cppNamespace
))
val
ret
=
m
.
ret
.
fold
(
"void"
)(
toCppType
(
_
,
spec
.
cppNamespace
))
val
params
=
m
.
params
.
map
(
p
=>
toCppParamType
(
p
,
spec
.
cppNamespace
,
"c_"
))
val
params
=
m
.
params
.
map
(
p
=>
toCppParamType
(
p
,
spec
.
cppNamespace
,
"c_"
))
writeJniTypeParams
(
w
,
typeParams
)
writeJniTypeParams
(
w
,
typeParams
)
w
.
w
(
s
"$ret $jni
ClassName
::JavaProxy::JavaProxy::${idCpp.method(m.ident)}${params.mkString("
(
", "
,
", "
)
")}"
).
bracedSemi
{
w
.
w
(
s
"$ret $jni
Self
::JavaProxy::JavaProxy::${idCpp.method(m.ident)}${params.mkString("
(
", "
,
", "
)
")}"
).
bracedSemi
{
w
.
wl
(
s
"JNIEnv * const jniEnv = djinni::jniGetThreadEnv();"
)
w
.
wl
(
s
"JNIEnv * const jniEnv = djinni::jniGetThreadEnv();"
)
w
.
wl
(
s
"djinni::JniLocalScope jscope(jniEnv, 10);"
)
w
.
wl
(
s
"djinni::JniLocalScope jscope(jniEnv, 10);"
)
val
jniArgs
=
mutable
.
ListBuffer
[
String
]()
val
jniArgs
=
mutable
.
ListBuffer
[
String
]()
...
@@ -272,7 +272,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -272,7 +272,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
if
(
i
.
ext
.
cpp
)
{
if
(
i
.
ext
.
cpp
)
{
w
.
wl
(
s
"using namespace ::${spec.jniNamespace};"
)
w
.
wl
(
s
"using namespace ::${spec.jniNamespace};"
)
// Generate CEXPORT functions for JNI to call.
// Generate CEXPORT functions for JNI to call.
val
classIdentMunged
=
withPackage
(
spec
.
javaPackage
,
idJava
.
ty
(
ident
)
)
val
classIdentMunged
=
javaMarshal
.
fqTypename
(
ident
,
i
)
.
replaceAllLiterally
(
"_"
,
"_1"
)
.
replaceAllLiterally
(
"_"
,
"_1"
)
.
replaceAllLiterally
(
"."
,
"_"
)
.
replaceAllLiterally
(
"."
,
"_"
)
val
prefix
=
"Java_"
+
classIdentMunged
val
prefix
=
"Java_"
+
classIdentMunged
...
@@ -302,13 +302,13 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -302,13 +302,13 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
}
}
}
}
nativeHook
(
"nativeDestroy"
,
false
,
Seq
.
empty
,
None
,
{
nativeHook
(
"nativeDestroy"
,
false
,
Seq
.
empty
,
None
,
{
w
.
wl
(
s
"delete reinterpret_cast<djinni::CppProxyHandle<$
selfQ
>*>(nativeRef);"
)
w
.
wl
(
s
"delete reinterpret_cast<djinni::CppProxyHandle<$
cppSelf
>*>(nativeRef);"
)
})
})
for
(
m
<-
i
.
methods
)
{
for
(
m
<-
i
.
methods
)
{
val
nativeAddon
=
if
(
m
.
static
)
""
else
"native_"
val
nativeAddon
=
if
(
m
.
static
)
""
else
"native_"
nativeHook
(
nativeAddon
+
idJava
.
method
(
m
.
ident
),
m
.
static
,
m
.
params
,
m
.
ret
,
{
nativeHook
(
nativeAddon
+
idJava
.
method
(
m
.
ident
),
m
.
static
,
m
.
params
,
m
.
ret
,
{
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
//w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);")
if
(!
m
.
static
)
w
.
wl
(
s
"const std::shared_ptr<$
selfQ> & ref = djinni::CppProxyHandle<$selfQ
>::get(nativeRef);"
)
if
(!
m
.
static
)
w
.
wl
(
s
"const std::shared_ptr<$
cppSelf> & ref = djinni::CppProxyHandle<$cppSelf
>::get(nativeRef);"
)
for
(
p
<-
m
.
params
)
{
for
(
p
<-
m
.
params
)
{
val
jniHelperClass
=
toJniHelperClass
(
p
.
ty
)
val
jniHelperClass
=
toJniHelperClass
(
p
.
ty
)
val
cppType
=
toCppType
(
p
.
ty
,
spec
.
cppNamespace
)
val
cppType
=
toCppType
(
p
.
ty
,
spec
.
cppNamespace
)
...
@@ -318,7 +318,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -318,7 +318,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
}
}
val
callArgs
=
m
.
params
.
map
(
p
=>
"c_"
+
idCpp
.
local
(
p
.
ident
)).
mkString
(
", "
)
val
callArgs
=
m
.
params
.
map
(
p
=>
"c_"
+
idCpp
.
local
(
p
.
ident
)).
mkString
(
", "
)
val
methodName
=
idCpp
.
method
(
m
.
ident
)
val
methodName
=
idCpp
.
method
(
m
.
ident
)
val
callExpr
=
if
(
m
.
static
)
s
"$
selfQ
::$methodName($callArgs)"
else
s
"ref->$methodName($callArgs)"
val
callExpr
=
if
(
m
.
static
)
s
"$
cppSelf
::$methodName($callArgs)"
else
s
"ref->$methodName($callArgs)"
w
.
wl
w
.
wl
m
.
ret
match
{
m
.
ret
match
{
case
Some
(
r
)
=>
case
Some
(
r
)
=>
...
@@ -354,35 +354,8 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
...
@@ -354,35 +354,8 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
}
}
}
}
def
toJavaClassLookup
(
name
:
String
,
javaPackage
:
Option
[
String
])
:
String
=
{
val
javaClassName
=
idJava
.
ty
(
name
)
javaPackage
.
fold
(
javaClassName
)(
p
=>
p
.
replaceAllLiterally
(
"."
,
"/"
)
+
"/"
+
javaClassName
)
}
def
toJavaTypeSig
(
ty
:
TypeRef
,
javaPackage
:
Option
[
String
]
=
None
)
:
String
=
{
def
f
(
e
:
MExpr
)
:
String
=
e
.
base
match
{
case
o
:
MOpaque
=>
o
match
{
case
p
:
MPrimitive
=>
p
.
jSig
case
MString
=>
"Ljava/lang/String;"
case
MDate
=>
"Ljava/util/Date;"
case
MBinary
=>
"[B"
case
MOptional
=>
e
.
args
.
head
.
base
match
{
case
p
:
MPrimitive
=>
s
"Ljava/lang/${p.jBoxed};"
case
MOptional
=>
throw
new
AssertionError
(
"nested optional?"
)
case
m
=>
f
(
e
.
args
.
head
)
}
case
MList
=>
"Ljava/util/ArrayList;"
case
MSet
=>
"Ljava/util/HashSet;"
case
MMap
=>
"Ljava/util/HashMap;"
}
case
MParam
(
_
)
=>
"Ljava/lang/Object;"
case
d
:
MDef
=>
s
"L${toJavaClassLookup(d.name, javaPackage)};"
}
f
(
ty
.
resolved
)
}
def
toJavaMethodSig
(
javaPackage
:
Option
[
String
],
params
:
Iterable
[
Field
],
ret
:
Option
[
TypeRef
])
=
{
def
toJavaMethodSig
(
javaPackage
:
Option
[
String
],
params
:
Iterable
[
Field
],
ret
:
Option
[
TypeRef
])
=
{
params
.
map
(
f
=>
toJavaTypeSig
(
f
.
ty
,
javaPackage
)).
mkString
(
"("
,
""
,
")"
)
+
ret
.
fold
(
"V"
)(
toJavaTypeSig
(
_
,
javaPackage
))
params
.
map
(
f
=>
jniMarshal
.
typename
(
f
.
ty
)).
mkString
(
"("
,
""
,
")"
)
+
ret
.
fold
(
"V"
)(
jniMarshal
.
typename
(
_
))
}
}
def
writeJniTypeParams
(
w
:
IndentWriter
,
params
:
Seq
[
TypeParam
])
{
def
writeJniTypeParams
(
w
:
IndentWriter
,
params
:
Seq
[
TypeParam
])
{
...
...
src/source/JNIMarshal.scala
0 → 100644
View file @
4b803ef0
package
djinni
import
djinni.ast._
import
djinni.generatorTools._
import
djinni.meta._
class
JNIMarshal
(
spec
:
Spec
)
extends
Marshal
(
spec
)
{
// For JNI typename() is always fully qualified and describes the mangled Java type to be used in field/method signatures
def
typename
(
tm
:
MExpr
)
:
String
=
javaTypeSignature
(
tm
)
def
typename
(
name
:
String
,
ty
:
TypeDef
)
:
String
=
throw
new
AssertionError
(
"not supported"
)
def
fqTypename
(
tm
:
MExpr
)
:
String
=
typename
(
tm
)
def
fqTypename
(
name
:
String
,
ty
:
TypeDef
)
:
String
=
typename
(
name
,
ty
)
// Name for the autogenerated class containing field/method IDs and toJava()/fromJava() methods
def
helperClass
(
name
:
String
)
=
spec
.
jniClassIdentStyle
(
name
)
def
fqHelperClass
(
name
:
String
)
=
withNs
(
Some
(
spec
.
jniNamespace
),
helperClass
(
name
))
def
toJniType
(
ty
:
TypeRef
)
:
String
=
toJniType
(
ty
.
resolved
,
false
)
def
toJniType
(
m
:
MExpr
,
needRef
:
Boolean
)
:
String
=
m
.
base
match
{
case
p
:
MPrimitive
=>
if
(
needRef
)
"jobject"
else
p
.
jniName
case
MString
=>
"jstring"
case
MOptional
=>
toJniType
(
m
.
args
.
head
,
true
)
case
MBinary
=>
"jbyteArray"
case
tp
:
MParam
=>
helperClass
(
tp
.
name
)
+
"::JniType"
case
_
=>
"jobject"
}
// The mangled Java typename without the "L...;" decoration useful only for class reflection on our own type
def
undecoratedTypename
(
name
:
String
,
ty
:
TypeDef
)
:
String
=
{
val
javaClassName
=
idJava
.
ty
(
name
)
spec
.
javaPackage
.
fold
(
javaClassName
)(
p
=>
p
.
replaceAllLiterally
(
"."
,
"/"
)
+
"/"
+
javaClassName
)
}
private
def
javaTypeSignature
(
tm
:
MExpr
)
:
String
=
tm
.
base
match
{
case
o
:
MOpaque
=>
o
match
{
case
p
:
MPrimitive
=>
p
.
jSig
case
MString
=>
"Ljava/lang/String;"
case
MDate
=>
"Ljava/util/Date;"
case
MBinary
=>
"[B"
case
MOptional
=>
tm
.
args
.
head
.
base
match
{
case
p
:
MPrimitive
=>
s
"Ljava/lang/${p.jBoxed};"
case
MOptional
=>
throw
new
AssertionError
(
"nested optional?"
)
case
m
=>
javaTypeSignature
(
tm
.
args
.
head
)
}
case
MList
=>
"Ljava/util/ArrayList;"
case
MSet
=>
"Ljava/util/HashSet;"
case
MMap
=>
"Ljava/util/HashMap;"
}
case
MParam
(
_
)
=>
"Ljava/lang/Object;"
case
d
:
MDef
=>
s
"L${undecoratedTypename(d.name, d.body)};"
}
}
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