164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 264f5c95fSŁukasz Kosmaty 364f5c95fSŁukasz Kosmaty #pragma once 464f5c95fSŁukasz Kosmaty 565a981ddSŁukasz Kosmaty #include "types/CppType.h" 665a981ddSŁukasz Kosmaty #include "types/ExpectedType.h" 765a981ddSŁukasz Kosmaty #include "types/AnyType.h" 86f5b8a20SŁukasz Kosmaty 964f5c95fSŁukasz Kosmaty #include <jsi/jsi.h> 1064f5c95fSŁukasz Kosmaty #include <fbjni/fbjni.h> 1164f5c95fSŁukasz Kosmaty #include <ReactCommon/TurboModuleUtils.h> 1264f5c95fSŁukasz Kosmaty #include <react/jni/ReadableNativeArray.h> 1364f5c95fSŁukasz Kosmaty #include <memory> 1465a981ddSŁukasz Kosmaty #include <vector> 1564f5c95fSŁukasz Kosmaty #include <folly/dynamic.h> 1664f5c95fSŁukasz Kosmaty #include <jsi/JSIDynamic.h> 1764f5c95fSŁukasz Kosmaty 1864f5c95fSŁukasz Kosmaty namespace jni = facebook::jni; 1964f5c95fSŁukasz Kosmaty namespace jsi = facebook::jsi; 2064f5c95fSŁukasz Kosmaty namespace react = facebook::react; 2164f5c95fSŁukasz Kosmaty 2264f5c95fSŁukasz Kosmaty namespace expo { 2364f5c95fSŁukasz Kosmaty class JSIInteropModuleRegistry; 2464f5c95fSŁukasz Kosmaty 2564f5c95fSŁukasz Kosmaty /** 2664f5c95fSŁukasz Kosmaty * A class that holds information about the exported function. 2764f5c95fSŁukasz Kosmaty */ 2864f5c95fSŁukasz Kosmaty class MethodMetadata { 2964f5c95fSŁukasz Kosmaty public: 3064f5c95fSŁukasz Kosmaty /** 3164f5c95fSŁukasz Kosmaty * Function name 3264f5c95fSŁukasz Kosmaty */ 3364f5c95fSŁukasz Kosmaty std::string name; 3464f5c95fSŁukasz Kosmaty /** 35cf4fff55SŁukasz Kosmaty * Whether this function takes owner 36cf4fff55SŁukasz Kosmaty */ 37cf4fff55SŁukasz Kosmaty bool takesOwner; 38cf4fff55SŁukasz Kosmaty /** 3964f5c95fSŁukasz Kosmaty * Number of arguments 4064f5c95fSŁukasz Kosmaty */ 4164f5c95fSŁukasz Kosmaty int args; 42cf4fff55SŁukasz Kosmaty /** 4364f5c95fSŁukasz Kosmaty * Whether this function is async 4464f5c95fSŁukasz Kosmaty */ 4564f5c95fSŁukasz Kosmaty bool isAsync; 4665a981ddSŁukasz Kosmaty /** 4765a981ddSŁukasz Kosmaty * Representation of expected argument types. 4865a981ddSŁukasz Kosmaty */ 4965a981ddSŁukasz Kosmaty std::vector<std::unique_ptr<AnyType>> argTypes; 509ebf31e6SŁukasz Kosmaty 5164f5c95fSŁukasz Kosmaty MethodMetadata( 5264f5c95fSŁukasz Kosmaty std::string name, 53cf4fff55SŁukasz Kosmaty bool takesOwner, 5464f5c95fSŁukasz Kosmaty int args, 5564f5c95fSŁukasz Kosmaty bool isAsync, 5665a981ddSŁukasz Kosmaty jni::local_ref<jni::JArrayClass<ExpectedType>> expectedArgTypes, 5765a981ddSŁukasz Kosmaty jni::global_ref<jobject> &&jBodyReference 5865a981ddSŁukasz Kosmaty ); 5965a981ddSŁukasz Kosmaty 6065a981ddSŁukasz Kosmaty MethodMetadata( 6165a981ddSŁukasz Kosmaty std::string name, 62cf4fff55SŁukasz Kosmaty bool takesOwner, 6365a981ddSŁukasz Kosmaty int args, 6465a981ddSŁukasz Kosmaty bool isAsync, 6565a981ddSŁukasz Kosmaty std::vector<std::unique_ptr<AnyType>> &&expectedArgTypes, 6664f5c95fSŁukasz Kosmaty jni::global_ref<jobject> &&jBodyReference 6764f5c95fSŁukasz Kosmaty ); 6864f5c95fSŁukasz Kosmaty 6964f5c95fSŁukasz Kosmaty // We deleted the copy contractor to not deal with transforming the ownership of the `jBodyReference`. 7064f5c95fSŁukasz Kosmaty MethodMetadata(const MethodMetadata &) = delete; 7164f5c95fSŁukasz Kosmaty 7247a022e6SŁukasz Kosmaty MethodMetadata(MethodMetadata &&other) = default; 7347a022e6SŁukasz Kosmaty 7464f5c95fSŁukasz Kosmaty /** 7564f5c95fSŁukasz Kosmaty * Transforms metadata to a jsi::Function. 7664f5c95fSŁukasz Kosmaty * 7764f5c95fSŁukasz Kosmaty * @param runtime 7864f5c95fSŁukasz Kosmaty * @param moduleRegistry 7964f5c95fSŁukasz Kosmaty * @return shared ptr to the jsi::Function that wrapped the underlying Kotlin's function. 8064f5c95fSŁukasz Kosmaty */ 8164f5c95fSŁukasz Kosmaty std::shared_ptr<jsi::Function> toJSFunction( 8264f5c95fSŁukasz Kosmaty jsi::Runtime &runtime, 8364f5c95fSŁukasz Kosmaty JSIInteropModuleRegistry *moduleRegistry 8464f5c95fSŁukasz Kosmaty ); 8564f5c95fSŁukasz Kosmaty 8647a022e6SŁukasz Kosmaty /** 8747a022e6SŁukasz Kosmaty * Calls the underlying Kotlin function. 8847a022e6SŁukasz Kosmaty */ 8947a022e6SŁukasz Kosmaty jsi::Value callSync( 9047a022e6SŁukasz Kosmaty jsi::Runtime &rt, 9147a022e6SŁukasz Kosmaty JSIInteropModuleRegistry *moduleRegistry, 92cf4fff55SŁukasz Kosmaty const jsi::Value &thisValue, 9347a022e6SŁukasz Kosmaty const jsi::Value *args, 9447a022e6SŁukasz Kosmaty size_t count 9547a022e6SŁukasz Kosmaty ); 9647a022e6SŁukasz Kosmaty 97*ecb7f347SŁukasz Kosmaty jni::local_ref<jobject> callJNISync( 98*ecb7f347SŁukasz Kosmaty JNIEnv *env, 99*ecb7f347SŁukasz Kosmaty jsi::Runtime &rt, 100*ecb7f347SŁukasz Kosmaty JSIInteropModuleRegistry *moduleRegistry, 101*ecb7f347SŁukasz Kosmaty const jsi::Value &thisValue, 102*ecb7f347SŁukasz Kosmaty const jsi::Value *args, 103*ecb7f347SŁukasz Kosmaty size_t count 104*ecb7f347SŁukasz Kosmaty ); 105*ecb7f347SŁukasz Kosmaty 10664f5c95fSŁukasz Kosmaty private: 10764f5c95fSŁukasz Kosmaty /** 10864f5c95fSŁukasz Kosmaty * Reference to one of two java objects - `JNIFunctionBody` or `JNIAsyncFunctionBody`. 10964f5c95fSŁukasz Kosmaty * 11064f5c95fSŁukasz Kosmaty * In case when `isAsync` is `true`, this variable will point to `JNIAsyncFunctionBody`. 11164f5c95fSŁukasz Kosmaty * Otherwise to `JNIFunctionBody` 11264f5c95fSŁukasz Kosmaty */ 11364f5c95fSŁukasz Kosmaty jni::global_ref<jobject> jBodyReference; 11464f5c95fSŁukasz Kosmaty 11564f5c95fSŁukasz Kosmaty /** 11664f5c95fSŁukasz Kosmaty * To not create a jsi::Function always when we need it, we cached that value. 11764f5c95fSŁukasz Kosmaty */ 11864f5c95fSŁukasz Kosmaty std::shared_ptr<jsi::Function> body = nullptr; 11964f5c95fSŁukasz Kosmaty 1209ebf31e6SŁukasz Kosmaty jsi::Function toSyncFunction(jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry); 12164f5c95fSŁukasz Kosmaty 12264f5c95fSŁukasz Kosmaty jsi::Function toAsyncFunction(jsi::Runtime &runtime, JSIInteropModuleRegistry *moduleRegistry); 12364f5c95fSŁukasz Kosmaty 12464f5c95fSŁukasz Kosmaty jsi::Function createPromiseBody( 12564f5c95fSŁukasz Kosmaty jsi::Runtime &runtime, 12664f5c95fSŁukasz Kosmaty JSIInteropModuleRegistry *moduleRegistry, 1277ed3a4bfSŁukasz Kosmaty jobjectArray globalArgs 1289ebf31e6SŁukasz Kosmaty ); 1299ebf31e6SŁukasz Kosmaty 1307ed3a4bfSŁukasz Kosmaty jobjectArray convertJSIArgsToJNI( 1319ebf31e6SŁukasz Kosmaty JSIInteropModuleRegistry *moduleRegistry, 1329ebf31e6SŁukasz Kosmaty JNIEnv *env, 1339ebf31e6SŁukasz Kosmaty jsi::Runtime &rt, 134cf4fff55SŁukasz Kosmaty const jsi::Value &thisValue, 1359ebf31e6SŁukasz Kosmaty const jsi::Value *args, 1367ed3a4bfSŁukasz Kosmaty size_t count 13764f5c95fSŁukasz Kosmaty ); 13864f5c95fSŁukasz Kosmaty }; 13964f5c95fSŁukasz Kosmaty } // namespace expo 140