From: Jean Privat Date: Mon, 9 Nov 2015 15:39:14 +0000 (-0500) Subject: Merge: Java FFI: add GC pinning support X-Git-Tag: v0.8~100 X-Git-Url: http://nitlanguage.org?hp=883a6deafab95f0c7cc675094e66add5a4e45779 Merge: Java FFI: add GC pinning support Adds a missing features to the Java FFI: pinning references to Nit objects from Java. Both services, `..._incr_ref` and `..._decr_ref`, are "simple" redirections from Java to the nitni service in C through the JNI. Pull-Request: #1820 Reviewed-by: Jean Privat --- diff --git a/src/ffi/java.nit b/src/ffi/java.nit index eca32ac..1adb9c9 100644 --- a/src/ffi/java.nit +++ b/src/ffi/java.nit @@ -220,6 +220,9 @@ redef class MModule for cb in callbacks do jni_methods.add_all(cb.jni_methods_declaration(self)) end + for cb in callbacks_used_from_java.types do + jni_methods.add_all(cb.jni_methods_declaration(self)) + end var cf = new CFunction("void nit_ffi_with_java_register_natives(JNIEnv* env, jclass jclazz)") cf.exprs.add """ @@ -470,6 +473,38 @@ redef class MType # Used by `JavaLanguage::compile_extern_method` when calling JNI's `CallStatic*Method`. # This strategy is used by JNI to type the return of callbacks to Java. private fun jni_signature_alt: String do return "Int" + + redef fun compile_callback_to_java(mmodule, mainmodule, ccu) + do + var java_file = mmodule.java_file + if java_file == null then return + + for variation in ["incr", "decr"] do + var friendly_name = "{mangled_cname}_{variation}_ref" + + # C + var csignature = "void {mmodule.impl_java_class_name}_{friendly_name}(JNIEnv *env, jclass clazz, jint object)" + var cf = new CFunction("JNIEXPORT {csignature}") + cf.exprs.add "\tnitni_global_ref_{variation}((void*)(long)object);" + ccu.add_non_static_local_function cf + + # Java + java_file.class_content.add "private native static void {friendly_name}(int object);\n" + end + end + + redef fun jni_methods_declaration(from_mmodule) + do + var arr = new Array[String] + for variation in ["incr", "decr"] do + var friendly_name = "{mangled_cname}_{variation}_ref" + var jni_format = "(I)V" + var cname = "{from_mmodule.impl_java_class_name}_{friendly_name}" + arr.add """{"{{{friendly_name}}}", "{{{jni_format}}}", {{{cname}}}}""" + end + + return arr + end end redef class MClassType diff --git a/tests/sav/test_ffi_java_refs.res b/tests/sav/test_ffi_java_refs.res new file mode 100644 index 0000000..422c2b7 --- /dev/null +++ b/tests/sav/test_ffi_java_refs.res @@ -0,0 +1,2 @@ +a +b diff --git a/tests/test_ffi_java_refs.nit b/tests/test_ffi_java_refs.nit new file mode 100644 index 0000000..efab321 --- /dev/null +++ b/tests/test_ffi_java_refs.nit @@ -0,0 +1,27 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import java + +class A + fun foo in "Java" `{ + A_incr_ref(self); + System.out.println("a"); + A_decr_ref(self); + System.out.println("b"); + `} +end + +var a = new A +a.foo