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 makeNativeMethod("installJSIForTests", 25 JSIInteropModuleRegistry::installJSIForTests), 26 makeNativeMethod("evaluateScript", JSIInteropModuleRegistry::evaluateScript), 27 makeNativeMethod("global", JSIInteropModuleRegistry::global), 28 makeNativeMethod("createObject", JSIInteropModuleRegistry::createObject), 29 makeNativeMethod("drainJSEventLoop", JSIInteropModuleRegistry::drainJSEventLoop), 30 }); 31 } 32 33 JSIInteropModuleRegistry::JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis) 34 : javaPart_(jni::make_global(jThis)) {} 35 36 void JSIInteropModuleRegistry::installJSI( 37 jlong jsRuntimePointer, 38 jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder, 39 jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder 40 ) { 41 auto runtime = reinterpret_cast<jsi::Runtime *>(jsRuntimePointer); 42 runtimeHolder = std::make_shared<JavaScriptRuntime>( 43 runtime, 44 jsInvokerHolder->cthis()->getCallInvoker(), 45 nativeInvokerHolder->cthis()->getCallInvoker() 46 ); 47 48 auto expoModules = std::make_shared<ExpoModulesHostObject>(this); 49 auto expoModulesObject = jsi::Object::createFromHostObject(*runtime, expoModules); 50 51 runtime 52 ->global() 53 .setProperty( 54 *runtime, 55 "ExpoModules", 56 std::move(expoModulesObject) 57 ); 58 } 59 60 void JSIInteropModuleRegistry::installJSIForTests() { 61 runtimeHolder = std::make_shared<JavaScriptRuntime>(); 62 jsi::Runtime &jsiRuntime = *runtimeHolder->get(); 63 64 auto expoModules = std::make_shared<ExpoModulesHostObject>(this); 65 auto expoModulesObject = jsi::Object::createFromHostObject(jsiRuntime, expoModules); 66 67 jsiRuntime 68 .global() 69 .setProperty( 70 jsiRuntime, 71 "ExpoModules", 72 std::move(expoModulesObject) 73 ); 74 } 75 76 jni::local_ref<JavaScriptModuleObject::javaobject> 77 JSIInteropModuleRegistry::callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const { 78 const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() 79 ->getMethod<jni::local_ref<JavaScriptModuleObject::javaobject>( 80 std::string)>( 81 "getJavaScriptModuleObject" 82 ); 83 84 return method(javaPart_, moduleName); 85 } 86 87 jni::local_ref<jni::JArrayClass<jni::JString>> 88 JSIInteropModuleRegistry::callGetJavaScriptModulesNames() const { 89 const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() 90 ->getMethod<jni::local_ref<jni::JArrayClass<jni::JString>>()>( 91 "getJavaScriptModulesName" 92 ); 93 return method(javaPart_); 94 } 95 96 jni::local_ref<JavaScriptModuleObject::javaobject> 97 JSIInteropModuleRegistry::getModule(const std::string &moduleName) const { 98 return callGetJavaScriptModuleObjectMethod(moduleName); 99 } 100 101 jni::local_ref<jni::JArrayClass<jni::JString>> JSIInteropModuleRegistry::getModulesName() const { 102 return callGetJavaScriptModulesNames(); 103 } 104 105 jni::local_ref<JavaScriptValue::javaobject> JSIInteropModuleRegistry::evaluateScript( 106 jni::JString script 107 ) { 108 return runtimeHolder->evaluateScript(script.toStdString()); 109 } 110 111 jni::local_ref<JavaScriptObject::javaobject> JSIInteropModuleRegistry::global() { 112 return runtimeHolder->global(); 113 } 114 115 jni::local_ref<JavaScriptObject::javaobject> JSIInteropModuleRegistry::createObject() { 116 return runtimeHolder->createObject(); 117 } 118 119 void JSIInteropModuleRegistry::drainJSEventLoop() { 120 runtimeHolder->drainJSEventLoop(); 121 } 122 } // namespace expo 123