• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 KOALA_ANI
17 #define KOALA_ANI
18 
19 #include <memory>
20 #include <vector>
21 #include <string>
22 #include <cmath>
23 #include <tuple>
24 #include <unordered_map>
25 
26 #include "ani.h"
27 #include "koala-types.h"
28 
29 template<class T>
30 struct InteropTypeConverter {
31     using InteropType = T;
convertFromInteropTypeConverter32     static T convertFrom(ani_env* env, InteropType value) { return value; }
convertToInteropTypeConverter33     static InteropType convertTo(ani_env* env, T value) { return value; }
releaseInteropTypeConverter34     static void release(ani_env* env, InteropType value, T converted) {}
35 };
36 
37 template<>
38 struct InteropTypeConverter<KStringPtr> {
39     using InteropType = ani_string;
40     static KStringPtr convertFrom(ani_env* env, InteropType value) {
41         if (value == nullptr) return KStringPtr();
42         KStringPtr result;
43         // Notice that we use UTF length for buffer size, but counter is expressed in number of Unicode chars.
44         ani_size lengthUtf8 = 0;
45         env->String_GetUTF8Size(value, &lengthUtf8);
46         result.resize(lengthUtf8);
47         ani_size lengthUtf16 = 0;
48         env->String_GetUTF16Size(value, &lengthUtf16);
49         ani_size count;
50         env->String_GetUTF8SubString(value, 0, lengthUtf16, result.data(), result.length(), &count);
51         return result;
52     }
53     static InteropType convertTo(ani_env* env, const KStringPtr& value) {
54       ani_string result;
55       env->String_NewUTF8(value.c_str(), value.length(), &result);
56       return result;
57     }
58     static void release(ani_env* env, InteropType value, const KStringPtr& converted) {}
59 };
60 
61 template<>
62 struct InteropTypeConverter<KNativePointer> {
63     using InteropType = ani_long;
64     static KNativePointer convertFrom(ani_env* env, InteropType value) {
65       return reinterpret_cast<KNativePointer>(value);
66     }
67     static InteropType convertTo(ani_env* env, KNativePointer value) {
68       return reinterpret_cast<ani_long>(value);
69     }
70     static void release(ani_env* env, InteropType value, KNativePointer converted) {}
71 };
72 
73 template<>
74 struct InteropTypeConverter<KInt*> {
75     using InteropType = ani_fixedarray_int;
76     static KInt* convertFrom(ani_env* env, InteropType value) {
77       if (!value) return nullptr;
78       ani_size length = 0;
79       env->FixedArray_GetLength(value, &length);
80       KInt* result = new KInt[length];
81       env->FixedArray_GetRegion_Int(value, 0, length, result);
82       return result;
83     }
84     static InteropType convertTo(ani_env* env, KInt* value) = delete;
85     static void release(ani_env* env, InteropType value, KInt* converted) {
86       if (converted) delete [] converted;
87     }
88 };
89 
90 template<>
91 struct InteropTypeConverter<KFloat*> {
92     using InteropType = ani_fixedarray_float;
93     static KFloat* convertFrom(ani_env* env, InteropType value) {
94       if (!value) return nullptr;
95       ani_size length = 0;
96       env->FixedArray_GetLength(value, &length);
97       KFloat* result = new KFloat[length];
98       env->FixedArray_GetRegion_Float(value, 0, length, result);
99       return result;
100     }
101     static InteropType convertTo(ani_env* env, KFloat* value) = delete;
102     static void release(ani_env* env, InteropType value, KFloat* converted) {
103       if (converted) delete [] converted;
104     }
105 };
106 
107 template<>
108 struct InteropTypeConverter<KByte*> {
109     using InteropType = ani_fixedarray_byte;
110     static KByte* convertFrom(ani_env* env, InteropType value) {
111       if (!value) return nullptr;
112       ani_size length = 0;
113       env->FixedArray_GetLength(value, &length);
114       KByte* result = new KByte[length];
115       env->FixedArray_GetRegion_Byte(value, 0, length, (ani_byte*)result);
116       return result;
117     }
118     static InteropType convertTo(ani_env* env, KByte* value) = delete;
119     static void release(ani_env* env, InteropType value, KByte* converted) {
120       if (converted) delete [] converted;
121     }
122 };
123 
124 template <> struct InteropTypeConverter<KInteropNumber> {
125   using InteropType = ani_double;
126   static KInteropNumber convertFrom(ani_env *env, InteropType value) {
127     return KInteropNumber::fromDouble(value);
128   }
129   static InteropType convertTo(ani_env *env, KInteropNumber value) {
130     return value.asDouble();
131   }
132   static void release(ani_env *env, InteropType value,
133                       KInteropNumber converted) {}
134 };
135 
136 template<>
137 struct InteropTypeConverter<KLength> {
138   using InteropType = ani_ref;
139   static KLength convertFrom(ani_env* env, InteropType value) {
140     // TODO: implement me
141     return KLength( { 0, 0, 0, 0});
142   }
143   static InteropType convertTo(ani_env* env, KLength value) = delete;
144   static void release(ani_env* env, InteropType value, const KLength& converted) {}
145 };
146 
147 template <typename Type>
148 inline typename InteropTypeConverter<Type>::InteropType makeResult(ani_env* env, Type value) {
149   return InteropTypeConverter<Type>::convertTo(env, value);
150 }
151 
152 template <typename Type>
153 inline Type getArgument(ani_env* env, typename InteropTypeConverter<Type>::InteropType arg) {
154   return InteropTypeConverter<Type>::convertFrom(env, arg);
155 }
156 
157 template <typename Type>
158 inline void releaseArgument(ani_env* env, typename InteropTypeConverter<Type>::InteropType arg, Type& data) {
159   InteropTypeConverter<Type>::release(env, arg, data);
160 }
161 
162 #define ANI_SLOW_NATIVE_FLAG 1
163 
164 class AniExports {
165     std::unordered_map<std::string,
166         std::vector<std::tuple<std::string, std::string, void*, int>>> implementations;
167     std::unordered_map<std::string, std::string> classpaths;
168 
169 public:
170     static AniExports* getInstance();
171 
172     std::vector<std::string> getModules();
173     void addMethod(const char* module, const char* name, const char* type, void* impl, int flags);
174     const std::vector<std::tuple<std::string, std::string, void*, int>>& getMethods(const std::string& module);
175 
176     void setClasspath(const char* module, const char* classpath);
177     const std::string& getClasspath(const std::string& module);
178 };
179 
180 #define KOALA_QUOTE0(x) #x
181 #define KOALA_QUOTE(x) KOALA_QUOTE0(x)
182 
183 #ifdef _MSC_VER
184 #define MAKE_ANI_EXPORT(module, name, type, flag)                             \
185     static void __init_##name() {                               \
186         AniExports::getInstance()->addMethod(KOALA_QUOTE(module), "_"#name, type, reinterpret_cast<void *>(Ani_##name), flag); \
187     }                                                           \
188     namespace {                                                 \
189       struct __Init_##name {                                    \
190         __Init_##name() {  __init_##name(); }                   \
191       } __Init_##name##_v;                                      \
192     }
193 #define KOALA_ANI_INTEROP_MODULE_CLASSPATH(module, classpath)                                 \
194     static void __init_classpath_##module() {                                                 \
195         AniExports::getInstance()->setClasspath(KOALA_QUOTE(module), classpath); \
196     }                                                                                         \
197     namespace {                                                                               \
198       struct __Init_classpath_##module {                                                      \
199         __Init_classpath_##module() {  __init_classpath_##module(); }                         \
200       } __Init_classpath_##module##_v;                                                        \
201     }
202 #else
203 #define MAKE_ANI_EXPORT(module, name, type, flag) \
204     __attribute__((constructor)) \
205     static void __init_ets_##name() { \
206         AniExports::getInstance()->addMethod(KOALA_QUOTE(module), "_"#name, type, reinterpret_cast<void *>(Ani_##name), flag); \
207     }
208 #define KOALA_ANI_INTEROP_MODULE_CLASSPATH(module, classpath)                                 \
209     __attribute__((constructor))                                                              \
210     static void __init_ani_classpath_##module() {                                             \
211         AniExports::getInstance()->setClasspath(KOALA_QUOTE(module), classpath); \
212     }
213 #endif
214 
215 #define KOALA_INTEROP_0(name, Ret) \
216   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz) { \
217       KOALA_MAYBE_LOG(name)                       \
218       return makeResult<Ret>(env, impl_##name()); \
219   } \
220 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret, 0)
221 
222 #define KOALA_INTEROP_1(name, Ret, P0) \
223   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
224    InteropTypeConverter<P0>::InteropType _p0) { \
225       KOALA_MAYBE_LOG(name)                   \
226       P0 p0 = getArgument<P0>(env, _p0); \
227       auto rv = makeResult<Ret>(env, impl_##name(p0)); \
228       releaseArgument(env, _p0, p0); \
229       return rv; \
230   } \
231 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0, 0)
232 
233 #define KOALA_INTEROP_2(name, Ret, P0, P1) \
234   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
235     InteropTypeConverter<P0>::InteropType _p0, \
236     InteropTypeConverter<P1>::InteropType _p1) { \
237       KOALA_MAYBE_LOG(name)                   \
238       P0 p0 = getArgument<P0>(env, _p0); \
239       P1 p1 = getArgument<P1>(env, _p1); \
240       auto rv = makeResult<Ret>(env, impl_##name(p0, p1)); \
241       releaseArgument(env, _p0, p0); \
242       releaseArgument(env, _p1, p1); \
243       return rv; \
244   } \
245 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1, 0)
246 
247 #define KOALA_INTEROP_3(name, Ret, P0, P1, P2) \
248   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
249     InteropTypeConverter<P0>::InteropType _p0, \
250     InteropTypeConverter<P1>::InteropType _p1, \
251     InteropTypeConverter<P2>::InteropType _p2) { \
252       KOALA_MAYBE_LOG(name)                   \
253       P0 p0 = getArgument<P0>(env, _p0); \
254       P1 p1 = getArgument<P1>(env, _p1); \
255       P2 p2 = getArgument<P2>(env, _p2); \
256       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2)); \
257       releaseArgument(env, _p0, p0); \
258       releaseArgument(env, _p1, p1); \
259       releaseArgument(env, _p2, p2); \
260       return rv; \
261   } \
262 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2, 0)
263 
264 #define KOALA_INTEROP_4(name, Ret, P0, P1, P2, P3) \
265   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
266     InteropTypeConverter<P0>::InteropType _p0, \
267     InteropTypeConverter<P1>::InteropType _p1, \
268     InteropTypeConverter<P2>::InteropType _p2, \
269     InteropTypeConverter<P3>::InteropType _p3) { \
270       KOALA_MAYBE_LOG(name)                   \
271       P0 p0 = getArgument<P0>(env, _p0); \
272       P1 p1 = getArgument<P1>(env, _p1); \
273       P2 p2 = getArgument<P2>(env, _p2); \
274       P3 p3 = getArgument<P3>(env, _p3); \
275       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3)); \
276       releaseArgument(env, _p0, p0); \
277       releaseArgument(env, _p1, p1); \
278       releaseArgument(env, _p2, p2); \
279       releaseArgument(env, _p3, p3); \
280       return rv; \
281   } \
282 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3, 0)
283 
284 #define KOALA_INTEROP_5(name, Ret, P0, P1, P2, P3, P4) \
285   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
286     InteropTypeConverter<P0>::InteropType _p0, \
287     InteropTypeConverter<P1>::InteropType _p1, \
288     InteropTypeConverter<P2>::InteropType _p2, \
289     InteropTypeConverter<P3>::InteropType _p3, \
290     InteropTypeConverter<P4>::InteropType _p4) { \
291       KOALA_MAYBE_LOG(name) \
292       P0 p0 = getArgument<P0>(env, _p0); \
293       P1 p1 = getArgument<P1>(env, _p1); \
294       P2 p2 = getArgument<P2>(env, _p2); \
295       P3 p3 = getArgument<P3>(env, _p3); \
296       P4 p4 = getArgument<P4>(env, _p4); \
297       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4)); \
298       releaseArgument(env, _p0, p0); \
299       releaseArgument(env, _p1, p1); \
300       releaseArgument(env, _p2, p2); \
301       releaseArgument(env, _p3, p3); \
302       releaseArgument(env, _p4, p4); \
303       return rv; \
304   } \
305 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4, 0)
306 
307 #define KOALA_INTEROP_6(name, Ret, P0, P1, P2, P3, P4, P5) \
308 InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
309   InteropTypeConverter<P0>::InteropType _p0, \
310   InteropTypeConverter<P1>::InteropType _p1, \
311   InteropTypeConverter<P2>::InteropType _p2, \
312   InteropTypeConverter<P3>::InteropType _p3, \
313   InteropTypeConverter<P4>::InteropType _p4, \
314   InteropTypeConverter<P5>::InteropType _p5) { \
315       KOALA_MAYBE_LOG(name) \
316       P0 p0 = getArgument<P0>(env, _p0); \
317       P1 p1 = getArgument<P1>(env, _p1); \
318       P2 p2 = getArgument<P2>(env, _p2); \
319       P3 p3 = getArgument<P3>(env, _p3); \
320       P4 p4 = getArgument<P4>(env, _p4); \
321       P5 p5 = getArgument<P5>(env, _p5); \
322       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5)); \
323       releaseArgument(env, _p0, p0); \
324       releaseArgument(env, _p1, p1); \
325       releaseArgument(env, _p2, p2); \
326       releaseArgument(env, _p3, p3); \
327       releaseArgument(env, _p4, p4); \
328       releaseArgument(env, _p5, p5); \
329       return rv; \
330   } \
331 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5, 0)
332 
333 #define KOALA_INTEROP_7(name, Ret, P0, P1, P2, P3, P4, P5, P6) \
334   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
335     InteropTypeConverter<P0>::InteropType _p0, \
336     InteropTypeConverter<P1>::InteropType _p1, \
337     InteropTypeConverter<P2>::InteropType _p2, \
338     InteropTypeConverter<P3>::InteropType _p3, \
339     InteropTypeConverter<P4>::InteropType _p4, \
340     InteropTypeConverter<P5>::InteropType _p5, \
341     InteropTypeConverter<P6>::InteropType _p6) { \
342       KOALA_MAYBE_LOG(name) \
343       P0 p0 = getArgument<P0>(env, _p0); \
344       P1 p1 = getArgument<P1>(env, _p1); \
345       P2 p2 = getArgument<P2>(env, _p2); \
346       P3 p3 = getArgument<P3>(env, _p3); \
347       P4 p4 = getArgument<P4>(env, _p4); \
348       P5 p5 = getArgument<P5>(env, _p5); \
349       P6 p6 = getArgument<P6>(env, _p6); \
350       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6)); \
351       releaseArgument(env, _p0, p0); \
352       releaseArgument(env, _p1, p1); \
353       releaseArgument(env, _p2, p2); \
354       releaseArgument(env, _p3, p3); \
355       releaseArgument(env, _p4, p4); \
356       releaseArgument(env, _p5, p5); \
357       releaseArgument(env, _p6, p6); \
358       return rv; \
359   } \
360 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6, 0)
361 
362 #define KOALA_INTEROP_8(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7) \
363   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, \
364     InteropTypeConverter<P0>::InteropType _p0, \
365     InteropTypeConverter<P1>::InteropType _p1, \
366     InteropTypeConverter<P2>::InteropType _p2, \
367     InteropTypeConverter<P3>::InteropType _p3, \
368     InteropTypeConverter<P4>::InteropType _p4, \
369     InteropTypeConverter<P5>::InteropType _p5, \
370     InteropTypeConverter<P6>::InteropType _p6, \
371     InteropTypeConverter<P7>::InteropType _p7) { \
372       KOALA_MAYBE_LOG(name) \
373       P0 p0 = getArgument<P0>(env, _p0); \
374       P1 p1 = getArgument<P1>(env, _p1); \
375       P2 p2 = getArgument<P2>(env, _p2); \
376       P3 p3 = getArgument<P3>(env, _p3); \
377       P4 p4 = getArgument<P4>(env, _p4); \
378       P5 p5 = getArgument<P5>(env, _p5); \
379       P6 p6 = getArgument<P6>(env, _p6); \
380       P7 p7 = getArgument<P7>(env, _p7); \
381       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7)); \
382       releaseArgument(env, _p0, p0); \
383       releaseArgument(env, _p1, p1); \
384       releaseArgument(env, _p2, p2); \
385       releaseArgument(env, _p3, p3); \
386       releaseArgument(env, _p4, p4); \
387       releaseArgument(env, _p5, p5); \
388       releaseArgument(env, _p6, p6); \
389       releaseArgument(env, _p7, p7); \
390       return rv; \
391   } \
392 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7, 0)
393 
394 #define KOALA_INTEROP_9(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8) \
395   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
396     InteropTypeConverter<P0>::InteropType _p0, \
397     InteropTypeConverter<P1>::InteropType _p1, \
398     InteropTypeConverter<P2>::InteropType _p2, \
399     InteropTypeConverter<P3>::InteropType _p3, \
400     InteropTypeConverter<P4>::InteropType _p4, \
401     InteropTypeConverter<P5>::InteropType _p5, \
402     InteropTypeConverter<P6>::InteropType _p6, \
403     InteropTypeConverter<P7>::InteropType _p7, \
404     InteropTypeConverter<P8>::InteropType _p8) { \
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       P4 p4 = getArgument<P4>(env, _p4); \
411       P5 p5 = getArgument<P5>(env, _p5); \
412       P6 p6 = getArgument<P6>(env, _p6); \
413       P7 p7 = getArgument<P7>(env, _p7); \
414       P8 p8 = getArgument<P8>(env, _p8); \
415       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8)); \
416       releaseArgument(env, _p0, p0); \
417       releaseArgument(env, _p1, p1); \
418       releaseArgument(env, _p2, p2); \
419       releaseArgument(env, _p3, p3); \
420       releaseArgument(env, _p4, p4); \
421       releaseArgument(env, _p5, p5); \
422       releaseArgument(env, _p6, p6); \
423       releaseArgument(env, _p7, p7); \
424       releaseArgument(env, _p8, p8); \
425       return rv; \
426   } \
427   MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8, 0)
428 
429 #define KOALA_INTEROP_10(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
430   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
431     InteropTypeConverter<P0>::InteropType _p0, \
432     InteropTypeConverter<P1>::InteropType _p1, \
433     InteropTypeConverter<P2>::InteropType _p2, \
434     InteropTypeConverter<P3>::InteropType _p3, \
435     InteropTypeConverter<P4>::InteropType _p4, \
436     InteropTypeConverter<P5>::InteropType _p5, \
437     InteropTypeConverter<P6>::InteropType _p6, \
438     InteropTypeConverter<P7>::InteropType _p7, \
439     InteropTypeConverter<P8>::InteropType _p8, \
440     InteropTypeConverter<P9>::InteropType _p9) { \
441       KOALA_MAYBE_LOG(name) \
442       P0 p0 = getArgument<P0>(env, _p0); \
443       P1 p1 = getArgument<P1>(env, _p1); \
444       P2 p2 = getArgument<P2>(env, _p2); \
445       P3 p3 = getArgument<P3>(env, _p3); \
446       P4 p4 = getArgument<P4>(env, _p4); \
447       P5 p5 = getArgument<P5>(env, _p5); \
448       P6 p6 = getArgument<P6>(env, _p6); \
449       P7 p7 = getArgument<P7>(env, _p7); \
450       P8 p8 = getArgument<P8>(env, _p8); \
451       P9 p9 = getArgument<P9>(env, _p9); \
452       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)); \
453       releaseArgument(env, _p0, p0); \
454       releaseArgument(env, _p1, p1); \
455       releaseArgument(env, _p2, p2); \
456       releaseArgument(env, _p3, p3); \
457       releaseArgument(env, _p4, p4); \
458       releaseArgument(env, _p5, p5); \
459       releaseArgument(env, _p6, p6); \
460       releaseArgument(env, _p7, p7); \
461       releaseArgument(env, _p8, p8); \
462       releaseArgument(env, _p9, p9); \
463       return rv; \
464    } \
465 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9, 0)
466 
467 #define KOALA_INTEROP_11(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
468   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
469     InteropTypeConverter<P0>::InteropType _p0, \
470     InteropTypeConverter<P1>::InteropType _p1, \
471     InteropTypeConverter<P2>::InteropType _p2, \
472     InteropTypeConverter<P3>::InteropType _p3, \
473     InteropTypeConverter<P4>::InteropType _p4, \
474     InteropTypeConverter<P5>::InteropType _p5, \
475     InteropTypeConverter<P6>::InteropType _p6, \
476     InteropTypeConverter<P7>::InteropType _p7, \
477     InteropTypeConverter<P8>::InteropType _p8, \
478     InteropTypeConverter<P9>::InteropType _p9, \
479     InteropTypeConverter<P10>::InteropType _p10) { \
480       KOALA_MAYBE_LOG(name) \
481       P0 p0 = getArgument<P0>(env, _p0); \
482       P1 p1 = getArgument<P1>(env, _p1); \
483       P2 p2 = getArgument<P2>(env, _p2); \
484       P3 p3 = getArgument<P3>(env, _p3); \
485       P4 p4 = getArgument<P4>(env, _p4); \
486       P5 p5 = getArgument<P5>(env, _p5); \
487       P6 p6 = getArgument<P6>(env, _p6); \
488       P7 p7 = getArgument<P7>(env, _p7); \
489       P8 p8 = getArgument<P8>(env, _p8); \
490       P9 p9 = getArgument<P9>(env, _p9); \
491       P10 p10 = getArgument<P10>(env, _p10); \
492       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)); \
493       releaseArgument(env, _p0, p0); \
494       releaseArgument(env, _p1, p1); \
495       releaseArgument(env, _p2, p2); \
496       releaseArgument(env, _p3, p3); \
497       releaseArgument(env, _p4, p4); \
498       releaseArgument(env, _p5, p5); \
499       releaseArgument(env, _p6, p6); \
500       releaseArgument(env, _p7, p7); \
501       releaseArgument(env, _p8, p8); \
502       releaseArgument(env, _p9, p9); \
503       releaseArgument(env, _p10, p10); \
504       return rv; \
505   } \
506 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10, 0)
507 
508 #define KOALA_INTEROP_12(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
509   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
510     InteropTypeConverter<P0>::InteropType _p0, \
511     InteropTypeConverter<P1>::InteropType _p1, \
512     InteropTypeConverter<P2>::InteropType _p2, \
513     InteropTypeConverter<P3>::InteropType _p3, \
514     InteropTypeConverter<P4>::InteropType _p4, \
515     InteropTypeConverter<P5>::InteropType _p5, \
516     InteropTypeConverter<P6>::InteropType _p6, \
517     InteropTypeConverter<P7>::InteropType _p7, \
518     InteropTypeConverter<P8>::InteropType _p8, \
519     InteropTypeConverter<P9>::InteropType _p9, \
520     InteropTypeConverter<P10>::InteropType _p10, \
521     InteropTypeConverter<P11>::InteropType _p11) { \
522       KOALA_MAYBE_LOG(name) \
523       P0 p0 = getArgument<P0>(env, _p0); \
524       P1 p1 = getArgument<P1>(env, _p1); \
525       P2 p2 = getArgument<P2>(env, _p2); \
526       P3 p3 = getArgument<P3>(env, _p3); \
527       P4 p4 = getArgument<P4>(env, _p4); \
528       P5 p5 = getArgument<P5>(env, _p5); \
529       P6 p6 = getArgument<P6>(env, _p6); \
530       P7 p7 = getArgument<P7>(env, _p7); \
531       P8 p8 = getArgument<P8>(env, _p8); \
532       P9 p9 = getArgument<P9>(env, _p9); \
533       P10 p10 = getArgument<P10>(env, _p10); \
534       P11 p11 = getArgument<P11>(env, _p11); \
535       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)); \
536       releaseArgument(env, _p0, p0); \
537       releaseArgument(env, _p1, p1); \
538       releaseArgument(env, _p2, p2); \
539       releaseArgument(env, _p3, p3); \
540       releaseArgument(env, _p4, p4); \
541       releaseArgument(env, _p5, p5); \
542       releaseArgument(env, _p6, p6); \
543       releaseArgument(env, _p7, p7); \
544       releaseArgument(env, _p8, p8); \
545       releaseArgument(env, _p9, p9); \
546       releaseArgument(env, _p10, p10); \
547       releaseArgument(env, _p11, p11); \
548       return rv; \
549   } \
550 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11, 0)
551 
552 #define KOALA_INTEROP_13(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
553   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
554     InteropTypeConverter<P0>::InteropType _p0, \
555     InteropTypeConverter<P1>::InteropType _p1, \
556     InteropTypeConverter<P2>::InteropType _p2, \
557     InteropTypeConverter<P3>::InteropType _p3, \
558     InteropTypeConverter<P4>::InteropType _p4, \
559     InteropTypeConverter<P5>::InteropType _p5, \
560     InteropTypeConverter<P6>::InteropType _p6, \
561     InteropTypeConverter<P7>::InteropType _p7, \
562     InteropTypeConverter<P8>::InteropType _p8, \
563     InteropTypeConverter<P9>::InteropType _p9, \
564     InteropTypeConverter<P10>::InteropType _p10, \
565     InteropTypeConverter<P11>::InteropType _p11, \
566     InteropTypeConverter<P12>::InteropType _p12) { \
567       KOALA_MAYBE_LOG(name) \
568       P0 p0 = getArgument<P0>(env, _p0); \
569       P1 p1 = getArgument<P1>(env, _p1); \
570       P2 p2 = getArgument<P2>(env, _p2); \
571       P3 p3 = getArgument<P3>(env, _p3); \
572       P4 p4 = getArgument<P4>(env, _p4); \
573       P5 p5 = getArgument<P5>(env, _p5); \
574       P6 p6 = getArgument<P6>(env, _p6); \
575       P7 p7 = getArgument<P7>(env, _p7); \
576       P8 p8 = getArgument<P8>(env, _p8); \
577       P9 p9 = getArgument<P9>(env, _p9); \
578       P10 p10 = getArgument<P10>(env, _p10); \
579       P11 p11 = getArgument<P11>(env, _p11); \
580       P12 p12 = getArgument<P12>(env, _p12); \
581       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)); \
582       releaseArgument(env, _p0, p0); \
583       releaseArgument(env, _p1, p1); \
584       releaseArgument(env, _p2, p2); \
585       releaseArgument(env, _p3, p3); \
586       releaseArgument(env, _p4, p4); \
587       releaseArgument(env, _p5, p5); \
588       releaseArgument(env, _p6, p6); \
589       releaseArgument(env, _p7, p7); \
590       releaseArgument(env, _p8, p8); \
591       releaseArgument(env, _p9, p9); \
592       releaseArgument(env, _p10, p10); \
593       releaseArgument(env, _p11, p11); \
594       releaseArgument(env, _p12, p12); \
595       return rv; \
596   } \
597   MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12, 0)
598 
599 #define KOALA_INTEROP_14(name, Ret, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
600   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
601     InteropTypeConverter<P0>::InteropType _p0, \
602     InteropTypeConverter<P1>::InteropType _p1, \
603     InteropTypeConverter<P2>::InteropType _p2, \
604     InteropTypeConverter<P3>::InteropType _p3, \
605     InteropTypeConverter<P4>::InteropType _p4, \
606     InteropTypeConverter<P5>::InteropType _p5, \
607     InteropTypeConverter<P6>::InteropType _p6, \
608     InteropTypeConverter<P7>::InteropType _p7, \
609     InteropTypeConverter<P8>::InteropType _p8, \
610     InteropTypeConverter<P9>::InteropType _p9, \
611     InteropTypeConverter<P10>::InteropType _p10, \
612     InteropTypeConverter<P11>::InteropType _p11, \
613     InteropTypeConverter<P12>::InteropType _p12, \
614     InteropTypeConverter<P13>::InteropType _p13) { \
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       P11 p11 = getArgument<P11>(env, _p11); \
628       P12 p12 = getArgument<P12>(env, _p12); \
629       P13 p13 = getArgument<P13>(env, _p13); \
630       auto rv = makeResult<Ret>(env, impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)); \
631       releaseArgument(env, _p0, p0); \
632       releaseArgument(env, _p1, p1); \
633       releaseArgument(env, _p2, p2); \
634       releaseArgument(env, _p3, p3); \
635       releaseArgument(env, _p4, p4); \
636       releaseArgument(env, _p5, p5); \
637       releaseArgument(env, _p6, p6); \
638       releaseArgument(env, _p7, p7); \
639       releaseArgument(env, _p8, p8); \
640       releaseArgument(env, _p9, p9); \
641       releaseArgument(env, _p10, p10); \
642       releaseArgument(env, _p11, p11); \
643       releaseArgument(env, _p12, p12); \
644       releaseArgument(env, _p13, p13); \
645       return rv; \
646     } \
647 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12 "|" #P13, 0)
648 
649 #define KOALA_INTEROP_V0(name) \
650   void Ani_##name(ani_env *env) { \
651       KOALA_MAYBE_LOG(name)                   \
652       impl_##name(); \
653   } \
654 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void", 0)
655 
656 #define KOALA_INTEROP_V1(name, P0) \
657   void Ani_##name(ani_env *env, ani_class clazz, \
658   InteropTypeConverter<P0>::InteropType _p0) { \
659     KOALA_MAYBE_LOG(name)              \
660     P0 p0 = getArgument<P0>(env, _p0); \
661     impl_##name(p0); \
662     releaseArgument(env, _p0, p0); \
663   } \
664 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0, 0)
665 
666 #define KOALA_INTEROP_V2(name, P0, P1) \
667   void Ani_##name(ani_env *env, ani_class clazz, \
668     InteropTypeConverter<P0>::InteropType _p0, \
669     InteropTypeConverter<P1>::InteropType _p1) { \
670       KOALA_MAYBE_LOG(name) \
671       P0 p0 = getArgument<P0>(env, _p0); \
672       P1 p1 = getArgument<P1>(env, _p1); \
673       impl_##name(p0, p1); \
674       releaseArgument(env, _p0, p0); \
675       releaseArgument(env, _p1, p1); \
676    } \
677 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1, 0)
678 
679 #define KOALA_INTEROP_V3(name, P0, P1, P2) \
680   void Ani_##name(ani_env *env, ani_class clazz, \
681     InteropTypeConverter<P0>::InteropType _p0, \
682     InteropTypeConverter<P1>::InteropType _p1, \
683     InteropTypeConverter<P2>::InteropType _p2) { \
684       KOALA_MAYBE_LOG(name) \
685       P0 p0 = getArgument<P0>(env, _p0); \
686       P1 p1 = getArgument<P1>(env, _p1); \
687       P2 p2 = getArgument<P2>(env, _p2); \
688       impl_##name(p0, p1, p2); \
689       releaseArgument(env, _p0, p0); \
690       releaseArgument(env, _p1, p1); \
691       releaseArgument(env, _p2, p2); \
692   } \
693 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2, 0)
694 
695 #define KOALA_INTEROP_V4(name, P0, P1, P2, P3) \
696   void Ani_##name(ani_env *env, ani_class clazz, \
697     InteropTypeConverter<P0>::InteropType _p0, \
698     InteropTypeConverter<P1>::InteropType _p1, \
699     InteropTypeConverter<P2>::InteropType _p2, \
700     InteropTypeConverter<P3>::InteropType _p3) { \
701       KOALA_MAYBE_LOG(name) \
702       P0 p0 = getArgument<P0>(env, _p0); \
703       P1 p1 = getArgument<P1>(env, _p1); \
704       P2 p2 = getArgument<P2>(env, _p2); \
705       P3 p3 = getArgument<P3>(env, _p3); \
706       impl_##name(p0, p1, p2, p3); \
707       releaseArgument(env, _p0, p0); \
708       releaseArgument(env, _p1, p1); \
709       releaseArgument(env, _p2, p2); \
710       releaseArgument(env, _p3, p3); \
711 } \
712 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3, 0)
713 
714 #define KOALA_INTEROP_V5(name, P0, P1, P2, P3, P4) \
715   void Ani_##name(ani_env *env, ani_class clazz, \
716     InteropTypeConverter<P0>::InteropType _p0, \
717     InteropTypeConverter<P1>::InteropType _p1, \
718     InteropTypeConverter<P2>::InteropType _p2, \
719     InteropTypeConverter<P3>::InteropType _p3, \
720     InteropTypeConverter<P4>::InteropType _p4) { \
721       KOALA_MAYBE_LOG(name) \
722       P0 p0 = getArgument<P0>(env, _p0); \
723       P1 p1 = getArgument<P1>(env, _p1); \
724       P2 p2 = getArgument<P2>(env, _p2); \
725       P3 p3 = getArgument<P3>(env, _p3); \
726       P4 p4 = getArgument<P4>(env, _p4); \
727       impl_##name(p0, p1, p2, p3, p4); \
728       releaseArgument(env, _p0, p0); \
729       releaseArgument(env, _p1, p1); \
730       releaseArgument(env, _p2, p2); \
731       releaseArgument(env, _p3, p3); \
732       releaseArgument(env, _p4, p4); \
733 } \
734 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4, 0)
735 
736 #define KOALA_INTEROP_V6(name, P0, P1, P2, P3, P4, P5) \
737   void Ani_##name(ani_env *env, ani_class clazz, \
738     InteropTypeConverter<P0>::InteropType _p0, \
739     InteropTypeConverter<P1>::InteropType _p1, \
740     InteropTypeConverter<P2>::InteropType _p2, \
741     InteropTypeConverter<P3>::InteropType _p3, \
742     InteropTypeConverter<P4>::InteropType _p4, \
743     InteropTypeConverter<P5>::InteropType _p5) { \
744       KOALA_MAYBE_LOG(name) \
745       P0 p0 = getArgument<P0>(env, _p0); \
746       P1 p1 = getArgument<P1>(env, _p1); \
747       P2 p2 = getArgument<P2>(env, _p2); \
748       P3 p3 = getArgument<P3>(env, _p3); \
749       P4 p4 = getArgument<P4>(env, _p4); \
750       P5 p5 = getArgument<P5>(env, _p5); \
751       impl_##name(p0, p1, p2, p3, p4, p5); \
752       releaseArgument(env, _p0, p0); \
753       releaseArgument(env, _p1, p1); \
754       releaseArgument(env, _p2, p2); \
755       releaseArgument(env, _p3, p3); \
756       releaseArgument(env, _p4, p4); \
757       releaseArgument(env, _p5, p5); \
758   } \
759 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5, 0)
760 
761 #define KOALA_INTEROP_V7(name, P0, P1, P2, P3, P4, P5, P6) \
762   void Ani_##name(ani_env *env, ani_class clazz, \
763     InteropTypeConverter<P0>::InteropType _p0, \
764     InteropTypeConverter<P1>::InteropType _p1, \
765     InteropTypeConverter<P2>::InteropType _p2, \
766     InteropTypeConverter<P3>::InteropType _p3, \
767     InteropTypeConverter<P4>::InteropType _p4, \
768     InteropTypeConverter<P5>::InteropType _p5, \
769     InteropTypeConverter<P6>::InteropType _p6) { \
770       KOALA_MAYBE_LOG(name) \
771       P0 p0 = getArgument<P0>(env, _p0); \
772       P1 p1 = getArgument<P1>(env, _p1); \
773       P2 p2 = getArgument<P2>(env, _p2); \
774       P3 p3 = getArgument<P3>(env, _p3); \
775       P4 p4 = getArgument<P4>(env, _p4); \
776       P5 p5 = getArgument<P5>(env, _p5); \
777       P6 p6 = getArgument<P6>(env, _p6); \
778       impl_##name(p0, p1, p2, p3, p4, p5, p6); \
779       releaseArgument(env, _p0, p0); \
780       releaseArgument(env, _p1, p1); \
781       releaseArgument(env, _p2, p2); \
782       releaseArgument(env, _p3, p3); \
783       releaseArgument(env, _p4, p4); \
784       releaseArgument(env, _p5, p5); \
785       releaseArgument(env, _p6, p6); \
786   } \
787 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6, 0)
788 
789 #define KOALA_INTEROP_V8(name, P0, P1, P2, P3, P4, P5, P6, P7) \
790   void Ani_##name(ani_env *env, ani_class clazz, \
791     InteropTypeConverter<P0>::InteropType _p0, \
792     InteropTypeConverter<P1>::InteropType _p1, \
793     InteropTypeConverter<P2>::InteropType _p2, \
794     InteropTypeConverter<P3>::InteropType _p3, \
795     InteropTypeConverter<P4>::InteropType _p4, \
796     InteropTypeConverter<P5>::InteropType _p5, \
797     InteropTypeConverter<P6>::InteropType _p6, \
798     InteropTypeConverter<P7>::InteropType _p7) { \
799       KOALA_MAYBE_LOG(name) \
800       P0 p0 = getArgument<P0>(env, _p0); \
801       P1 p1 = getArgument<P1>(env, _p1); \
802       P2 p2 = getArgument<P2>(env, _p2); \
803       P3 p3 = getArgument<P3>(env, _p3); \
804       P4 p4 = getArgument<P4>(env, _p4); \
805       P5 p5 = getArgument<P5>(env, _p5); \
806       P6 p6 = getArgument<P6>(env, _p6); \
807       P7 p7 = getArgument<P7>(env, _p7); \
808       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7); \
809       releaseArgument(env, _p0, p0); \
810       releaseArgument(env, _p1, p1); \
811       releaseArgument(env, _p2, p2); \
812       releaseArgument(env, _p3, p3); \
813       releaseArgument(env, _p4, p4); \
814       releaseArgument(env, _p5, p5); \
815       releaseArgument(env, _p6, p6); \
816       releaseArgument(env, _p7, p7); \
817   } \
818 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7, 0)
819 
820 #define KOALA_INTEROP_V9(name, P0, P1, P2, P3, P4, P5, P6, P7, P8) \
821   void Ani_##name(ani_env *env, ani_class clazz, \
822     InteropTypeConverter<P0>::InteropType _p0, \
823     InteropTypeConverter<P1>::InteropType _p1, \
824     InteropTypeConverter<P2>::InteropType _p2, \
825     InteropTypeConverter<P3>::InteropType _p3, \
826     InteropTypeConverter<P4>::InteropType _p4, \
827     InteropTypeConverter<P5>::InteropType _p5, \
828     InteropTypeConverter<P6>::InteropType _p6, \
829     InteropTypeConverter<P7>::InteropType _p7, \
830     InteropTypeConverter<P8>::InteropType _p8) { \
831       KOALA_MAYBE_LOG(name) \
832       P0 p0 = getArgument<P0>(env, _p0); \
833       P1 p1 = getArgument<P1>(env, _p1); \
834       P2 p2 = getArgument<P2>(env, _p2); \
835       P3 p3 = getArgument<P3>(env, _p3); \
836       P4 p4 = getArgument<P4>(env, _p4); \
837       P5 p5 = getArgument<P5>(env, _p5); \
838       P6 p6 = getArgument<P6>(env, _p6); \
839       P7 p7 = getArgument<P7>(env, _p7); \
840       P8 p8 = getArgument<P8>(env, _p8); \
841       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8); \
842       releaseArgument(env, _p0, p0); \
843       releaseArgument(env, _p1, p1); \
844       releaseArgument(env, _p2, p2); \
845       releaseArgument(env, _p3, p3); \
846       releaseArgument(env, _p4, p4); \
847       releaseArgument(env, _p5, p5); \
848       releaseArgument(env, _p6, p6); \
849       releaseArgument(env, _p7, p7); \
850       releaseArgument(env, _p8, p8); \
851   } \
852 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8, 0)
853 
854 #define KOALA_INTEROP_V10(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9) \
855   void Ani_##name(ani_env *env, ani_class clazz, \
856     InteropTypeConverter<P0>::InteropType _p0, \
857     InteropTypeConverter<P1>::InteropType _p1, \
858     InteropTypeConverter<P2>::InteropType _p2, \
859     InteropTypeConverter<P3>::InteropType _p3, \
860     InteropTypeConverter<P4>::InteropType _p4, \
861     InteropTypeConverter<P5>::InteropType _p5, \
862     InteropTypeConverter<P6>::InteropType _p6, \
863     InteropTypeConverter<P7>::InteropType _p7, \
864     InteropTypeConverter<P8>::InteropType _p8, \
865     InteropTypeConverter<P9>::InteropType _p9) { \
866       KOALA_MAYBE_LOG(name) \
867       P0 p0 = getArgument<P0>(env, _p0); \
868       P1 p1 = getArgument<P1>(env, _p1); \
869       P2 p2 = getArgument<P2>(env, _p2); \
870       P3 p3 = getArgument<P3>(env, _p3); \
871       P4 p4 = getArgument<P4>(env, _p4); \
872       P5 p5 = getArgument<P5>(env, _p5); \
873       P6 p6 = getArgument<P6>(env, _p6); \
874       P7 p7 = getArgument<P7>(env, _p7); \
875       P8 p8 = getArgument<P8>(env, _p8); \
876       P9 p9 = getArgument<P9>(env, _p9); \
877       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
878       releaseArgument(env, _p0, p0); \
879       releaseArgument(env, _p1, p1); \
880       releaseArgument(env, _p2, p2); \
881       releaseArgument(env, _p3, p3); \
882       releaseArgument(env, _p4, p4); \
883       releaseArgument(env, _p5, p5); \
884       releaseArgument(env, _p6, p6); \
885       releaseArgument(env, _p7, p7); \
886       releaseArgument(env, _p8, p8); \
887       releaseArgument(env, _p9, p9); \
888 } \
889 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9, 0)
890 
891 #define KOALA_INTEROP_V11(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
892   void Ani_##name(ani_env *env, ani_class clazz, \
893     InteropTypeConverter<P0>::InteropType _p0, \
894     InteropTypeConverter<P1>::InteropType _p1, \
895     InteropTypeConverter<P2>::InteropType _p2, \
896     InteropTypeConverter<P3>::InteropType _p3, \
897     InteropTypeConverter<P4>::InteropType _p4, \
898     InteropTypeConverter<P5>::InteropType _p5, \
899     InteropTypeConverter<P6>::InteropType _p6, \
900     InteropTypeConverter<P7>::InteropType _p7, \
901     InteropTypeConverter<P8>::InteropType _p8, \
902     InteropTypeConverter<P9>::InteropType _p9, \
903     InteropTypeConverter<P10>::InteropType _p10) { \
904       KOALA_MAYBE_LOG(name) \
905       P0 p0 = getArgument<P0>(env, _p0); \
906       P1 p1 = getArgument<P1>(env, _p1); \
907       P2 p2 = getArgument<P2>(env, _p2); \
908       P3 p3 = getArgument<P3>(env, _p3); \
909       P4 p4 = getArgument<P4>(env, _p4); \
910       P5 p5 = getArgument<P5>(env, _p5); \
911       P6 p6 = getArgument<P6>(env, _p6); \
912       P7 p7 = getArgument<P7>(env, _p7); \
913       P8 p8 = getArgument<P8>(env, _p8); \
914       P9 p9 = getArgument<P9>(env, _p9); \
915       P10 p10 = getArgument<P10>(env, _p10); \
916       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
917       releaseArgument(env, _p0, p0); \
918       releaseArgument(env, _p1, p1); \
919       releaseArgument(env, _p2, p2); \
920       releaseArgument(env, _p3, p3); \
921       releaseArgument(env, _p4, p4); \
922       releaseArgument(env, _p5, p5); \
923       releaseArgument(env, _p6, p6); \
924       releaseArgument(env, _p7, p7); \
925       releaseArgument(env, _p8, p8); \
926       releaseArgument(env, _p9, p9); \
927       releaseArgument(env, _p10, p10); \
928   } \
929 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10, 0)
930 
931 #define KOALA_INTEROP_V12(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11) \
932   void Ani_##name(ani_env *env, ani_class clazz, \
933     InteropTypeConverter<P0>::InteropType _p0, \
934     InteropTypeConverter<P1>::InteropType _p1, \
935     InteropTypeConverter<P2>::InteropType _p2, \
936     InteropTypeConverter<P3>::InteropType _p3, \
937     InteropTypeConverter<P4>::InteropType _p4, \
938     InteropTypeConverter<P5>::InteropType _p5, \
939     InteropTypeConverter<P6>::InteropType _p6, \
940     InteropTypeConverter<P7>::InteropType _p7, \
941     InteropTypeConverter<P8>::InteropType _p8, \
942     InteropTypeConverter<P9>::InteropType _p9, \
943     InteropTypeConverter<P10>::InteropType _p10, \
944     InteropTypeConverter<P11>::InteropType _p11) { \
945       KOALA_MAYBE_LOG(name) \
946       P0 p0 = getArgument<P0>(env, _p0); \
947       P1 p1 = getArgument<P1>(env, _p1); \
948       P2 p2 = getArgument<P2>(env, _p2); \
949       P3 p3 = getArgument<P3>(env, _p3); \
950       P4 p4 = getArgument<P4>(env, _p4); \
951       P5 p5 = getArgument<P5>(env, _p5); \
952       P6 p6 = getArgument<P6>(env, _p6); \
953       P7 p7 = getArgument<P7>(env, _p7); \
954       P8 p8 = getArgument<P8>(env, _p8); \
955       P9 p9 = getArgument<P9>(env, _p9); \
956       P10 p10 = getArgument<P10>(env, _p10); \
957       P11 p11 = getArgument<P11>(env, _p11); \
958       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
959       releaseArgument(env, _p0, p0); \
960       releaseArgument(env, _p1, p1); \
961       releaseArgument(env, _p2, p2); \
962       releaseArgument(env, _p3, p3); \
963       releaseArgument(env, _p4, p4); \
964       releaseArgument(env, _p5, p5); \
965       releaseArgument(env, _p6, p6); \
966       releaseArgument(env, _p7, p7); \
967       releaseArgument(env, _p8, p8); \
968       releaseArgument(env, _p9, p9); \
969       releaseArgument(env, _p10, p10); \
970       releaseArgument(env, _p11, p11); \
971 } \
972 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11, 0)
973 
974 #define KOALA_INTEROP_V13(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12) \
975   void Ani_##name(ani_env *env, ani_class clazz, \
976     InteropTypeConverter<P0>::InteropType _p0, \
977     InteropTypeConverter<P1>::InteropType _p1, \
978     InteropTypeConverter<P2>::InteropType _p2, \
979     InteropTypeConverter<P3>::InteropType _p3, \
980     InteropTypeConverter<P4>::InteropType _p4, \
981     InteropTypeConverter<P5>::InteropType _p5, \
982     InteropTypeConverter<P6>::InteropType _p6, \
983     InteropTypeConverter<P7>::InteropType _p7, \
984     InteropTypeConverter<P8>::InteropType _p8, \
985     InteropTypeConverter<P9>::InteropType _p9, \
986     InteropTypeConverter<P10>::InteropType _p10, \
987     InteropTypeConverter<P11>::InteropType _p11, \
988     InteropTypeConverter<P12>::InteropType _p12) { \
989       KOALA_MAYBE_LOG(name) \
990       P0 p0 = getArgument<P0>(env, _p0); \
991       P1 p1 = getArgument<P1>(env, _p1); \
992       P2 p2 = getArgument<P2>(env, _p2); \
993       P3 p3 = getArgument<P3>(env, _p3); \
994       P4 p4 = getArgument<P4>(env, _p4); \
995       P5 p5 = getArgument<P5>(env, _p5); \
996       P6 p6 = getArgument<P6>(env, _p6); \
997       P7 p7 = getArgument<P7>(env, _p7); \
998       P8 p8 = getArgument<P8>(env, _p8); \
999       P9 p9 = getArgument<P9>(env, _p9); \
1000       P10 p10 = getArgument<P10>(env, _p10); \
1001       P11 p11 = getArgument<P11>(env, _p11); \
1002       P12 p12 = getArgument<P12>(env, _p12); \
1003       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \
1004       releaseArgument(env, _p0, p0); \
1005       releaseArgument(env, _p1, p1); \
1006       releaseArgument(env, _p2, p2); \
1007       releaseArgument(env, _p3, p3); \
1008       releaseArgument(env, _p4, p4); \
1009       releaseArgument(env, _p5, p5); \
1010       releaseArgument(env, _p6, p6); \
1011       releaseArgument(env, _p7, p7); \
1012       releaseArgument(env, _p8, p8); \
1013       releaseArgument(env, _p9, p9); \
1014       releaseArgument(env, _p10, p10); \
1015       releaseArgument(env, _p11, p11); \
1016       releaseArgument(env, _p12, p12); \
1017 } \
1018 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12, 0)
1019 
1020 #define KOALA_INTEROP_V14(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13) \
1021   void Ani_##name(ani_env *env, ani_class clazz, \
1022   InteropTypeConverter<P0>::InteropType _p0, \
1023   InteropTypeConverter<P1>::InteropType _p1, \
1024   InteropTypeConverter<P2>::InteropType _p2, \
1025   InteropTypeConverter<P3>::InteropType _p3, \
1026   InteropTypeConverter<P4>::InteropType _p4, \
1027   InteropTypeConverter<P5>::InteropType _p5, \
1028   InteropTypeConverter<P6>::InteropType _p6, \
1029   InteropTypeConverter<P7>::InteropType _p7, \
1030   InteropTypeConverter<P8>::InteropType _p8, \
1031   InteropTypeConverter<P9>::InteropType _p9, \
1032   InteropTypeConverter<P10>::InteropType _p10, \
1033   InteropTypeConverter<P11>::InteropType _p11, \
1034   InteropTypeConverter<P12>::InteropType _p12, \
1035   InteropTypeConverter<P13>::InteropType _p13) { \
1036       KOALA_MAYBE_LOG(name) \
1037       P0 p0 = getArgument<P0>(env, _p0); \
1038       P1 p1 = getArgument<P1>(env, _p1); \
1039       P2 p2 = getArgument<P2>(env, _p2); \
1040       P3 p3 = getArgument<P3>(env, _p3); \
1041       P4 p4 = getArgument<P4>(env, _p4); \
1042       P5 p5 = getArgument<P5>(env, _p5); \
1043       P6 p6 = getArgument<P6>(env, _p6); \
1044       P7 p7 = getArgument<P7>(env, _p7); \
1045       P8 p8 = getArgument<P8>(env, _p8); \
1046       P9 p9 = getArgument<P9>(env, _p9); \
1047       P10 p10 = getArgument<P10>(env, _p10); \
1048       P11 p11 = getArgument<P11>(env, _p11); \
1049       P12 p12 = getArgument<P12>(env, _p12); \
1050       P13 p13 = getArgument<P13>(env, _p13); \
1051       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \
1052       releaseArgument(env, _p0, p0); \
1053       releaseArgument(env, _p1, p1); \
1054       releaseArgument(env, _p2, p2); \
1055       releaseArgument(env, _p3, p3); \
1056       releaseArgument(env, _p4, p4); \
1057       releaseArgument(env, _p5, p5); \
1058       releaseArgument(env, _p6, p6); \
1059       releaseArgument(env, _p7, p7); \
1060       releaseArgument(env, _p8, p8); \
1061       releaseArgument(env, _p9, p9); \
1062       releaseArgument(env, _p10, p10); \
1063       releaseArgument(env, _p11, p11); \
1064       releaseArgument(env, _p12, p12); \
1065       releaseArgument(env, _p13, p13); \
1066 } \
1067 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12 "|" #P13, 0)
1068 
1069 #define KOALA_INTEROP_V15(name, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14) \
1070   void Ani_##name(ani_env *env, ani_class clazz, \
1071   InteropTypeConverter<P0>::InteropType _p0, \
1072   InteropTypeConverter<P1>::InteropType _p1, \
1073   InteropTypeConverter<P2>::InteropType _p2, \
1074   InteropTypeConverter<P3>::InteropType _p3, \
1075   InteropTypeConverter<P4>::InteropType _p4, \
1076   InteropTypeConverter<P5>::InteropType _p5, \
1077   InteropTypeConverter<P6>::InteropType _p6, \
1078   InteropTypeConverter<P7>::InteropType _p7, \
1079   InteropTypeConverter<P8>::InteropType _p8, \
1080   InteropTypeConverter<P9>::InteropType _p9, \
1081   InteropTypeConverter<P10>::InteropType _p10, \
1082   InteropTypeConverter<P11>::InteropType _p11, \
1083   InteropTypeConverter<P12>::InteropType _p12, \
1084   InteropTypeConverter<P13>::InteropType _p13, \
1085   InteropTypeConverter<P14>::InteropType _p14) { \
1086       KOALA_MAYBE_LOG(name) \
1087       P0 p0 = getArgument<P0>(env, _p0); \
1088       P1 p1 = getArgument<P1>(env, _p1); \
1089       P2 p2 = getArgument<P2>(env, _p2); \
1090       P3 p3 = getArgument<P3>(env, _p3); \
1091       P4 p4 = getArgument<P4>(env, _p4); \
1092       P5 p5 = getArgument<P5>(env, _p5); \
1093       P6 p6 = getArgument<P6>(env, _p6); \
1094       P7 p7 = getArgument<P7>(env, _p7); \
1095       P8 p8 = getArgument<P8>(env, _p8); \
1096       P9 p9 = getArgument<P9>(env, _p9); \
1097       P10 p10 = getArgument<P10>(env, _p10); \
1098       P11 p11 = getArgument<P11>(env, _p11); \
1099       P12 p12 = getArgument<P12>(env, _p12); \
1100       P13 p13 = getArgument<P13>(env, _p13); \
1101       P14 p14 = getArgument<P14>(env, _p14); \
1102       impl_##name(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \
1103       releaseArgument(env, _p0, p0); \
1104       releaseArgument(env, _p1, p1); \
1105       releaseArgument(env, _p2, p2); \
1106       releaseArgument(env, _p3, p3); \
1107       releaseArgument(env, _p4, p4); \
1108       releaseArgument(env, _p5, p5); \
1109       releaseArgument(env, _p6, p6); \
1110       releaseArgument(env, _p7, p7); \
1111       releaseArgument(env, _p8, p8); \
1112       releaseArgument(env, _p9, p9); \
1113       releaseArgument(env, _p10, p10); \
1114       releaseArgument(env, _p11, p11); \
1115       releaseArgument(env, _p12, p12); \
1116       releaseArgument(env, _p13, p13); \
1117       releaseArgument(env, _p14, p14); \
1118 } \
1119 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4 "|" #P5 "|" #P6 "|" #P7 "|" #P8 "|" #P9 "|" #P10 "|" #P11 "|" #P12 "|" #P13 "|" #P14, 0)
1120 
1121 #define KOALA_INTEROP_CTX_0(name, Ret) \
1122   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz) { \
1123       KOALA_MAYBE_LOG(name)                   \
1124       KVMContext ctx = (KVMContext)env; \
1125       auto rv = makeResult<Ret>(env, impl_##name(ctx)); \
1126       return rv; \
1127   } \
1128 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret, ANI_SLOW_NATIVE_FLAG)
1129 
1130 #define KOALA_INTEROP_CTX_1(name, Ret, P0) \
1131   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
1132    InteropTypeConverter<P0>::InteropType _p0) { \
1133       KOALA_MAYBE_LOG(name)                   \
1134       P0 p0 = getArgument<P0>(env, _p0); \
1135       KVMContext ctx = (KVMContext)env; \
1136       auto rv = makeResult<Ret>(env, impl_##name(ctx, p0)); \
1137       releaseArgument(env, _p0, p0); \
1138       return rv; \
1139   } \
1140 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0, ANI_SLOW_NATIVE_FLAG)
1141 
1142 #define KOALA_INTEROP_CTX_2(name, Ret, P0, P1) \
1143   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
1144     InteropTypeConverter<P0>::InteropType _p0, \
1145     InteropTypeConverter<P1>::InteropType _p1) { \
1146       KOALA_MAYBE_LOG(name)                   \
1147       P0 p0 = getArgument<P0>(env, _p0); \
1148       P1 p1 = getArgument<P1>(env, _p1); \
1149       KVMContext ctx = (KVMContext)env; \
1150       auto rv = makeResult<Ret>(env, impl_##name(ctx, p0, p1)); \
1151       releaseArgument(env, _p0, p0); \
1152       releaseArgument(env, _p1, p1); \
1153       return rv; \
1154   } \
1155 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1, ANI_SLOW_NATIVE_FLAG)
1156 
1157 #define KOALA_INTEROP_CTX_3(name, Ret, P0, P1, P2) \
1158   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
1159     InteropTypeConverter<P0>::InteropType _p0, \
1160     InteropTypeConverter<P1>::InteropType _p1, \
1161     InteropTypeConverter<P2>::InteropType _p2) { \
1162       KOALA_MAYBE_LOG(name)                   \
1163       P0 p0 = getArgument<P0>(env, _p0); \
1164       P1 p1 = getArgument<P1>(env, _p1); \
1165       P2 p2 = getArgument<P2>(env, _p2); \
1166       KVMContext ctx = (KVMContext)env; \
1167       auto rv = makeResult<Ret>(env, impl_##name(ctx, p0, p1, p2)); \
1168       releaseArgument(env, _p0, p0); \
1169       releaseArgument(env, _p1, p1); \
1170       releaseArgument(env, _p2, p2); \
1171       return rv; \
1172   } \
1173 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2, ANI_SLOW_NATIVE_FLAG)
1174 
1175 #define KOALA_INTEROP_CTX_4(name, Ret, P0, P1, P2, P3) \
1176   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
1177     InteropTypeConverter<P0>::InteropType _p0, \
1178     InteropTypeConverter<P1>::InteropType _p1, \
1179     InteropTypeConverter<P2>::InteropType _p2, \
1180     InteropTypeConverter<P3>::InteropType _p3) { \
1181       KOALA_MAYBE_LOG(name)                   \
1182       P0 p0 = getArgument<P0>(env, _p0); \
1183       P1 p1 = getArgument<P1>(env, _p1); \
1184       P2 p2 = getArgument<P2>(env, _p2); \
1185       P3 p3 = getArgument<P3>(env, _p3); \
1186       KVMContext ctx = (KVMContext)env; \
1187       auto rv = makeResult<Ret>(env, impl_##name(ctx, p0, p1, p2, p3)); \
1188       releaseArgument(env, _p0, p0); \
1189       releaseArgument(env, _p1, p1); \
1190       releaseArgument(env, _p2, p2); \
1191       releaseArgument(env, _p3, p3); \
1192       return rv; \
1193   } \
1194 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3, ANI_SLOW_NATIVE_FLAG)
1195 
1196 #define KOALA_INTEROP_CTX_5(name, Ret, P0, P1, P2, P3, P4) \
1197   InteropTypeConverter<Ret>::InteropType Ani_##name(ani_env *env, ani_class clazz, \
1198     InteropTypeConverter<P0>::InteropType _p0, \
1199     InteropTypeConverter<P1>::InteropType _p1, \
1200     InteropTypeConverter<P2>::InteropType _p2, \
1201     InteropTypeConverter<P3>::InteropType _p3 \
1202     InteropTypeConverter<P4>::InteropType _p4) { \
1203       KOALA_MAYBE_LOG(name)                   \
1204       P0 p0 = getArgument<P0>(env, _p0); \
1205       P1 p1 = getArgument<P1>(env, _p1); \
1206       P2 p2 = getArgument<P2>(env, _p2); \
1207       P3 p3 = getArgument<P3>(env, _p3); \
1208       P4 p4 = getArgument<P4>(env, _p4); \
1209       KVMContext ctx = (KVMContext)env; \
1210       auto rv = makeResult<Ret>(env, impl_##name(ctx, p0, p1, p2, p3, p4)); \
1211       releaseArgument(env, _p0, p0); \
1212       releaseArgument(env, _p1, p1); \
1213       releaseArgument(env, _p2, p2); \
1214       releaseArgument(env, _p3, p3); \
1215       releaseArgument(env, _p4, p4); \
1216       return rv; \
1217   } \
1218 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, #Ret "|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4, ANI_SLOW_NATIVE_FLAG)
1219 
1220 #define KOALA_INTEROP_CTX_V0(name)  \
1221   void Ani_##name(ani_env *env, ani_class clazz) { \
1222       KOALA_MAYBE_LOG(name)                   \
1223       KVMContext ctx = (KVMContext)env; \
1224       impl_##name(ctx); \
1225   } \
1226 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void", ANI_SLOW_NATIVE_FLAG)
1227 
1228 #define KOALA_INTEROP_CTX_V1(name, P0)  \
1229   void Ani_##name(ani_env *env, ani_class clazz, \
1230     InteropTypeConverter<P0>::InteropType _p0) { \
1231       KOALA_MAYBE_LOG(name)                   \
1232       P0 p0 = getArgument<P0>(env, _p0); \
1233       KVMContext ctx = (KVMContext)env; \
1234       impl_##name(ctx, p0); \
1235       releaseArgument(env, _p0, p0); \
1236   } \
1237 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0, ANI_SLOW_NATIVE_FLAG)
1238 
1239 #define KOALA_INTEROP_CTX_V2(name, P0, P1)  \
1240   void Ani_##name(ani_env *env, ani_class clazz, \
1241     InteropTypeConverter<P0>::InteropType _p0, \
1242     InteropTypeConverter<P1>::InteropType _p1) { \
1243       KOALA_MAYBE_LOG(name)                   \
1244       P0 p0 = getArgument<P0>(env, _p0); \
1245       P1 p1 = getArgument<P1>(env, _p1); \
1246       KVMContext ctx = (KVMContext)env; \
1247       impl_##name(ctx, p0, p1); \
1248       releaseArgument(env, _p0, p0); \
1249       releaseArgument(env, _p1, p1); \
1250   } \
1251 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1, ANI_SLOW_NATIVE_FLAG)
1252 
1253 #define KOALA_INTEROP_CTX_V3(name, P0, P1, P2)  \
1254   void Ani_##name(ani_env *env, ani_class clazz, \
1255     InteropTypeConverter<P0>::InteropType _p0, \
1256     InteropTypeConverter<P1>::InteropType _p1, \
1257     InteropTypeConverter<P2>::InteropType _p2) { \
1258       KOALA_MAYBE_LOG(name)                   \
1259       P0 p0 = getArgument<P0>(env, _p0); \
1260       P1 p1 = getArgument<P1>(env, _p1); \
1261       P2 p2 = getArgument<P2>(env, _p2); \
1262       KVMContext ctx = (KVMContext)env; \
1263       impl_##name(ctx, p0, p1, p2); \
1264       releaseArgument(env, _p0, p0); \
1265       releaseArgument(env, _p1, p1); \
1266       releaseArgument(env, _p2, p2); \
1267   } \
1268 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2, ANI_SLOW_NATIVE_FLAG)
1269 
1270 #define KOALA_INTEROP_CTX_V4(name, P0, P1, P2, P3)  \
1271   void Ani_##name(ani_env *env, ani_class clazz, \
1272     InteropTypeConverter<P0>::InteropType _p0, \
1273     InteropTypeConverter<P1>::InteropType _p1, \
1274     InteropTypeConverter<P2>::InteropType _p2, \
1275     InteropTypeConverter<P3>::InteropType _p3) { \
1276       KOALA_MAYBE_LOG(name)                   \
1277       P0 p0 = getArgument<P0>(env, _p0); \
1278       P1 p1 = getArgument<P1>(env, _p1); \
1279       P2 p2 = getArgument<P2>(env, _p2); \
1280       P3 p3 = getArgument<P3>(env, _p3); \
1281       KVMContext ctx = (KVMContext)env; \
1282       impl_##name(ctx, p0, p1, p2, p3); \
1283       releaseArgument(env, _p0, p0); \
1284       releaseArgument(env, _p1, p1); \
1285       releaseArgument(env, _p2, p2); \
1286       releaseArgument(env, _p3, p3); \
1287   } \
1288 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3, ANI_SLOW_NATIVE_FLAG)
1289 
1290 #define KOALA_INTEROP_CTX_V5(name, P0, P1, P2, P3, P4)  \
1291   void Ani_##name(ani_env *env, ani_class clazz, \
1292     InteropTypeConverter<P0>::InteropType _p0, \
1293     InteropTypeConverter<P1>::InteropType _p1, \
1294     InteropTypeConverter<P2>::InteropType _p2, \
1295     InteropTypeConverter<P3>::InteropType _p3, \
1296     InteropTypeConverter<P4>::InteropType _p4) { \
1297       KOALA_MAYBE_LOG(name)                   \
1298       P0 p0 = getArgument<P0>(env, _p0); \
1299       P1 p1 = getArgument<P1>(env, _p1); \
1300       P2 p2 = getArgument<P2>(env, _p2); \
1301       P3 p3 = getArgument<P3>(env, _p3); \
1302       P4 p4 = getArgument<P4>(env, _p4); \
1303       KVMContext ctx = (KVMContext)env; \
1304       impl_##name(ctx, p0, p1, p2, p3, p4); \
1305       releaseArgument(env, _p0, p0); \
1306       releaseArgument(env, _p1, p1); \
1307       releaseArgument(env, _p2, p2); \
1308       releaseArgument(env, _p3, p3); \
1309       releaseArgument(env, _p4, p4); \
1310   } \
1311 MAKE_ANI_EXPORT(KOALA_INTEROP_MODULE, name, "void|" #P0 "|" #P1 "|" #P2 "|" #P3 "|" #P4, ANI_SLOW_NATIVE_FLAG)
1312 
1313 bool setKoalaEtsNapiCallbackDispatcher(
1314     ani_env* ani_env,
1315     ani_class clazz,
1316     const char* dispatcherMethodName,
1317     const char* dispactherMethodSig
1318 );
1319 void getKoalaEtsNapiCallbackDispatcher(ani_class* clazz, ani_method* method);
1320 
1321 #define KOALA_INTEROP_CALL_VOID(venv, id, length, args)
1322 #define KOALA_INTEROP_CALL_INT(venv, id, length, args) { return 0; }
1323 #define KOALA_INTEROP_CALL_VOID_INTS32(venv, id, argc, args) { return; }
1324 #define KOALA_INTEROP_CALL_INT_INTS32(venv, id, argc, args) { return 0; }
1325 #define KOALA_INTEROP_THROW(vmContext, object, ...) { return __VA_ARGS__; }
1326 #define KOALA_INTEROP_THROW_STRING(vmContext, message, ...) { return __VA_ARGS__; }
1327 
1328 #endif // KOALA_ETS_NAPI
1329