From c7fa1db55c213473ac21d53525e576197bf6324e Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Mon, 11 May 2026 07:32:31 -0700 Subject: [PATCH] Remove legacy Hermes C++ code and HERMES_V1_ENABLED compile definition (#56731) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: - Remove all dead C++ code behind `!defined(HERMES_V1_ENABLED)` guards in `HermesExecutorFactory.cpp` and `HermesInstance.cpp` - Delete `Registration.h`, `Registration.cpp`, `ConnectionDemux.h`, `ConnectionDemux.cpp`, and `ConnectionDemuxTests.cpp` (entirely legacy code) - Remove `HERMES_V1_ENABLED` compile definition from `react-native-flags.cmake` - Remove `HERMES_V1_ENABLED` cache variable from Android `CMakeLists.txt` This is Phase 1 of removing legacy Hermes support. Since Hermes V1 is already the default on all platforms and the 0.86 branch has been cut, all legacy Hermes code is dead and can be safely removed. ## Changelog: [General][Breaking] - Remove Legacy Hermes from C++ code ## Test plan - [x] Android: `./gradlew :packages:rn-tester:android:app:assembleDebug` — BUILD SUCCEEDED - [x] iOS: `xcodebuild` rn-tester on iPhone 16 Pro simulator — BUILD SUCCEEDED Reviewed By: cortinico Differential Revision: D104228879 --- .../ReactAndroid/src/main/jni/CMakeLists.txt | 2 - .../cmake-utils/react-native-flags.cmake | 4 +- .../hermes/executor/HermesExecutorFactory.cpp | 85 +--------- .../chrome/ConnectionDemux.cpp | 143 ----------------- .../inspector-modern/chrome/ConnectionDemux.h | 55 ------- .../inspector-modern/chrome/Registration.cpp | 78 --------- .../inspector-modern/chrome/Registration.h | 39 ----- .../chrome/tests/ConnectionDemuxTests.cpp | 148 ------------------ .../react/runtime/hermes/HermesInstance.cpp | 89 ----------- 9 files changed, 7 insertions(+), 636 deletions(-) delete mode 100644 packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.cpp delete mode 100644 packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.h delete mode 100644 packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp delete mode 100644 packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.h delete mode 100644 packages/react-native/ReactCommon/hermes/inspector-modern/chrome/tests/ConnectionDemuxTests.cpp diff --git a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt index 01742cce7f07..13300ea8f8b7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt @@ -22,8 +22,6 @@ file(TO_CMAKE_PATH "${REACT_ANDROID_DIR}" REACT_ANDROID_DIR) file(TO_CMAKE_PATH "${REACT_BUILD_DIR}" REACT_BUILD_DIR) file(TO_CMAKE_PATH "${REACT_COMMON_DIR}" REACT_COMMON_DIR) -set(HERMES_V1_ENABLED OFF CACHE BOOL "Build with support for Hermes v1") - # If you have ccache installed, we're going to honor it. find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) diff --git a/packages/react-native/ReactCommon/cmake-utils/react-native-flags.cmake b/packages/react-native/ReactCommon/cmake-utils/react-native-flags.cmake index b8a420af216d..160e9da55d8f 100644 --- a/packages/react-native/ReactCommon/cmake-utils/react-native-flags.cmake +++ b/packages/react-native/ReactCommon/cmake-utils/react-native-flags.cmake @@ -32,7 +32,5 @@ function(target_compile_reactnative_options target_name scope) if(ANDROID) target_compile_definitions(${target_name} ${scope} RN_SERIALIZABLE_STATE) endif() - if(HERMES_V1_ENABLED) - target_compile_definitions(${target_name} ${scope} HERMES_V1_ENABLED=1) - endif() + target_compile_definitions(${target_name} ${scope} HERMES_V1_ENABLED=1) endfunction() diff --git a/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp b/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp index d83803fc4274..434224e0413b 100644 --- a/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp +++ b/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp @@ -17,11 +17,6 @@ #include -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) -#include -#include -#endif - using namespace facebook::hermes; using namespace facebook::jsi; @@ -29,43 +24,6 @@ namespace facebook::react { namespace { -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - -class HermesExecutorRuntimeAdapter - : public facebook::hermes::inspector_modern::RuntimeAdapter { - public: - HermesExecutorRuntimeAdapter( - std::shared_ptr runtime, - std::shared_ptr thread) - : runtime_(runtime), thread_(std::move(thread)) {} - - virtual ~HermesExecutorRuntimeAdapter() = default; - - HermesRuntime& getRuntime() override { - return *runtime_; - } - - void tickleJs() override { - thread_->runOnQueue( - [weakRuntime = std::weak_ptr(runtime_)]() { - auto runtime = weakRuntime.lock(); - if (!runtime) { - return; - } - jsi::Function func = - runtime->global().getPropertyAsFunction(*runtime, "__tickleJs"); - func.call(*runtime); - }); - } - - private: - std::shared_ptr runtime_; - - std::shared_ptr thread_; -}; - -#endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - struct ReentrancyCheck { // This is effectively a very subtle and complex assert, so only // include it in builds which would include asserts. @@ -133,14 +91,11 @@ struct ReentrancyCheck { #endif }; -// This adds ReentrancyCheck and debugger enable/teardown to the given -// Runtime. +// This adds ReentrancyCheck to the given Runtime. class DecoratedRuntime : public jsi::WithRuntimeDecorator { public: // The first argument may be another decorater which itself // decorates the real HermesRuntime, depending on the build config. - // The second argument is the real HermesRuntime as well to - // manage the debugger registration. DecoratedRuntime( std::unique_ptr runtime, HermesRuntime& hermesRuntime, @@ -149,42 +104,17 @@ class DecoratedRuntime : public jsi::WithRuntimeDecorator { const std::string& debuggerName) : jsi::WithRuntimeDecorator(*runtime, reentrancyCheck_), runtime_(std::move(runtime)) { -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - enableDebugger_ = enableDebugger; - if (enableDebugger_) { - std::shared_ptr rt(runtime_, &hermesRuntime); - auto adapter = - std::make_unique(rt, jsQueue); - debugToken_ = facebook::hermes::inspector_modern::chrome::enableDebugging( - std::move(adapter), debuggerName); - } -#else + (void)hermesRuntime; (void)jsQueue; -#endif // HERMES_ENABLE_DEBUGGER + (void)enableDebugger; + (void)debuggerName; } - ~DecoratedRuntime() { -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - if (enableDebugger_) { - facebook::hermes::inspector_modern::chrome::disableDebugging(debugToken_); - } -#endif // HERMES_ENABLE_DEBUGGER - } + ~DecoratedRuntime() {} private: - // runtime_ is a potentially decorated Runtime. - // hermesRuntime is a reference to a HermesRuntime managed by runtime_. - // - // HermesExecutorRuntimeAdapter requirements are kept, because the - // dtor will disable debugging on the HermesRuntime before the - // member managing it is destroyed. - std::shared_ptr runtime_; ReentrancyCheck reentrancyCheck_; -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - bool enableDebugger_; - facebook::hermes::inspector_modern::chrome::DebugSessionToken debugToken_; -#endif // HERMES_ENABLE_DEBUGGER }; } // namespace @@ -221,10 +151,7 @@ std::unique_ptr HermesExecutorFactory::createJSExecutor( // // DecoratedRuntime is held by JSIExecutor. When it gets used, it // will check that it's on the right thread, do any necessary trace - // logging, then call the real HermesRuntime. When it is destroyed, - // it will shut down the debugger before the HermesRuntime is. In - // the normal case where debugging is not compiled in, - // all that's left is the thread checking. + // logging, then call the real HermesRuntime. // Add js engine information to Error.prototype so in error reporting we // can send this information. diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.cpp b/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.cpp deleted file mode 100644 index ad07660ae18c..000000000000 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 "ConnectionDemux.h" - -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - -#include -#include - -#include - -#include - -namespace facebook::hermes::inspector_modern::chrome { - -using ::facebook::react::jsinspector_modern::ILocalConnection; -using ::facebook::react::jsinspector_modern::IRemoteConnection; - -namespace { - -class LocalConnection : public ILocalConnection { - public: - LocalConnection( - std::shared_ptr conn, - std::shared_ptr> inspectedContexts); - ~LocalConnection() override; - - void sendMessage(std::string message) override; - void disconnect() override; - - private: - std::shared_ptr conn_; - std::shared_ptr> inspectedContexts_; -}; - -LocalConnection::LocalConnection( - std::shared_ptr conn, - std::shared_ptr> inspectedContexts) - : conn_(conn), inspectedContexts_(std::move(inspectedContexts)) { - inspectedContexts_->insert(conn->getTitle()); -} - -LocalConnection::~LocalConnection() = default; - -void LocalConnection::sendMessage(std::string message) { - conn_->handle(std::move(message)); -} - -void LocalConnection::disconnect() { - inspectedContexts_->erase(conn_->getTitle()); - conn_->unregisterCallbacks(); -} - -} // namespace - -ConnectionDemux::ConnectionDemux( - facebook::react::jsinspector_modern::IInspector& inspector) - : globalInspector_(inspector), - inspectedContexts_(std::make_shared>()) {} - -ConnectionDemux::~ConnectionDemux() = default; - -DebugSessionToken ConnectionDemux::enableDebugging( - std::unique_ptr adapter, - const std::string& title) { - std::scoped_lock lock(mutex_); - - // TODO(#22976087): workaround for ComponentScript contexts never being - // destroyed. - // - // After a reload, the old ComponentScript VM instance stays alive. When we - // register the new CS VM instance, check for any previous CS VM (via strcmp - // of title) and remove them. - std::vector pagesToDelete; - for (auto& conn : conns_) { - if (conn.second->getTitle() == title) { - pagesToDelete.push_back(conn.first); - } - } - - for (auto pageId : pagesToDelete) { - removePage(pageId); - } - - auto waitForDebugger = - (inspectedContexts_->find(title) != inspectedContexts_->end()); - return addPage( - hermes::inspector_modern::chrome::CDPHandler::create( - std::move(adapter), title, waitForDebugger)); -} - -void ConnectionDemux::disableDebugging(DebugSessionToken session) { - std::scoped_lock lock(mutex_); - if (conns_.find(session) == conns_.end()) { - return; - } - removePage(session); -} - -int ConnectionDemux::addPage( - std::shared_ptr conn) { - auto connectFunc = [conn, this](std::unique_ptr remoteConn) - -> std::unique_ptr { - // This cannot be unique_ptr as std::function is copyable but unique_ptr - // isn't. TODO: Change the CDPHandler API to accommodate this and not - // require a copyable callback? - std::shared_ptr sharedConn = std::move(remoteConn); - if (!conn->registerCallbacks( - [sharedConn](const std::string& message) { - sharedConn->onMessage(message); - }, - [sharedConn]() { sharedConn->onDisconnect(); })) { - return nullptr; - } - - return std::make_unique(conn, inspectedContexts_); - }; - - int pageId = globalInspector_.addPage( - conn->getTitle(), "Hermes", std::move(connectFunc)); - conns_[pageId] = std::move(conn); - - return pageId; -} - -void ConnectionDemux::removePage(int pageId) { - globalInspector_.removePage(pageId); - - auto conn = conns_.at(pageId); - std::string title = conn->getTitle(); - inspectedContexts_->erase(title); - conn->unregisterCallbacks(); - conns_.erase(pageId); -} - -} // namespace facebook::hermes::inspector_modern::chrome - -#endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.h b/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.h deleted file mode 100644 index cc8dae74f8a4..000000000000 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace facebook::hermes::inspector_modern::chrome { - -/* - * ConnectionDemux keeps track of all debuggable Hermes runtimes (called - * "pages" in the higher-level React Native API) in this process. See - * Registration.h for documentation of the public API. - */ -class ConnectionDemux { - public: - explicit ConnectionDemux(facebook::react::jsinspector_modern::IInspector &inspector); - ~ConnectionDemux(); - - ConnectionDemux(const ConnectionDemux &) = delete; - ConnectionDemux &operator=(const ConnectionDemux &) = delete; - - DebugSessionToken enableDebugging(std::unique_ptr adapter, const std::string &title); - void disableDebugging(DebugSessionToken session); - - private: - int addPage(std::shared_ptr conn); - void removePage(int pageId); - - facebook::react::jsinspector_modern::IInspector &globalInspector_; - - std::mutex mutex_; - std::unordered_map> conns_; - std::shared_ptr> inspectedContexts_; -}; - -} // namespace facebook::hermes::inspector_modern::chrome - -#endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp b/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp deleted file mode 100644 index 3274cba4f592..000000000000 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 "Registration.h" -#include "ConnectionDemux.h" - -#if defined(HERMES_ENABLE_DEBUGGER) - -#include - -#if !defined(HERMES_V1_ENABLED) - -namespace facebook::hermes::inspector_modern::chrome { -namespace { - -ConnectionDemux& demux() { - static ConnectionDemux instance{ - facebook::react::jsinspector_modern::getInspectorInstance()}; - return instance; -} - -} // namespace - -DebugSessionToken enableDebugging( - std::unique_ptr adapter, - const std::string& title) { - return demux().enableDebugging(std::move(adapter), title); -} - -void disableDebugging(DebugSessionToken session) { - demux().disableDebugging(session); -} - -} // namespace facebook::hermes::inspector_modern::chrome - -#else - -namespace facebook::hermes::inspector_modern { -class RuntimeAdapter { - // Backwards compatibility definition fallback for libraries that are compiled - // without `HERMES_V1_ENABLED` but are linked against React Native with - // `HERMES_V1_ENABLED` which doesn't provide this symbol. - public: - virtual ~RuntimeAdapter() = 0; - virtual HermesRuntime& getRuntime() = 0; - virtual void tickleJs(); -}; - -namespace chrome { - -using DebugSessionToken = int; - -DebugSessionToken enableDebugging( - std::unique_ptr, - const std::string&) { - // Backwards compatibility fallback for libraries that are compiled without - // `HERMES_V1_ENABLED` but are linked against React Native with - // `HERMES_V1_ENABLED` which doesn't provide this symbol. - return -1; -}; - -void disableDebugging(DebugSessionToken) { - // Backwards compatibility fallback for libraries that are compiled without - // `HERMES_V1_ENABLED` but are linked against React Native with - // `HERMES_V1_ENABLED` which doesn't provide this symbol. -} - -} // namespace chrome - -} // namespace facebook::hermes::inspector_modern - -#endif // !defined(HERMES_V1_ENABLED) - -#endif // defined(HERMES_ENABLE_DEBUGGER) diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.h b/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.h deleted file mode 100644 index 2b60c27a6ee6..000000000000 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#pragma once - -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - -#include -#include - -#include -#include - -namespace facebook::hermes::inspector_modern::chrome { - -using DebugSessionToken = int; - -/* - * enableDebugging adds this runtime to the list of debuggable JS targets - * (called "pages" in the higher-level React Native API) in this process. It - * should be called before any JS runs in the runtime. The returned token - * can be used to disable debugging for this runtime. - */ -extern DebugSessionToken enableDebugging(std::unique_ptr adapter, const std::string &title); - -/* - * disableDebugging removes this runtime from the list of debuggable JS targets - * in this process. The runtime to remove is identified by the token returned - * from enableDebugging. - */ -extern void disableDebugging(DebugSessionToken session); - -} // namespace facebook::hermes::inspector_modern::chrome - -#endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) diff --git a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/tests/ConnectionDemuxTests.cpp b/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/tests/ConnectionDemuxTests.cpp deleted file mode 100644 index 0e652e207b18..000000000000 --- a/packages/react-native/ReactCommon/hermes/inspector-modern/chrome/tests/ConnectionDemuxTests.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace facebook { -namespace hermes { -namespace inspector_modern { -namespace chrome { - -using ::facebook::react::jsinspector_modern::IInspector; -using ::facebook::react::jsinspector_modern::InspectorPageDescription; -using ::facebook::react::jsinspector_modern::IRemoteConnection; - -namespace { - -std::unordered_map makePageMap( - const std::vector& pages) { - std::unordered_map pageMap; - - for (auto& page : pages) { - pageMap[page.id] = page.title; - } - - return pageMap; -} - -void expectPages( - IInspector& inspector, - const std::unordered_map& expected) { - auto pages = makePageMap(inspector.getPages()); - EXPECT_EQ(pages, expected); -} - -class TestRemoteConnection : public IRemoteConnection { - public: - class Data { - public: - void expectDisconnected() { - std::unique_lock lock(mutex_); - cv_.wait_for( - lock, std::chrono::milliseconds(2500), [&] { return !connected_; }); - EXPECT_FALSE(connected_); - } - - void setDisconnected() { - std::scoped_lock lock(mutex_); - connected_ = false; - cv_.notify_one(); - } - - private: - std::mutex mutex_; - std::condition_variable cv_; - bool connected_{true}; - }; - - TestRemoteConnection() : data_(std::make_shared()) {} - ~TestRemoteConnection() {} - - void onMessage(std::string message) override {} - - void onDisconnect() override { - data_->setDisconnected(); - } - - std::shared_ptr getData() { - return data_; - } - - private: - std::shared_ptr data_; -}; - -}; // namespace - -TEST(ConnectionDemuxTests, TestEnableDisable) { - std::shared_ptr runtime1( - facebook::hermes::makeHermesRuntime()); - std::shared_ptr runtime2( - facebook::hermes::makeHermesRuntime()); - auto inspector = - facebook::react::jsinspector_modern::makeTestInspectorInstance(); - - ConnectionDemux demux{*inspector}; - - int id1 = demux.enableDebugging( - std::make_unique(runtime1), "page1"); - int id2 = demux.enableDebugging( - std::make_unique(runtime2), "page2"); - - expectPages(*inspector, {{id1, "page1"}, {id2, "page2"}}); - - auto remoteConn1 = std::make_unique(); - auto remoteData1 = remoteConn1->getData(); - auto localConn1 = inspector->connect(id1, std::move(remoteConn1)); - EXPECT_NE(localConn1.get(), nullptr); - - { - // If we connect to the same page id again without disconnecting, we should - // get null - auto remoteConn = std::make_unique(); - auto localConn = inspector->connect(id1, std::move(remoteConn)); - EXPECT_EQ(localConn.get(), nullptr); - } - - auto remoteConn2 = std::make_unique(); - auto remoteData2 = remoteConn2->getData(); - auto localConn2 = inspector->connect(id2, std::move(remoteConn2)); - EXPECT_NE(localConn2.get(), nullptr); - - // Disable debugging on runtime2. This should remove its page from the list - // and call onDisconnect on its remoteConn - demux.disableDebugging(id2); - expectPages(*inspector, {{id1, "page1"}}); - remoteData2->expectDisconnected(); - - // Disconnect conn1. Its page should still be in the page list and - // onDisconnect should be called. - localConn1->disconnect(); - remoteData1->expectDisconnected(); - - { - // Should still be able to reconnect after disconnecting - auto remoteConn = std::make_unique(); - auto localConn = inspector->connect(id1, std::move(remoteConn)); - EXPECT_NE(localConn.get(), nullptr); - } -} - -} // namespace chrome -} // namespace inspector_modern -} // namespace hermes -} // namespace facebook diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp index b308cfd42082..d843a8338aeb 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp @@ -12,90 +12,11 @@ #include #include -#ifdef HERMES_ENABLE_DEBUGGER -#include - -#ifndef HERMES_V1_ENABLED -#include -#endif - -#include -#endif - using namespace facebook::hermes; using namespace facebook::jsi; namespace facebook::react { -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - -// Wrapper that strongly retains the HermesRuntime for on device debugging. -// -// HermesInstanceRuntimeAdapter needs to strongly retain the HermesRuntime. Why: -// - facebook::hermes::inspector_modern::chrome::Connection::Impl owns the -// Adapter -// - facebook::hermes::inspector_modern::chrome::Connection::Impl also owns -// jsi:: objects -// - jsi:: objects need to be deleted before the Runtime. -// -// If Adapter doesn't share ownership over jsi::Runtime, the runtime can be -// deleted before Connection::Impl cleans up all its jsi:: Objects. This will -// lead to a runtime crash. -class HermesInstanceRuntimeAdapter : public inspector_modern::RuntimeAdapter { - public: - HermesInstanceRuntimeAdapter( - std::shared_ptr hermesRuntime, - std::shared_ptr msgQueueThread) - : hermesRuntime_(std::move(hermesRuntime)), - messageQueueThread_(std::move(msgQueueThread)) {} - virtual ~HermesInstanceRuntimeAdapter() = default; - - HermesRuntime& getRuntime() override { - return *hermesRuntime_; - } - - void tickleJs() override { - std::weak_ptr weakRuntime(hermesRuntime_); - messageQueueThread_->runOnQueue([weakRuntime]() { - auto runtime = weakRuntime.lock(); - if (!runtime) { - return; - } - jsi::Function func = - runtime->global().getPropertyAsFunction(*runtime, "__tickleJs"); - func.call(*runtime); - }); - } - - private: - std::shared_ptr hermesRuntime_; - std::shared_ptr messageQueueThread_; -}; - -class DecoratedRuntime : public jsi::RuntimeDecorator { - public: - DecoratedRuntime( - std::unique_ptr runtime, - std::shared_ptr msgQueueThread) - : RuntimeDecorator(*runtime), runtime_(std::move(runtime)) { - auto adapter = std::make_unique( - runtime_, msgQueueThread); - - debugToken_ = inspector_modern::chrome::enableDebugging( - std::move(adapter), "Hermes Bridgeless React Native"); - } - - ~DecoratedRuntime() { - inspector_modern::chrome::disableDebugging(debugToken_); - } - - private: - std::shared_ptr runtime_; - inspector_modern::chrome::DebugSessionToken debugToken_; -}; - -#endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - class HermesJSRuntime : public JSRuntime { public: HermesJSRuntime( @@ -164,17 +85,7 @@ std::unique_ptr HermesInstance::createJSRuntime( .getPropertyAsObject(*hermesRuntime, "prototype"); errorPrototype.setProperty(*hermesRuntime, "jsEngine", "hermes"); -#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) - auto& inspectorFlags = jsinspector_modern::InspectorFlags::getInstance(); - if (!inspectorFlags.getFuseboxEnabled()) { - std::unique_ptr decoratedRuntime = - std::make_unique( - std::move(hermesRuntime), msgQueueThread); - return std::make_unique(std::move(decoratedRuntime)); - } -#else (void)msgQueueThread; -#endif HermesRuntime& hermesRuntimeRef = *hermesRuntime; return std::make_unique(