164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
264f5c95fSŁukasz Kosmaty 
364f5c95fSŁukasz Kosmaty #include "JNIFunctionBody.h"
4*e0f520f5SKudo Chien #include "Exceptions.h"
5b7d1787dSŁukasz Kosmaty #include "JavaReferencesCache.h"
664f5c95fSŁukasz Kosmaty 
764f5c95fSŁukasz Kosmaty namespace jni = facebook::jni;
864f5c95fSŁukasz Kosmaty namespace react = facebook::react;
964f5c95fSŁukasz Kosmaty 
1064f5c95fSŁukasz Kosmaty namespace expo {
11*e0f520f5SKudo Chien 
125e538c67SŁukasz Kosmaty jni::local_ref<jni::JObject>
invoke(jobjectArray args)1322d99763SŁukasz Kosmaty JNIFunctionBody::invoke(jobjectArray args) {
1447a022e6SŁukasz Kosmaty   // Do NOT use getClass here!
1547a022e6SŁukasz Kosmaty   // Method obtained from `getClass` will point to the overridden version of the method.
1647a022e6SŁukasz Kosmaty   // Because of that, it can't be cached - we will try to invoke the nonexistent method
1747a022e6SŁukasz Kosmaty   // if we receive an object of a different class than the one used to obtain the method id.
1847a022e6SŁukasz Kosmaty   // The only cacheable method id can be obtain from the base class.
1947a022e6SŁukasz Kosmaty   static const auto method = jni::findClassLocal("expo/modules/kotlin/jni/JNIFunctionBody")
205e538c67SŁukasz Kosmaty     ->getMethod<jni::local_ref<jni::JObject>(jobjectArray)>(
2122d99763SŁukasz Kosmaty       "invoke",
225e538c67SŁukasz Kosmaty       "([Ljava/lang/Object;)Ljava/lang/Object;"
2364f5c95fSŁukasz Kosmaty     );
2464f5c95fSŁukasz Kosmaty 
25*e0f520f5SKudo Chien   auto result = jni::Environment::current()->CallObjectMethod(this->self(), method.getId(), args);
26*e0f520f5SKudo Chien   throwPendingJniExceptionAsCppException();
27*e0f520f5SKudo Chien   return jni::adopt_local(static_cast<jni::JniType<jni::JObject>>(result));
2864f5c95fSŁukasz Kosmaty }
2964f5c95fSŁukasz Kosmaty 
invoke(jobjectArray args,jobject promise)309ebf31e6SŁukasz Kosmaty void JNIAsyncFunctionBody::invoke(
3122d99763SŁukasz Kosmaty   jobjectArray args,
329ebf31e6SŁukasz Kosmaty   jobject promise
339ebf31e6SŁukasz Kosmaty ) {
3447a022e6SŁukasz Kosmaty   // Do NOT use getClass here!
3547a022e6SŁukasz Kosmaty   // Method obtained from `getClass` will point to the overridden version of the method.
3647a022e6SŁukasz Kosmaty   // Because of that, it can't be cached - we will try to invoke the nonexistent method
3747a022e6SŁukasz Kosmaty   // if we receive an object of a different class than the one used to obtain the method id.
3847a022e6SŁukasz Kosmaty   // The only cacheable method id can be obtain from the base class.
3947a022e6SŁukasz Kosmaty   static const auto method = jni::findClassLocal("expo/modules/kotlin/jni/JNIAsyncFunctionBody")
4047a022e6SŁukasz Kosmaty     ->getMethod<
4122d99763SŁukasz Kosmaty       void(jobjectArray , jobject)
4264f5c95fSŁukasz Kosmaty     >(
4322d99763SŁukasz Kosmaty       "invoke",
445e538c67SŁukasz Kosmaty       "([Ljava/lang/Object;Lexpo/modules/kotlin/jni/PromiseImpl;)V"
4564f5c95fSŁukasz Kosmaty     );
4664f5c95fSŁukasz Kosmaty 
47*e0f520f5SKudo Chien   jni::Environment::current()->CallVoidMethod(this->self(), method.getId(), args, promise);
48*e0f520f5SKudo Chien   throwPendingJniExceptionAsCppException();
4964f5c95fSŁukasz Kosmaty }
50*e0f520f5SKudo Chien 
5164f5c95fSŁukasz Kosmaty } // namespace expo
52