diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp index 3d8a9f74652..deabc529969 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.cpp @@ -28,7 +28,7 @@ void JHermesInstance::registerNatives() { }); } -std::unique_ptr JHermesInstance::createJSRuntime( +std::unique_ptr JHermesInstance::createJSRuntime( std::shared_ptr msgQueueThread) noexcept { return HermesInstance::createJSRuntime( reactNativeConfig_, nullptr, msgQueueThread); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h index abc417cc065..5ee3450442d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h @@ -35,7 +35,7 @@ class JHermesInstance JHermesInstance(std::shared_ptr reactNativeConfig) : reactNativeConfig_(reactNativeConfig){}; - std::unique_ptr createJSRuntime( + std::unique_ptr createJSRuntime( std::shared_ptr msgQueueThread) noexcept; ~JHermesInstance() {} diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp index 068e02b41b8..e49a55d5024 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jsc/jni/OnLoad.cpp @@ -30,9 +30,9 @@ class JSCInstance : public jni::HybridClass { }); } - std::unique_ptr createJSRuntime( + std::unique_ptr createJSRuntime( std::shared_ptr msgQueueThread) noexcept { - return jsc::makeJSCRuntime(); + return std::make_unique(jsc::makeJSCRuntime()); } private: diff --git a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp new file mode 100644 index 00000000000..a0b11fe6686 --- /dev/null +++ b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "JSRuntimeFactory.h" + +namespace facebook::react { +jsi::Runtime& JSIRuntimeHolder::getRuntime() noexcept { + return *runtime_; +} + +JSIRuntimeHolder::JSIRuntimeHolder(std::unique_ptr runtime) + : runtime_(std::move(runtime)) { + assert(runtime_ != nullptr); +} +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h index 431a2930650..110c1f26590 100644 --- a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h +++ b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h @@ -13,15 +13,38 @@ namespace facebook::react { +/** + * An interface that represents an instance of a JS VM + */ +class JSRuntime { + public: + virtual jsi::Runtime& getRuntime() noexcept = 0; + + virtual ~JSRuntime() = default; +}; + /** * Interface for a class that creates instances of a JS VM */ class JSRuntimeFactory { public: - virtual std::unique_ptr createJSRuntime( + virtual std::unique_ptr createJSRuntime( std::shared_ptr msgQueueThread) noexcept = 0; virtual ~JSRuntimeFactory() = default; }; +/** + * Utility class for creating a JSRuntime from a uniquely owned jsi::Runtime. + */ +class JSIRuntimeHolder : public JSRuntime { + public: + jsi::Runtime& getRuntime() noexcept override; + + explicit JSIRuntimeHolder(std::unique_ptr runtime); + + private: + std::unique_ptr runtime_; +}; + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec index 54dcb839fdf..b8bd53b8aac 100644 --- a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec +++ b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec @@ -48,6 +48,7 @@ Pod::Spec.new do |s| s.dependency "React-jsitracing" s.dependency "React-utils" s.dependency "React-jsi" + s.dependency "React-RuntimeCore" if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index d671bace703..76b8029d258 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -26,7 +26,7 @@ namespace facebook::react { ReactInstance::ReactInstance( - std::unique_ptr runtime, + std::unique_ptr runtime, std::shared_ptr jsMessageQueueThread, std::shared_ptr timerManager, JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc, @@ -36,7 +36,7 @@ ReactInstance::ReactInstance( timerManager_(std::move(timerManager)), jsErrorHandler_(jsErrorHandlingFunc), hasFatalJsError_(std::make_shared(false)) { - auto runtimeExecutor = [weakRuntime = std::weak_ptr(runtime_), + auto runtimeExecutor = [weakRuntime = std::weak_ptr(runtime_), weakTimerManager = std::weak_ptr(timerManager_), weakJsMessageQueueThread = @@ -63,20 +63,20 @@ ReactInstance::ReactInstance( sharedJsMessageQueueThread->runOnQueue( [weakRuntime, weakTimerManager, callback = std::move(callback)]() { if (auto strongRuntime = weakRuntime.lock()) { + jsi::Runtime& jsiRuntime = strongRuntime->getRuntime(); SystraceSection s("ReactInstance::_runtimeExecutor[Callback]"); try { - callback(*strongRuntime); + callback(jsiRuntime); // If we have first-class support for microtasks, // they would've been called as part of the previous callback. if (!CoreFeatures::enableMicrotasks) { if (auto strongTimerManager = weakTimerManager.lock()) { - strongTimerManager->callReactNativeMicrotasks( - *strongRuntime); + strongTimerManager->callReactNativeMicrotasks(jsiRuntime); } } } catch (jsi::JSError& originalError) { - handleJSError(*strongRuntime, originalError, true); + handleJSError(jsiRuntime, originalError, true); } } }); diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h index 0d1762af01c..caad761b7f0 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h @@ -14,6 +14,7 @@ #include #include #include +#include #include namespace facebook::react { @@ -29,7 +30,7 @@ class ReactInstance final { using BindingsInstallFunc = std::function; ReactInstance( - std::unique_ptr runtime, + std::unique_ptr runtime, std::shared_ptr jsMessageQueueThread, std::shared_ptr timerManager, JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc, @@ -64,7 +65,7 @@ class ReactInstance final { void handleMemoryPressureJs(int pressureLevel); private: - std::shared_ptr runtime_; + std::shared_ptr runtime_; std::shared_ptr jsMessageQueueThread_; std::shared_ptr bufferedRuntimeExecutor_; std::shared_ptr timerManager_; diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt index 955bb14c946..e46f159bd12 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(bridgelesshermes hermes_inspector_modern jsi hermes_executor_common + bridgeless ) if(${CMAKE_BUILD_TYPE} MATCHES Debug) diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp index d682224485a..0918259c77e 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp @@ -89,7 +89,7 @@ class DecoratedRuntime : public jsi::RuntimeDecorator { #endif -std::unique_ptr HermesInstance::createJSRuntime( +std::unique_ptr HermesInstance::createJSRuntime( std::shared_ptr reactNativeConfig, std::shared_ptr<::hermes::vm::CrashManager> cm, std::shared_ptr msgQueueThread) noexcept { @@ -144,10 +144,10 @@ std::unique_ptr HermesInstance::createJSRuntime( std::unique_ptr decoratedRuntime = std::make_unique( std::move(hermesRuntime), msgQueueThread); - return decoratedRuntime; + return std::make_unique(std::move(decoratedRuntime)); #endif - return hermesRuntime; + return std::make_unique(std::move(hermesRuntime)); } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.h b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.h index 63f3f73ba42..71b08d2fd5b 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.h @@ -11,12 +11,13 @@ #include #include #include +#include namespace facebook::react { class HermesInstance { public: - static std::unique_ptr createJSRuntime( + static std::unique_ptr createJSRuntime( std::shared_ptr reactNativeConfig, std::shared_ptr<::hermes::vm::CrashManager> cm, std::shared_ptr msgQueueThread) noexcept; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h index d811aa63356..533aa82b924 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h @@ -26,7 +26,7 @@ class RCTHermesInstance : public JSRuntimeFactory { std::shared_ptr reactNativeConfig, CrashManagerProvider crashManagerProvider); - std::unique_ptr createJSRuntime( + std::unique_ptr createJSRuntime( std::shared_ptr msgQueueThread) noexcept override; ~RCTHermesInstance(){}; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.mm index 04335ccd9c2..c3e4951ded6 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.mm @@ -20,7 +20,7 @@ RCTHermesInstance::RCTHermesInstance( { } -std::unique_ptr RCTHermesInstance::createJSRuntime( +std::unique_ptr RCTHermesInstance::createJSRuntime( std::shared_ptr msgQueueThread) noexcept { return _hermesInstance->createJSRuntime( diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.h index 8ad3220f45d..bdd653287d0 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.h @@ -16,7 +16,7 @@ class RCTJscInstance : public JSRuntimeFactory { public: RCTJscInstance(); - std::unique_ptr createJSRuntime( + std::unique_ptr createJSRuntime( std::shared_ptr msgQueueThread) noexcept override; ~RCTJscInstance(){}; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.mm index 168ddc3aa12..c56c466909d 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.mm @@ -13,10 +13,9 @@ namespace react { RCTJscInstance::RCTJscInstance() {} -std::unique_ptr RCTJscInstance::createJSRuntime( - std::shared_ptr msgQueueThread) noexcept +std::unique_ptr RCTJscInstance::createJSRuntime(std::shared_ptr msgQueueThread) noexcept { - return jsc::makeJSCRuntime(); + return std::make_unique(jsc::makeJSCRuntime()); } } // namespace react diff --git a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp index 0d8ea7f3285..3f8a36b39da 100644 --- a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +++ b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp @@ -116,8 +116,9 @@ class ReactInstanceTest : public ::testing::Test { ReactInstanceTest() {} void SetUp() override { - auto runtime = hermes::makeHermesRuntime(); - runtime_ = runtime.get(); + auto runtime = + std::make_unique(hermes::makeHermesRuntime()); + runtime_ = &runtime->getRuntime(); messageQueueThread_ = std::make_shared(); auto mockRegistry = std::make_unique(); mockRegistry_ = mockRegistry.get();