1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo)
2 
3 #include "JSIInteropModuleRegistry.h"
4 #include "ExpoModulesHostObject.h"
5 
6 #include <fbjni/detail/Meta.h>
7 #include <fbjni/fbjni.h>
8 
9 #include <memory>
10 
11 namespace jni = facebook::jni;
12 namespace jsi = facebook::jsi;
13 
14 namespace expo {
15 jni::local_ref<JSIInteropModuleRegistry::jhybriddata>
16 JSIInteropModuleRegistry::initHybrid(jni::alias_ref<jhybridobject> jThis) {
17   return makeCxxInstance(jThis);
18 }
19 
20 void JSIInteropModuleRegistry::registerNatives() {
21   registerHybrid({
22                    makeNativeMethod("initHybrid", JSIInteropModuleRegistry::initHybrid),
23                    makeNativeMethod("installJSI", JSIInteropModuleRegistry::installJSI)
24                  });
25 }
26 
27 JSIInteropModuleRegistry::JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis)
28   : javaPart_(jni::make_global(jThis)) {}
29 
30 void JSIInteropModuleRegistry::installJSI(
31   jlong jsRuntimePointer,
32   jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder,
33   jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder
34 ) {
35   auto runtime = reinterpret_cast<jsi::Runtime *>(jsRuntimePointer);
36   runtimeHolder = std::make_unique<JavaScriptRuntime>(runtime);
37   jsInvoker = jsInvokerHolder->cthis()->getCallInvoker();
38   nativeInvoker = nativeInvokerHolder->cthis()->getCallInvoker();
39 
40   auto expoModules = std::make_shared<ExpoModulesHostObject>(this);
41   auto expoModulesObject = jsi::Object::createFromHostObject(*runtime, expoModules);
42 
43   runtime
44     ->global()
45     .setProperty(
46       *runtime,
47       "ExpoModules",
48       std::move(expoModulesObject)
49     );
50 }
51 
52 jni::local_ref<JavaScriptModuleObject::javaobject>
53 JSIInteropModuleRegistry::callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const {
54   const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal()
55     ->getMethod<jni::local_ref<JavaScriptModuleObject::javaobject>(
56       std::string)>(
57       "getJavaScriptModuleObject"
58     );
59 
60   return method(javaPart_, moduleName);
61 }
62 
63 jni::local_ref<JavaScriptModuleObject::javaobject>
64 JSIInteropModuleRegistry::getModule(const std::string &moduleName) const {
65   return callGetJavaScriptModuleObjectMethod(moduleName);
66 }
67 } // namespace expo
68