// Copyright © 2021-present 650 Industries, Inc. (aka Expo) #include "JSIInteropModuleRegistry.h" #include "ExpoModulesHostObject.h" #include "JavaReferencesCache.h" #include "JSReferencesCache.h" #include #include #include namespace jni = facebook::jni; namespace jsi = facebook::jsi; namespace expo { jni::local_ref JSIInteropModuleRegistry::initHybrid(jni::alias_ref jThis) { return makeCxxInstance(jThis); } void JSIInteropModuleRegistry::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", JSIInteropModuleRegistry::initHybrid), makeNativeMethod("installJSI", JSIInteropModuleRegistry::installJSI), makeNativeMethod("installJSIForTests", JSIInteropModuleRegistry::installJSIForTests), makeNativeMethod("evaluateScript", JSIInteropModuleRegistry::evaluateScript), makeNativeMethod("global", JSIInteropModuleRegistry::global), makeNativeMethod("createObject", JSIInteropModuleRegistry::createObject), makeNativeMethod("drainJSEventLoop", JSIInteropModuleRegistry::drainJSEventLoop), }); } JSIInteropModuleRegistry::JSIInteropModuleRegistry(jni::alias_ref jThis) : javaPart_(jni::make_global(jThis)) {} void JSIInteropModuleRegistry::installJSI( jlong jsRuntimePointer, jni::alias_ref jsInvokerHolder, jni::alias_ref nativeInvokerHolder ) { auto runtime = reinterpret_cast(jsRuntimePointer); jsRegistry = std::make_unique(*runtime); runtimeHolder = std::make_shared( this, runtime, jsInvokerHolder->cthis()->getCallInvoker(), nativeInvokerHolder->cthis()->getCallInvoker() ); auto expoModules = std::make_shared(this); auto expoModulesObject = jsi::Object::createFromHostObject(*runtime, expoModules); // Define the `global.expo.modules` object. runtimeHolder ->getMainObject() ->setProperty( *runtime, "modules", expoModulesObject ); // Also define `global.ExpoModules` for backwards compatibility (used before SDK47, can be removed in SDK48). runtime ->global() .setProperty( *runtime, "ExpoModules", expoModulesObject ); } void JSIInteropModuleRegistry::installJSIForTests() { #if !UNIT_TEST throw std::logic_error("The function is only available when UNIT_TEST is defined."); #else runtimeHolder = std::make_shared(this); jsi::Runtime &jsiRuntime = runtimeHolder->get(); jsRegistry = std::make_unique(jsiRuntime); auto expoModules = std::make_shared(this); auto expoModulesObject = jsi::Object::createFromHostObject(jsiRuntime, expoModules); runtimeHolder ->getMainObject() ->setProperty( jsiRuntime, "modules", std::move(expoModulesObject) ); #endif // !UNIT_TEST } jni::local_ref JSIInteropModuleRegistry::callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const { const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() ->getMethod( std::string)>( "getJavaScriptModuleObject" ); return method(javaPart_, moduleName); } jni::local_ref> JSIInteropModuleRegistry::callGetJavaScriptModulesNames() const { const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() ->getMethod>()>( "getJavaScriptModulesName" ); return method(javaPart_); } bool JSIInteropModuleRegistry::callHasModule(const std::string &moduleName) const { const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() ->getMethod( "hasModule" ); return (bool) method(javaPart_, moduleName); } jni::local_ref JSIInteropModuleRegistry::getModule(const std::string &moduleName) const { return callGetJavaScriptModuleObjectMethod(moduleName); } bool JSIInteropModuleRegistry::hasModule(const std::string &moduleName) const { return callHasModule(moduleName); } jni::local_ref> JSIInteropModuleRegistry::getModulesName() const { return callGetJavaScriptModulesNames(); } jni::local_ref JSIInteropModuleRegistry::evaluateScript( jni::JString script ) { return runtimeHolder->evaluateScript(script.toStdString()); } jni::local_ref JSIInteropModuleRegistry::global() { return runtimeHolder->global(); } jni::local_ref JSIInteropModuleRegistry::createObject() { return runtimeHolder->createObject(); } void JSIInteropModuleRegistry::drainJSEventLoop() { runtimeHolder->drainJSEventLoop(); } void JSIInteropModuleRegistry::registerSharedObject( jni::local_ref native, jni::local_ref js ) { const static auto method = expo::JSIInteropModuleRegistry::javaClassLocal() ->getMethod, jni::local_ref)>( "registerSharedObject" ); method(javaPart_, std::move(native), std::move(js)); } } // namespace expo