packages feed

jni 0.2.3 → 0.3.0

raw patch · 5 files changed

+1024/−815 lines, 5 filesdep +choicedep ~inline-cnew-uploader

Dependencies added: choice

Dependency ranges changed: inline-c

Files

jni.cabal view
@@ -1,5 +1,5 @@ name:                jni-version:             0.2.3+version:             0.3.0 synopsis:            Complete JNI raw bindings. description:         Please see README.md. homepage:            https://github.com/tweag/inline-java/tree/master/jni#readme@@ -34,8 +34,10 @@   build-depends:     base >= 4.7 && < 5,     bytestring >=0.10,+    choice >= 0.2.0,     containers >=0.5,-    inline-c >=0.5,+    inline-c >=0.5.6.1,     singletons >= 2.0,     thread-local-storage >=0.1+  build-tools: cpphs   default-language: Haskell2010
src/Foreign/JNI.c view
@@ -20,12 +20,12 @@ }  -JNIEnv * inline_c_Foreign_JNI_3_99b0dd0131b646dafcbe5e45017817ad4c5859cb() {+JNIEnv * inline_c_Foreign_JNI_3_7a31865bf33245c9e432165e1fe1577264708e3b() {        jsize num_jvms;       JavaVM *jvm;-      -+                                                                              +                                                            JNI_GetCreatedJavaVMs(&jvm, 1, &num_jvms);       JNIEnv *env; @@ -34,9 +34,9 @@               exit(EFAULT);       } -      --+                                                                               +                  +                (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void**)&env, NULL);       return env;  }@@ -336,121 +336,149 @@ }  -jobject inline_c_Foreign_JNI_53_8c39298123ed5c8656bc5277898eef8b54389907(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+void inline_c_Foreign_JNI_53_ace3bc46d6fd80627af710dce368567213addfaa(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject gobj_inline_c_2) {+ (*env_inline_c_0)->DeleteGlobalRef(env_inline_c_1+                                                              ,gobj_inline_c_2);+                          +}+++jobject inline_c_Foreign_JNI_54_16595ba5c6f78926bf8bd31d9d0e8bf072131bb0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) { return (-      (*env_inline_c_0)->NewGlobalRef(env_inline_c_1,-                                      obj_inline_c_2) );+        (*env_inline_c_0)->NewGlobalRef(env_inline_c_1,+                                        obj_inline_c_2) ); }  -void inline_c_Foreign_JNI_54_03477bcc772fad6c91dec2c4c759fcb4fc07724e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+jobject inline_c_Foreign_JNI_55_286b821e24496c30618bcd36d10e07939424a96e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+return (+      (*env_inline_c_0)->NewLocalRef(env_inline_c_1,+                                     obj_inline_c_2) );+} -      (*env_inline_c_0)->DeleteGlobalRef(env_inline_c_1,-                                         obj_inline_c_2); ++void inline_c_Foreign_JNI_56_f46c3362caa2b895c87351e1914a06c012eee294(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {++      (*env_inline_c_0)->DeleteLocalRef(env_inline_c_1,+                                        obj_inline_c_2) ; }  -void inline_c_Foreign_JNI_55_1fc0f64f3f314012d49ffbd906fd558d03aef37d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-       (*env_inline_c_0)->CallVoidMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) ;+jint inline_c_Foreign_JNI_57_c49bfdb1320e2f77592a15068a422089ae09feba(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jint capacity_inline_c_2) {++      (*env_inline_c_0)->PushLocalFrame(env_inline_c_1,+                                        capacity_inline_c_2);  }  -jobject inline_c_Foreign_JNI_56_203a086f6ff15893a2417732fde0904a88dd4307(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallObjectMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jobject inline_c_Foreign_JNI_58_53148f1b21d55375d63ea7ade9238bc4f16e149e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+return (+      (*env_inline_c_0)->PopLocalFrame(env_inline_c_1,+                                       obj_inline_c_2) ); }  -jboolean inline_c_Foreign_JNI_57_b729da20539bd62f9d8b8e8579dbf42bbafc76c4(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallBooleanMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+void inline_c_Foreign_JNI_59_8d66436d754c77c4f92234fe2c72cb9e8a9ad940(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+       (*env_inline_c_0)->CallVoidMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ; }  -jbyte inline_c_Foreign_JNI_58_4e4bdbfc154de6ffe6eb562e1edfcbb529c275e8(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallByteMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jobject inline_c_Foreign_JNI_60_15d6a4ae1fac1a6ba84db740b2bfac9d44b23329(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallObjectMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jchar inline_c_Foreign_JNI_59_5e000da030371e4db09c808934e3e5f504eda6c9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallCharMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jboolean inline_c_Foreign_JNI_61_71e1f15d31cfe83371d148dbf20d2aebf0293c53(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallBooleanMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jshort inline_c_Foreign_JNI_60_516aded3c2f638c87a12e56d246bdcea1c7e1a47(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallShortMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jbyte inline_c_Foreign_JNI_62_5c031f42ce827bc7ef3320331f4333dfb7ddaa3a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallByteMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jint inline_c_Foreign_JNI_61_58b123994733ee132cc23af0e5a7da34ef37f584(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallIntMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jchar inline_c_Foreign_JNI_63_f67cb9064f7392b8f942ac21b300b8594ddc8043(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallCharMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jlong inline_c_Foreign_JNI_62_46357804ee4af723721f601341c61ac4eecad475(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallLongMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jshort inline_c_Foreign_JNI_64_3dc48e937e27459da9000a1fba7694c91562fbd6(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallShortMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jfloat inline_c_Foreign_JNI_63_75b26f9688a40ee63e314f73ee5f9563c48e02c0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallFloatMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jint inline_c_Foreign_JNI_65_0d9906f84552f67ba8fc08d4403ca6919417f4de(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallIntMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -jdouble inline_c_Foreign_JNI_64_f33654d183f21d1a2c8ffc121684d4e60e273fa2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {-return (       (*env_inline_c_0)->CallDoubleMethodA(env_inline_c_1,                                                obj_inline_c_2,                                                method_inline_c_3,                                                cargs_inline_c_4) );+jlong inline_c_Foreign_JNI_66_ff3b913f1c1e13665522e2fa9f46cf345cef625e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallLongMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ); }  -void inline_c_Foreign_JNI_65_5e76a5cd24826d8a13100c53ae77823083465978(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jfloat inline_c_Foreign_JNI_67_7d9a7c851ecb7d144f8aadac5cb17df79f87edfc(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallFloatMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );+}+++jdouble inline_c_Foreign_JNI_68_9928358856d291d7c670b6bb00810c66255dcc65(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+return (       (*env_inline_c_0)->CallDoubleMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );+}+++void inline_c_Foreign_JNI_69_5e76a5cd24826d8a13100c53ae77823083465978(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {        (*env_inline_c_0)->CallStaticVoidMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ; }  -jobject inline_c_Foreign_JNI_66_6b65c20aae594d93c02434b3de002e443794ad14(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jobject inline_c_Foreign_JNI_70_6b65c20aae594d93c02434b3de002e443794ad14(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticObjectMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jboolean inline_c_Foreign_JNI_67_58bcbcce6c8bf92799bd1db44c288a7b0a260a36(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jboolean inline_c_Foreign_JNI_71_58bcbcce6c8bf92799bd1db44c288a7b0a260a36(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticBooleanMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jbyte inline_c_Foreign_JNI_68_1f0c41a419f29557514552df4d07022a006f2ca3(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jbyte inline_c_Foreign_JNI_72_1f0c41a419f29557514552df4d07022a006f2ca3(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticByteMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jchar inline_c_Foreign_JNI_69_51a3cb1cefc6391ba5958a887d84196690a418f2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jchar inline_c_Foreign_JNI_73_51a3cb1cefc6391ba5958a887d84196690a418f2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticCharMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jshort inline_c_Foreign_JNI_70_5822dfce2b301e3b90f80885a4a5838bdc57cd44(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jshort inline_c_Foreign_JNI_74_5822dfce2b301e3b90f80885a4a5838bdc57cd44(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticShortMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jint inline_c_Foreign_JNI_71_4fdc28424fe7ef156763f715ef79463ed387abb2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jint inline_c_Foreign_JNI_75_4fdc28424fe7ef156763f715ef79463ed387abb2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticIntMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jlong inline_c_Foreign_JNI_72_93382b358dc7f0275c6a620eaa67fdfd75167d54(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jlong inline_c_Foreign_JNI_76_93382b358dc7f0275c6a620eaa67fdfd75167d54(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticLongMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jfloat inline_c_Foreign_JNI_73_89ea2435847f3d94e8b71bcceba739a077829ca9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jfloat inline_c_Foreign_JNI_77_89ea2435847f3d94e8b71bcceba739a077829ca9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticFloatMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jdouble inline_c_Foreign_JNI_74_0b9bb41f21f19495338507ff5779f50a17ac0245(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {+jdouble inline_c_Foreign_JNI_78_0b9bb41f21f19495338507ff5779f50a17ac0245(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) { return (       (*env_inline_c_0)->CallStaticDoubleMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ); }  -jobjectArray inline_c_Foreign_JNI_75_0b57533e83360b5a6660bf703521b3b6c2fbec66(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2, jclass cls_inline_c_3) {+jobjectArray inline_c_Foreign_JNI_79_0b57533e83360b5a6660bf703521b3b6c2fbec66(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2, jclass cls_inline_c_3) { return (       (*env_inline_c_0)->NewObjectArray(env_inline_c_1,                                         sz_inline_c_2,@@ -459,47 +487,47 @@ }  -jbooleanArray inline_c_Foreign_JNI_76_b1841567b8f0e99405458b9e8a3b7f3a3e20812f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jbooleanArray inline_c_Foreign_JNI_80_b1841567b8f0e99405458b9e8a3b7f3a3e20812f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewBooleanArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jbyteArray inline_c_Foreign_JNI_77_1a9345ff427557126ba3aa5f0fb460f3df632ff8(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jbyteArray inline_c_Foreign_JNI_81_1a9345ff427557126ba3aa5f0fb460f3df632ff8(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewByteArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jcharArray inline_c_Foreign_JNI_78_b00869a9422815fdc3aa43f15e3b782dc6f19e03(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jcharArray inline_c_Foreign_JNI_82_b00869a9422815fdc3aa43f15e3b782dc6f19e03(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewCharArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jshortArray inline_c_Foreign_JNI_79_06a1e38de0ed2d7764757388457ed0797c72d8aa(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jshortArray inline_c_Foreign_JNI_83_06a1e38de0ed2d7764757388457ed0797c72d8aa(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewShortArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jintArray inline_c_Foreign_JNI_80_af7c087746afd64be9d977ebf078c2df4b3d918e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jintArray inline_c_Foreign_JNI_84_af7c087746afd64be9d977ebf078c2df4b3d918e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewIntArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jlongArray inline_c_Foreign_JNI_81_270c75c62cc97fdc3741af544fa35a61abf37fba(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jlongArray inline_c_Foreign_JNI_85_270c75c62cc97fdc3741af544fa35a61abf37fba(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewLongArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jfloatArray inline_c_Foreign_JNI_82_312dee8af1c4b2058cb1b2703277cf297ba34224(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jfloatArray inline_c_Foreign_JNI_86_312dee8af1c4b2058cb1b2703277cf297ba34224(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewFloatArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jdoubleArray inline_c_Foreign_JNI_83_103070e78986a21762e18c9aebfa9162a3565d9b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {+jdoubleArray inline_c_Foreign_JNI_87_103070e78986a21762e18c9aebfa9162a3565d9b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) { return (       (*env_inline_c_0)->NewDoubleArray(env_inline_c_1,                                               sz_inline_c_2) ); }  -jstring inline_c_Foreign_JNI_84_d5ed5b314231e7dc3292c2329a2cb4191e262633(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jchar * ptr_inline_c_2, jsize len_inline_c_3) {+jstring inline_c_Foreign_JNI_88_d5ed5b314231e7dc3292c2329a2cb4191e262633(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jchar * ptr_inline_c_2, jsize len_inline_c_3) { return (       (*env_inline_c_0)->NewString(env_inline_c_1,                                    ptr_inline_c_2,@@ -507,61 +535,61 @@ }  -jsize inline_c_Foreign_JNI_85_9be0134c89fa74c4d07a2601d81d89982ce8bdf6(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2) {+jsize inline_c_Foreign_JNI_89_9be0134c89fa74c4d07a2601d81d89982ce8bdf6(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2) { return (       (*env_inline_c_0)->GetArrayLength(env_inline_c_1,                                         array_inline_c_2) ); }  -jsize inline_c_Foreign_JNI_86_2e55ce4ded52c43b7b69c0c49c4425aef4f8a80b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) {+jsize inline_c_Foreign_JNI_90_2e55ce4ded52c43b7b69c0c49c4425aef4f8a80b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) { return (       (*env_inline_c_0)->GetStringLength(env_inline_c_1,                                          jstr_inline_c_2) ); }  -jboolean * inline_c_Foreign_JNI_87_153a97a3a91d03dbe7d10fe0e3d48afaa842ee96(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jboolean * inline_c_Foreign_JNI_91_153a97a3a91d03dbe7d10fe0e3d48afaa842ee96(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetBooleanArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jbyte * inline_c_Foreign_JNI_88_b630cdc25e3d575cad69a3fc3bec490a99a6ab49(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jbyte * inline_c_Foreign_JNI_92_b630cdc25e3d575cad69a3fc3bec490a99a6ab49(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetByteArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jchar * inline_c_Foreign_JNI_89_7c0f806fe4d40ac0c1d06b4ccccc42fdc562c8ec(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jchar * inline_c_Foreign_JNI_93_7c0f806fe4d40ac0c1d06b4ccccc42fdc562c8ec(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetCharArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jshort * inline_c_Foreign_JNI_90_66e42eb3b8a0e71cc0cc2b722b925689a20ed23f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jshort * inline_c_Foreign_JNI_94_66e42eb3b8a0e71cc0cc2b722b925689a20ed23f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetShortArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jint * inline_c_Foreign_JNI_91_9ca3666fbed332c3a833881ceba71295e27d5d16(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jint * inline_c_Foreign_JNI_95_9ca3666fbed332c3a833881ceba71295e27d5d16(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetIntArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jlong * inline_c_Foreign_JNI_92_3bd0969839fbd68b98c00a27f6197704f6e2718b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jlong * inline_c_Foreign_JNI_96_3bd0969839fbd68b98c00a27f6197704f6e2718b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetLongArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jfloat * inline_c_Foreign_JNI_93_1799b6e92e7df6d5155518d25fe2fde47055a7ff(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jfloat * inline_c_Foreign_JNI_97_1799b6e92e7df6d5155518d25fe2fde47055a7ff(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetFloatArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -jdouble * inline_c_Foreign_JNI_94_6b454504f66bff257e7cb14d00f7064112a8f5a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {+jdouble * inline_c_Foreign_JNI_98_6b454504f66bff257e7cb14d00f7064112a8f5a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) { return (       (*env_inline_c_0)->GetDoubleArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) ); }  -const jchar * inline_c_Foreign_JNI_95_ac075a3bdcb535575fe36c6f7b5eb3d66ace44a7(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) {+const jchar * inline_c_Foreign_JNI_99_ac075a3bdcb535575fe36c6f7b5eb3d66ace44a7(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) { return (       (*env_inline_c_0)->GetStringChars(env_inline_c_1,                                         jstr_inline_c_2,@@ -569,87 +597,87 @@ }  -void inline_c_Foreign_JNI_96_c405fd2cc3cc77bea5093b022f17d3b2c443e2a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbooleanArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jboolean * buf_inline_c_5) {+void inline_c_Foreign_JNI_100_c405fd2cc3cc77bea5093b022f17d3b2c443e2a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbooleanArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jboolean * buf_inline_c_5) {        (*env_inline_c_0)->SetBooleanArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_97_6aefb6e6ad5f3a169ff39bd2c3186b897bcd220f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbyteArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jbyte * buf_inline_c_5) {+void inline_c_Foreign_JNI_101_6aefb6e6ad5f3a169ff39bd2c3186b897bcd220f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbyteArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jbyte * buf_inline_c_5) {        (*env_inline_c_0)->SetByteArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_98_a1e161a18fa39331bad743b7e07b0399b3104242(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jcharArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jchar * buf_inline_c_5) {+void inline_c_Foreign_JNI_102_a1e161a18fa39331bad743b7e07b0399b3104242(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jcharArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jchar * buf_inline_c_5) {        (*env_inline_c_0)->SetCharArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_99_4221edb9c7b0c1666f5952fe23aad965e2f58085(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jshortArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jshort * buf_inline_c_5) {+void inline_c_Foreign_JNI_103_4221edb9c7b0c1666f5952fe23aad965e2f58085(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jshortArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jshort * buf_inline_c_5) {        (*env_inline_c_0)->SetShortArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_100_0cf86cc89e108bd7ed150e5aad2e7d8d8f95dd7a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jintArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jint * buf_inline_c_5) {+void inline_c_Foreign_JNI_104_0cf86cc89e108bd7ed150e5aad2e7d8d8f95dd7a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jintArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jint * buf_inline_c_5) {        (*env_inline_c_0)->SetIntArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_101_983cb43fd1962ef866086f1819815a8b05791888(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jlongArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jlong * buf_inline_c_5) {+void inline_c_Foreign_JNI_105_983cb43fd1962ef866086f1819815a8b05791888(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jlongArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jlong * buf_inline_c_5) {        (*env_inline_c_0)->SetLongArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_102_26c6b32031e2561eb5fc3b047d493c3a784bbf40(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jfloatArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jfloat * buf_inline_c_5) {+void inline_c_Foreign_JNI_106_26c6b32031e2561eb5fc3b047d493c3a784bbf40(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jfloatArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jfloat * buf_inline_c_5) {        (*env_inline_c_0)->SetFloatArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_103_fbded71aa93cca94c495be618b75c7f610619a93(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jdoubleArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jdouble * buf_inline_c_5) {+void inline_c_Foreign_JNI_107_fbded71aa93cca94c495be618b75c7f610619a93(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jdoubleArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jdouble * buf_inline_c_5) {        (*env_inline_c_0)->SetDoubleArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ; }  -void inline_c_Foreign_JNI_104_5d5355f911ff38accf7df59e4f3407823efa0055(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jboolean * xs_inline_c_3) {+void inline_c_Foreign_JNI_108_5d5355f911ff38accf7df59e4f3407823efa0055(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jboolean * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseBooleanArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_105_93701f28f0a45b8531f977f3ad28d48b747bb58c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jbyte * xs_inline_c_3) {+void inline_c_Foreign_JNI_109_93701f28f0a45b8531f977f3ad28d48b747bb58c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jbyte * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseByteArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_106_d799968701da7f57e4eb07390e1efda373184222(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jchar * xs_inline_c_3) {+void inline_c_Foreign_JNI_110_d799968701da7f57e4eb07390e1efda373184222(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jchar * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseCharArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_107_03e0c5a40ab324b1c42f0b70ceaeb6b1605a0ded(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jshort * xs_inline_c_3) {+void inline_c_Foreign_JNI_111_03e0c5a40ab324b1c42f0b70ceaeb6b1605a0ded(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jshort * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseShortArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_108_4c2726a53e147cd6eb61733e27bfc599bc883f74(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jint * xs_inline_c_3) {+void inline_c_Foreign_JNI_112_4c2726a53e147cd6eb61733e27bfc599bc883f74(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jint * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseIntArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_109_9e1790871e959852cb5032b3f2833c370b81bb0f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jlong * xs_inline_c_3) {+void inline_c_Foreign_JNI_113_9e1790871e959852cb5032b3f2833c370b81bb0f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jlong * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseLongArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_110_44c06b418c79983d60f09ffc49851077b1feb632(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jfloat * xs_inline_c_3) {+void inline_c_Foreign_JNI_114_44c06b418c79983d60f09ffc49851077b1feb632(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jfloat * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseFloatArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_111_94830601ce91790b75e74abe9c9819be2e748762(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jdouble * xs_inline_c_3) {+void inline_c_Foreign_JNI_115_94830601ce91790b75e74abe9c9819be2e748762(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jdouble * xs_inline_c_3) {        (*env_inline_c_0)->ReleaseDoubleArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ; }  -void inline_c_Foreign_JNI_112_7a962d5f8e6114066dca42386535e4a079022eae(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2, jchar * chars_inline_c_3) {+void inline_c_Foreign_JNI_116_7a962d5f8e6114066dca42386535e4a079022eae(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2, jchar * chars_inline_c_3) {        (*env_inline_c_0)->ReleaseStringChars(env_inline_c_1,                                             jstr_inline_c_2,@@ -657,7 +685,7 @@ }  -jobject inline_c_Foreign_JNI_113_bb66272284cce01d85b6ec31967e1a66eae7e0c5(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2, jsize i_inline_c_3) {+jobject inline_c_Foreign_JNI_117_bb66272284cce01d85b6ec31967e1a66eae7e0c5(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2, jsize i_inline_c_3) { return (       (*env_inline_c_0)->GetObjectArrayElement(env_inline_c_1,                                                array_inline_c_2,@@ -665,7 +693,7 @@ }  -void inline_c_Foreign_JNI_114_c069b4edd080791f4858d4a7a48b8c42c99c8e4a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobjectArray array_inline_c_2, jsize i_inline_c_3, jobject x_inline_c_4) {+void inline_c_Foreign_JNI_118_c069b4edd080791f4858d4a7a48b8c42c99c8e4a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobjectArray array_inline_c_2, jsize i_inline_c_3, jobject x_inline_c_4) {        (*env_inline_c_0)->SetObjectArrayElement(env_inline_c_1,                                                array_inline_c_2,
+ src/Foreign/JNI.cpphs view
@@ -0,0 +1,839 @@+-- | Low-level bindings to the Java Native Interface (JNI).+--+-- Read the+-- <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html JNI spec>+-- for authoritative documentation as to what each of the functions in+-- this module does. The names of the bindings in this module were chosen to+-- match the names of the functions in the JNI spec.+--+-- All bindings in this module access the JNI via a thread-local variable of+-- type @JNIEnv *@. If the current OS thread has not yet been "attached" to the+-- JVM, it is attached implicitly upon the first call to one of these bindings+-- in the current thread.+--+-- The 'String' type in this module is the type of JNI strings. See+-- "Foreign.JNI.String".++{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ViewPatterns #-}++-- XXX pgmP directive should be redundant. But necessary to workaround+-- https://github.com/haskell/cabal/issues/4278.+{-# OPTIONS_GHC -fno-warn-name-shadowing -pgmPcpphs -optP--cpp #-}++-- XXX This file uses cpphs for preprocessing instead of the system's native+-- CPP, because the OS X has subtly different whitespace behaviour in the+-- presence of concatenation.++module Foreign.JNI+  ( -- * JNI functions+    -- ** VM creation+    withJVM+    -- ** Class loading+  , defineClass+  , JNINativeMethod(..)+  , registerNatives+    -- ** Exceptions+  , JVMException(..)+  , throw+  , throwNew+    -- ** Query functions+  , findClass+  , getFieldID+  , getStaticFieldID+  , getMethodID+  , getStaticMethodID+  , getObjectClass+    -- ** Reference manipulation+  , newGlobalRef+  , deleteGlobalRef+  , newLocalRef+  , deleteLocalRef+  , pushLocalFrame+  , popLocalFrame+    -- ** Field accessor functions+    -- *** Get fields+  , getObjectField+  , getBooleanField+  , getIntField+  , getLongField+  , getCharField+  , getShortField+  , getByteField+  , getDoubleField+  , getFloatField+    -- *** Get static fields+  , getStaticObjectField+  , getStaticBooleanField+  , getStaticIntField+  , getStaticLongField+  , getStaticCharField+  , getStaticShortField+  , getStaticByteField+  , getStaticDoubleField+  , getStaticFloatField+    -- *** Set fields+  , setObjectField+  , setBooleanField+  , setIntField+  , setLongField+  , setCharField+  , setShortField+  , setByteField+  , setDoubleField+  , setFloatField+    -- *** Set static fields+  , setStaticObjectField+  , setStaticBooleanField+  , setStaticIntField+  , setStaticLongField+  , setStaticCharField+  , setStaticShortField+  , setStaticByteField+  , setStaticDoubleField+  , setStaticFloatField+    -- ** Method invocation+  , callObjectMethod+  , callBooleanMethod+  , callIntMethod+  , callLongMethod+  , callCharMethod+  , callShortMethod+  , callByteMethod+  , callDoubleMethod+  , callFloatMethod+  , callVoidMethod+  , callStaticObjectMethod+  , callStaticVoidMethod+  , callStaticBooleanMethod+  , callStaticIntMethod+  , callStaticLongMethod+  , callStaticCharMethod+  , callStaticShortMethod+  , callStaticByteMethod+  , callStaticDoubleMethod+  , callStaticFloatMethod+    -- ** Object construction+  , newObject+  , newString+  , newObjectArray+  , newBooleanArray+  , newByteArray+  , newCharArray+  , newShortArray+  , newIntArray+  , newLongArray+  , newFloatArray+  , newDoubleArray+    -- ** Array manipulation+  , getArrayLength+  , getStringLength+  , ArrayCopyFailed(..)+  , getBooleanArrayElements+  , getByteArrayElements+  , getCharArrayElements+  , getShortArrayElements+  , getIntArrayElements+  , getLongArrayElements+  , getFloatArrayElements+  , getDoubleArrayElements+  , getStringChars+  , setBooleanArrayRegion+  , setByteArrayRegion+  , setCharArrayRegion+  , setShortArrayRegion+  , setIntArrayRegion+  , setLongArrayRegion+  , setFloatArrayRegion+  , setDoubleArrayRegion+  , releaseBooleanArrayElements+  , releaseByteArrayElements+  , releaseCharArrayElements+  , releaseShortArrayElements+  , releaseIntArrayElements+  , releaseLongArrayElements+  , releaseFloatArrayElements+  , releaseDoubleArrayElements+  , releaseStringChars+  , getObjectArrayElement+  , setObjectArrayElement+  ) where++import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)+import Control.Exception (Exception, bracket, finally, throwIO)+import Control.Monad (join, unless, void, when)+import Data.Choice+import Data.Coerce+import Data.Int+import Data.IORef (IORef, newIORef, readIORef, atomicModifyIORef)+import Data.Word+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.Monoid ((<>))+import Data.Typeable (Typeable)+import Data.TLS.PThread+import Foreign.C (CChar)+import Foreign.ForeignPtr+  ( finalizeForeignPtr+  , newForeignPtr_+  , withForeignPtr+  )+import Foreign.JNI.NativeMethod+import Foreign.JNI.Types+import qualified Foreign.JNI.String as JNI+import Foreign.Marshal.Array+import Foreign.Ptr (Ptr, nullPtr)+import GHC.ForeignPtr (newConcForeignPtr)+import qualified Language.C.Inline as C+import qualified Language.C.Inline.Unsafe as CU+import System.IO.Unsafe (unsafePerformIO)+import Prelude hiding (String)++C.context (C.baseCtx <> C.bsCtx <> jniCtx)++C.include "<jni.h>"+C.include "<errno.h>"+C.include "<stdlib.h>"++-- | A JNI call may cause a (Java) exception to be raised. This module raises it+-- as a Haskell exception wrapping the Java exception.+newtype JVMException = JVMException JThrowable+  deriving (Show, Typeable)++instance Exception JVMException++-- | Thrown when @Get<PrimitiveType>ArrayElements@ returns a null pointer,+-- because it wanted to copy the array contents but couldn't. In this case the+-- JVM doesn't throw OutOfMemory according to the JNI spec.+data ArrayCopyFailed = ArrayCopyFailed+  deriving (Show, Typeable)++instance Exception ArrayCopyFailed++objectFromPtr :: Ptr (J a) -> IO (J a)+objectFromPtr ptr = J <$> newForeignPtr_ ptr++-- | Map Java exceptions to Haskell exceptions.+throwIfException :: Ptr JNIEnv -> IO a -> IO a+throwIfException env m = m `finally` do+    excptr <- [CU.exp| jthrowable { (*$(JNIEnv *env))->ExceptionOccurred($(JNIEnv *env)) } |]+    unless (excptr == nullPtr) $ do+      [CU.exp| void { (*$(JNIEnv *env))->ExceptionDescribe($(JNIEnv *env)) } |]+      [CU.exp| void { (*$(JNIEnv *env))->ExceptionClear($(JNIEnv *env)) } |]+      throwIO . JVMException =<< newGlobalRef =<< objectFromPtr excptr++-- | Check whether a pointer is null.+throwIfNull :: IO (Ptr a) -> IO (Ptr a)+throwIfNull m = do+    ptr <- m+    if ptr == nullPtr+    then throwIO ArrayCopyFailed+    else return ptr++-- | A read-write lock+--+-- Concurrent readers are allowed, but only one writer is supported.+newtype RWLock =+    RWLock (IORef (Int, RWWantedState))+    -- ^ A count of the held read locks and the wanted state++-- | The wanted state of the RW+data RWWantedState+    = Reading            -- ^ There are no writers+    | Writing (MVar ())+       -- ^ A writer wants to write, grant no more read locks. The MVar is used+       -- to notify the writer when the currently held read locks are released.++-- | Creates a new read-write lock.+newRWLock :: IO RWLock+newRWLock = RWLock <$> newIORef (0, Reading)++-- | Tries to acquire a read lock. If this call returns `Do #read`, no writer+-- will be granted a lock before the read lock is released.+tryAcquireReadLock :: RWLock -> IO (Choice "read")+tryAcquireReadLock (RWLock ref) = do+    atomicModifyIORef ref $ \case+      (!readers,  Reading) -> ((readers + 1, Reading),    Do #read)+      st                   -> (                       st, Don't #read)++-- | Releases a read lock.+releaseReadLock :: RWLock -> IO ()+releaseReadLock (RWLock ref) = do+    st <- atomicModifyIORef ref $+            \st@(readers, aim) -> ((readers - 1, aim), st)+    case st of+      -- Notify the writer if I'm the last reader.+      (0, Writing mv) -> putMVar mv ()+      _               -> return ()++-- | Waits until the current read locks are released and grants a write lock.+acquireWriteLock :: RWLock -> IO ()+acquireWriteLock (RWLock ref) = do+    mv <- newEmptyMVar+    join $ atomicModifyIORef ref $ \case+      (0, _) -> ((0, Writing mv),   return ())+      st     -> (               st, takeMVar mv)++-- | This lock is used to avoid the JVM from dying before any finalizers+-- deleting global references are finished.+--+-- Finalizers try to acquire read locks.+--+-- The JVM acquires a write lock before shutdown. Thence, finalizers fail to+-- acquire read locks and behave as noops.+globalJVMLock :: RWLock+globalJVMLock = unsafePerformIO newRWLock+{-# NOINLINE globalJVMLock #-}++-- | A global mutable cell holding the TLS variable, whose content is set once+-- for each thread.+envTlsRef :: IORef (TLS (Ptr JNIEnv))+{-# NOINLINE envTlsRef #-}+envTlsRef = unsafePerformIO $ do+    -- It doesn't matter if this computation ends up running twice, say because+    -- of lazy blackholing.+    !tls <- mkTLS $ [C.block| JNIEnv* {+      jsize num_jvms;+      JavaVM *jvm;+      /* Assume there's at most one JVM. The current JNI spec (2016) says only+       * one JVM per process is supported anyways. */+      JNI_GetCreatedJavaVMs(&jvm, 1, &num_jvms);+      JNIEnv *env;++      if(!num_jvms) {+              fprintf(stderr, "No JVM has been initialized yet.\n");+              exit(EFAULT);+      }++      /* Attach as daemon to match GHC's usual semantics for threads, which are+       * daemonic.+       */+      (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void**)&env, NULL);+      return env; } |]+    newIORef tls++-- | Run an action against the appropriate 'JNIEnv'.+--+-- Each OS thread has its own 'JNIEnv', which this function gives access to.+--+-- TODO check whether this call is only safe from a (bound) thread.+withJNIEnv :: (Ptr JNIEnv -> IO a) -> IO a+withJNIEnv f = f =<< getTLS =<< readIORef envTlsRef++useAsCStrings :: [ByteString] -> ([Ptr CChar] -> IO a) -> IO a+useAsCStrings strs m =+  foldr (\str k cstrs -> BS.useAsCString str $ \cstr -> k (cstr:cstrs)) m strs []++-- | Create a new JVM, with the given arguments. /Can only be called once/. Best+-- practice: use it to wrap your @main@ function.+withJVM :: [ByteString] -> IO a -> IO a+withJVM options action =+    bracket ini fini (const action)+  where+    ini = do+      useAsCStrings options $ \cstrs -> do+        withArray cstrs $ \(coptions :: Ptr (Ptr CChar)) -> do+          let n = fromIntegral (length cstrs) :: C.CInt+          [C.block| JavaVM * {+            JavaVM *jvm;+            JNIEnv *env;+            JavaVMInitArgs vm_args;+            JavaVMOption *options = malloc(sizeof(JavaVMOption) * $(int n));+            for(int i = 0; i < $(int n); i++)+                    options[i].optionString = $(char **coptions)[i];+            vm_args.version = JNI_VERSION_1_6;+            vm_args.nOptions = $(int n);+            vm_args.options = options;+            vm_args.ignoreUnrecognized = 0;+            JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);+            free(options);+            return jvm; } |]+    fini jvm = do+      acquireWriteLock globalJVMLock+      [C.block| void { (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm)); } |]++defineClass+  :: Coercible o (J ('Class "java.lang.ClassLoader"))+  => JNI.String -- ^ Class name+  -> o          -- ^ Loader+  -> ByteString -- ^ Bytecode buffer+  -> IO JClass+defineClass name (coerce -> upcast -> loader) buf = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString name $ \namep ->+    objectFromPtr =<<+    [CU.exp| jclass {+      (*$(JNIEnv *env))->DefineClass($(JNIEnv *env),+                                     $(char *namep),+                                     $fptr-ptr:(jobject loader),+                                     $bs-ptr:buf,+                                     $bs-len:buf) } |]+registerNatives+  :: JClass+  -> [JNINativeMethod]+  -> IO ()+registerNatives cls methods = withJNIEnv $ \env ->+    throwIfException env $+    withArray methods $ \cmethods -> do+      let numMethods = fromIntegral $ length methods+      _ <- [CU.exp| jint {+             (*$(JNIEnv *env))->RegisterNatives($(JNIEnv *env),+                                                $fptr-ptr:(jclass cls),+                                                $(JNINativeMethod *cmethods),+                                                $(int numMethods)) } |]+      return ()++throw :: Coercible o (J a) => o -> IO ()+throw (coerce -> upcast -> obj) = withJNIEnv $ \env -> void $ do+    [CU.exp| jint {+       (*$(JNIEnv *env))->Throw($(JNIEnv *env),+                                $fptr-ptr:(jobject obj)) } |]++throwNew :: JClass -> JNI.String -> IO ()+throwNew cls msg = withJNIEnv $ \env ->+    JNI.withString msg $ \msgp -> void $ do+    [CU.exp| jint {+       (*$(JNIEnv *env))->ThrowNew($(JNIEnv *env),+                                   $fptr-ptr:(jclass cls),+                                   $(char *msgp)) } |]++findClass+  :: JNI.String -- ^ Class name+  -> IO JClass+findClass name = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString name $ \namep ->+    objectFromPtr =<<+    [CU.exp| jclass { (*$(JNIEnv *env))->FindClass($(JNIEnv *env), $(char *namep)) } |]++newObject :: JClass -> JNI.String -> [JValue] -> IO JObject+newObject cls sig args = withJNIEnv $ \env ->+    throwIfException env $+    withJValues args $ \cargs -> do+      constr <- getMethodID cls "<init>" sig+      objectFromPtr =<< [CU.exp| jobject {+        (*$(JNIEnv *env))->NewObjectA($(JNIEnv *env),+                                      $fptr-ptr:(jclass cls),+                                      $(jmethodID constr),+                                      $(jvalue *cargs)) } |]++getFieldID+  :: JClass -- ^ A class object as returned by 'findClass'+  -> JNI.String -- ^ Field name+  -> JNI.String -- ^ JNI signature+  -> IO JFieldID+getFieldID cls fieldname sig = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString fieldname $ \fieldnamep ->+    JNI.withString sig $ \sigp ->+    [CU.exp| jfieldID {+      (*$(JNIEnv *env))->GetFieldID($(JNIEnv *env),+                                    $fptr-ptr:(jclass cls),+                                    $(char *fieldnamep),+                                    $(char *sigp)) } |]++getStaticFieldID+  :: JClass -- ^ A class object as returned by 'findClass'+  -> JNI.String -- ^ Field name+  -> JNI.String -- ^ JNI signature+  -> IO JFieldID+getStaticFieldID cls fieldname sig = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString fieldname $ \fieldnamep ->+    JNI.withString sig $ \sigp ->+    [CU.exp| jfieldID {+      (*$(JNIEnv *env))->GetStaticFieldID($(JNIEnv *env),+                                          $fptr-ptr:(jclass cls),+                                          $(char *fieldnamep),+                                          $(char *sigp)) } |]++#define GET_FIELD(name, hs_rettype, c_rettype) \+get/**/name/**/Field :: Coercible o (J a) => o -> JFieldID -> IO hs_rettype; \+get/**/name/**/Field (coerce -> upcast -> obj) field = withJNIEnv $ \env -> \+    throwIfException env $ \+    [CU.exp| c_rettype { \+      (*$(JNIEnv *env))->Get/**/name/**/Field($(JNIEnv *env), \+                                              $fptr-ptr:(jobject obj), \+                                              $(jfieldID field)) } |]++getObjectField :: Coercible o (J a) => o -> JFieldID -> IO JObject+getObjectField x y =+    let GET_FIELD(Object, (Ptr JObject), jobject)+    in objectFromPtr =<< getObjectField x y+GET_FIELD(Boolean, Word8, jboolean)+GET_FIELD(Byte, CChar, jbyte)+GET_FIELD(Char, Word16, jchar)+GET_FIELD(Short, Int16, jshort)+GET_FIELD(Int, Int32, jint)+GET_FIELD(Long, Int64, jlong)+GET_FIELD(Float, Float, jfloat)+GET_FIELD(Double, Double, jdouble)++#define GET_STATIC_FIELD(name, hs_rettype, c_rettype) \+getStatic/**/name/**/Field :: JClass -> JFieldID -> IO hs_rettype; \+getStatic/**/name/**/Field klass field = withJNIEnv $ \env -> \+    throwIfException env $ \+    [CU.exp| c_rettype { \+      (*$(JNIEnv *env))->GetStatic/**/name/**/Field($(JNIEnv *env), \+                                                    $fptr-ptr:(jclass klass), \+                                                    $(jfieldID field)) } |]++getStaticObjectField :: JClass -> JFieldID -> IO JObject+getStaticObjectField x y =+    let GET_STATIC_FIELD(Object, (Ptr JObject), jobject)+    in objectFromPtr =<< getStaticObjectField x y+GET_STATIC_FIELD(Boolean, Word8, jboolean)+GET_STATIC_FIELD(Byte, CChar, jbyte)+GET_STATIC_FIELD(Char, Word16, jchar)+GET_STATIC_FIELD(Short, Int16, jshort)+GET_STATIC_FIELD(Int, Int32, jint)+GET_STATIC_FIELD(Long, Int64, jlong)+GET_STATIC_FIELD(Float, Float, jfloat)+GET_STATIC_FIELD(Double, Double, jdouble)++#define SET_FIELD(name, hs_fieldtype, c_fieldtype) \+set/**/name/**/Field :: Coercible o (J a) => o -> JFieldID -> hs_fieldtype -> IO (); \+set/**/name/**/Field (coerce -> upcast -> obj) field x = \+    withJNIEnv $ \env -> \+    throwIfException env $ \+    [CU.block| void { \+      (*$(JNIEnv *env))->Set/**/name/**/Field($(JNIEnv *env), \+                                              $fptr-ptr:(jobject obj), \+                                              $(jfieldID field), \+                                              $(c_fieldtype x)); } |]++setObjectField :: Coercible o (J a) => o -> JFieldID -> JObject -> IO ()+setObjectField x y z =+    let SET_FIELD(Object, (Ptr JObject), jobject)+    in withForeignPtr (coerce z) (setObjectField x y)+SET_FIELD(Boolean, Word8, jboolean)+SET_FIELD(Byte, CChar, jbyte)+SET_FIELD(Char, Word16, jchar)+SET_FIELD(Short, Int16, jshort)+SET_FIELD(Int, Int32, jint)+SET_FIELD(Long, Int64, jlong)+SET_FIELD(Float, Float, jfloat)+SET_FIELD(Double, Double, jdouble)++#define SET_STATIC_FIELD(name, hs_fieldtype, c_fieldtype) \+setStatic/**/name/**/Field :: JClass -> JFieldID -> hs_fieldtype -> IO (); \+setStatic/**/name/**/Field klass field x = \+    withJNIEnv $ \env -> \+    throwIfException env $ \+    [CU.block| void { \+      (*$(JNIEnv *env))->SetStatic/**/name/**/Field($(JNIEnv *env), \+                                                    $fptr-ptr:(jclass klass), \+                                                    $(jfieldID field), \+                                                    $(c_fieldtype x)); } |]++setStaticObjectField :: JClass -> JFieldID -> JObject -> IO ()+setStaticObjectField x y z =+    let SET_STATIC_FIELD(Object, (Ptr JObject), jobject)+    in withForeignPtr (coerce z) (setStaticObjectField x y)+SET_STATIC_FIELD(Boolean, Word8, jboolean)+SET_STATIC_FIELD(Byte, CChar, jbyte)+SET_STATIC_FIELD(Char, Word16, jchar)+SET_STATIC_FIELD(Short, Int16, jshort)+SET_STATIC_FIELD(Int, Int32, jint)+SET_STATIC_FIELD(Long, Int64, jlong)+SET_STATIC_FIELD(Float, Float, jfloat)+SET_STATIC_FIELD(Double, Double, jdouble)++getMethodID+  :: JClass -- ^ A class object as returned by 'findClass'+  -> JNI.String -- ^ Field name+  -> JNI.String -- ^ JNI signature+  -> IO JMethodID+getMethodID cls methodname sig = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString methodname $ \methodnamep ->+    JNI.withString sig $ \sigp ->+    [CU.exp| jmethodID {+      (*$(JNIEnv *env))->GetMethodID($(JNIEnv *env),+                                     $fptr-ptr:(jclass cls),+                                     $(char *methodnamep),+                                     $(char *sigp)) } |]++getStaticMethodID+  :: JClass -- ^ A class object as returned by 'findClass'+  -> JNI.String -- ^ Field name+  -> JNI.String -- ^ JNI signature+  -> IO JMethodID+getStaticMethodID cls methodname sig = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString methodname $ \methodnamep ->+    JNI.withString sig $ \sigp ->+    [CU.exp| jmethodID {+      (*$(JNIEnv *env))->GetStaticMethodID($(JNIEnv *env),+                                           $fptr-ptr:(jclass cls),+                                           $(char *methodnamep),+                                           $(char *sigp)) } |]++getObjectClass :: Coercible o (J ty) => o -> IO JClass+getObjectClass (coerce -> upcast -> obj) = withJNIEnv $ \env ->+    objectFromPtr =<<+    [CU.exp| jclass {+      (*$(JNIEnv *env))->GetObjectClass($(JNIEnv *env),+                                        $fptr-ptr:(jobject obj)) } |]++-- | Creates a global reference to the object referred to by+-- the given reference.+--+-- Arranges for a finalizer to call 'deleteGlobalRef' when the+-- global reference is no longer reachable on the Haskell side.+newGlobalRef :: Coercible o (J ty) => o -> IO o+newGlobalRef (coerce -> upcast -> obj) = withJNIEnv $ \env -> do+    gobj <-+      [CU.exp| jobject {+        (*$(JNIEnv *env))->NewGlobalRef($(JNIEnv *env),+                                        $fptr-ptr:(jobject obj)) } |]+    coerce <$> J <$> newConcForeignPtr gobj (finalize gobj)+  where+    finalize gobj = do+      bracket (tryAcquireReadLock globalJVMLock)+              (\doRead -> when (toBool doRead) $ releaseReadLock globalJVMLock)+              $ \doRead ->+        when (toBool doRead) $ withJNIEnv $ \env ->+          [CU.block| void { (*$(JNIEnv *env))->DeleteGlobalRef($(JNIEnv *env)+                                                              ,$(jobject gobj));+                          } |]++deleteGlobalRef :: Coercible o (J ty) => o -> IO ()+deleteGlobalRef (coerce -> J p) = finalizeForeignPtr p++-- NB: Cannot add a finalizer to local references because it may+-- run in a thread where the reference is not valid.+newLocalRef :: Coercible o (J ty) => o -> IO (J ty)+newLocalRef (coerce -> upcast -> obj) = withJNIEnv $ \env ->+    unsafeCast <$> (objectFromPtr =<<)+    [CU.exp| jobject {+      (*$(JNIEnv *env))->NewLocalRef($(JNIEnv *env),+                                     $fptr-ptr:(jobject obj)) } |]++deleteLocalRef :: Coercible o (J ty) => o -> IO ()+deleteLocalRef (coerce -> upcast -> obj) = withJNIEnv $ \env ->+    [CU.exp| void {+      (*$(JNIEnv *env))->DeleteLocalRef($(JNIEnv *env),+                                        $fptr-ptr:(jobject obj)) } |]++pushLocalFrame :: Int32 -> IO ()+pushLocalFrame (coerce -> capacity) = withJNIEnv $ \env ->+    -- We ignore the output as it is always 0 on success and throws an+    -- exception otherwise.+    throwIfException env $ void $+    [CU.block| jint {+      (*$(JNIEnv *env))->PushLocalFrame($(JNIEnv *env),+                                        $(jint capacity)); } |]++popLocalFrame :: Coercible o (J ty) => o -> IO o+popLocalFrame (coerce -> upcast -> obj) = withJNIEnv $ \env ->+    coerce <$> (objectFromPtr =<<)+    [CU.exp| jobject {+      (*$(JNIEnv *env))->PopLocalFrame($(JNIEnv *env),+                                       $fptr-ptr:(jobject obj)) } |]++-- Modern CPP does have ## for concatenating strings, but we use the hacky /**/+-- comment syntax for string concatenation. This is because GHC passes+-- the -traditional flag to the preprocessor by default, which turns off several+-- modern CPP features.++#define CALL_METHOD(name, hs_rettype, c_rettype) \+call/**/name/**/Method :: Coercible o (J a) => o -> JMethodID -> [JValue] -> IO hs_rettype; \+call/**/name/**/Method (coerce -> upcast -> obj) method args = withJNIEnv $ \env -> \+    throwIfException env $ \+    withJValues args $ \cargs -> \+    [C.exp| c_rettype { \+      (*$(JNIEnv *env))->Call/**/name/**/MethodA($(JNIEnv *env), \+                                                 $fptr-ptr:(jobject obj), \+                                                 $(jmethodID method), \+                                                 $(jvalue *cargs)) } |]++CALL_METHOD(Void, (), void)+callObjectMethod :: Coercible o (J a) => o -> JMethodID -> [JValue] -> IO JObject+callObjectMethod x y z =+    let CALL_METHOD(Object, (Ptr JObject), jobject)+    in objectFromPtr =<< callObjectMethod x y z+callBooleanMethod :: Coercible o (J a) => o -> JMethodID -> [JValue] -> IO Bool+callBooleanMethod x y z =+    let CALL_METHOD(Boolean, Word8, jboolean)+    in toEnum . fromIntegral <$> callBooleanMethod x y z+CALL_METHOD(Byte, CChar, jbyte)+CALL_METHOD(Char, Word16, jchar)+CALL_METHOD(Short, Int16, jshort)+CALL_METHOD(Int, Int32, jint)+CALL_METHOD(Long, Int64, jlong)+CALL_METHOD(Float, Float, jfloat)+CALL_METHOD(Double, Double, jdouble)++#define CALL_STATIC_METHOD(name, hs_rettype, c_rettype) \+callStatic/**/name/**/Method :: JClass -> JMethodID -> [JValue] -> IO hs_rettype; \+callStatic/**/name/**/Method cls method args = withJNIEnv $ \env -> \+    throwIfException env $ \+    withJValues args $ \cargs -> \+    [C.exp| c_rettype { \+      (*$(JNIEnv *env))->CallStatic/**/name/**/MethodA($(JNIEnv *env), \+                                                       $fptr-ptr:(jclass cls), \+                                                       $(jmethodID method), \+                                                       $(jvalue *cargs)) } |]++CALL_STATIC_METHOD(Void, (), void)+callStaticObjectMethod :: JClass -> JMethodID -> [JValue] -> IO JObject+callStaticObjectMethod x y z =+    let CALL_STATIC_METHOD(Object, (Ptr JObject), jobject)+    in objectFromPtr =<< callStaticObjectMethod x y z+callStaticBooleanMethod :: JClass -> JMethodID -> [JValue] -> IO Bool+callStaticBooleanMethod x y z =+    let CALL_STATIC_METHOD(Boolean, Word8, jboolean)+    in toEnum . fromIntegral <$> callStaticBooleanMethod x y z+CALL_STATIC_METHOD(Byte, CChar, jbyte)+CALL_STATIC_METHOD(Char, Word16, jchar)+CALL_STATIC_METHOD(Short, Int16, jshort)+CALL_STATIC_METHOD(Int, Int32, jint)+CALL_STATIC_METHOD(Long, Int64, jlong)+CALL_STATIC_METHOD(Float, Float, jfloat)+CALL_STATIC_METHOD(Double, Double, jdouble)++newObjectArray :: Int32 -> JClass -> IO JObjectArray+newObjectArray sz cls = withJNIEnv $ \env ->+    throwIfException env $+    objectFromPtr =<<+    [CU.exp| jobjectArray {+      (*$(JNIEnv *env))->NewObjectArray($(JNIEnv *env),+                                        $(jsize sz),+                                        $fptr-ptr:(jclass cls),+                                        NULL) } |]++#define NEW_ARRAY(name, c_rettype) \+new/**/name/**/Array :: Int32 -> IO J/**/name/**/Array; \+new/**/name/**/Array sz = withJNIEnv $ \env -> \+    throwIfException env $ \+    objectFromPtr =<< \+    [CU.exp| c_rettype/**/Array { \+      (*$(JNIEnv *env))->New/**/name/**/Array($(JNIEnv *env), \+                                              $(jsize sz)) } |]++NEW_ARRAY(Boolean, jboolean)+NEW_ARRAY(Byte, jbyte)+NEW_ARRAY(Char, jchar)+NEW_ARRAY(Short, jshort)+NEW_ARRAY(Int, jint)+NEW_ARRAY(Long, jlong)+NEW_ARRAY(Float, jfloat)+NEW_ARRAY(Double, jdouble)++newString :: Ptr Word16 -> Int32 -> IO JString+newString ptr len = withJNIEnv $ \env ->+    throwIfException env $+    objectFromPtr =<<+    [CU.exp| jstring {+      (*$(JNIEnv *env))->NewString($(JNIEnv *env),+                                   $(jchar *ptr),+                                   $(jsize len)) } |]++getArrayLength :: Coercible o (JArray a) => o -> IO Int32+getArrayLength (coerce -> upcast -> array) = withJNIEnv $ \env ->+    [C.exp| jsize {+      (*$(JNIEnv *env))->GetArrayLength($(JNIEnv *env),+                                        $fptr-ptr:(jarray array)) } |]++getStringLength :: JString -> IO Int32+getStringLength jstr = withJNIEnv $ \env ->+    [CU.exp| jsize {+      (*$(JNIEnv *env))->GetStringLength($(JNIEnv *env),+                                         $fptr-ptr:(jstring jstr)) } |]++#define GET_ARRAY_ELEMENTS(name, hs_rettype, c_rettype) \+get/**/name/**/ArrayElements :: J/**/name/**/Array -> IO (Ptr hs_rettype); \+get/**/name/**/ArrayElements (upcast -> array) = withJNIEnv $ \env -> \+    throwIfNull $ \+    [CU.exp| c_rettype* { \+      (*$(JNIEnv *env))->Get/**/name/**/ArrayElements($(JNIEnv *env), \+                                                      $fptr-ptr:(jobject array), \+                                                      NULL) } |]++GET_ARRAY_ELEMENTS(Boolean, Word8, jboolean)+GET_ARRAY_ELEMENTS(Byte, CChar, jbyte)+GET_ARRAY_ELEMENTS(Char, Word16, jchar)+GET_ARRAY_ELEMENTS(Short, Int16, jshort)+GET_ARRAY_ELEMENTS(Int, Int32, jint)+GET_ARRAY_ELEMENTS(Long, Int64, jlong)+GET_ARRAY_ELEMENTS(Float, Float, jfloat)+GET_ARRAY_ELEMENTS(Double, Double, jdouble)++getStringChars :: JString -> IO (Ptr Word16)+getStringChars jstr = withJNIEnv $ \env ->+    throwIfNull $+    [CU.exp| const jchar* {+      (*$(JNIEnv *env))->GetStringChars($(JNIEnv *env),+                                        $fptr-ptr:(jstring jstr),+                                        NULL) } |]++#define SET_ARRAY_REGION(name, hs_argtype, c_argtype) \+set/**/name/**/ArrayRegion :: J/**/name/**/Array -> Int32 -> Int32 -> Ptr hs_argtype -> IO (); \+set/**/name/**/ArrayRegion array start len buf = withJNIEnv $ \env -> \+    throwIfException env $ \+    [CU.exp| void { \+      (*$(JNIEnv *env))->Set/**/name/**/ArrayRegion($(JNIEnv *env), \+                                                    $fptr-ptr:(c_argtype/**/Array array), \+                                                    $(jsize start), \+                                                    $(jsize len), \+                                                    $(c_argtype *buf)) } |]++SET_ARRAY_REGION(Boolean, Word8, jboolean)+SET_ARRAY_REGION(Byte, CChar, jbyte)+SET_ARRAY_REGION(Char, Word16, jchar)+SET_ARRAY_REGION(Short, Int16, jshort)+SET_ARRAY_REGION(Int, Int32, jint)+SET_ARRAY_REGION(Long, Int64, jlong)+SET_ARRAY_REGION(Float, Float, jfloat)+SET_ARRAY_REGION(Double, Double, jdouble)++#define RELEASE_ARRAY_ELEMENTS(name, hs_argtype, c_argtype) \+release/**/name/**/ArrayElements :: J/**/name/**/Array -> Ptr hs_argtype -> IO (); \+release/**/name/**/ArrayElements (upcast -> array) xs = withJNIEnv $ \env -> \+    [CU.exp| void { \+      (*$(JNIEnv *env))->Release/**/name/**/ArrayElements($(JNIEnv *env), \+                                                          $fptr-ptr:(jobject array), \+                                                          $(c_argtype *xs), \+                                                          JNI_ABORT) } |]++RELEASE_ARRAY_ELEMENTS(Boolean, Word8, jboolean)+RELEASE_ARRAY_ELEMENTS(Byte, CChar, jbyte)+RELEASE_ARRAY_ELEMENTS(Char, Word16, jchar)+RELEASE_ARRAY_ELEMENTS(Short, Int16, jshort)+RELEASE_ARRAY_ELEMENTS(Int, Int32, jint)+RELEASE_ARRAY_ELEMENTS(Long, Int64, jlong)+RELEASE_ARRAY_ELEMENTS(Float, Float, jfloat)+RELEASE_ARRAY_ELEMENTS(Double, Double, jdouble)++releaseStringChars :: JString -> Ptr Word16 -> IO ()+releaseStringChars jstr chars = withJNIEnv $ \env ->+    [CU.exp| void {+      (*$(JNIEnv *env))->ReleaseStringChars($(JNIEnv *env),+                                            $fptr-ptr:(jstring jstr),+                                            $(jchar *chars)) } |]++getObjectArrayElement :: Coercible o (JArray a) => o -> Int32 -> IO (J a)+getObjectArrayElement (coerce -> upcast -> array) i = withJNIEnv $ \env ->+    unsafeCast <$> (objectFromPtr =<<)+    [C.exp| jobject {+      (*$(JNIEnv *env))->GetObjectArrayElement($(JNIEnv *env),+                                               $fptr-ptr:(jarray array),+                                               $(jsize i)) } |]++setObjectArrayElement :: Coercible o (J a) => JObjectArray -> Int32 -> o -> IO ()+setObjectArrayElement array i (coerce -> upcast -> x) = withJNIEnv $ \env ->+    [C.exp| void {+      (*$(JNIEnv *env))->SetObjectArrayElement($(JNIEnv *env),+                                               $fptr-ptr:(jobjectArray array),+                                               $(jsize i),+                                               $fptr-ptr:(jobject x)); } |]
− src/Foreign/JNI.hs
@@ -1,686 +0,0 @@--- | Low-level bindings to the Java Native Interface (JNI).------ Read the--- <https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html JNI spec>--- for authoritative documentation as to what each of the functions in--- this module does. The names of the bindings in this module were chosen to--- match the names of the functions in the JNI spec.------ All bindings in this module access the JNI via a thread-local variable of--- type @JNIEnv *@. If the current OS thread has not yet been "attached" to the--- JVM, it is attached implicitly upon the first call to one of these bindings--- in the current thread.------ The 'String' type in this module is the type of JNI strings. See "Foreign.JNI.String".-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ViewPatterns #-}--{-# OPTIONS_GHC -fno-warn-name-shadowing #-}--module Foreign.JNI-  ( -- * JNI functions-    -- ** VM creation-    withJVM-    -- ** Class loading-  , defineClass-  , JNINativeMethod(..)-  , registerNatives-    -- ** Exceptions-  , throw-  , throwNew-    -- ** Query functions-  , findClass-  , getFieldID-  , getStaticFieldID-  , getMethodID-  , getStaticMethodID-  , getObjectClass-    -- ** Reference manipulation-  , newGlobalRef-  , deleteGlobalRef-    -- ** Field accessor functions-    -- *** Get fields-  , getObjectField-  , getBooleanField-  , getIntField-  , getLongField-  , getCharField-  , getShortField-  , getByteField-  , getDoubleField-  , getFloatField-    -- *** Get static fields-  , getStaticObjectField-  , getStaticBooleanField-  , getStaticIntField-  , getStaticLongField-  , getStaticCharField-  , getStaticShortField-  , getStaticByteField-  , getStaticDoubleField-  , getStaticFloatField-    -- *** Set fields-  , setObjectField-  , setBooleanField-  , setIntField-  , setLongField-  , setCharField-  , setShortField-  , setByteField-  , setDoubleField-  , setFloatField-    -- *** Set static fields-  , setStaticObjectField-  , setStaticBooleanField-  , setStaticIntField-  , setStaticLongField-  , setStaticCharField-  , setStaticShortField-  , setStaticByteField-  , setStaticDoubleField-  , setStaticFloatField-    -- ** Method invocation-  , callObjectMethod-  , callBooleanMethod-  , callIntMethod-  , callLongMethod-  , callCharMethod-  , callShortMethod-  , callByteMethod-  , callDoubleMethod-  , callFloatMethod-  , callVoidMethod-  , callStaticObjectMethod-  , callStaticVoidMethod-  , callStaticBooleanMethod-  , callStaticIntMethod-  , callStaticLongMethod-  , callStaticCharMethod-  , callStaticShortMethod-  , callStaticByteMethod-  , callStaticDoubleMethod-  , callStaticFloatMethod-    -- ** Object construction-  , newObject-  , newString-  , newObjectArray-  , newBooleanArray-  , newByteArray-  , newCharArray-  , newShortArray-  , newIntArray-  , newLongArray-  , newFloatArray-  , newDoubleArray-    -- ** Array manipulation-  , getArrayLength-  , getStringLength-  , getBooleanArrayElements-  , getByteArrayElements-  , getCharArrayElements-  , getShortArrayElements-  , getIntArrayElements-  , getLongArrayElements-  , getFloatArrayElements-  , getDoubleArrayElements-  , getStringChars-  , setBooleanArrayRegion-  , setByteArrayRegion-  , setCharArrayRegion-  , setShortArrayRegion-  , setIntArrayRegion-  , setLongArrayRegion-  , setFloatArrayRegion-  , setDoubleArrayRegion-  , releaseBooleanArrayElements-  , releaseByteArrayElements-  , releaseCharArrayElements-  , releaseShortArrayElements-  , releaseIntArrayElements-  , releaseLongArrayElements-  , releaseFloatArrayElements-  , releaseDoubleArrayElements-  , releaseStringChars-  , getObjectArrayElement-  , setObjectArrayElement-  ) where--import Control.Exception (Exception, bracket, finally, throwIO)-import Control.Monad (unless, void)-import Data.Coerce-import Data.Int-import Data.IORef (IORef, newIORef, readIORef)-import Data.Word-import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import Data.Monoid ((<>))-import Data.Typeable (Typeable)-import Data.TLS.PThread-import Foreign.C (CChar)-import Foreign.JNI.NativeMethod-import Foreign.JNI.Types-import qualified Foreign.JNI.String as JNI-import Foreign.Marshal.Array-import Foreign.Ptr (Ptr, nullPtr)-import qualified Language.C.Inline as C-import qualified Language.C.Inline.Unsafe as CU-import System.IO.Unsafe (unsafePerformIO)-import Prelude hiding (String)--C.context (C.baseCtx <> C.bsCtx <> jniCtx)--C.include "<jni.h>"-C.include "<errno.h>"-C.include "<stdlib.h>"--data JavaException = JavaException JThrowable-  deriving (Show, Typeable)--instance Exception JavaException---- | Thrown when @Get<PrimitiveType>ArrayElements@ returns a null pointer,--- because it wanted to copy the array contents but couldn't. In this case the--- JVM doesn't throw OutOfMemory according to the JNI spec.-data ArrayCopyFailed = ArrayCopyFailed-  deriving (Show, Typeable)--instance Exception ArrayCopyFailed---- | Map Java exceptions to Haskell exceptions.-throwIfException :: Ptr JNIEnv -> IO a -> IO a-throwIfException env m = m `finally` do-    J excptr <- [CU.exp| jthrowable { (*$(JNIEnv *env))->ExceptionOccurred($(JNIEnv *env)) } |]-    unless (excptr == nullPtr) $ do-      [CU.exp| void { (*$(JNIEnv *env))->ExceptionDescribe($(JNIEnv *env)) } |]-      [CU.exp| void { (*$(JNIEnv *env))->ExceptionClear($(JNIEnv *env)) } |]-      throwIO $ JavaException (J excptr)---- | Check whether a pointer is null.-throwIfNull :: IO (Ptr a) -> IO (Ptr a)-throwIfNull m = do-    ptr <- m-    if ptr == nullPtr-    then throwIO ArrayCopyFailed-    else return ptr---- | A global mutable cell holding the TLS variable, whose content is set once--- for each thread.-envTlsRef :: IORef (TLS (Ptr JNIEnv))-{-# NOINLINE envTlsRef #-}-envTlsRef = unsafePerformIO $ do-    -- It doesn't matter if this computation ends up running twice, say because-    -- of lazy blackholing.-    !tls <- mkTLS $ [C.block| JNIEnv* {-      jsize num_jvms;-      JavaVM *jvm;-      /* Assume there's at most one JVM. The current JNI spec (2016) says only-       * one JVM per process is supported anyways. */-      JNI_GetCreatedJavaVMs(&jvm, 1, &num_jvms);-      JNIEnv *env;--      if(!num_jvms) {-              fprintf(stderr, "No JVM has been initialized yet.\n");-              exit(EFAULT);-      }--      /* Attach as daemon to match GHC's usual semantics for threads, which are-       * daemonic.-       */-      (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void**)&env, NULL);-      return env; } |]-    newIORef tls---- | Run an action against the appropriate 'JNIEnv'.------ Each OS thread has its own 'JNIEnv', which this function gives access to.------ TODO check whether this call is only safe from a (bound) thread.-withJNIEnv :: (Ptr JNIEnv -> IO a) -> IO a-withJNIEnv f = f =<< getTLS =<< readIORef envTlsRef--useAsCStrings :: [ByteString] -> ([Ptr CChar] -> IO a) -> IO a-useAsCStrings strs m =-  foldr (\str k cstrs -> BS.useAsCString str $ \cstr -> k (cstr:cstrs)) m strs []---- | Create a new JVM, with the given arguments. /Can only be called once/. Best--- practice: use it to wrap your @main@ function.-withJVM :: [ByteString] -> IO a -> IO a-withJVM options action =-    bracket ini fini (const action)-  where-    ini = do-      useAsCStrings options $ \cstrs -> do-        withArray cstrs $ \(coptions :: Ptr (Ptr CChar)) -> do-          let n = fromIntegral (length cstrs) :: C.CInt-          [C.block| JavaVM * {-            JavaVM *jvm;-            JNIEnv *env;-            JavaVMInitArgs vm_args;-            JavaVMOption *options = malloc(sizeof(JavaVMOption) * $(int n));-            for(int i = 0; i < $(int n); i++)-                    options[i].optionString = $(char **coptions)[i];-            vm_args.version = JNI_VERSION_1_6;-            vm_args.nOptions = $(int n);-            vm_args.options = options;-            vm_args.ignoreUnrecognized = 0;-            JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);-            free(options);-            return jvm; } |]-    fini jvm = [C.block| void { (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm)); } |]--defineClass-  :: Coercible o (J ('Class "java.lang.ClassLoader"))-  => JNI.String -- ^ Class name-  -> o          -- ^ Loader-  -> ByteString -- ^ Bytecode buffer-  -> IO JClass-defineClass name (coerce -> upcast -> loader) buf = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString name $ \namep ->-    [CU.exp| jclass {-      (*$(JNIEnv *env))->DefineClass($(JNIEnv *env),-                                     $(char *namep),-                                     $(jobject loader),-                                     $bs-ptr:buf,-                                     $bs-len:buf) } |]-registerNatives-  :: JClass-  -> [JNINativeMethod]-  -> IO ()-registerNatives cls methods = withJNIEnv $ \env ->-    throwIfException env $-    withArray methods $ \cmethods -> do-      let numMethods = fromIntegral $ length methods-      _ <- [CU.exp| jint {-             (*$(JNIEnv *env))->RegisterNatives($(JNIEnv *env),-                                                $(jclass cls),-                                                $(JNINativeMethod *cmethods),-                                                $(int numMethods)) } |]-      return ()--throw :: Coercible o (J a) => o -> IO ()-throw (coerce -> upcast -> obj) = withJNIEnv $ \env -> void $ do-    [CU.exp| jint {-       (*$(JNIEnv *env))->Throw($(JNIEnv *env),-                                $(jobject obj)) } |]--throwNew :: JClass -> JNI.String -> IO ()-throwNew cls msg = withJNIEnv $ \env ->-    JNI.withString msg $ \msgp -> void $ do-    [CU.exp| jint {-       (*$(JNIEnv *env))->ThrowNew($(JNIEnv *env),-                                   $(jclass cls),-                                   $(char *msgp)) } |]--findClass-  :: JNI.String -- ^ Class name-  -> IO JClass-findClass name = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString name $ \namep ->-    [CU.exp| jclass { (*$(JNIEnv *env))->FindClass($(JNIEnv *env), $(char *namep)) } |]--newObject :: JClass -> JNI.String -> [JValue] -> IO JObject-newObject cls sig args = withJNIEnv $ \env ->-    throwIfException env $-    withArray args $ \cargs -> do-      constr <- getMethodID cls "<init>" sig-      [CU.exp| jobject {-        (*$(JNIEnv *env))->NewObjectA($(JNIEnv *env),-                                      $(jclass cls),-                                      $(jmethodID constr),-                                      $(jvalue *cargs)) } |]--getFieldID-  :: JClass -- ^ A class object as returned by 'findClass'-  -> JNI.String -- ^ Field name-  -> JNI.String -- ^ JNI signature-  -> IO JFieldID-getFieldID cls fieldname sig = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString fieldname $ \fieldnamep ->-    JNI.withString sig $ \sigp ->-    [CU.exp| jfieldID {-      (*$(JNIEnv *env))->GetFieldID($(JNIEnv *env),-                                    $(jclass cls),-                                    $(char *fieldnamep),-                                    $(char *sigp)) } |]--getStaticFieldID-  :: JClass -- ^ A class object as returned by 'findClass'-  -> JNI.String -- ^ Field name-  -> JNI.String -- ^ JNI signature-  -> IO JFieldID-getStaticFieldID cls fieldname sig = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString fieldname $ \fieldnamep ->-    JNI.withString sig $ \sigp ->-    [CU.exp| jfieldID {-      (*$(JNIEnv *env))->GetStaticFieldID($(JNIEnv *env),-                                          $(jclass cls),-                                          $(char *fieldnamep),-                                          $(char *sigp)) } |]--#define GET_FIELD(name, hs_rettype, c_rettype) \-get/**/name/**/Field :: Coercible o (J a) => o -> JFieldID -> IO hs_rettype; \-get/**/name/**/Field (coerce -> upcast -> obj) field = withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.exp| c_rettype { \-      (*$(JNIEnv *env))->Get/**/name/**/Field($(JNIEnv *env), \-                                              $(jobject obj), \-                                              $(jfieldID field)) } |]--GET_FIELD(Object, JObject, jobject)-GET_FIELD(Boolean, Word8, jboolean)-GET_FIELD(Byte, CChar, jbyte)-GET_FIELD(Char, Word16, jchar)-GET_FIELD(Short, Int16, jshort)-GET_FIELD(Int, Int32, jint)-GET_FIELD(Long, Int64, jlong)-GET_FIELD(Float, Float, jfloat)-GET_FIELD(Double, Double, jdouble)--#define GET_STATIC_FIELD(name, hs_rettype, c_rettype) \-getStatic/**/name/**/Field :: JClass -> JFieldID -> IO hs_rettype; \-getStatic/**/name/**/Field klass field = withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.exp| c_rettype { \-      (*$(JNIEnv *env))->GetStatic/**/name/**/Field($(JNIEnv *env), \-                                                    $(jclass klass), \-                                                    $(jfieldID field)) } |]--GET_STATIC_FIELD(Object, JObject, jobject)-GET_STATIC_FIELD(Boolean, Word8, jboolean)-GET_STATIC_FIELD(Byte, CChar, jbyte)-GET_STATIC_FIELD(Char, Word16, jchar)-GET_STATIC_FIELD(Short, Int16, jshort)-GET_STATIC_FIELD(Int, Int32, jint)-GET_STATIC_FIELD(Long, Int64, jlong)-GET_STATIC_FIELD(Float, Float, jfloat)-GET_STATIC_FIELD(Double, Double, jdouble)--#define SET_FIELD(name, hs_fieldtype, c_fieldtype) \-set/**/name/**/Field :: Coercible o (J a) => o -> JFieldID -> hs_fieldtype -> IO (); \-set/**/name/**/Field (coerce -> upcast -> obj) field x = \-    withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.block| void { \-      (*$(JNIEnv *env))->Set/**/name/**/Field($(JNIEnv *env), \-                                              $(jobject obj), \-                                              $(jfieldID field), \-                                              $(c_fieldtype x)); } |]--SET_FIELD(Object, JObject, jobject)-SET_FIELD(Boolean, Word8, jboolean)-SET_FIELD(Byte, CChar, jbyte)-SET_FIELD(Char, Word16, jchar)-SET_FIELD(Short, Int16, jshort)-SET_FIELD(Int, Int32, jint)-SET_FIELD(Long, Int64, jlong)-SET_FIELD(Float, Float, jfloat)-SET_FIELD(Double, Double, jdouble)--#define SET_STATIC_FIELD(name, hs_fieldtype, c_fieldtype) \-setStatic/**/name/**/Field :: JClass -> JFieldID -> hs_fieldtype -> IO (); \-setStatic/**/name/**/Field klass field x = \-    withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.block| void { \-      (*$(JNIEnv *env))->SetStatic/**/name/**/Field($(JNIEnv *env), \-                                                    $(jclass klass), \-                                                    $(jfieldID field), \-                                                    $(c_fieldtype x)); } |]--SET_STATIC_FIELD(Object, JObject, jobject)-SET_STATIC_FIELD(Boolean, Word8, jboolean)-SET_STATIC_FIELD(Byte, CChar, jbyte)-SET_STATIC_FIELD(Char, Word16, jchar)-SET_STATIC_FIELD(Short, Int16, jshort)-SET_STATIC_FIELD(Int, Int32, jint)-SET_STATIC_FIELD(Long, Int64, jlong)-SET_STATIC_FIELD(Float, Float, jfloat)-SET_STATIC_FIELD(Double, Double, jdouble)--getMethodID-  :: JClass -- ^ A class object as returned by 'findClass'-  -> JNI.String -- ^ Field name-  -> JNI.String -- ^ JNI signature-  -> IO JMethodID-getMethodID cls methodname sig = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString methodname $ \methodnamep ->-    JNI.withString sig $ \sigp ->-    [CU.exp| jmethodID {-      (*$(JNIEnv *env))->GetMethodID($(JNIEnv *env),-                                     $(jclass cls),-                                     $(char *methodnamep),-                                     $(char *sigp)) } |]--getStaticMethodID-  :: JClass -- ^ A class object as returned by 'findClass'-  -> JNI.String -- ^ Field name-  -> JNI.String -- ^ JNI signature-  -> IO JMethodID-getStaticMethodID cls methodname sig = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString methodname $ \methodnamep ->-    JNI.withString sig $ \sigp ->-    [CU.exp| jmethodID {-      (*$(JNIEnv *env))->GetStaticMethodID($(JNIEnv *env),-                                           $(jclass cls),-                                           $(char *methodnamep),-                                           $(char *sigp)) } |]--getObjectClass :: Coercible o (J ty) => o -> IO JClass-getObjectClass (coerce -> upcast -> obj) = withJNIEnv $ \env ->-    [CU.exp| jclass {-      (*$(JNIEnv *env))->GetObjectClass($(JNIEnv *env),-                                        $(jobject obj)) } |]--newGlobalRef :: Coercible o (J ty) => o -> IO o-newGlobalRef (coerce -> upcast -> obj) = withJNIEnv $ \env ->-    fmap coerce $-    [CU.exp| jobject {-      (*$(JNIEnv *env))->NewGlobalRef($(JNIEnv *env),-                                      $(jobject obj)) } |]--deleteGlobalRef :: Coercible o (J ty) => o -> IO ()-deleteGlobalRef (coerce -> upcast -> obj) = withJNIEnv $ \env ->-    [CU.block| void {-      (*$(JNIEnv *env))->DeleteGlobalRef($(JNIEnv *env),-                                         $(jobject obj)); } |]---- Modern CPP does have ## for concatenating strings, but we use the hacky /**/--- comment syntax for string concatenation. This is because GHC passes--- the -traditional flag to the preprocessor by default, which turns off several--- modern CPP features.--#define CALL_METHOD(name, hs_rettype, c_rettype) \-call/**/name/**/Method :: Coercible o (J a) => o -> JMethodID -> [JValue] -> IO hs_rettype; \-call/**/name/**/Method (coerce -> upcast -> obj) method args = withJNIEnv $ \env -> \-    throwIfException env $ \-    withArray args $ \cargs -> \-    [C.exp| c_rettype { \-      (*$(JNIEnv *env))->Call/**/name/**/MethodA($(JNIEnv *env), \-                                               $(jobject obj), \-                                               $(jmethodID method), \-                                               $(jvalue *cargs)) } |]--CALL_METHOD(Void, (), void)-CALL_METHOD(Object, JObject, jobject)-callBooleanMethod :: Coercible o (J a) => o -> JMethodID -> [JValue] -> IO Bool-callBooleanMethod x y z =-    let CALL_METHOD(Boolean, Word8, jboolean)-    in toEnum . fromIntegral <$> callBooleanMethod x y z-CALL_METHOD(Byte, CChar, jbyte)-CALL_METHOD(Char, Word16, jchar)-CALL_METHOD(Short, Int16, jshort)-CALL_METHOD(Int, Int32, jint)-CALL_METHOD(Long, Int64, jlong)-CALL_METHOD(Float, Float, jfloat)-CALL_METHOD(Double, Double, jdouble)--#define CALL_STATIC_METHOD(name, hs_rettype, c_rettype) \-callStatic/**/name/**/Method :: JClass -> JMethodID -> [JValue] -> IO hs_rettype; \-callStatic/**/name/**/Method cls method args = withJNIEnv $ \env -> \-    throwIfException env $ \-    withArray args $ \cargs -> \-    [C.exp| c_rettype { \-      (*$(JNIEnv *env))->CallStatic/**/name/**/MethodA($(JNIEnv *env), \-                                                       $(jclass cls), \-                                                       $(jmethodID method), \-                                                       $(jvalue *cargs)) } |]--CALL_STATIC_METHOD(Void, (), void)-CALL_STATIC_METHOD(Object, JObject, jobject)-callStaticBooleanMethod :: JClass -> JMethodID -> [JValue] -> IO Bool-callStaticBooleanMethod x y z =-    let CALL_STATIC_METHOD(Boolean, Word8, jboolean)-    in toEnum . fromIntegral <$> callStaticBooleanMethod x y z-CALL_STATIC_METHOD(Byte, CChar, jbyte)-CALL_STATIC_METHOD(Char, Word16, jchar)-CALL_STATIC_METHOD(Short, Int16, jshort)-CALL_STATIC_METHOD(Int, Int32, jint)-CALL_STATIC_METHOD(Long, Int64, jlong)-CALL_STATIC_METHOD(Float, Float, jfloat)-CALL_STATIC_METHOD(Double, Double, jdouble)--newObjectArray :: Int32 -> JClass -> IO JObjectArray-newObjectArray sz cls = withJNIEnv $ \env ->-    throwIfException env $-    [CU.exp| jobjectArray {-      (*$(JNIEnv *env))->NewObjectArray($(JNIEnv *env),-                                        $(jsize sz),-                                        $(jclass cls),-                                        NULL) } |]--#define NEW_ARRAY(name, c_rettype) \-new/**/name/**/Array :: Int32 -> IO J/**/name/**/Array; \-new/**/name/**/Array sz = withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.exp| c_rettype/**/Array { \-      (*$(JNIEnv *env))->New/**/name/**/Array($(JNIEnv *env), \-                                              $(jsize sz)) } |]--NEW_ARRAY(Boolean, jboolean)-NEW_ARRAY(Byte, jbyte)-NEW_ARRAY(Char, jchar)-NEW_ARRAY(Short, jshort)-NEW_ARRAY(Int, jint)-NEW_ARRAY(Long, jlong)-NEW_ARRAY(Float, jfloat)-NEW_ARRAY(Double, jdouble)--newString :: Ptr Word16 -> Int32 -> IO JString-newString ptr len = withJNIEnv $ \env ->-    throwIfException env $-    [CU.exp| jstring {-      (*$(JNIEnv *env))->NewString($(JNIEnv *env),-                                   $(jchar *ptr),-                                   $(jsize len)) } |]--getArrayLength :: Coercible o (JArray a) => o -> IO Int32-getArrayLength (coerce -> upcast -> array) = withJNIEnv $ \env ->-    [C.exp| jsize {-      (*$(JNIEnv *env))->GetArrayLength($(JNIEnv *env),-                                        $(jarray array)) } |]--getStringLength :: JString -> IO Int32-getStringLength jstr = withJNIEnv $ \env ->-    [CU.exp| jsize {-      (*$(JNIEnv *env))->GetStringLength($(JNIEnv *env),-                                         $(jstring jstr)) } |]--#define GET_ARRAY_ELEMENTS(name, hs_rettype, c_rettype) \-get/**/name/**/ArrayElements :: J/**/name/**/Array -> IO (Ptr hs_rettype); \-get/**/name/**/ArrayElements (upcast -> array) = withJNIEnv $ \env -> \-    throwIfNull $ \-    [CU.exp| c_rettype* { \-      (*$(JNIEnv *env))->Get/**/name/**/ArrayElements($(JNIEnv *env), \-                                                      $(jobject array), \-                                                      NULL) } |]--GET_ARRAY_ELEMENTS(Boolean, Word8, jboolean)-GET_ARRAY_ELEMENTS(Byte, CChar, jbyte)-GET_ARRAY_ELEMENTS(Char, Word16, jchar)-GET_ARRAY_ELEMENTS(Short, Int16, jshort)-GET_ARRAY_ELEMENTS(Int, Int32, jint)-GET_ARRAY_ELEMENTS(Long, Int64, jlong)-GET_ARRAY_ELEMENTS(Float, Float, jfloat)-GET_ARRAY_ELEMENTS(Double, Double, jdouble)--getStringChars :: JString -> IO (Ptr Word16)-getStringChars jstr = withJNIEnv $ \env ->-    throwIfNull $-    [CU.exp| const jchar* {-      (*$(JNIEnv *env))->GetStringChars($(JNIEnv *env),-                                        $(jstring jstr),-                                        NULL) } |]--#define SET_ARRAY_REGION(name, hs_argtype, c_argtype) \-set/**/name/**/ArrayRegion :: J/**/name/**/Array -> Int32 -> Int32 -> Ptr hs_argtype -> IO (); \-set/**/name/**/ArrayRegion array start len buf = withJNIEnv $ \env -> \-    throwIfException env $ \-    [CU.exp| void { \-      (*$(JNIEnv *env))->Set/**/name/**/ArrayRegion($(JNIEnv *env), \-                                                    $(c_argtype/**/Array array), \-                                                    $(jsize start), \-                                                    $(jsize len), \-                                                    $(c_argtype *buf)) } |]--SET_ARRAY_REGION(Boolean, Word8, jboolean)-SET_ARRAY_REGION(Byte, CChar, jbyte)-SET_ARRAY_REGION(Char, Word16, jchar)-SET_ARRAY_REGION(Short, Int16, jshort)-SET_ARRAY_REGION(Int, Int32, jint)-SET_ARRAY_REGION(Long, Int64, jlong)-SET_ARRAY_REGION(Float, Float, jfloat)-SET_ARRAY_REGION(Double, Double, jdouble)--#define RELEASE_ARRAY_ELEMENTS(name, hs_argtype, c_argtype) \-release/**/name/**/ArrayElements :: J/**/name/**/Array -> Ptr hs_argtype -> IO (); \-release/**/name/**/ArrayElements (upcast -> array) xs = withJNIEnv $ \env -> \-    [CU.exp| void { \-      (*$(JNIEnv *env))->Release/**/name/**/ArrayElements($(JNIEnv *env), \-                                                          $(jobject array), \-                                                          $(c_argtype *xs), \-                                                          JNI_ABORT) } |]--RELEASE_ARRAY_ELEMENTS(Boolean, Word8, jboolean)-RELEASE_ARRAY_ELEMENTS(Byte, CChar, jbyte)-RELEASE_ARRAY_ELEMENTS(Char, Word16, jchar)-RELEASE_ARRAY_ELEMENTS(Short, Int16, jshort)-RELEASE_ARRAY_ELEMENTS(Int, Int32, jint)-RELEASE_ARRAY_ELEMENTS(Long, Int64, jlong)-RELEASE_ARRAY_ELEMENTS(Float, Float, jfloat)-RELEASE_ARRAY_ELEMENTS(Double, Double, jdouble)--releaseStringChars :: JString -> Ptr Word16 -> IO ()-releaseStringChars jstr chars = withJNIEnv $ \env ->-    [CU.exp| void {-      (*$(JNIEnv *env))->ReleaseStringChars($(JNIEnv *env),-                                            $(jstring jstr),-                                            $(jchar *chars)) } |]--getObjectArrayElement :: Coercible o (JArray a) => o -> Int32 -> IO (J a)-getObjectArrayElement (coerce -> upcast -> array) i = withJNIEnv $ \env -> unsafeCast <$>-    [C.exp| jobject {-      (*$(JNIEnv *env))->GetObjectArrayElement($(JNIEnv *env),-                                               $(jarray array),-                                               $(jsize i)) } |]--setObjectArrayElement :: Coercible o (J a) => JObjectArray -> Int32 -> o -> IO ()-setObjectArrayElement array i (coerce -> upcast -> x) = withJNIEnv $ \env ->-    [C.exp| void {-      (*$(JNIEnv *env))->SetObjectArrayElement($(JNIEnv *env),-                                               $(jobjectArray array),-                                               $(jsize i),-                                               $(jobject x)); } |]
src/Foreign/JNI/Types.hs view
@@ -38,6 +38,7 @@   , JMethodID(..)   , JFieldID(..)   , JValue(..)+  , withJValues     -- * JNI defined object types   , JObject   , JClass@@ -63,7 +64,7 @@ import Data.ByteString.Builder (Builder) import Data.Char (chr, ord) import Data.Int-import Data.Map (fromList)+import qualified Data.Map as Map import Data.Monoid ((<>)) import Data.Singletons   ( Sing@@ -74,16 +75,23 @@ #endif   ) import Data.Singletons.TypeLits (KnownSymbol, symbolVal)-import Data.String (fromString) import Data.Word import Foreign.C (CChar)+import Foreign.ForeignPtr+  ( ForeignPtr+  , castForeignPtr+  , newForeignPtr_+  , withForeignPtr+  ) import Foreign.JNI.NativeMethod import qualified Foreign.JNI.String as JNI+import Foreign.Marshal.Alloc (allocaBytesAligned) import Foreign.Ptr import Foreign.Storable (Storable(..)) import GHC.TypeLits (Symbol) import Language.C.Types (TypeSpecifier(TypeName))-import Language.C.Inline.Context (Context(..))+import Language.C.Inline.Context (Context(..), fptrCtx)+import System.IO.Unsafe (unsafePerformIO)  -- | A JVM instance. newtype JVM = JVM_ (Ptr JVM)@@ -122,9 +130,9 @@ instance IsReferenceType ty => IsReferenceType ('Generic ty tys)  data instance Sing (a :: JType) where-  SClass :: JNI.String -> Sing ('Class sym)-  SIface :: JNI.String -> Sing ('Iface sym)-  SPrim :: JNI.String -> Sing ('Prim sym)+  SClass :: String -> Sing ('Class sym)+  SIface :: String -> Sing ('Iface sym)+  SPrim :: String -> Sing ('Prim sym)   SArray :: Sing ty -> Sing ('Array ty)   SGeneric :: Sing ty -> Sing tys -> Sing ('Generic ty tys)   SVoid :: Sing 'Void@@ -132,11 +140,11 @@ -- XXX SingI constraint temporary hack because GHC 7.10 has trouble inferring -- this constraint in 'signature'. instance (KnownSymbol sym, SingI sym) => SingI ('Class (sym :: Symbol)) where-  sing = SClass $ fromString $ symbolVal (undefined :: proxy sym)+  sing = SClass $ symbolVal (undefined :: proxy sym) instance (KnownSymbol sym, SingI sym) => SingI ('Iface (sym :: Symbol)) where-  sing = SIface $ fromString $ symbolVal (undefined :: proxy sym)+  sing = SIface $ symbolVal (undefined :: proxy sym) instance (KnownSymbol sym, SingI sym) => SingI ('Prim (sym :: Symbol)) where-  sing = SPrim $ fromString $ symbolVal (undefined :: proxy sym)+  sing = SPrim $ symbolVal (undefined :: proxy sym) instance SingI ty => SingI ('Array ty) where   sing = SArray sing instance (SingI ty, SingI tys) => SingI ('Generic ty tys) where@@ -148,14 +156,14 @@ type a <> g = 'Generic a g  -- | Type indexed Java Objects.-newtype J (a :: JType) = J (Ptr (J a))-  deriving (Eq, Show, Storable)+newtype J (a :: JType) = J (ForeignPtr (J a))+  deriving (Eq, Show)  type role J representational  -- | The null reference. jnull :: J a-jnull = J nullPtr+jnull = J $ unsafePerformIO $ newForeignPtr_ nullPtr  -- | Any object can be cast to @Object@. upcast :: J a -> JObject@@ -163,7 +171,7 @@  -- | Unsafe type cast. Should only be used to downcast. unsafeCast :: J a -> J b-unsafeCast (J x) = J (castPtr x)+unsafeCast (J x) = J (castForeignPtr x)  -- | Parameterize the type of an object, making its type a /generic type/. generic :: J a -> J (a <> g)@@ -205,25 +213,42 @@   (JLong x) == (JLong y) = x == y   (JFloat x) == (JFloat y) = x == y   (JDouble x) == (JDouble y) = x == y-  (JObject (J x)) == (JObject (J y)) = castPtr x == castPtr y+  (JObject (J x)) == (JObject (J y)) = castForeignPtr x == castForeignPtr y   _ == _ = False -instance Storable JValue where-  sizeOf _ = 8-  alignment _ = 8+sizeOfJValue, alignmentJValue :: Int+sizeOfJValue      = 8+alignmentJValue   = 8 -  poke p (JBoolean x) = poke (castPtr p) x-  poke p (JByte x) = poke (castPtr p) x-  poke p (JChar x) = poke (castPtr p) x-  poke p (JShort x) = poke (castPtr p) x-  poke p (JInt x) = poke (castPtr p) x-  poke p (JLong x) = poke (castPtr p) x-  poke p (JFloat x) = poke (castPtr p) x-  poke p (JDouble x) = poke (castPtr p) x-  poke p (JObject x) = poke (castPtr p :: Ptr (J a)) x+-- | @withJValue jvalues f@ provides a pointer to an array containing the given+-- @jvalues@.+--+-- The array is valid only while evaluating @f@.+withJValues :: [JValue] -> (Ptr JValue -> IO a) -> IO a+withJValues args f =+    allocaBytesAligned (sizeOfJValue * length args) alignmentJValue $ \p ->+      foldr (.) id (zipWith (withJValueOff p) [0..] args) (f p) -  peek _ = error "Storable JValue: undefined peek"+-- @withJValueOff p n jvalue io@ writes the given @jvalue@ to @p `plusPtr` n@+-- and runs @io@.+--+-- The jvalue is guaranteed to stay valid while @io@ evaluates.+withJValueOff :: Ptr JValue -> Int -> JValue -> IO a -> IO a+withJValueOff p n jvalue io = case jvalue of+    JBoolean x -> pokeByteOff (castPtr p) offset x >> io+    JByte    x -> pokeByteOff (castPtr p) offset x >> io+    JChar    x -> pokeByteOff (castPtr p) offset x >> io+    JShort   x -> pokeByteOff (castPtr p) offset x >> io+    JInt     x -> pokeByteOff (castPtr p) offset x >> io+    JLong    x -> pokeByteOff (castPtr p) offset x >> io+    JFloat   x -> pokeByteOff (castPtr p) offset x >> io+    JDouble  x -> pokeByteOff (castPtr p) offset x >> io +    JObject (J x) -> withForeignPtr x $ \xp ->+      pokeByteOff (castPtr p) offset xp >> io+  where+    offset = n * sizeOfJValue+ -- | Get the Java type of a value. #if MIN_VERSION_singletons(2,2,0) jtypeOf :: JValue -> SomeSing JType@@ -257,9 +282,10 @@ referenceTypeName (SGeneric ty@(SIface _) _) = referenceTypeName ty referenceTypeName _ = error "referenceTypeName: Impossible." -classSymbolBuilder :: JNI.String -> Builder+classSymbolBuilder :: String -> Builder classSymbolBuilder sym =-    Prim.primMapByteStringFixed (subst Prim.>$< Prim.word8) (JNI.toByteString sym)+    Prim.primMapByteStringFixed (subst Prim.>$< Prim.word8)+      (JNI.toByteString $ JNI.fromChars sym)   where     subst (chr . fromIntegral -> '.') = fromIntegral (ord '/')     subst x = x@@ -275,7 +301,7 @@ signatureBuilder (SPrim "long") = Builder.char7 'J' signatureBuilder (SPrim "float") = Builder.char7 'F' signatureBuilder (SPrim "double") = Builder.char7 'D'-signatureBuilder (SPrim sym) = error $ "Unknown primitive: " ++ show sym+signatureBuilder (SPrim sym) = error $ "Unknown primitive: " ++ sym signatureBuilder (SArray ty) = Builder.char7 '[' <> signatureBuilder ty signatureBuilder (SGeneric ty _) = signatureBuilder ty signatureBuilder SVoid = Builder.char7 'V'@@ -317,7 +343,7 @@ type JDoubleArray = JArray ('Prim "double")  jniCtx :: Context-jniCtx = mempty { ctxTypesTable = fromList tytab }+jniCtx = mempty { ctxTypesTable = Map.fromList tytab } <> fptrCtx   where     tytab =       [ -- Primitive types@@ -330,20 +356,20 @@       , (TypeName "jfloat", [t| Float |])       , (TypeName "jdouble", [t| Double |])       -- Reference types-      , (TypeName "jobject", [t| JObject |])-      , (TypeName "jclass", [t| JClass |])-      , (TypeName "jstring", [t| JString |])-      , (TypeName "jarray", [t| JObject |])-      , (TypeName "jobjectArray", [t| JObjectArray |])-      , (TypeName "jbooleanArray", [t| JBooleanArray |])-      , (TypeName "jbyteArray", [t| JByteArray |])-      , (TypeName "jcharArray", [t| JCharArray |])-      , (TypeName "jshortArray", [t| JShortArray |])-      , (TypeName "jintArray", [t| JIntArray |])-      , (TypeName "jlongArray", [t| JLongArray |])-      , (TypeName "jfloatArray", [t| JFloatArray |])-      , (TypeName "jdoubleArray", [t| JDoubleArray |])-      , (TypeName "jthrowable", [t| JThrowable |])+      , (TypeName "jobject", [t| Ptr JObject |])+      , (TypeName "jclass", [t| Ptr JClass |])+      , (TypeName "jstring", [t| Ptr JString |])+      , (TypeName "jarray", [t| Ptr JObject |])+      , (TypeName "jobjectArray", [t| Ptr JObjectArray |])+      , (TypeName "jbooleanArray", [t| Ptr JBooleanArray |])+      , (TypeName "jbyteArray", [t| Ptr JByteArray |])+      , (TypeName "jcharArray", [t| Ptr JCharArray |])+      , (TypeName "jshortArray", [t| Ptr JShortArray |])+      , (TypeName "jintArray", [t| Ptr JIntArray |])+      , (TypeName "jlongArray", [t| Ptr JLongArray |])+      , (TypeName "jfloatArray", [t| Ptr JFloatArray |])+      , (TypeName "jdoubleArray", [t| Ptr JDoubleArray |])+      , (TypeName "jthrowable", [t| Ptr JThrowable |])       -- Internal types       , (TypeName "JavaVM", [t| JVM |])       , (TypeName "JNIEnv", [t| JNIEnv |])