• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CONVERTORS_JNI_H
17 #define CONVERTORS_JNI_H
18 
19 #ifdef KOALA_JNI
20 
21 #include <jni.h>
22 
23 #include <cmath>
24 #include <unordered_map>
25 #include <vector>
26 #include <string>
27 #include <tuple>
28 
29 #include "koala-types.h"
30 
31 #define KOALA_JNI_CALL(type) extern "C" JNIEXPORT type JNICALL
32 
33 class JniExports {
34     std::unordered_map<std::string,
35       std::vector<std::tuple<std::string, std::string, void*>>> implementations;
36 
37 public:
38     static JniExports* getInstance();
39 
40     std::vector<std::string> getModules();
41     void addMethod(const char* module, const char* name, const char* type, void* impl);
42     const std::vector<std::tuple<std::string, std::string, void*>>& getMethods(const std::string& module);
43 };
44 
45 #define KOALA_QUOTE0(x) #x
46 #define KOALA_QUOTE(x) KOALA_QUOTE0(x)
47 
48 #ifdef _MSC_VER
49 #define MAKE_JNI_EXPORT(module, name, type)                             \
50     static void __init_##name() {                               \
51         JniExports::getInstance()->addMethod(KOALA_QUOTE(module), "_"#name, type, reinterpret_cast<void *>(Java_org_##name)); \
52     }                                                           \
53     namespace {                                                 \
54       struct __Init_##name {                                    \
55         __Init_##name() {  __init_##name(); }                   \
56       } __Init_##name##_v;                                      \
57     }
58 #else
59 #define MAKE_JNI_EXPORT(module, name, type) \
60     __attribute__((constructor)) \
61     static void __init_jni_##name() { \
62         JniExports::getInstance()->addMethod(KOALA_QUOTE(module), "_"#name, type, reinterpret_cast<void *>(Java_org_##name)); \
63     }
64 #endif
65 
66 template<class T>
67 struct InteropTypeConverter {
68     using InteropType = T;
convertFromInteropTypeConverter69     static T convertFrom(JNIEnv* env, InteropType value) { return value; }
convertToInteropTypeConverter70     static InteropType convertTo(JNIEnv* env, T value) { return value; }
releaseInteropTypeConverter71     static void release(JNIEnv* env, InteropType value, T converted) {}
72 };
73 
74 template<class T>
75 struct SlowInteropTypeConverter {
76     using InteropType = T;
convertFromSlowInteropTypeConverter77     static inline T convertFrom(JNIEnv* env, InteropType value) { return value; }
convertToSlowInteropTypeConverter78     static inline InteropType convertTo(JNIEnv* env, T value) { return value; }
releaseSlowInteropTypeConverter79     static void release(JNIEnv* env, InteropType value, T converted) {}
80 };
81 
82 template<>
83 struct InteropTypeConverter<KStringPtr> {
84     using InteropType = jstring;
85     static inline KStringPtr convertFrom0(JNIEnv* env, InteropType value) {
86         if (value == nullptr) return KStringPtr();
87         jboolean isCopy;
88         // TODO: use GetStringCritical() instead and utf-8 encode manually.
89 		    const char* str_value = env->GetStringUTFChars(value, &isCopy);
90         int len = env->GetStringUTFLength(value);
91         KStringPtr result(str_value, len, false);
92         return result;
93     }
94     static KStringPtr convertFrom(JNIEnv* env, InteropType value) {
95         if (value == nullptr) return KStringPtr();
96         KStringPtr result;
97         // Notice that we use UTF length for buffer size, but counter is expressed in number of Unicode chars.
98         result.resize( env->GetStringUTFLength(value));
99         env->GetStringUTFRegion(value, 0, env->GetStringLength(value), result.data());
100         return result;
101     }
102     static InteropType convertTo(JNIEnv* env, KStringPtr value) = delete;
103     static inline void release(JNIEnv* env, InteropType value, const KStringPtr& converted) {
104     }
105 };
106 
107 template<>
108 struct SlowInteropTypeConverter<KVMObjectHandle> {
109     using InteropType = jobject;
110     static inline KVMObjectHandle convertFrom(JNIEnv* env, InteropType value) {
111         return reinterpret_cast<KVMObjectHandle>(value);
112     }
113     static InteropType convertTo(JNIEnv* env, KVMObjectHandle value) {
114       return reinterpret_cast<jobject>(value);
115     }
116     static inline void release(JNIEnv* env, InteropType value, KVMObjectHandle converted) {
117     }
118 };
119 
120 template<>
121 struct SlowInteropTypeConverter<KStringPtr> {
122     using InteropType = jstring;
123     static inline KStringPtr convertFrom(JNIEnv* env, InteropType value) {
124         if (value == nullptr) return KStringPtr();
125         jboolean isCopy;
126 		    const char* str_value = env->GetStringUTFChars(value, &isCopy);
127         int len = env->GetStringLength(value);
128         KStringPtr result(str_value, len, false);
129         return result;
130     }
131     static InteropType convertTo(JNIEnv* env, KStringPtr value) {
132       return env->NewStringUTF(value.c_str());
133     }
134     static inline void release(JNIEnv* env, InteropType value, const KStringPtr& converted) {
135       env->ReleaseStringUTFChars(value, converted.data());
136     }
137 };
138 
139 template<>
140 struct SlowInteropTypeConverter<KInteropBuffer> {
141     using InteropType = jarray;
142     static inline KInteropBuffer convertFrom(JNIEnv* env, InteropType value) {
143         if (value == nullptr) return KInteropBuffer();
144         KInteropBuffer result({env->GetArrayLength(value), reinterpret_cast<KByte*>(env->GetPrimitiveArrayCritical(value, nullptr))});
145         return result;
146     }
147     static InteropType convertTo(JNIEnv* env, KInteropBuffer value) {
148       int bufferLength = value.length;
149       jarray result = env->NewByteArray(bufferLength);
150       void* data = env->GetPrimitiveArrayCritical(result, nullptr);
151 #ifdef __STDC_LIB_EXT1__
152       errno_t res = memcpy_s(data, bufferLength, value.data, bufferLength);
153       if (res != EOK) {
154         return result;
155       }
156 #else
157       memcpy(data, value.data, bufferLength);
158 #endif
159       env->ReleasePrimitiveArrayCritical(result, data, 0);
160       return result;
161     }
162     static inline void release(JNIEnv* env, InteropType value, const KInteropBuffer& converted) {
163       env->ReleasePrimitiveArrayCritical(value, converted.data, 0);
164     }
165 };
166 
167 template<>
168 struct SlowInteropTypeConverter<KInteropReturnBuffer> {
169     using InteropType = jarray;
170     static inline KInteropReturnBuffer convertFrom(JNIEnv* env, InteropType value) = delete;
171     static InteropType convertTo(JNIEnv* env, KInteropReturnBuffer value) {
172       int bufferLength = value.length;
173       jarray result = env->NewByteArray(bufferLength);
174       void* data = env->GetPrimitiveArrayCritical(result, nullptr);
175 #ifdef __STDC_LIB_EXT1__
176       errno_t res = memcpy_s(data, bufferLength, value.data, bufferLength);
177       if (res != EOK) {
178         return result;
179       }
180 #else
181       memcpy(data, value.data, bufferLength);
182 #endif
183       env->ReleasePrimitiveArrayCritical(result, data, 0);
184       value.dispose(value.data, bufferLength);
185       return result;
186     }
187     static inline void release(JNIEnv* env, InteropType value, const KInteropReturnBuffer& converted) = delete;
188 };
189 
190 template<>
191 struct InteropTypeConverter<KByte*> {
192     using InteropType = jbyteArray;
193     static inline KByte* convertFrom(JNIEnv* env, InteropType value) {
194         return value ? reinterpret_cast<KByte*>(env->GetPrimitiveArrayCritical(value, nullptr)) : nullptr;
195     }
196     static InteropType convertTo(JNIEnv* env, KByte* value) = delete;
197     static inline void release(JNIEnv* env, InteropType value, KByte* converted) {
198         if (converted) env->ReleasePrimitiveArrayCritical(value, converted, 0);
199     }
200 };
201 
202 template<>
203 struct SlowInteropTypeConverter<KByte*> {
204     using InteropType = jbyteArray;
205     static inline KByte* convertFrom(JNIEnv* env, InteropType value) {
206         return value ? reinterpret_cast<KByte*>(env->GetByteArrayElements(value, nullptr)) : nullptr;
207     }
208     static InteropType convertTo(JNIEnv* env, KByte* value) = delete;
209     static inline void release(JNIEnv* env, InteropType value, KByte* converted) {
210         if (converted) env->ReleaseByteArrayElements(value, reinterpret_cast<jbyte*>(converted), 0);
211     }
212 };
213 
214 template<>
215 struct InteropTypeConverter<KInt*> {
216     using InteropType = jintArray;
217     static KInt* convertFrom(JNIEnv* env, InteropType value) {
218         return value ? reinterpret_cast<KInt*>(env->GetPrimitiveArrayCritical(value, nullptr)) : nullptr;
219     }
220     static InteropType convertTo(JNIEnv* env, KInt* value) = delete;
221     static void release(JNIEnv* env, InteropType value, KInt* converted) {
222          env->ReleasePrimitiveArrayCritical(value, converted, 0);
223     }
224 };
225 
226 template<>
227 struct SlowInteropTypeConverter<KInt*> {
228     using InteropType = jintArray;
229     static KInt* convertFrom(JNIEnv* env, InteropType value) {
230         return value ? reinterpret_cast<KInt*>(env->GetIntArrayElements(value, nullptr)) : nullptr;
231     }
232     static InteropType convertTo(JNIEnv* env, KInt* value) = delete;
233     static void release(JNIEnv* env, InteropType value, KInt* converted) {
234          env->ReleaseIntArrayElements(value, reinterpret_cast<jint*>(converted), 0);
235     }
236 };
237 
238 template<>
239 struct InteropTypeConverter<KFloat*> {
240     using InteropType = jfloatArray;
241     static KFloat* convertFrom(JNIEnv* env, InteropType value) {
242         return value ? reinterpret_cast<KFloat*>(env->GetPrimitiveArrayCritical(value, nullptr)) : nullptr;
243     }
244     static InteropType convertTo(JNIEnv* env, KFloat* value) = delete;
245     static void release(JNIEnv* env, InteropType value, KFloat* converted) {
246         env->ReleasePrimitiveArrayCritical(value, converted, 0);
247     }
248 };
249 
250 template<>
251 struct SlowInteropTypeConverter<KFloat*> {
252     using InteropType = jfloatArray;
253     static KFloat* convertFrom(JNIEnv* env, InteropType value) {
254         return value ? reinterpret_cast<KFloat*>(env->GetFloatArrayElements(value, nullptr)) : nullptr;
255     }
256     static InteropType convertTo(JNIEnv* env, KFloat* value) = delete;
257     static void release(JNIEnv* env, InteropType value, KFloat* converted) {
258         env->ReleaseFloatArrayElements(value, reinterpret_cast<jfloat*>(converted), 0);
259     }
260 };
261 
262 template<>
263 struct InteropTypeConverter<KNativePointer> {
264     using InteropType = jlong;
265     static KNativePointer convertFrom(JNIEnv* env, InteropType value) {
266       return reinterpret_cast<KNativePointer>(value);
267     }
268     static InteropType convertTo(JNIEnv* env, KNativePointer value) {
269       return reinterpret_cast<jlong>(value);
270     }
271     static inline void release(JNIEnv* env, InteropType value, KNativePointer converted) {}
272 };
273 
274 template<>
275 struct SlowInteropTypeConverter<KNativePointer> {
276     using InteropType = jlong;
277     static KNativePointer convertFrom(JNIEnv* env, InteropType value) {
278       return reinterpret_cast<KNativePointer>(value);
279     }
280     static InteropType convertTo(JNIEnv* env, KNativePointer value) {
281       return reinterpret_cast<jlong>(value);
282     }
283     static void release(JNIEnv* env, InteropType value, KNativePointer converted) {}
284 };
285 
286 template<>
287 struct InteropTypeConverter<KInteropNumber> {
288     using InteropType = jdouble;
289     static KInteropNumber convertFrom(JNIEnv* env, InteropType value) {
290         return KInteropNumber::fromDouble(value);
291     }
292     static InteropType convertTo(JNIEnv* env, KInteropNumber value) {
293         return value.asDouble();
294     }
295     static inline void release(JNIEnv* env, InteropType value, KInteropNumber converted) {}
296 };
297 
298 template<>
299 struct SlowInteropTypeConverter<KInteropNumber> {
300     using InteropType = jdouble;
301     static KInteropNumber convertFrom(JNIEnv* env, InteropType value) {
302         return KInteropNumber::fromDouble(value);
303     }
304     static InteropType convertTo(JNIEnv* env, KInteropNumber value) {
305         return value.asDouble();
306     }
307     static void release(JNIEnv* env, InteropType value, KInteropNumber converted) {}
308 };
309 
310 template<>
311 struct InteropTypeConverter<KLength> {
312     using InteropType = jstring;
313     static KLength convertFrom(JNIEnv* env, InteropType value) {
314         KLength result = { 0 };
315 
316         if (value == nullptr) {
317             result.type = -1; // ARK_RUNTIME_UNEXPECTED
318             return result;
319         }
320         jboolean isCopy;
321         const char* str_value = env->GetStringUTFChars(value, &isCopy);
322         int len = env->GetStringLength(value);
323         KStringPtr kStr(str_value, len, false);
324         parseKLength(kStr, &result);
325         env->ReleaseStringUTFChars(value, str_value);
326         result.type = 2; // ARK_RUNTIME_STRING
327         result.resource = 0;
328 
329         return result;
330     }
331     static InteropType convertTo(JNIEnv* env, KLength value) = delete;
332     static inline void release(JNIEnv* env, InteropType value, KLength converted) {}
333 };
334 
335 template <typename Type>
336 inline Type getArgument(JNIEnv* env, typename InteropTypeConverter<Type>::InteropType arg) {
337   return InteropTypeConverter<Type>::convertFrom(env, arg);
338 }
339 
340 template <typename Type>
341 inline void releaseArgument(JNIEnv* env, typename InteropTypeConverter<Type>::InteropType arg, Type& data) {
342   InteropTypeConverter<Type>::release(env, arg, data);
343 }
344 
345 #ifndef KOALA_INTEROP_MODULE
346 #error KOALA_INTEROP_MODULE is undefined
347 #endif
348 
349 #define KOALA_INTEROP_0(name, Ret) \
350   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance) { \
351       KOALA_MAYBE_LOG(name) \
352       return InteropTypeConverter<Ret>::convertTo(env, impl_##name()); \
353   } \
354 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret)
355 
356 #define KOALA_INTEROP_1(name, Ret, P0) \
357    KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) \
358    Java_org_##name(JNIEnv* env, jclass instance, \
359     InteropTypeConverter<P0>::InteropType _p0) { \
360       KOALA_MAYBE_LOG(name) \
361       P0 p0 = getArgument<P0>(env, _p0); \
362       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0)); \
363       releaseArgument(env, _p0, p0); \
364       return rv; \
365   } \
366 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0)
367 
368 #define KOALA_INTEROP_2(name, Ret, P0, P1) \
369   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
370   InteropTypeConverter<P0>::InteropType _p0, \
371   InteropTypeConverter<P1>::InteropType _p1) { \
372       KOALA_MAYBE_LOG(name) \
373       P0 p0 = getArgument<P0>(env, _p0); \
374       P1 p1 = getArgument<P1>(env, _p1); \
375       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1)); \
376       releaseArgument(env, _p0, p0); \
377       releaseArgument(env, _p1, p1); \
378       return rv; \
379 } \
380 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1)
381 
382 #define KOALA_INTEROP_3(name, Ret, P0, P1, P2) \
383   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
384   InteropTypeConverter<P0>::InteropType _p0, \
385   InteropTypeConverter<P1>::InteropType _p1, \
386   InteropTypeConverter<P2>::InteropType _p2) { \
387       KOALA_MAYBE_LOG(name) \
388       P0 p0 = getArgument<P0>(env, _p0); \
389       P1 p1 = getArgument<P1>(env, _p1); \
390       P2 p2 = getArgument<P2>(env, _p2); \
391       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2)); \
392       releaseArgument(env, _p0, p0); \
393       releaseArgument(env, _p1, p1); \
394       releaseArgument(env, _p2, p2); \
395       return rv; \
396 } \
397 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2)
398 
399 #define KOALA_INTEROP_4(name, Ret, P0, P1, P2, P3) \
400   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
401   InteropTypeConverter<P0>::InteropType _p0, \
402   InteropTypeConverter<P1>::InteropType _p1, \
403   InteropTypeConverter<P2>::InteropType _p2, \
404   InteropTypeConverter<P3>::InteropType _p3) { \
405       KOALA_MAYBE_LOG(name) \
406       P0 p0 = getArgument<P0>(env, _p0); \
407       P1 p1 = getArgument<P1>(env, _p1); \
408       P2 p2 = getArgument<P2>(env, _p2); \
409       P3 p3 = getArgument<P3>(env, _p3); \
410       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3)); \
411       releaseArgument(env, _p0, p0); \
412       releaseArgument(env, _p1, p1); \
413       releaseArgument(env, _p2, p2); \
414       releaseArgument(env, _p3, p3); \
415       return rv; \
416 } \
417 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3)
418 
419 #define KOALA_INTEROP_5(name, Ret, P0, P1, P2, P3, P4) \
420   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
421     InteropTypeConverter<P0>::InteropType _p0, \
422     InteropTypeConverter<P1>::InteropType _p1, \
423     InteropTypeConverter<P2>::InteropType _p2, \
424     InteropTypeConverter<P3>::InteropType _p3, \
425     InteropTypeConverter<P4>::InteropType _p4) { \
426       KOALA_MAYBE_LOG(name) \
427       P0 p0 = getArgument<P0>(env, _p0); \
428       P1 p1 = getArgument<P1>(env, _p1); \
429       P2 p2 = getArgument<P2>(env, _p2); \
430       P3 p3 = getArgument<P3>(env, _p3); \
431       P4 p4 = getArgument<P4>(env, _p4); \
432       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4)); \
433       releaseArgument(env, _p0, p0); \
434       releaseArgument(env, _p1, p1); \
435       releaseArgument(env, _p2, p2); \
436       releaseArgument(env, _p3, p3); \
437       releaseArgument(env, _p4, p4); \
438       return rv; \
439 } \
440 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4)
441 
442 #define KOALA_INTEROP_6(name, Ret, P0, P1, P2, P3, P4, P5) \
443   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
444   InteropTypeConverter<P0>::InteropType _p0, \
445   InteropTypeConverter<P1>::InteropType _p1, \
446   InteropTypeConverter<P2>::InteropType _p2, \
447   InteropTypeConverter<P3>::InteropType _p3, \
448   InteropTypeConverter<P4>::InteropType _p4, \
449   InteropTypeConverter<P5>::InteropType _p5) { \
450       KOALA_MAYBE_LOG(name) \
451       P0 p0 = getArgument<P0>(env, _p0); \
452       P1 p1 = getArgument<P1>(env, _p1); \
453       P2 p2 = getArgument<P2>(env, _p2); \
454       P3 p3 = getArgument<P3>(env, _p3); \
455       P4 p4 = getArgument<P4>(env, _p4); \
456       P5 p5 = getArgument<P5>(env, _p5); \
457       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5)); \
458       releaseArgument(env, _p0, p0); \
459       releaseArgument(env, _p1, p1); \
460       releaseArgument(env, _p2, p2); \
461       releaseArgument(env, _p3, p3); \
462       releaseArgument(env, _p4, p4); \
463       releaseArgument(env, _p5, p5); \
464       return rv; \
465 } \
466 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5)
467 
468 #define KOALA_INTEROP_7(name, Ret, P0, P1, P2, P3, P4, P5, P6) \
469   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
470     InteropTypeConverter<P0>::InteropType _p0, \
471     InteropTypeConverter<P1>::InteropType _p1, \
472     InteropTypeConverter<P2>::InteropType _p2, \
473     InteropTypeConverter<P3>::InteropType _p3, \
474     InteropTypeConverter<P4>::InteropType _p4, \
475     InteropTypeConverter<P5>::InteropType _p5, \
476     InteropTypeConverter<P6>::InteropType _p6) { \
477       KOALA_MAYBE_LOG(name) \
478       P0 p0 = getArgument<P0>(env, _p0); \
479       P1 p1 = getArgument<P1>(env, _p1); \
480       P2 p2 = getArgument<P2>(env, _p2); \
481       P3 p3 = getArgument<P3>(env, _p3); \
482       P4 p4 = getArgument<P4>(env, _p4); \
483       P5 p5 = getArgument<P5>(env, _p5); \
484       P6 p6 = getArgument<P6>(env, _p6); \
485       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6)); \
486       releaseArgument(env, _p0, p0); \
487       releaseArgument(env, _p1, p1); \
488       releaseArgument(env, _p2, p2); \
489       releaseArgument(env, _p3, p3); \
490       releaseArgument(env, _p4, p4); \
491       releaseArgument(env, _p5, p5); \
492       releaseArgument(env, _p6, p6); \
493       return rv; \
494 } \
495 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6)
496 
497 #define KOALA_INTEROP_8(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7) \
498   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
499   InteropTypeConverter<P0>::InteropType _p0, \
500   InteropTypeConverter<P1>::InteropType _p1, \
501   InteropTypeConverter<P2>::InteropType _p2, \
502   InteropTypeConverter<P3>::InteropType _p3, \
503   InteropTypeConverter<P4>::InteropType _p4, \
504   InteropTypeConverter<P5>::InteropType _p5, \
505   InteropTypeConverter<P6>::InteropType _p6, \
506   InteropTypeConverter<P7>::InteropType _p7) { \
507       KOALA_MAYBE_LOG(name) \
508       P0 p0 = getArgument<P0>(env, _p0); \
509       P1 p1 = getArgument<P1>(env, _p1); \
510       P2 p2 = getArgument<P2>(env, _p2); \
511       P3 p3 = getArgument<P3>(env, _p3); \
512       P4 p4 = getArgument<P4>(env, _p4); \
513       P5 p5 = getArgument<P5>(env, _p5); \
514       P6 p6 = getArgument<P6>(env, _p6); \
515       P7 p7 = getArgument<P7>(env, _p7); \
516       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7)); \
517       releaseArgument(env, _p0, p0); \
518       releaseArgument(env, _p1, p1); \
519       releaseArgument(env, _p2, p2); \
520       releaseArgument(env, _p3, p3); \
521       releaseArgument(env, _p4, p4); \
522       releaseArgument(env, _p5, p5); \
523       releaseArgument(env, _p6, p6); \
524       releaseArgument(env, _p7, p7); \
525       return rv; \
526 } \
527 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7)
528 
529 #define KOALA_INTEROP_9(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8) \
530   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
531   InteropTypeConverter<P0>::InteropType _p0, \
532   InteropTypeConverter<P1>::InteropType _p1, \
533   InteropTypeConverter<P2>::InteropType _p2, \
534   InteropTypeConverter<P3>::InteropType _p3, \
535   InteropTypeConverter<P4>::InteropType _p4, \
536   InteropTypeConverter<P5>::InteropType _p5, \
537   InteropTypeConverter<P6>::InteropType _p6, \
538   InteropTypeConverter<P7>::InteropType _p7, \
539   InteropTypeConverter<P8>::InteropType _p8) { \
540       KOALA_MAYBE_LOG(name) \
541       P0 p0 = getArgument<P0>(env, _p0); \
542       P1 p1 = getArgument<P1>(env, _p1); \
543       P2 p2 = getArgument<P2>(env, _p2); \
544       P3 p3 = getArgument<P3>(env, _p3); \
545       P4 p4 = getArgument<P4>(env, _p4); \
546       P5 p5 = getArgument<P5>(env, _p5); \
547       P6 p6 = getArgument<P6>(env, _p6); \
548       P7 p7 = getArgument<P7>(env, _p7); \
549       P8 p8 = getArgument<P8>(env, _p8); \
550       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8)); \
551       releaseArgument(env, _p0, p0); \
552       releaseArgument(env, _p1, p1); \
553       releaseArgument(env, _p2, p2); \
554       releaseArgument(env, _p3, p3); \
555       releaseArgument(env, _p4, p4); \
556       releaseArgument(env, _p5, p5); \
557       releaseArgument(env, _p6, p6); \
558       releaseArgument(env, _p7, p7); \
559       releaseArgument(env, _p8, p8); \
560       return rv; \
561 } \
562 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8)
563 
564 #define KOALA_INTEROP_10(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
565   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
566   InteropTypeConverter<P0>::InteropType _p0, \
567   InteropTypeConverter<P1>::InteropType _p1, \
568   InteropTypeConverter<P2>::InteropType _p2, \
569   InteropTypeConverter<P3>::InteropType _p3, \
570   InteropTypeConverter<P4>::InteropType _p4, \
571   InteropTypeConverter<P5>::InteropType _p5, \
572   InteropTypeConverter<P6>::InteropType _p6, \
573   InteropTypeConverter<P7>::InteropType _p7, \
574   InteropTypeConverter<P8>::InteropType _p8, \
575   InteropTypeConverter<P9>::InteropType _p9) { \
576       KOALA_MAYBE_LOG(name) \
577       P0 p0 = getArgument<P0>(env, _p0); \
578       P1 p1 = getArgument<P1>(env, _p1); \
579       P2 p2 = getArgument<P2>(env, _p2); \
580       P3 p3 = getArgument<P3>(env, _p3); \
581       P4 p4 = getArgument<P4>(env, _p4); \
582       P5 p5 = getArgument<P5>(env, _p5); \
583       P6 p6 = getArgument<P6>(env, _p6); \
584       P7 p7 = getArgument<P7>(env, _p7); \
585       P8 p8 = getArgument<P8>(env, _p8); \
586       P9 p9 = getArgument<P9>(env, _p9); \
587       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); \
588       releaseArgument(env, _p0, p0); \
589       releaseArgument(env, _p1, p1); \
590       releaseArgument(env, _p2, p2); \
591       releaseArgument(env, _p3, p3); \
592       releaseArgument(env, _p4, p4); \
593       releaseArgument(env, _p5, p5); \
594       releaseArgument(env, _p6, p6); \
595       releaseArgument(env, _p7, p7); \
596       releaseArgument(env, _p8, p8); \
597       releaseArgument(env, _p9, p9); \
598       return rv; \
599 } \
600 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9)
601 
602 #define KOALA_INTEROP_11(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
603   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
604   InteropTypeConverter<P0>::InteropType _p0, \
605   InteropTypeConverter<P1>::InteropType _p1, \
606   InteropTypeConverter<P2>::InteropType _p2, \
607   InteropTypeConverter<P3>::InteropType _p3, \
608   InteropTypeConverter<P4>::InteropType _p4, \
609   InteropTypeConverter<P5>::InteropType _p5, \
610   InteropTypeConverter<P6>::InteropType _p6, \
611   InteropTypeConverter<P7>::InteropType _p7, \
612   InteropTypeConverter<P8>::InteropType _p8, \
613   InteropTypeConverter<P9>::InteropType _p9, \
614   InteropTypeConverter<P10>::InteropType _p10) { \
615       KOALA_MAYBE_LOG(name) \
616       P0 p0 = getArgument<P0>(env, _p0); \
617       P1 p1 = getArgument<P1>(env, _p1); \
618       P2 p2 = getArgument<P2>(env, _p2); \
619       P3 p3 = getArgument<P3>(env, _p3); \
620       P4 p4 = getArgument<P4>(env, _p4); \
621       P5 p5 = getArgument<P5>(env, _p5); \
622       P6 p6 = getArgument<P6>(env, _p6); \
623       P7 p7 = getArgument<P7>(env, _p7); \
624       P8 p8 = getArgument<P8>(env, _p8); \
625       P9 p9 = getArgument<P9>(env, _p9); \
626       P10 p10 = getArgument<P10>(env, _p10); \
627       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \
628       releaseArgument(env, _p0, p0); \
629       releaseArgument(env, _p1, p1); \
630       releaseArgument(env, _p2, p2); \
631       releaseArgument(env, _p3, p3); \
632       releaseArgument(env, _p4, p4); \
633       releaseArgument(env, _p5, p5); \
634       releaseArgument(env, _p6, p6); \
635       releaseArgument(env, _p7, p7); \
636       releaseArgument(env, _p8, p8); \
637       releaseArgument(env, _p9, p9); \
638       releaseArgument(env, _p10, p10); \
639       return rv; \
640 } \
641 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10)
642 
643 #define KOALA_INTEROP_12(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
644   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
645     InteropTypeConverter<P0>::InteropType _p0, \
646     InteropTypeConverter<P1>::InteropType _p1, \
647     InteropTypeConverter<P2>::InteropType _p2, \
648     InteropTypeConverter<P3>::InteropType _p3, \
649     InteropTypeConverter<P4>::InteropType _p4, \
650     InteropTypeConverter<P5>::InteropType _p5, \
651     InteropTypeConverter<P6>::InteropType _p6, \
652     InteropTypeConverter<P7>::InteropType _p7, \
653     InteropTypeConverter<P8>::InteropType _p8, \
654     InteropTypeConverter<P9>::InteropType _p9, \
655     InteropTypeConverter<P10>::InteropType _p10, \
656     InteropTypeConverter<P11>::InteropType _p11) { \
657       KOALA_MAYBE_LOG(name) \
658       P0 p0 = getArgument<P0>(env, _p0); \
659       P1 p1 = getArgument<P1>(env, _p1); \
660       P2 p2 = getArgument<P2>(env, _p2); \
661       P3 p3 = getArgument<P3>(env, _p3); \
662       P4 p4 = getArgument<P4>(env, _p4); \
663       P5 p5 = getArgument<P5>(env, _p5); \
664       P6 p6 = getArgument<P6>(env, _p6); \
665       P7 p7 = getArgument<P7>(env, _p7); \
666       P8 p8 = getArgument<P8>(env, _p8); \
667       P9 p9 = getArgument<P9>(env, _p9); \
668       P10 p10 = getArgument<P10>(env, _p10); \
669       P11 p11 = getArgument<P11>(env, _p11); \
670       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \
671       releaseArgument(env, _p0, p0); \
672       releaseArgument(env, _p1, p1); \
673       releaseArgument(env, _p2, p2); \
674       releaseArgument(env, _p3, p3); \
675       releaseArgument(env, _p4, p4); \
676       releaseArgument(env, _p5, p5); \
677       releaseArgument(env, _p6, p6); \
678       releaseArgument(env, _p7, p7); \
679       releaseArgument(env, _p8, p8); \
680       releaseArgument(env, _p9, p9); \
681       releaseArgument(env, _p10, p10); \
682       releaseArgument(env, _p11, p11); \
683       return rv; \
684 } \
685 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11)
686 
687 #define KOALA_INTEROP_13(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
688   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
689     InteropTypeConverter<P0>::InteropType _p0, \
690     InteropTypeConverter<P1>::InteropType _p1, \
691     InteropTypeConverter<P2>::InteropType _p2, \
692     InteropTypeConverter<P3>::InteropType _p3, \
693     InteropTypeConverter<P4>::InteropType _p4, \
694     InteropTypeConverter<P5>::InteropType _p5, \
695     InteropTypeConverter<P6>::InteropType _p6, \
696     InteropTypeConverter<P7>::InteropType _p7, \
697     InteropTypeConverter<P8>::InteropType _p8, \
698     InteropTypeConverter<P9>::InteropType _p9, \
699     InteropTypeConverter<P10>::InteropType _p10, \
700     InteropTypeConverter<P11>::InteropType _p11, \
701     InteropTypeConverter<P12>::InteropType _p12) { \
702       KOALA_MAYBE_LOG(name) \
703       P0 p0 = getArgument<P0>(env, _p0); \
704       P1 p1 = getArgument<P1>(env, _p1); \
705       P2 p2 = getArgument<P2>(env, _p2); \
706       P3 p3 = getArgument<P3>(env, _p3); \
707       P4 p4 = getArgument<P4>(env, _p4); \
708       P5 p5 = getArgument<P5>(env, _p5); \
709       P6 p6 = getArgument<P6>(env, _p6); \
710       P7 p7 = getArgument<P7>(env, _p7); \
711       P8 p8 = getArgument<P8>(env, _p8); \
712       P9 p9 = getArgument<P9>(env, _p9); \
713       P10 p10 = getArgument<P10>(env, _p10); \
714       P11 p11 = getArgument<P11>(env, _p11); \
715       P12 p12 = getArgument<P12>(env, _p12); \
716       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \
717       releaseArgument(env, _p0, p0); \
718       releaseArgument(env, _p1, p1); \
719       releaseArgument(env, _p2, p2); \
720       releaseArgument(env, _p3, p3); \
721       releaseArgument(env, _p4, p4); \
722       releaseArgument(env, _p5, p5); \
723       releaseArgument(env, _p6, p6); \
724       releaseArgument(env, _p7, p7); \
725       releaseArgument(env, _p8, p8); \
726       releaseArgument(env, _p9, p9); \
727       releaseArgument(env, _p10, p10); \
728       releaseArgument(env, _p11, p11); \
729       releaseArgument(env, _p12, p12); \
730       return rv; \
731 } \
732 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9"|" #P10 "|" #P11 "|" #P12)
733 
734 #define KOALA_INTEROP_14(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
735   KOALA_JNI_CALL(InteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
736     InteropTypeConverter<P0>::InteropType _p0, \
737     InteropTypeConverter<P1>::InteropType _p1, \
738     InteropTypeConverter<P2>::InteropType _p2, \
739     InteropTypeConverter<P3>::InteropType _p3, \
740     InteropTypeConverter<P4>::InteropType _p4, \
741     InteropTypeConverter<P5>::InteropType _p5, \
742     InteropTypeConverter<P6>::InteropType _p6, \
743     InteropTypeConverter<P7>::InteropType _p7, \
744     InteropTypeConverter<P8>::InteropType _p8, \
745     InteropTypeConverter<P9>::InteropType _p9, \
746     InteropTypeConverter<P10>::InteropType _p10, \
747     InteropTypeConverter<P11>::InteropType _p11, \
748     InteropTypeConverter<P12>::InteropType _p12, \
749     InteropTypeConverter<P13>::InteropType _p13) { \
750       KOALA_MAYBE_LOG(name) \
751       P0 p0 = getArgument<P0>(env, _p0); \
752       P1 p1 = getArgument<P1>(env, _p1); \
753       P2 p2 = getArgument<P2>(env, _p2); \
754       P3 p3 = getArgument<P3>(env, _p3); \
755       P4 p4 = getArgument<P4>(env, _p4); \
756       P5 p5 = getArgument<P5>(env, _p5); \
757       P6 p6 = getArgument<P6>(env, _p6); \
758       P7 p7 = getArgument<P7>(env, _p7); \
759       P8 p8 = getArgument<P8>(env, _p8); \
760       P9 p9 = getArgument<P9>(env, _p9); \
761       P10 p10 = getArgument<P10>(env, _p10); \
762       P11 p11 = getArgument<P11>(env, _p11); \
763       P12 p12 = getArgument<P12>(env, _p12); \
764       P13 p13 = getArgument<P13>(env, _p13); \
765       auto rv = InteropTypeConverter<Ret>::convertTo(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \
766       releaseArgument(env, _p0, p0); \
767       releaseArgument(env, _p1, p1); \
768       releaseArgument(env, _p2, p2); \
769       releaseArgument(env, _p3, p3); \
770       releaseArgument(env, _p4, p4); \
771       releaseArgument(env, _p5, p5); \
772       releaseArgument(env, _p6, p6); \
773       releaseArgument(env, _p7, p7); \
774       releaseArgument(env, _p8, p8); \
775       releaseArgument(env, _p9, p9); \
776       releaseArgument(env, _p10, p10); \
777       releaseArgument(env, _p11, p11); \
778       releaseArgument(env, _p12, p12); \
779       releaseArgument(env, _p13, p13); \
780       return rv; \
781 } \
782 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9"|" #P10 "|" #P11 "|" #P12 "|" #P13)
783 
784 
785 #define KOALA_INTEROP_V0(name) \
786   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance) { \
787       KOALA_MAYBE_LOG(name) \
788       impl_##name(); \
789   } \
790 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void")
791 
792 #define KOALA_INTEROP_V1(name, P0) \
793    KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
794     InteropTypeConverter<P0>::InteropType _p0) { \
795       KOALA_MAYBE_LOG(name) \
796       P0 p0 = getArgument<P0>(env, _p0); \
797       impl_##name(p0); \
798       releaseArgument(env, _p0, p0); \
799   } \
800 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0)
801 
802 #define KOALA_INTEROP_V2(name, P0, P1) \
803   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
804    InteropTypeConverter<P0>::InteropType _p0, \
805    InteropTypeConverter<P1>::InteropType _p1) { \
806       KOALA_MAYBE_LOG(name) \
807       P0 p0 = getArgument<P0>(env, _p0); \
808       P1 p1 = getArgument<P1>(env, _p1); \
809       impl_##name(p0, p1); \
810       releaseArgument(env, _p0, p0); \
811       releaseArgument(env, _p1, p1); \
812 } \
813 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1)
814 
815 #define KOALA_INTEROP_V3(name, P0, P1, P2) \
816   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
817    InteropTypeConverter<P0>::InteropType _p0, \
818    InteropTypeConverter<P1>::InteropType _p1, \
819    InteropTypeConverter<P2>::InteropType _p2) { \
820       KOALA_MAYBE_LOG(name) \
821       P0 p0 = getArgument<P0>(env, _p0); \
822       P1 p1 = getArgument<P1>(env, _p1); \
823       P2 p2 = getArgument<P2>(env, _p2); \
824       impl_##name(p0, p1, p2); \
825       releaseArgument(env, _p0, p0); \
826       releaseArgument(env, _p1, p1); \
827       releaseArgument(env, _p2, p2); \
828 } \
829 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2)
830 
831 #define KOALA_INTEROP_V4(name, P0, P1, P2, P3) \
832   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
833   InteropTypeConverter<P0>::InteropType _p0, \
834   InteropTypeConverter<P1>::InteropType _p1, \
835   InteropTypeConverter<P2>::InteropType _p2, \
836   InteropTypeConverter<P3>::InteropType _p3) { \
837       KOALA_MAYBE_LOG(name) \
838       P0 p0 = getArgument<P0>(env, _p0); \
839       P1 p1 = getArgument<P1>(env, _p1); \
840       P2 p2 = getArgument<P2>(env, _p2); \
841       P3 p3 = getArgument<P3>(env, _p3); \
842       impl_##name(p0, p1, p2, p3); \
843       releaseArgument(env, _p0, p0); \
844       releaseArgument(env, _p1, p1); \
845       releaseArgument(env, _p2, p2); \
846       releaseArgument(env, _p3, p3); \
847 } \
848 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3)
849 
850 #define KOALA_INTEROP_V5(name, P0, P1, P2, P3, P4) \
851   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
852   InteropTypeConverter<P0>::InteropType _p0, \
853   InteropTypeConverter<P1>::InteropType _p1, \
854   InteropTypeConverter<P2>::InteropType _p2, \
855   InteropTypeConverter<P3>::InteropType _p3, \
856   InteropTypeConverter<P4>::InteropType _p4) { \
857       KOALA_MAYBE_LOG(name) \
858       P0 p0 = getArgument<P0>(env, _p0); \
859       P1 p1 = getArgument<P1>(env, _p1); \
860       P2 p2 = getArgument<P2>(env, _p2); \
861       P3 p3 = getArgument<P3>(env, _p3); \
862       P4 p4 = getArgument<P4>(env, _p4); \
863       impl_##name(p0, p1, p2, p3, p4); \
864       releaseArgument(env, _p0, p0); \
865       releaseArgument(env, _p1, p1); \
866       releaseArgument(env, _p2, p2); \
867       releaseArgument(env, _p3, p3); \
868       releaseArgument(env, _p4, p4); \
869 } \
870 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4)
871 
872 #define KOALA_INTEROP_V6(name, P0, P1, P2, P3, P4, P5) \
873   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
874   InteropTypeConverter<P0>::InteropType _p0, \
875   InteropTypeConverter<P1>::InteropType _p1, \
876   InteropTypeConverter<P2>::InteropType _p2, \
877   InteropTypeConverter<P3>::InteropType _p3, \
878   InteropTypeConverter<P4>::InteropType _p4, \
879   InteropTypeConverter<P5>::InteropType _p5) { \
880       KOALA_MAYBE_LOG(name) \
881       P0 p0 = getArgument<P0>(env, _p0); \
882       P1 p1 = getArgument<P1>(env, _p1); \
883       P2 p2 = getArgument<P2>(env, _p2); \
884       P3 p3 = getArgument<P3>(env, _p3); \
885       P4 p4 = getArgument<P4>(env, _p4); \
886       P5 p5 = getArgument<P5>(env, _p5); \
887       impl_##name(p0, p1, p2, p3, p4, p5); \
888       releaseArgument(env, _p0, p0); \
889       releaseArgument(env, _p1, p1); \
890       releaseArgument(env, _p2, p2); \
891       releaseArgument(env, _p3, p3); \
892       releaseArgument(env, _p4, p4); \
893       releaseArgument(env, _p5, p5); \
894 } \
895 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5)
896 
897 #define KOALA_INTEROP_V7(name, P0, P1, P2, P3, P4, P5, P6) \
898   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
899   InteropTypeConverter<P0>::InteropType _p0, \
900   InteropTypeConverter<P1>::InteropType _p1, \
901   InteropTypeConverter<P2>::InteropType _p2, \
902   InteropTypeConverter<P3>::InteropType _p3, \
903   InteropTypeConverter<P4>::InteropType _p4, \
904   InteropTypeConverter<P5>::InteropType _p5, \
905   InteropTypeConverter<P6>::InteropType _p6) { \
906       KOALA_MAYBE_LOG(name) \
907       P0 p0 = getArgument<P0>(env, _p0); \
908       P1 p1 = getArgument<P1>(env, _p1); \
909       P2 p2 = getArgument<P2>(env, _p2); \
910       P3 p3 = getArgument<P3>(env, _p3); \
911       P4 p4 = getArgument<P4>(env, _p4); \
912       P5 p5 = getArgument<P5>(env, _p5); \
913       P6 p6 = getArgument<P6>(env, _p6); \
914       impl_##name(p0, p1, p2, p3, p4, p5, p6); \
915       releaseArgument(env, _p0, p0); \
916       releaseArgument(env, _p1, p1); \
917       releaseArgument(env, _p2, p2); \
918       releaseArgument(env, _p3, p3); \
919       releaseArgument(env, _p4, p4); \
920       releaseArgument(env, _p5, p5); \
921       releaseArgument(env, _p6, p6); \
922 } \
923 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6)
924 
925 #define KOALA_INTEROP_V8(name, P0, P1, P2, P3, P4, P5, P6, P7) \
926   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
927   InteropTypeConverter<P0>::InteropType _p0, \
928   InteropTypeConverter<P1>::InteropType _p1, \
929   InteropTypeConverter<P2>::InteropType _p2, \
930   InteropTypeConverter<P3>::InteropType _p3, \
931   InteropTypeConverter<P4>::InteropType _p4, \
932   InteropTypeConverter<P5>::InteropType _p5, \
933   InteropTypeConverter<P6>::InteropType _p6, \
934   InteropTypeConverter<P7>::InteropType _p7) { \
935       KOALA_MAYBE_LOG(name) \
936       P0 p0 = getArgument<P0>(env, _p0); \
937       P1 p1 = getArgument<P1>(env, _p1); \
938       P2 p2 = getArgument<P2>(env, _p2); \
939       P3 p3 = getArgument<P3>(env, _p3); \
940       P4 p4 = getArgument<P4>(env, _p4); \
941       P5 p5 = getArgument<P5>(env, _p5); \
942       P6 p6 = getArgument<P6>(env, _p6); \
943       P7 p7 = getArgument<P7>(env, _p7); \
944       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7); \
945       releaseArgument(env, _p0, p0); \
946       releaseArgument(env, _p1, p1); \
947       releaseArgument(env, _p2, p2); \
948       releaseArgument(env, _p3, p3); \
949       releaseArgument(env, _p4, p4); \
950       releaseArgument(env, _p5, p5); \
951       releaseArgument(env, _p6, p6); \
952       releaseArgument(env, _p7, p7); \
953 } \
954 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7)
955 
956 #define KOALA_INTEROP_V9(name, P0, P1, P2, P3, P4, P5, P6, P7, P8) \
957   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
958     InteropTypeConverter<P0>::InteropType _p0, \
959     InteropTypeConverter<P1>::InteropType _p1, \
960     InteropTypeConverter<P2>::InteropType _p2, \
961     InteropTypeConverter<P3>::InteropType _p3, \
962     InteropTypeConverter<P4>::InteropType _p4, \
963     InteropTypeConverter<P5>::InteropType _p5, \
964     InteropTypeConverter<P6>::InteropType _p6, \
965     InteropTypeConverter<P7>::InteropType _p7, \
966     InteropTypeConverter<P8>::InteropType _p8) { \
967       KOALA_MAYBE_LOG(name) \
968       P0 p0 = getArgument<P0>(env, _p0); \
969       P1 p1 = getArgument<P1>(env, _p1); \
970       P2 p2 = getArgument<P2>(env, _p2); \
971       P3 p3 = getArgument<P3>(env, _p3); \
972       P4 p4 = getArgument<P4>(env, _p4); \
973       P5 p5 = getArgument<P5>(env, _p5); \
974       P6 p6 = getArgument<P6>(env, _p6); \
975       P7 p7 = getArgument<P7>(env, _p7); \
976       P8 p8 = getArgument<P8>(env, _p8); \
977       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8); \
978       releaseArgument(env, _p0, p0); \
979       releaseArgument(env, _p1, p1); \
980       releaseArgument(env, _p2, p2); \
981       releaseArgument(env, _p3, p3); \
982       releaseArgument(env, _p4, p4); \
983       releaseArgument(env, _p5, p5); \
984       releaseArgument(env, _p6, p6); \
985       releaseArgument(env, _p7, p7); \
986       releaseArgument(env, _p8, p8); \
987 } \
988 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8)
989 
990 #define KOALA_INTEROP_V10(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
991   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
992   InteropTypeConverter<P0>::InteropType _p0, \
993   InteropTypeConverter<P1>::InteropType _p1, \
994   InteropTypeConverter<P2>::InteropType _p2, \
995   InteropTypeConverter<P3>::InteropType _p3, \
996   InteropTypeConverter<P4>::InteropType _p4, \
997   InteropTypeConverter<P5>::InteropType _p5, \
998   InteropTypeConverter<P6>::InteropType _p6, \
999   InteropTypeConverter<P7>::InteropType _p7, \
1000   InteropTypeConverter<P8>::InteropType _p8, \
1001   InteropTypeConverter<P9>::InteropType _p9) { \
1002       KOALA_MAYBE_LOG(name) \
1003       P0 p0 = getArgument<P0>(env, _p0); \
1004       P1 p1 = getArgument<P1>(env, _p1); \
1005       P2 p2 = getArgument<P2>(env, _p2); \
1006       P3 p3 = getArgument<P3>(env, _p3); \
1007       P4 p4 = getArgument<P4>(env, _p4); \
1008       P5 p5 = getArgument<P5>(env, _p5); \
1009       P6 p6 = getArgument<P6>(env, _p6); \
1010       P7 p7 = getArgument<P7>(env, _p7); \
1011       P8 p8 = getArgument<P8>(env, _p8); \
1012       P9 p9 = getArgument<P9>(env, _p9); \
1013       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
1014       releaseArgument(env, _p0, p0); \
1015       releaseArgument(env, _p1, p1); \
1016       releaseArgument(env, _p2, p2); \
1017       releaseArgument(env, _p3, p3); \
1018       releaseArgument(env, _p4, p4); \
1019       releaseArgument(env, _p5, p5); \
1020       releaseArgument(env, _p6, p6); \
1021       releaseArgument(env, _p7, p7); \
1022       releaseArgument(env, _p8, p8); \
1023       releaseArgument(env, _p9, p9); \
1024 } \
1025 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9)
1026 
1027 #define KOALA_INTEROP_V11(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
1028   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1029   InteropTypeConverter<P0>::InteropType _p0, \
1030   InteropTypeConverter<P1>::InteropType _p1, \
1031   InteropTypeConverter<P2>::InteropType _p2, \
1032   InteropTypeConverter<P3>::InteropType _p3, \
1033   InteropTypeConverter<P4>::InteropType _p4, \
1034   InteropTypeConverter<P5>::InteropType _p5, \
1035   InteropTypeConverter<P6>::InteropType _p6, \
1036   InteropTypeConverter<P7>::InteropType _p7, \
1037   InteropTypeConverter<P8>::InteropType _p8, \
1038   InteropTypeConverter<P9>::InteropType _p9, \
1039   InteropTypeConverter<P10>::InteropType _p10) { \
1040       KOALA_MAYBE_LOG(name) \
1041       P0 p0 = getArgument<P0>(env, _p0); \
1042       P1 p1 = getArgument<P1>(env, _p1); \
1043       P2 p2 = getArgument<P2>(env, _p2); \
1044       P3 p3 = getArgument<P3>(env, _p3); \
1045       P4 p4 = getArgument<P4>(env, _p4); \
1046       P5 p5 = getArgument<P5>(env, _p5); \
1047       P6 p6 = getArgument<P6>(env, _p6); \
1048       P7 p7 = getArgument<P7>(env, _p7); \
1049       P8 p8 = getArgument<P8>(env, _p8); \
1050       P9 p9 = getArgument<P9>(env, _p9); \
1051       P10 p10 = getArgument<P10>(env, _p10); \
1052       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
1053       releaseArgument(env, _p0, p0); \
1054       releaseArgument(env, _p1, p1); \
1055       releaseArgument(env, _p2, p2); \
1056       releaseArgument(env, _p3, p3); \
1057       releaseArgument(env, _p4, p4); \
1058       releaseArgument(env, _p5, p5); \
1059       releaseArgument(env, _p6, p6); \
1060       releaseArgument(env, _p7, p7); \
1061       releaseArgument(env, _p8, p8); \
1062       releaseArgument(env, _p9, p9); \
1063       releaseArgument(env, _p10, p10); \
1064 } \
1065 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10)
1066 
1067 #define KOALA_INTEROP_V12(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
1068   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1069   InteropTypeConverter<P0>::InteropType _p0, \
1070   InteropTypeConverter<P1>::InteropType _p1, \
1071   InteropTypeConverter<P2>::InteropType _p2, \
1072   InteropTypeConverter<P3>::InteropType _p3, \
1073   InteropTypeConverter<P4>::InteropType _p4, \
1074   InteropTypeConverter<P5>::InteropType _p5, \
1075   InteropTypeConverter<P6>::InteropType _p6, \
1076   InteropTypeConverter<P7>::InteropType _p7, \
1077   InteropTypeConverter<P8>::InteropType _p8, \
1078   InteropTypeConverter<P9>::InteropType _p9, \
1079   InteropTypeConverter<P10>::InteropType _p10, \
1080   InteropTypeConverter<P11>::InteropType _p11) { \
1081       KOALA_MAYBE_LOG(name) \
1082       P0 p0 = getArgument<P0>(env, _p0); \
1083       P1 p1 = getArgument<P1>(env, _p1); \
1084       P2 p2 = getArgument<P2>(env, _p2); \
1085       P3 p3 = getArgument<P3>(env, _p3); \
1086       P4 p4 = getArgument<P4>(env, _p4); \
1087       P5 p5 = getArgument<P5>(env, _p5); \
1088       P6 p6 = getArgument<P6>(env, _p6); \
1089       P7 p7 = getArgument<P7>(env, _p7); \
1090       P8 p8 = getArgument<P8>(env, _p8); \
1091       P9 p9 = getArgument<P9>(env, _p9); \
1092       P10 p10 = getArgument<P10>(env, _p10); \
1093       P11 p11 = getArgument<P11>(env, _p11); \
1094       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
1095       releaseArgument(env, _p0, p0); \
1096       releaseArgument(env, _p1, p1); \
1097       releaseArgument(env, _p2, p2); \
1098       releaseArgument(env, _p3, p3); \
1099       releaseArgument(env, _p4, p4); \
1100       releaseArgument(env, _p5, p5); \
1101       releaseArgument(env, _p6, p6); \
1102       releaseArgument(env, _p7, p7); \
1103       releaseArgument(env, _p8, p8); \
1104       releaseArgument(env, _p9, p9); \
1105       releaseArgument(env, _p10, p10); \
1106       releaseArgument(env, _p11, p11); \
1107 } \
1108 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11)
1109 
1110 #define KOALA_INTEROP_V13(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
1111   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1112   InteropTypeConverter<P0>::InteropType _p0, \
1113   InteropTypeConverter<P1>::InteropType _p1, \
1114   InteropTypeConverter<P2>::InteropType _p2, \
1115   InteropTypeConverter<P3>::InteropType _p3, \
1116   InteropTypeConverter<P4>::InteropType _p4, \
1117   InteropTypeConverter<P5>::InteropType _p5, \
1118   InteropTypeConverter<P6>::InteropType _p6, \
1119   InteropTypeConverter<P7>::InteropType _p7, \
1120   InteropTypeConverter<P8>::InteropType _p8, \
1121   InteropTypeConverter<P9>::InteropType _p9, \
1122   InteropTypeConverter<P10>::InteropType _p10, \
1123   InteropTypeConverter<P11>::InteropType _p11, \
1124   InteropTypeConverter<P12>::InteropType _p12) { \
1125       KOALA_MAYBE_LOG(name) \
1126       P0 p0 = getArgument<P0>(env, _p0); \
1127       P1 p1 = getArgument<P1>(env, _p1); \
1128       P2 p2 = getArgument<P2>(env, _p2); \
1129       P3 p3 = getArgument<P3>(env, _p3); \
1130       P4 p4 = getArgument<P4>(env, _p4); \
1131       P5 p5 = getArgument<P5>(env, _p5); \
1132       P6 p6 = getArgument<P6>(env, _p6); \
1133       P7 p7 = getArgument<P7>(env, _p7); \
1134       P8 p8 = getArgument<P8>(env, _p8); \
1135       P9 p9 = getArgument<P9>(env, _p9); \
1136       P10 p10 = getArgument<P10>(env, _p10); \
1137       P11 p11 = getArgument<P11>(env, _p11); \
1138       P12 p12 = getArgument<P12>(env, _p12); \
1139       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
1140       releaseArgument(env, _p0, p0); \
1141       releaseArgument(env, _p1, p1); \
1142       releaseArgument(env, _p2, p2); \
1143       releaseArgument(env, _p3, p3); \
1144       releaseArgument(env, _p4, p4); \
1145       releaseArgument(env, _p5, p5); \
1146       releaseArgument(env, _p6, p6); \
1147       releaseArgument(env, _p7, p7); \
1148       releaseArgument(env, _p8, p8); \
1149       releaseArgument(env, _p9, p9); \
1150       releaseArgument(env, _p10, p10); \
1151       releaseArgument(env, _p11, p11); \
1152       releaseArgument(env, _p12, p12); \
1153 } \
1154 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12)
1155 
1156 #define KOALA_INTEROP_V14(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
1157   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1158   InteropTypeConverter<P0>::InteropType _p0, \
1159   InteropTypeConverter<P1>::InteropType _p1, \
1160   InteropTypeConverter<P2>::InteropType _p2, \
1161   InteropTypeConverter<P3>::InteropType _p3, \
1162   InteropTypeConverter<P4>::InteropType _p4, \
1163   InteropTypeConverter<P5>::InteropType _p5, \
1164   InteropTypeConverter<P6>::InteropType _p6, \
1165   InteropTypeConverter<P7>::InteropType _p7, \
1166   InteropTypeConverter<P8>::InteropType _p8, \
1167   InteropTypeConverter<P9>::InteropType _p9, \
1168   InteropTypeConverter<P10>::InteropType _p10, \
1169   InteropTypeConverter<P11>::InteropType _p11, \
1170   InteropTypeConverter<P12>::InteropType _p12, \
1171   InteropTypeConverter<P13>::InteropType _p13) { \
1172       KOALA_MAYBE_LOG(name) \
1173       P0 p0 = getArgument<P0>(env, _p0); \
1174       P1 p1 = getArgument<P1>(env, _p1); \
1175       P2 p2 = getArgument<P2>(env, _p2); \
1176       P3 p3 = getArgument<P3>(env, _p3); \
1177       P4 p4 = getArgument<P4>(env, _p4); \
1178       P5 p5 = getArgument<P5>(env, _p5); \
1179       P6 p6 = getArgument<P6>(env, _p6); \
1180       P7 p7 = getArgument<P7>(env, _p7); \
1181       P8 p8 = getArgument<P8>(env, _p8); \
1182       P9 p9 = getArgument<P9>(env, _p9); \
1183       P10 p10 = getArgument<P10>(env, _p10); \
1184       P11 p11 = getArgument<P11>(env, _p11); \
1185       P12 p12 = getArgument<P12>(env, _p12); \
1186       P13 p13 = getArgument<P13>(env, _p13); \
1187       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
1188       releaseArgument(env, _p0, p0); \
1189       releaseArgument(env, _p1, p1); \
1190       releaseArgument(env, _p2, p2); \
1191       releaseArgument(env, _p3, p3); \
1192       releaseArgument(env, _p4, p4); \
1193       releaseArgument(env, _p5, p5); \
1194       releaseArgument(env, _p6, p6); \
1195       releaseArgument(env, _p7, p7); \
1196       releaseArgument(env, _p8, p8); \
1197       releaseArgument(env, _p9, p9); \
1198       releaseArgument(env, _p10, p10); \
1199       releaseArgument(env, _p11, p11); \
1200       releaseArgument(env, _p12, p12); \
1201       releaseArgument(env, _p13, p13); \
1202 } \
1203 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12 "|" #P13)
1204 
1205 #define KOALA_INTEROP_V15(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
1206   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1207   InteropTypeConverter<P0>::InteropType _p0, \
1208   InteropTypeConverter<P1>::InteropType _p1, \
1209   InteropTypeConverter<P2>::InteropType _p2, \
1210   InteropTypeConverter<P3>::InteropType _p3, \
1211   InteropTypeConverter<P4>::InteropType _p4, \
1212   InteropTypeConverter<P5>::InteropType _p5, \
1213   InteropTypeConverter<P6>::InteropType _p6, \
1214   InteropTypeConverter<P7>::InteropType _p7, \
1215   InteropTypeConverter<P8>::InteropType _p8, \
1216   InteropTypeConverter<P9>::InteropType _p9, \
1217   InteropTypeConverter<P10>::InteropType _p10, \
1218   InteropTypeConverter<P11>::InteropType _p11, \
1219   InteropTypeConverter<P12>::InteropType _p12, \
1220   InteropTypeConverter<P13>::InteropType _p13, \
1221   InteropTypeConverter<P14>::InteropType _p14) { \
1222       KOALA_MAYBE_LOG(name) \
1223       P0 p0 = getArgument<P0>(env, _p0); \
1224       P1 p1 = getArgument<P1>(env, _p1); \
1225       P2 p2 = getArgument<P2>(env, _p2); \
1226       P3 p3 = getArgument<P3>(env, _p3); \
1227       P4 p4 = getArgument<P4>(env, _p4); \
1228       P5 p5 = getArgument<P5>(env, _p5); \
1229       P6 p6 = getArgument<P6>(env, _p6); \
1230       P7 p7 = getArgument<P7>(env, _p7); \
1231       P8 p8 = getArgument<P8>(env, _p8); \
1232       P9 p9 = getArgument<P9>(env, _p9); \
1233       P10 p10 = getArgument<P10>(env, _p10); \
1234       P11 p11 = getArgument<P11>(env, _p11); \
1235       P12 p12 = getArgument<P12>(env, _p12); \
1236       P13 p13 = getArgument<P13>(env, _p13); \
1237       P14 p14 = getArgument<P14>(env, _p14); \
1238       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
1239       releaseArgument(env, _p0, p0); \
1240       releaseArgument(env, _p1, p1); \
1241       releaseArgument(env, _p2, p2); \
1242       releaseArgument(env, _p3, p3); \
1243       releaseArgument(env, _p4, p4); \
1244       releaseArgument(env, _p5, p5); \
1245       releaseArgument(env, _p6, p6); \
1246       releaseArgument(env, _p7, p7); \
1247       releaseArgument(env, _p8, p8); \
1248       releaseArgument(env, _p9, p9); \
1249       releaseArgument(env, _p10, p10); \
1250       releaseArgument(env, _p11, p11); \
1251       releaseArgument(env, _p12, p12); \
1252       releaseArgument(env, _p13, p13); \
1253       releaseArgument(env, _p14, p14); \
1254 }  \
1255 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12 "|" #P13 "|" #P14)
1256 
1257 #define KOALA_INTEROP_CTX_0(name, Ret) \
1258    KOALA_JNI_CALL(SlowInteropTypeConverter<Ret>::InteropType) \
1259    Java_org_##name(JNIEnv* env, jclass instance) { \
1260       KOALA_MAYBE_LOG(name) \
1261       KVMContext ctx = (KVMContext)env; \
1262       auto rv = SlowInteropTypeConverter<Ret>::convertTo(env, impl_##name(ctx)); \
1263       return rv; \
1264   } \
1265 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret)
1266 
1267 #define KOALA_INTEROP_CTX_1(name, Ret, P0) \
1268    KOALA_JNI_CALL(SlowInteropTypeConverter<Ret>::InteropType) \
1269    Java_org_##name(JNIEnv* env, jclass instance, \
1270     SlowInteropTypeConverter<P0>::InteropType _p0) { \
1271       KOALA_MAYBE_LOG(name) \
1272       P0 p0 = getArgument<P0>(env, _p0); \
1273       KVMContext ctx = (KVMContext)env; \
1274       auto rv = SlowInteropTypeConverter<Ret>::convertTo(env, impl_##name(ctx, p0)); \
1275       releaseArgument(env, _p0, p0); \
1276       return rv; \
1277   } \
1278 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0)
1279 
1280 #define KOALA_INTEROP_CTX_2(name, Ret, P0, P1) \
1281   KOALA_JNI_CALL(SlowInteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
1282   SlowInteropTypeConverter<P0>::InteropType _p0, \
1283   SlowInteropTypeConverter<P1>::InteropType _p1) { \
1284       KOALA_MAYBE_LOG(name) \
1285       P0 p0 = getArgument<P0>(env, _p0); \
1286       P1 p1 = getArgument<P1>(env, _p1); \
1287       KVMContext ctx = (KVMContext)env; \
1288       auto rv = SlowInteropTypeConverter<Ret>::convertTo(env, impl_##name(ctx, p0, p1)); \
1289       releaseArgument(env, _p0, p0); \
1290       releaseArgument(env, _p1, p1); \
1291       return rv; \
1292 } \
1293 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1)
1294 
1295 #define KOALA_INTEROP_CTX_3(name, Ret, P0, P1, P2) \
1296   KOALA_JNI_CALL(SlowInteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
1297   SlowInteropTypeConverter<P0>::InteropType _p0, \
1298   SlowInteropTypeConverter<P1>::InteropType _p1, \
1299   SlowInteropTypeConverter<P2>::InteropType _p2) { \
1300       KOALA_MAYBE_LOG(name) \
1301       P0 p0 = getArgument<P0>(env, _p0); \
1302       P1 p1 = getArgument<P1>(env, _p1); \
1303       P2 p2 = getArgument<P2>(env, _p2); \
1304       KVMContext ctx = (KVMContext)env; \
1305       auto rv = SlowInteropTypeConverter<Ret>::convertTo(env, impl_##name(ctx, p0, p1, p2)); \
1306       releaseArgument(env, _p0, p0); \
1307       releaseArgument(env, _p1, p1); \
1308       releaseArgument(env, _p2, p2); \
1309       return rv; \
1310 } \
1311 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2)
1312 
1313 #define KOALA_INTEROP_CTX_4(name, Ret, P0, P1, P2, P3) \
1314   KOALA_JNI_CALL(SlowInteropTypeConverter<Ret>::InteropType) Java_org_##name(JNIEnv* env, jclass instance, \
1315   SlowInteropTypeConverter<P0>::InteropType _p0, \
1316   SlowInteropTypeConverter<P1>::InteropType _p1, \
1317   SlowInteropTypeConverter<P2>::InteropType _p2, \
1318   SlowInteropTypeConverter<P3>::InteropType _p3) { \
1319       KOALA_MAYBE_LOG(name) \
1320       P0 p0 = getArgument<P0>(env, _p0); \
1321       P1 p1 = getArgument<P1>(env, _p1); \
1322       P2 p2 = getArgument<P2>(env, _p2); \
1323       P3 p3 = getArgument<P3>(env, _p3); \
1324       KVMContext ctx = (KVMContext)env; \
1325       auto rv = SlowInteropTypeConverter<Ret>::convertTo(env, impl_##name(ctx, p0, p1, p2, p3)); \
1326       releaseArgument(env, _p0, p0); \
1327       releaseArgument(env, _p1, p1); \
1328       releaseArgument(env, _p2, p2); \
1329       releaseArgument(env, _p3, p3); \
1330       return rv; \
1331 } \
1332 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3)
1333 
1334 #define KOALA_INTEROP_CTX_V0(name) \
1335    KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance) { \
1336       KOALA_MAYBE_LOG(name) \
1337       KVMContext ctx = (KVMContext)env; \
1338       impl_##name(ctx); \
1339   } \
1340 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void")
1341 
1342 #define KOALA_INTEROP_CTX_V1(name, P0) \
1343    KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1344     SlowInteropTypeConverter<P0>::InteropType _p0) { \
1345       KOALA_MAYBE_LOG(name) \
1346       P0 p0 = getArgument<P0>(env, _p0); \
1347       KVMContext ctx = (KVMContext)env; \
1348       impl_##name(ctx, p0); \
1349       releaseArgument(env, _p0, p0); \
1350   } \
1351 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0)
1352 
1353 #define KOALA_INTEROP_CTX_V2(name, P0, P1) \
1354   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1355    SlowInteropTypeConverter<P0>::InteropType _p0, \
1356    SlowInteropTypeConverter<P1>::InteropType _p1) { \
1357       KOALA_MAYBE_LOG(name) \
1358       P0 p0 = getArgument<P0>(env, _p0); \
1359       P1 p1 = getArgument<P1>(env, _p1); \
1360       KVMContext ctx = (KVMContext)env; \
1361       impl_##name(ctx, p0, p1); \
1362       releaseArgument(env, _p0, p0); \
1363       releaseArgument(env, _p1, p1); \
1364 } \
1365 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1)
1366 
1367 #define KOALA_INTEROP_CTX_V3(name, P0, P1, P2) \
1368   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1369    SlowInteropTypeConverter<P0>::InteropType _p0, \
1370    SlowInteropTypeConverter<P1>::InteropType _p1, \
1371    SlowInteropTypeConverter<P2>::InteropType _p2) { \
1372       KOALA_MAYBE_LOG(name) \
1373       P0 p0 = getArgument<P0>(env, _p0); \
1374       P1 p1 = getArgument<P1>(env, _p1); \
1375       P2 p2 = getArgument<P2>(env, _p2); \
1376       KVMContext ctx = (KVMContext)env; \
1377       impl_##name(ctx, p0, p1, p2); \
1378       releaseArgument(env, _p0, p0); \
1379       releaseArgument(env, _p1, p1); \
1380       releaseArgument(env, _p2, p2); \
1381 } \
1382 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2)
1383 
1384 #define KOALA_INTEROP_CTX_V4(name, P0, P1, P2, P3) \
1385   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1386    SlowInteropTypeConverter<P0>::InteropType _p0, \
1387    SlowInteropTypeConverter<P1>::InteropType _p1, \
1388    SlowInteropTypeConverter<P2>::InteropType _p2, \
1389    SlowInteropTypeConverter<P3>::InteropType _p3) { \
1390       KOALA_MAYBE_LOG(name) \
1391       P0 p0 = getArgument<P0>(env, _p0); \
1392       P1 p1 = getArgument<P1>(env, _p1); \
1393       P2 p2 = getArgument<P2>(env, _p2); \
1394       P3 p3 = getArgument<P3>(env, _p3); \
1395       KVMContext ctx = (KVMContext)env; \
1396       impl_##name(ctx, p0, p1, p2, p3); \
1397       releaseArgument(env, _p0, p0); \
1398       releaseArgument(env, _p1, p1); \
1399       releaseArgument(env, _p2, p2); \
1400       releaseArgument(env, _p3, p3); \
1401 } \
1402 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3)
1403 
1404 #define KOALA_INTEROP_CTX_V5(name, P0, P1, P2, P3, P4) \
1405   KOALA_JNI_CALL(void) Java_org_##name(JNIEnv* env, jclass instance, \
1406    SlowInteropTypeConverter<P0>::InteropType _p0, \
1407    SlowInteropTypeConverter<P1>::InteropType _p1, \
1408    SlowInteropTypeConverter<P2>::InteropType _p2, \
1409    SlowInteropTypeConverter<P3>::InteropType _p3, \
1410    SlowInteropTypeConverter<P4>::InteropType _p4) { \
1411       KOALA_MAYBE_LOG(name) \
1412       P0 p0 = getArgument<P0>(env, _p0); \
1413       P1 p1 = getArgument<P1>(env, _p1); \
1414       P2 p2 = getArgument<P2>(env, _p2); \
1415       P3 p3 = getArgument<P3>(env, _p3); \
1416       P4 p4 = getArgument<P4>(env, _p4); \
1417       KVMContext ctx = (KVMContext)env; \
1418       impl_##name(ctx, p0, p1, p2, p3, p4); \
1419       releaseArgument(env, _p0, p0); \
1420       releaseArgument(env, _p1, p1); \
1421       releaseArgument(env, _p2, p2); \
1422       releaseArgument(env, _p3, p3); \
1423       releaseArgument(env, _p4, p4); \
1424 } \
1425 MAKE_JNI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4)
1426 
1427 bool setKoalaJniCallbackDispatcher(
1428     JNIEnv* env,
1429     jclass clazz,
1430     const char* dispatcherMethodName,
1431     const char* dispactherMethodSig
1432 );
1433 void getKoalaJniCallbackDispatcher(jclass* clazz, jmethodID* method);
1434 
1435 #define KOALA_INTEROP_CALL_VOID(venv, id, length, args)                            \
1436 {                                                                                  \
1437   jclass clazz = nullptr;                                                          \
1438   jmethodID method = nullptr;                                                      \
1439   getKoalaJniCallbackDispatcher(&clazz, &method);                                  \
1440   JNIEnv* jniEnv = reinterpret_cast<JNIEnv*>(venv);                                \
1441   jniEnv->PushLocalFrame(1);                                                       \
1442   jbyteArray args_jni = jniEnv->NewByteArray(length);                              \
1443   jniEnv->SetByteArrayRegion(args_jni, 0, length, reinterpret_cast<jbyte*>(args)); \
1444   jniEnv->CallStaticIntMethod(clazz, method, id, args_jni, length);                \
1445   jniEnv->GetByteArrayRegion(args_jni, 0, length, reinterpret_cast<jbyte*>(args)); \
1446   jniEnv->PopLocalFrame(nullptr);                                                  \
1447 }
1448 
1449 #define KOALA_INTEROP_CALL_INT(venv, id, length, args)                             \
1450 {                                                                                  \
1451   jclass clazz = nullptr;                                                          \
1452   jmethodID method = nullptr;                                                      \
1453   getKoalaJniCallbackDispatcher(&clazz, &method);                                  \
1454   JNIEnv* jniEnv = reinterpret_cast<JNIEnv*>(venv);                                \
1455   jniEnv->PushLocalFrame(1);                                                       \
1456   jbyteArray args_jni = jniEnv->NewByteArray(length);                              \
1457   jniEnv->SetByteArrayRegion(args_jni, 0, length, reinterpret_cast<jbyte*>(args)); \
1458   int32_t rv = jniEnv->CallStaticIntMethod(clazz, method, id, args_jni, length);   \
1459   jniEnv->GetByteArrayRegion(args_jni, 0, length, reinterpret_cast<jbyte*>(args)); \
1460   jniEnv->PopLocalFrame(nullptr);                                                  \
1461   return rv;                                                                       \
1462 }
1463 
1464 #define KOALA_INTEROP_CALL_VOID_INTS32(venv, id, argc, args) KOALA_INTEROP_CALL_VOID(venv, id, (argc) * sizeof(int32_t), args)
1465 #define KOALA_INTEROP_CALL_INT_INTS32(venv, id, argc, args) KOALA_INTEROP_CALL_INT(venv, id, (argc) * sizeof(int32_t), args)
1466 
1467 #define KOALA_INTEROP_THROW(vmContext, object, ...) \
1468    do { \
1469      JNIEnv* env = reinterpret_cast<JNIEnv*>(vmContext); \
1470      env->Throw(object); \
1471      return __VA_ARGS__; \
1472    } while (0)
1473 
1474 #define KOALA_INTEROP_THROW_STRING(vmContext, message, ...) \
1475   do { \
1476     JNIEnv* env = reinterpret_cast<JNIEnv*>(vmContext); \
1477     const static jclass errorClass = env->FindClass("java/lang/RuntimeException"); \
1478     env->ThrowNew(errorClass, message); \
1479   } while (0)
1480 
1481 #endif  // KOALA_JNI_CALL
1482 
1483 #endif // CONVERTORS_JNI_H