packages feed

jni 0.5.0 → 0.5.1

raw patch · 4 files changed

+1738/−992 lines, 4 filesdep ~inline-c

Dependency ranges changed: inline-c

Files

jni.cabal view
@@ -1,5 +1,5 @@ name:                jni-version:             0.5.0+version:             0.5.1 synopsis:            Complete JNI raw bindings. description:         Please see README.md. homepage:            https://github.com/tweag/inline-java/tree/master/jni#readme@@ -32,16 +32,16 @@   other-modules:     Foreign.JNI.NativeMethod   build-depends:-    base >= 4.7 && < 5,+    base >=4.7 && <5,     bytestring >=0.10,-    choice >= 0.2.0,+    choice >=0.2.0,     containers >=0.5,     constraints >=0.8,-    deepseq >= 1.4.2,-    singletons >= 2.0+    deepseq >=1.4.2,+    singletons >=2.0   if impl(ghc < 8.2.1)     build-depends:-      inline-c >=0.5.6.1+      inline-c >=0.5.6.1 && <0.6   else     build-depends:       inline-c >=0.6
src/Foreign/JNI.c view
@@ -0,0 +1,745 @@++#include <jni.h>++#include <stdio.h>++#include <errno.h>++#include <stdlib.h>++static __thread JNIEnv* jniEnv; ++jthrowable inline_c_Foreign_JNI_0_547acbc2ed14c804f8e5133e90bd68e8a83f9c40(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {+return ( (*env_inline_c_0)->ExceptionOccurred(env_inline_c_1) );+}+++void inline_c_Foreign_JNI_1_78814a28f200ba50ae6a800d1c57dc6512afa523(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {+ (*env_inline_c_0)->ExceptionDescribe(env_inline_c_1) ;+}+++void inline_c_Foreign_JNI_2_fa3d0bf0766f27928a66a4776f60d76979f8c97d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {+ (*env_inline_c_0)->ExceptionClear(env_inline_c_1) ;+}+++jint inline_c_Foreign_JNI_3_4732b21c46e22bd0b636479445ab969eac58c90f() {+return ( JNI_OK );+}+++jint inline_c_Foreign_JNI_4_e4f86790d79a32d6ee762a76428f9737dcfd28e4() {+return ( JNI_EDETACHED );+}+++jint inline_c_Foreign_JNI_5_11ef4c1fdcde263336fdb13b08ff0f2e19d0df2f(JavaVM * jvm_inline_c_0, JavaVM * jvm_inline_c_1) {+return (+        (*jvm_inline_c_0)->AttachCurrentThreadAsDaemon(jvm_inline_c_1, &jniEnv, NULL)+      );+}+++jint inline_c_Foreign_JNI_6_ea397df40babee4a972104da3a793b58426edf8b(JavaVM * jvm_inline_c_0, JavaVM * jvm_inline_c_1) {++      int rc = (*jvm_inline_c_0)->DetachCurrentThread(jvm_inline_c_1);+      if (rc == JNI_OK)+        jniEnv = NULL;+      return rc;+    +}+++jint inline_c_Foreign_JNI_7_abd19e7710ee92af6af62dba0642a93990484215(JavaVM ** pjvm_inline_c_0, jsize * pnum_jvms_inline_c_1) {+return (+        JNI_GetCreatedJavaVMs(pjvm_inline_c_0, 1, pnum_jvms_inline_c_1)+      );+}+++JNIEnv * inline_c_Foreign_JNI_8_43fe8189512df285da66021808b0754ca40f395a() {+return ( jniEnv );+}+++jint inline_c_Foreign_JNI_9_8e0aa50b329d6b67b682632f070f9d76ef38dd38(JavaVM * jvm_inline_c_0, JavaVM * jvm_inline_c_1) {+return (+          (*jvm_inline_c_0)->GetEnv(jvm_inline_c_1, (void**)&jniEnv, JNI_VERSION_1_6)+        );+}+++JNIEnv * inline_c_Foreign_JNI_10_43fe8189512df285da66021808b0754ca40f395a() {+return ( jniEnv );+}+++JavaVM * inline_c_Foreign_JNI_11_567b31ebdc829d5f3987ca20c011e0704e8241fa(int n_inline_c_0, int n_inline_c_1, char ** coptions_inline_c_2, int n_inline_c_3) {++          JavaVM *jvm;+          JavaVMInitArgs vm_args;+          JavaVMOption *options = malloc(sizeof(JavaVMOption) * n_inline_c_0);+          for(int i = 0; i < n_inline_c_1; i++)+                  options[i].optionString = coptions_inline_c_2[i];+          vm_args.version = JNI_VERSION_1_6;+          vm_args.nOptions = n_inline_c_3;+          vm_args.options = options;+          vm_args.ignoreUnrecognized = 0;+          JNI_CreateJavaVM(&jvm, (void**)&jniEnv, &vm_args);+          free(options);+          return jvm; +}+++void inline_c_Foreign_JNI_12_1292fdfa6a16275159c7a7a90ac6ee443f45ad6c(JavaVM * jvm_inline_c_0, JavaVM * jvm_inline_c_1) {++        (*jvm_inline_c_0)->DestroyJavaVM(jvm_inline_c_1);+        jniEnv = NULL;+    +}+++jclass inline_c_Foreign_JNI_13_8c440e181516a3630ffa1c69f19cdd49c5ea5146(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, char * namep_inline_c_2, jobject loader_inline_c_3, char * buf_inline_c_4, long buf_inline_c_5) {+return (+      (*env_inline_c_0)->DefineClass(env_inline_c_1,+                                     namep_inline_c_2,+                                     loader_inline_c_3,+                                     buf_inline_c_4,+                                     buf_inline_c_5) );+}+++jint inline_c_Foreign_JNI_14_b2b4b4a025c54c183ac34fda20ed77aaa1cbd6ed(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, JNINativeMethod * cmethods_inline_c_3, int numMethods_inline_c_4) {+return (+             (*env_inline_c_0)->RegisterNatives(env_inline_c_1,+                                                cls_inline_c_2,+                                                cmethods_inline_c_3,+                                                numMethods_inline_c_4) );+}+++jint inline_c_Foreign_JNI_15_7da57142503fa6323136b7c159710e69a3507ecd(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+return (+       (*env_inline_c_0)->Throw(env_inline_c_1,+                                obj_inline_c_2) );+}+++jint inline_c_Foreign_JNI_16_28bfcee12881af1c4a1c7de9b19c8263659c32d9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * msgp_inline_c_3) {+return (+       (*env_inline_c_0)->ThrowNew(env_inline_c_1,+                                   cls_inline_c_2,+                                   msgp_inline_c_3) );+}+++jclass inline_c_Foreign_JNI_17_98f2efdfb85a70a64012d4a321b2e1b53ec6d783(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, char * namep_inline_c_2) {+return ( (*env_inline_c_0)->FindClass(env_inline_c_1, namep_inline_c_2) );+}+++jobject inline_c_Foreign_JNI_18_db79f2d25dd672f2593a68b078850f23bf59b54d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID constr_inline_c_3, jvalue * cargs_inline_c_4) {+return (+        (*env_inline_c_0)->NewObjectA(env_inline_c_1,+                                      cls_inline_c_2,+                                      constr_inline_c_3,+                                      cargs_inline_c_4) );+}+++jfieldID inline_c_Foreign_JNI_19_24f9a5b843f700dd367457745083b0f737727165(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * fieldnamep_inline_c_3, char * sigp_inline_c_4) {+return (+      (*env_inline_c_0)->GetFieldID(env_inline_c_1,+                                    cls_inline_c_2,+                                    fieldnamep_inline_c_3,+                                    sigp_inline_c_4) );+}+++jfieldID inline_c_Foreign_JNI_20_7f51c9e3dfc10d19fa55f2bad6ee5d30c55df36e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * fieldnamep_inline_c_3, char * sigp_inline_c_4) {+return (+      (*env_inline_c_0)->GetStaticFieldID(env_inline_c_1,+                                          cls_inline_c_2,+                                          fieldnamep_inline_c_3,+                                          sigp_inline_c_4) );+}+++jobject inline_c_Foreign_JNI_21_d3bbd4f49ae66a171a74a554b1ad29de1e653fbe(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetObjectField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jboolean inline_c_Foreign_JNI_22_a6c318bded4eb76e31688bb79797fe16d6ad53cd(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetBooleanField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jbyte inline_c_Foreign_JNI_23_ce49e2a35bd9168e5441c414c23484ab5ed3bfd1(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetByteField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jchar inline_c_Foreign_JNI_24_c943f6f26c7dc18be8ee2dbae90e076a32d0bc7b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetCharField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jshort inline_c_Foreign_JNI_25_4f9206f7afb17d7f7a4ca9c25e5e6ed84e09389c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetShortField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jint inline_c_Foreign_JNI_26_0163f5dc997937b24f9a57dbb7fac4a42db7f087(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetIntField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jlong inline_c_Foreign_JNI_27_46309075736c07065202cd83573f912c5501b005(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetLongField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jfloat inline_c_Foreign_JNI_28_2c66977fbc363fd8fb05ce6ab75fd556531d5a17(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetFloatField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jdouble inline_c_Foreign_JNI_29_272ef095b5f25c1f0f9482e390b6a782adff8c47(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetDoubleField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );+}+++jobject inline_c_Foreign_JNI_30_5c71747967eb4276bca3e20b379750babbebda8e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticObjectField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jboolean inline_c_Foreign_JNI_31_b176fa5abc4a517382107db7f9cf6e9d39f42790(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticBooleanField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jbyte inline_c_Foreign_JNI_32_27a626282a93b144decfac0d91b1620bd593f9b3(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticByteField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jchar inline_c_Foreign_JNI_33_a04d9bdb806b0e16000ef35f7159e5dd16b3dd70(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticCharField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jshort inline_c_Foreign_JNI_34_5bbf8ff1a31ec47edf1a6f51423acec6a8c165d9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticShortField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jint inline_c_Foreign_JNI_35_e412724b75f372f7be355611dc8047fb9ae1126b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticIntField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jlong inline_c_Foreign_JNI_36_89d32b3c2be6d4e4e01285d42a1845567da8d5ef(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticLongField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jfloat inline_c_Foreign_JNI_37_fb5c2b1d3de9b233f712bd7c5d5e38deb356b1e9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticFloatField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++jdouble inline_c_Foreign_JNI_38_492512f55c5b7ee515200d9a8a08009e7788aa22(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {+return (       (*env_inline_c_0)->GetStaticDoubleField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );+}+++void inline_c_Foreign_JNI_39_584abfc1ea057f29617db577aa8a7bcf87c50277(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jobject x_inline_c_4) {+       (*env_inline_c_0)->SetObjectField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_40_d740752f4e956bdbcfdeb49ad9c4daac79454740(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jboolean x_inline_c_4) {+       (*env_inline_c_0)->SetBooleanField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_41_7c7e899dc92453c6973878ad7b630dca1101ec2f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jbyte x_inline_c_4) {+       (*env_inline_c_0)->SetByteField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_42_77351519d67b4f4ab49c6b1dc32a190a8f7a2524(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jchar x_inline_c_4) {+       (*env_inline_c_0)->SetCharField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_43_cbc8c11ddfd08b4a88953c743e6ea91feb0ac607(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jshort x_inline_c_4) {+       (*env_inline_c_0)->SetShortField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_44_f318d1d52db33d7bf0dc7e5c6e9e0a71484ecb5d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jint x_inline_c_4) {+       (*env_inline_c_0)->SetIntField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_45_0d005c04266d114f3826b408c1b80edae3cd0fe9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jlong x_inline_c_4) {+       (*env_inline_c_0)->SetLongField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_46_6a8a9ce4e7e8acae90231495db2fd8854b488d5d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jfloat x_inline_c_4) {+       (*env_inline_c_0)->SetFloatField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_47_c3947546832da8a398f347c27908ee58b78f6b9d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jdouble x_inline_c_4) {+       (*env_inline_c_0)->SetDoubleField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); +}+++void inline_c_Foreign_JNI_48_b84acff3f2e26a2a2d4e3f2a7fa46cdfbc099912(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jobject x_inline_c_4) {+       (*env_inline_c_0)->SetStaticObjectField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_49_a02725e5169b86b9c1c527aaf96872a055940707(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jboolean x_inline_c_4) {+       (*env_inline_c_0)->SetStaticBooleanField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_50_a3232ebc0e49f3217ef3dd1bce52bbb83462aede(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jbyte x_inline_c_4) {+       (*env_inline_c_0)->SetStaticByteField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_51_6e323e9e26073d2c2b53ede3444cdf73ce5b4aad(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jchar x_inline_c_4) {+       (*env_inline_c_0)->SetStaticCharField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_52_f6cfa9b49f03261d0c67c68fb9595a818e3e28cb(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jshort x_inline_c_4) {+       (*env_inline_c_0)->SetStaticShortField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_53_f382d7603879ddb1eca55b052c49ed4b418e2cc7(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jint x_inline_c_4) {+       (*env_inline_c_0)->SetStaticIntField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_54_02c96789057bffbad5c0921c8e94f8ffc7f6a392(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jlong x_inline_c_4) {+       (*env_inline_c_0)->SetStaticLongField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_55_2f1ae23c6909cb66e439ed94bb49a5b5b117268c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jfloat x_inline_c_4) {+       (*env_inline_c_0)->SetStaticFloatField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++void inline_c_Foreign_JNI_56_3f17c8ae6483640141674f2ae41409e830a60690(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jdouble x_inline_c_4) {+       (*env_inline_c_0)->SetStaticDoubleField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); +}+++jmethodID inline_c_Foreign_JNI_57_e722a7a0d6891db8a6cda0ec21cc6312aaeec3c0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * methodnamep_inline_c_3, char * sigp_inline_c_4) {+return (+      (*env_inline_c_0)->GetMethodID(env_inline_c_1,+                                     cls_inline_c_2,+                                     methodnamep_inline_c_3,+                                     sigp_inline_c_4) );+}+++jmethodID inline_c_Foreign_JNI_58_196e9055f6891bfa3cf856c108612c9572ecc877(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * methodnamep_inline_c_3, char * sigp_inline_c_4) {+return (+      (*env_inline_c_0)->GetStaticMethodID(env_inline_c_1,+                                           cls_inline_c_2,+                                           methodnamep_inline_c_3,+                                           sigp_inline_c_4) );+}+++jclass inline_c_Foreign_JNI_59_9f847198f949d76076adbd2e63e17b2ed0e73c41(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+return (+      (*env_inline_c_0)->GetObjectClass(env_inline_c_1,+                                        obj_inline_c_2) );+}+++jobject inline_c_Foreign_JNI_60_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) );+}+++jobject inline_c_Foreign_JNI_61_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) );+}+++void inline_c_Foreign_JNI_62_f542a39c35a9eb0c083a4e59c4f21de5ad94e141(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {+ (*env_inline_c_0)->DeleteGlobalRef(env_inline_c_1+                                                            ,obj_inline_c_2);+                        +}+++jobject inline_c_Foreign_JNI_63_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) );+}+++void inline_c_Foreign_JNI_64_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) ;+}+++jint inline_c_Foreign_JNI_65_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_66_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) );+}+++void inline_c_Foreign_JNI_67_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) ;+}+++jobject inline_c_Foreign_JNI_68_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) );+}+++jboolean inline_c_Foreign_JNI_69_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) );+}+++jbyte inline_c_Foreign_JNI_70_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) );+}+++jchar inline_c_Foreign_JNI_71_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) );+}+++jshort inline_c_Foreign_JNI_72_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) );+}+++jint inline_c_Foreign_JNI_73_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) );+}+++jlong inline_c_Foreign_JNI_74_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) );+}+++jfloat inline_c_Foreign_JNI_75_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_76_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_77_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_78_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_79_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_80_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_81_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_82_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_83_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_84_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_85_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_86_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_87_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,+                                        cls_inline_c_3,+                                        NULL) );+}+++jbooleanArray inline_c_Foreign_JNI_88_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_89_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_90_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_91_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_92_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_93_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_94_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_95_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_96_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,+                                   len_inline_c_3) );+}+++jsize inline_c_Foreign_JNI_97_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_98_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_99_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_100_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_101_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_102_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_103_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_104_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_105_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_106_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_107_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,+                                        NULL) );+}+++void inline_c_Foreign_JNI_108_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_109_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_110_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_111_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_112_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_113_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_114_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_115_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_116_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_117_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_118_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_119_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_120_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_121_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_122_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_123_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_124_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,+                                            chars_inline_c_3) ;+}+++jobject inline_c_Foreign_JNI_125_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,+                                               i_inline_c_3) );+}+++void inline_c_Foreign_JNI_126_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,+                                               i_inline_c_3,+                                               x_inline_c_4); ;+}+
− src/Foreign/JNI.cpphs
@@ -1,986 +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 DataKinds #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# 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 management-    withJVM-  , newJVM-  , destroyJVM-    -- ** Class loading-  , defineClass-  , JNINativeMethod(..)-  , registerNatives-    -- ** String wrappers-  , ReferenceTypeName-  , MethodSignature-  , Signature-    -- ** Exceptions-  , JVMException(..)-  , throw-  , throwNew-    -- ** Query functions-  , findClass-  , getFieldID-  , getStaticFieldID-  , getMethodID-  , getStaticMethodID-  , getObjectClass-    -- ** Reference manipulation-  , newGlobalRef-  , deleteGlobalRef-  , newGlobalRefNonFinalized-  , deleteGlobalRefNonFinalized-  , 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(..)-  , NullPointerException(..)-  , 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-    -- * Thread management-  , attachCurrentThreadAsDaemon-  , detachCurrentThread-  , runInAttachedThread-  ) where--import Control.Concurrent (isCurrentThreadBound, rtsSupportsBoundThreads)-import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)-import Control.Exception (Exception, bracket, bracket_, catch, finally, throwIO)-import Control.Monad (join, unless, void, when)-import Data.Choice-import Data.Coerce-import Data.Int-import Data.IORef (IORef, newIORef, atomicModifyIORef)-import Data.Word-import Data.ByteString (ByteString)-import qualified Data.ByteString as BS-import Data.Monoid ((<>))-import Data.Typeable (Typeable)-import Foreign.C (CChar)-import Foreign.ForeignPtr-  ( finalizeForeignPtr-  , newForeignPtr_-  , withForeignPtr-  )-import Foreign.JNI.Internal-import Foreign.JNI.NativeMethod-import Foreign.JNI.Types-import qualified Foreign.JNI.String as JNI-import Foreign.Marshal.Alloc (alloca)-import Foreign.Marshal.Array-import Foreign.Ptr (Ptr, nullPtr)-import Foreign.Storable (peek)-import GHC.ForeignPtr (newConcForeignPtr)-import GHC.Stack (HasCallStack, callStack, getCallStack, prettySrcLoc)-import qualified Language.C.Inline as C-import qualified Language.C.Inline.Unsafe as CU-import System.IO (fixIO)-import System.IO.Unsafe (unsafePerformIO)-import Prelude hiding (String)-import qualified Prelude--C.context (C.baseCtx <> C.bsCtx <> jniCtx)--C.include "<jni.h>"-C.include "<stdio.h>"-C.include "<errno.h>"-C.include "<stdlib.h>"---- A thread-local variable to cache the JNI environment. Accessing this variable--- is faster than calling @jvm->GetEnv()@.-$(C.verbatim "static __thread JNIEnv* jniEnv; ")---- | 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 (Exception, Show, Typeable)---- | A null reference is found where a non-null reference was expected.-data NullPointerException = NullPointerException-  deriving (Exception, Show, Typeable)---- | A JNI call is made from a thread not attached to the JVM.-data ThreadNotAttached = ThreadNotAttached-  deriving (Exception, Show, Typeable)---- | A JNI call is made from an unbound thread.-data ThreadNotBound = ThreadNotBound-  deriving (Exception, Show, Typeable)---- | Thrown when an JNI call is made from an unbound thread.-data JNIError = JNIError Prelude.String Int32-  deriving (Show, Typeable)--instance Exception JNIError---- | 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---- | Throws an error if the given reference is null, otherwise performs--- the given io action.-throwIfJNull :: J ty -> IO a -> IO a-throwIfJNull j io =-    if j == jnull-    then throwIO NullPointerException-    else io---- | 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.-      (1, 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 $ \(readers, _) ->-      ((readers, Writing mv), when (readers > 0) (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 #-}--throwIfNotOK_ :: HasCallStack => IO Int32 -> IO ()-throwIfNotOK_ m = m >>= \case-  rc-    | rc == [CU.pure| jint { JNI_OK } |] -> return ()-    | rc == [CU.pure| jint { JNI_EDETACHED } |] -> throwIO ThreadNotAttached-    | otherwise -> throwIO $ JNIError (prettySrcLoc loc) rc-  where-    (_, loc):_ = getCallStack callStack--attachCurrentThreadAsDaemon :: IO ()-attachCurrentThreadAsDaemon = do-    throwIfNotOK_-      [CU.exp| jint {-        (*$(JavaVM* jvm))->AttachCurrentThreadAsDaemon($(JavaVM* jvm), &jniEnv, NULL)-      } |]--detachCurrentThread :: IO ()-detachCurrentThread =-    throwIfNotOK_-    [CU.block| jint {-      int rc = (*$(JavaVM* jvm))->DetachCurrentThread($(JavaVM* jvm));-      if (rc == JNI_OK)-        jniEnv = NULL;-      return rc;-    } |]---- | Attaches the calling thread to the JVM, runs the given IO action and--- then detaches the thread.------ If the thread is already attached no attaching and detaching is performed.-runInAttachedThread :: IO a -> IO a-runInAttachedThread io = do-    attached <--      catch (getJNIEnv >> return True) (\ThreadNotBound -> return False)-    if attached-    then io-    else bracket_-          attachCurrentThreadAsDaemon-          detachCurrentThread-          io---- | The current JVM------ Assumes there's at most one JVM. The current JNI spec (2016) says only--- one JVM per process is supported anyways.-{-# NOINLINE jvm #-}-jvm :: Ptr JVM-jvm = unsafePerformIO $ alloca $ \pjvm -> alloca $ \pnum_jvms -> do-    throwIfNotOK_-      [CU.exp| jint {-        JNI_GetCreatedJavaVMs($(JavaVM** pjvm), 1, $(jsize* pnum_jvms))-      }|]-    num_jvms <- peek pnum_jvms-    when (num_jvms == 0) $-      fail "JNI_GetCreatedJavaVMs: No JVM has been initialized yet."-    when (num_jvms > 1) $-      fail "JNI_GetCreatedJavaVMs: There are multiple JVMs but only one is supported."-    peek pjvm---- | Yields the JNIEnv of the calling thread.------ Yields @Nothing@ if the calling thread is not attached to the JVM.-getJNIEnv :: IO (Ptr JNIEnv)-getJNIEnv = [CU.exp| JNIEnv* { jniEnv } |] >>= \case-    env | env == nullPtr -> do-      throwIfNotOK_-        [CU.exp| jint {-          (*$(JavaVM* jvm))->GetEnv($(JavaVM* jvm), (void**)&jniEnv, JNI_VERSION_1_6)-        }|]-      [CU.exp| JNIEnv* { jniEnv } |]-    env -> return env---- | Run an action against the appropriate 'JNIEnv'.------ Each OS thread has its own 'JNIEnv', which this function gives access to.-withJNIEnv :: (Ptr JNIEnv -> IO a) -> IO a-withJNIEnv f = getJNIEnv >>= f--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 'withJVM' instead. Only useful for GHCi.-newJVM :: [ByteString] -> IO JVM-newJVM options = JVM_ <$> do-    useAsCStrings options $ \cstrs -> do-      withArray cstrs $ \(coptions :: Ptr (Ptr CChar)) -> do-        let n = fromIntegral (length cstrs) :: C.CInt-        checkBoundness-        [C.block| JavaVM * {-          JavaVM *jvm;-          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**)&jniEnv, &vm_args);-          free(options);-          return jvm; } |]--  where-    checkBoundness :: IO ()-    checkBoundness = when rtsSupportsBoundThreads $ do-      bound <- isCurrentThreadBound-      unless bound (throwIO ThreadNotBound)---- | Deallocate a 'JVM' created using 'newJVM'.-destroyJVM :: JVM -> IO ()-destroyJVM (JVM_ jvm) = do-    acquireWriteLock globalJVMLock-    [C.block| void {-        (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm));-        jniEnv = NULL;-    } |]---- | Create a new JVM, with the given arguments. Destroy it once the given--- action completes. /Can only be called once/. Best practice: use it to wrap--- your @main@ function.-withJVM :: [ByteString] -> IO a -> IO a-withJVM options action = bracket (newJVM options) destroyJVM (const action)--defineClass-  :: Coercible o (J ('Class "java.lang.ClassLoader"))-  => ReferenceTypeName -- ^ Class name-  -> o -- ^ Loader-  -> ByteString -- ^ Bytecode buffer-  -> IO JClass-defineClass (coerce -> 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 = throwIfJNull cls $ withJNIEnv $ \env ->-    JNI.withString msg $ \msgp -> void $ do-    [CU.exp| jint {-       (*$(JNIEnv *env))->ThrowNew($(JNIEnv *env),-                                   $fptr-ptr:(jclass cls),-                                   $(char *msgp)) } |]--findClass-  :: ReferenceTypeName -- ^ Class name-  -> IO JClass-findClass (coerce -> name) = withJNIEnv $ \env ->-    throwIfException env $-    JNI.withString name $ \namep ->-    objectFromPtr =<<-    [CU.exp| jclass { (*$(JNIEnv *env))->FindClass($(JNIEnv *env), $(char *namep)) } |]--newObject :: JClass -> MethodSignature -> [JValue] -> IO JObject-newObject cls (coerce -> sig) args = throwIfJNull cls $ 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-  -> Signature -- ^ JNI signature-  -> IO JFieldID-getFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $-    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-  -> Signature -- ^ JNI signature-  -> IO JFieldID-getStaticFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $-    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 = throwIfJNull klass $ \-    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 = throwIfJNull klass $ \-    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-  -> MethodSignature -- ^ JNI signature-  -> IO JMethodID-getMethodID cls methodname (coerce -> sig) = throwIfJNull cls $-    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-  -> MethodSignature -- ^ JNI signature-  -> IO JMethodID-getStaticMethodID cls methodname (coerce -> sig) = throwIfJNull cls $-    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) = throwIfJNull 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)) } |]-    fixIO $ \j ->-      coerce <$> J <$> newConcForeignPtr gobj (deleteGlobalRefNonFinalized j)--deleteGlobalRef :: Coercible o (J ty) => o -> IO ()-deleteGlobalRef (coerce -> J p) = finalizeForeignPtr p---- | Like 'newGlobalRef' but it doesn't attach a finalizer to destroy--- the reference when it is not longer reachable. Use--- 'deleteGlobalRefNonFinalized' to destroy this reference.-newGlobalRefNonFinalized :: Coercible o (J ty) => o -> IO o-newGlobalRefNonFinalized (coerce -> upcast -> obj) = withJNIEnv $ \env -> do-    gobj <--      [CU.exp| jobject {-        (*$(JNIEnv *env))->NewGlobalRef($(JNIEnv *env),-                                        $fptr-ptr:(jobject obj)) } |]-    coerce <$> J <$> newForeignPtr_ gobj---- | Like 'deleteGlobalRef' but it can be used only on references created with--- 'newGlobalRefNonFinalized'.-deleteGlobalRefNonFinalized :: Coercible o (J ty) => o -> IO ()-deleteGlobalRefNonFinalized (coerce -> upcast -> obj) = do-    bracket (tryAcquireReadLock globalJVMLock)-            (\doRead -> when (toBool doRead) $ releaseReadLock globalJVMLock)-            $ \doRead ->-      when (toBool doRead) $ withJNIEnv $ \env -> do-        [CU.block| void { (*$(JNIEnv *env))->DeleteGlobalRef($(JNIEnv *env)-                                                            ,$fptr-ptr:(jobject obj));-                        } |]---- 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 = throwIfJNull cls $ \-    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 = throwIfJNull 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) = throwIfJNull array $-    withJNIEnv $ \env ->-    [C.exp| jsize {-      (*$(JNIEnv *env))->GetArrayLength($(JNIEnv *env),-                                        $fptr-ptr:(jarray array)) } |]--getStringLength :: JString -> IO Int32-getStringLength jstr = throwIfJNull 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) = throwIfJNull 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 = throwIfJNull 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 = throwIfJNull array $ \-    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 = throwIfJNull array $ \-    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 = throwIfJNull jstr $ withJNIEnv $ \env ->-    [CU.exp| void {-      (*$(JNIEnv *env))->ReleaseStringChars($(JNIEnv *env),-                                            $fptr-ptr:(jstring jstr),-                                            $(jchar *chars)) } |]--getObjectArrayElement-  :: forall a o.-     (IsReferenceType a, Coercible o (J a))-  => JArray a-  -> Int32-  -> IO o-getObjectArrayElement (arrayUpcast -> array) i = throwIfJNull array $-    withJNIEnv $ \env ->-    ( (coerce :: J a -> o)-    . (unsafeCast :: JObject -> J a)-    ) <$> (objectFromPtr =<<)-    [C.exp| jobject {-      (*$(JNIEnv *env))->GetObjectArrayElement($(JNIEnv *env),-                                               $fptr-ptr:(jarray array),-                                               $(jsize i)) } |]--setObjectArrayElement-  :: forall a o.-     (IsReferenceType a, Coercible o (J a))-  => JArray a-  -> Int32-  -> o-  -> IO ()-setObjectArrayElement (arrayUpcast -> array)-                      i-                      ((coerce :: o -> J a) -> upcast -> x) =-    throwIfJNull array $-    withJNIEnv $ \env ->-    [C.exp| void {-      (*$(JNIEnv *env))->SetObjectArrayElement($(JNIEnv *env),-                                               $fptr-ptr:(jobjectArray array),-                                               $(jsize i),-                                               $fptr-ptr:(jobject x)); } |]
+ src/Foreign/JNI.hs view
@@ -0,0 +1,987 @@+-- | 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 DeriveAnyClass #-}+{-# 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 management+    withJVM+  , newJVM+  , destroyJVM+    -- ** Class loading+  , defineClass+  , JNINativeMethod(..)+  , registerNatives+    -- ** String wrappers+  , ReferenceTypeName+  , MethodSignature+  , Signature+    -- ** Exceptions+  , JVMException(..)+  , throw+  , throwNew+    -- ** Query functions+  , findClass+  , getFieldID+  , getStaticFieldID+  , getMethodID+  , getStaticMethodID+  , getObjectClass+    -- ** Reference manipulation+  , newGlobalRef+  , deleteGlobalRef+  , newGlobalRefNonFinalized+  , deleteGlobalRefNonFinalized+  , 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(..)+  , NullPointerException(..)+  , 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+    -- * Thread management+  , attachCurrentThreadAsDaemon+  , detachCurrentThread+  , runInAttachedThread+  ) where++import Control.Concurrent (isCurrentThreadBound, rtsSupportsBoundThreads)+import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)+import Control.Exception (Exception, bracket, bracket_, catch, finally, throwIO)+import Control.Monad (join, unless, void, when)+import Data.Choice+import Data.Coerce+import Data.Int+import Data.IORef (IORef, newIORef, atomicModifyIORef)+import Data.Word+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.Monoid ((<>))+import Data.Typeable (Typeable)+import Foreign.C (CChar)+import Foreign.ForeignPtr+  ( finalizeForeignPtr+  , newForeignPtr_+  , withForeignPtr+  )+import Foreign.JNI.Internal+import Foreign.JNI.NativeMethod+import Foreign.JNI.Types+import qualified Foreign.JNI.String as JNI+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Array+import Foreign.Ptr (Ptr, nullPtr)+import Foreign.Storable (peek)+import GHC.ForeignPtr (newConcForeignPtr)+import GHC.Stack (HasCallStack, callStack, getCallStack, prettySrcLoc)+import qualified Language.C.Inline as C+import qualified Language.C.Inline.Unsafe as CU+import System.IO (fixIO)+import System.IO.Unsafe (unsafePerformIO)+import Prelude hiding (String)+import qualified Prelude++C.context (C.baseCtx <> C.bsCtx <> jniCtx)++C.include "<jni.h>"+C.include "<stdio.h>"+C.include "<errno.h>"+C.include "<stdlib.h>"++-- A thread-local variable to cache the JNI environment. Accessing this variable+-- is faster than calling @jvm->GetEnv()@.+$(C.verbatim "static __thread JNIEnv* jniEnv; ")++-- | 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 (Exception, Show, Typeable)++-- | A null reference is found where a non-null reference was expected.+data NullPointerException = NullPointerException+  deriving (Exception, Show, Typeable)++-- | A JNI call is made from a thread not attached to the JVM.+data ThreadNotAttached = ThreadNotAttached+  deriving (Exception, Show, Typeable)++-- | A JNI call is made from an unbound thread.+data ThreadNotBound = ThreadNotBound+  deriving (Exception, Show, Typeable)++-- | Thrown when an JNI call is made from an unbound thread.+data JNIError = JNIError Prelude.String Int32+  deriving (Show, Typeable)++instance Exception JNIError++-- | 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++-- | Throws an error if the given reference is null, otherwise performs+-- the given io action.+throwIfJNull :: J ty -> IO a -> IO a+throwIfJNull j io =+    if j == jnull+    then throwIO NullPointerException+    else io++-- | 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.+      (1, 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 $ \(readers, _) ->+      ((readers, Writing mv), when (readers > 0) (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 #-}++throwIfNotOK_ :: HasCallStack => IO Int32 -> IO ()+throwIfNotOK_ m = m >>= \case+  rc+    | rc == [CU.pure| jint { JNI_OK } |] -> return ()+    | rc == [CU.pure| jint { JNI_EDETACHED } |] -> throwIO ThreadNotAttached+    | otherwise -> throwIO $ JNIError (prettySrcLoc loc) rc+  where+    (_, loc):_ = getCallStack callStack++attachCurrentThreadAsDaemon :: IO ()+attachCurrentThreadAsDaemon = do+    throwIfNotOK_+      [CU.exp| jint {+        (*$(JavaVM* jvm))->AttachCurrentThreadAsDaemon($(JavaVM* jvm), &jniEnv, NULL)+      } |]++detachCurrentThread :: IO ()+detachCurrentThread =+    throwIfNotOK_+    [CU.block| jint {+      int rc = (*$(JavaVM* jvm))->DetachCurrentThread($(JavaVM* jvm));+      if (rc == JNI_OK)+        jniEnv = NULL;+      return rc;+    } |]++-- | Attaches the calling thread to the JVM, runs the given IO action and+-- then detaches the thread.+--+-- If the thread is already attached no attaching and detaching is performed.+runInAttachedThread :: IO a -> IO a+runInAttachedThread io = do+    attached <-+      catch (getJNIEnv >> return True) (\ThreadNotBound -> return False)+    if attached+    then io+    else bracket_+          attachCurrentThreadAsDaemon+          detachCurrentThread+          io++-- | The current JVM+--+-- Assumes there's at most one JVM. The current JNI spec (2016) says only+-- one JVM per process is supported anyways.+{-# NOINLINE jvm #-}+jvm :: Ptr JVM+jvm = unsafePerformIO $ alloca $ \pjvm -> alloca $ \pnum_jvms -> do+    throwIfNotOK_+      [CU.exp| jint {+        JNI_GetCreatedJavaVMs($(JavaVM** pjvm), 1, $(jsize* pnum_jvms))+      }|]+    num_jvms <- peek pnum_jvms+    when (num_jvms == 0) $+      fail "JNI_GetCreatedJavaVMs: No JVM has been initialized yet."+    when (num_jvms > 1) $+      fail "JNI_GetCreatedJavaVMs: There are multiple JVMs but only one is supported."+    peek pjvm++-- | Yields the JNIEnv of the calling thread.+--+-- Yields @Nothing@ if the calling thread is not attached to the JVM.+getJNIEnv :: IO (Ptr JNIEnv)+getJNIEnv = [CU.exp| JNIEnv* { jniEnv } |] >>= \case+    env | env == nullPtr -> do+      throwIfNotOK_+        [CU.exp| jint {+          (*$(JavaVM* jvm))->GetEnv($(JavaVM* jvm), (void**)&jniEnv, JNI_VERSION_1_6)+        }|]+      [CU.exp| JNIEnv* { jniEnv } |]+    env -> return env++-- | Run an action against the appropriate 'JNIEnv'.+--+-- Each OS thread has its own 'JNIEnv', which this function gives access to.+withJNIEnv :: (Ptr JNIEnv -> IO a) -> IO a+withJNIEnv f = getJNIEnv >>= f++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 'withJVM' instead. Only useful for GHCi.+newJVM :: [ByteString] -> IO JVM+newJVM options = JVM_ <$> do+    useAsCStrings options $ \cstrs -> do+      withArray cstrs $ \(coptions :: Ptr (Ptr CChar)) -> do+        let n = fromIntegral (length cstrs) :: C.CInt+        checkBoundness+        [C.block| JavaVM * {+          JavaVM *jvm;+          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**)&jniEnv, &vm_args);+          free(options);+          return jvm; } |]++  where+    checkBoundness :: IO ()+    checkBoundness = when rtsSupportsBoundThreads $ do+      bound <- isCurrentThreadBound+      unless bound (throwIO ThreadNotBound)++-- | Deallocate a 'JVM' created using 'newJVM'.+destroyJVM :: JVM -> IO ()+destroyJVM (JVM_ jvm) = do+    acquireWriteLock globalJVMLock+    [C.block| void {+        (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm));+        jniEnv = NULL;+    } |]++-- | Create a new JVM, with the given arguments. Destroy it once the given+-- action completes. /Can only be called once/. Best practice: use it to wrap+-- your @main@ function.+withJVM :: [ByteString] -> IO a -> IO a+withJVM options action = bracket (newJVM options) destroyJVM (const action)++defineClass+  :: Coercible o (J ('Class "java.lang.ClassLoader"))+  => ReferenceTypeName -- ^ Class name+  -> o -- ^ Loader+  -> ByteString -- ^ Bytecode buffer+  -> IO JClass+defineClass (coerce -> 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 = throwIfJNull cls $ withJNIEnv $ \env ->+    JNI.withString msg $ \msgp -> void $ do+    [CU.exp| jint {+       (*$(JNIEnv *env))->ThrowNew($(JNIEnv *env),+                                   $fptr-ptr:(jclass cls),+                                   $(char *msgp)) } |]++findClass+  :: ReferenceTypeName -- ^ Class name+  -> IO JClass+findClass (coerce -> name) = withJNIEnv $ \env ->+    throwIfException env $+    JNI.withString name $ \namep ->+    objectFromPtr =<<+    [CU.exp| jclass { (*$(JNIEnv *env))->FindClass($(JNIEnv *env), $(char *namep)) } |]++newObject :: JClass -> MethodSignature -> [JValue] -> IO JObject+newObject cls (coerce -> sig) args = throwIfJNull cls $ 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+  -> Signature -- ^ JNI signature+  -> IO JFieldID+getFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $+    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+  -> Signature -- ^ JNI signature+  -> IO JFieldID+getStaticFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $+    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 = throwIfJNull klass $ \+    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 = throwIfJNull klass $ \+    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+  -> MethodSignature -- ^ JNI signature+  -> IO JMethodID+getMethodID cls methodname (coerce -> sig) = throwIfJNull cls $+    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+  -> MethodSignature -- ^ JNI signature+  -> IO JMethodID+getStaticMethodID cls methodname (coerce -> sig) = throwIfJNull cls $+    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) = throwIfJNull 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)) } |]+    fixIO $ \j ->+      coerce <$> J <$> newConcForeignPtr gobj (deleteGlobalRefNonFinalized j)++deleteGlobalRef :: Coercible o (J ty) => o -> IO ()+deleteGlobalRef (coerce -> J p) = finalizeForeignPtr p++-- | Like 'newGlobalRef' but it doesn't attach a finalizer to destroy+-- the reference when it is not longer reachable. Use+-- 'deleteGlobalRefNonFinalized' to destroy this reference.+newGlobalRefNonFinalized :: Coercible o (J ty) => o -> IO o+newGlobalRefNonFinalized (coerce -> upcast -> obj) = withJNIEnv $ \env -> do+    gobj <-+      [CU.exp| jobject {+        (*$(JNIEnv *env))->NewGlobalRef($(JNIEnv *env),+                                        $fptr-ptr:(jobject obj)) } |]+    coerce <$> J <$> newForeignPtr_ gobj++-- | Like 'deleteGlobalRef' but it can be used only on references created with+-- 'newGlobalRefNonFinalized'.+deleteGlobalRefNonFinalized :: Coercible o (J ty) => o -> IO ()+deleteGlobalRefNonFinalized (coerce -> upcast -> obj) = do+    bracket (tryAcquireReadLock globalJVMLock)+            (\doRead -> when (toBool doRead) $ releaseReadLock globalJVMLock)+            $ \doRead ->+      when (toBool doRead) $ withJNIEnv $ \env -> do+        [CU.block| void { (*$(JNIEnv *env))->DeleteGlobalRef($(JNIEnv *env)+                                                            ,$fptr-ptr:(jobject obj));+                        } |]++-- 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 o+newLocalRef (coerce -> upcast -> obj) = withJNIEnv $ \env ->+    coerce <$> (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 = throwIfJNull cls $ \+    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 = throwIfJNull 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) = throwIfJNull array $+    withJNIEnv $ \env ->+    [C.exp| jsize {+      (*$(JNIEnv *env))->GetArrayLength($(JNIEnv *env),+                                        $fptr-ptr:(jarray array)) } |]++getStringLength :: JString -> IO Int32+getStringLength jstr = throwIfJNull 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) = throwIfJNull 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 = throwIfJNull 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 = throwIfJNull array $ \+    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 = throwIfJNull array $ \+    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 = throwIfJNull jstr $ withJNIEnv $ \env ->+    [CU.exp| void {+      (*$(JNIEnv *env))->ReleaseStringChars($(JNIEnv *env),+                                            $fptr-ptr:(jstring jstr),+                                            $(jchar *chars)) } |]++getObjectArrayElement+  :: forall a o.+     (IsReferenceType a, Coercible o (J a))+  => JArray a+  -> Int32+  -> IO o+getObjectArrayElement (arrayUpcast -> array) i = throwIfJNull array $+    withJNIEnv $ \env ->+    ( (coerce :: J a -> o)+    . (unsafeCast :: JObject -> J a)+    ) <$> (objectFromPtr =<<)+    [C.exp| jobject {+      (*$(JNIEnv *env))->GetObjectArrayElement($(JNIEnv *env),+                                               $fptr-ptr:(jarray array),+                                               $(jsize i)) } |]++setObjectArrayElement+  :: forall a o.+     (IsReferenceType a, Coercible o (J a))+  => JArray a+  -> Int32+  -> o+  -> IO ()+setObjectArrayElement (arrayUpcast -> array)+                      i+                      ((coerce :: o -> J a) -> upcast -> x) =+    throwIfJNull array $+    withJNIEnv $ \env ->+    [C.exp| void {+      (*$(JNIEnv *env))->SetObjectArrayElement($(JNIEnv *env),+                                               $fptr-ptr:(jobjectArray array),+                                               $(jsize i),+                                               $fptr-ptr:(jobject x)); } |]