/
githubmr
/
facebook-react-native
Обзор
Документация
Войти
/
githubmr
/
facebook-react-native
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp
179 строк
6 KB
Gang Zhao
Revert deletion of old Hermes CDPHandler (#54078)
08 окт 2025, 05:39
08 окт 2025, 05:39
e32307e
Код
Авторство
О чём код?
/* * 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 "HermesInstance.h" #include <hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.h> #include <jsi/jsilib.h> #include <jsinspector-modern/InspectorFlags.h> #include <react/featureflags/ReactNativeFeatureFlags.h> #ifdef HERMES_ENABLE_DEBUGGER #include <hermes/inspector-modern/chrome/Registration.h> #ifndef HERMES_V1_ENABLED #include <hermes/inspector/RuntimeAdapter.h> #endif #include <jsi/decorator.h> #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> hermesRuntime, std::shared_ptr<MessageQueueThread> msgQueueThread) : hermesRuntime_(std::move(hermesRuntime)), messageQueueThread_(std::move(msgQueueThread)) {} virtual ~HermesInstanceRuntimeAdapter() = default; HermesRuntime& getRuntime() override { return *hermesRuntime_; } void tickleJs() override { std::weak_ptr<HermesRuntime> 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> hermesRuntime_; std::shared_ptr<MessageQueueThread> messageQueueThread_; }; class DecoratedRuntime : public jsi::RuntimeDecorator<jsi::Runtime> { public: DecoratedRuntime( std::unique_ptr<HermesRuntime> runtime, std::shared_ptr<MessageQueueThread> msgQueueThread) : RuntimeDecorator<jsi::Runtime>(*runtime), runtime_(std::move(runtime)) { auto adapter = std::make_unique<HermesInstanceRuntimeAdapter>( runtime_, msgQueueThread); debugToken_ = inspector_modern::chrome::enableDebugging( std::move(adapter), "Hermes Bridgeless React Native"); } ~DecoratedRuntime() { inspector_modern::chrome::disableDebugging(debugToken_); } private: std::shared_ptr<HermesRuntime> runtime_; inspector_modern::chrome::DebugSessionToken debugToken_; }; #endif // defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED) class HermesJSRuntime : public JSRuntime { public: HermesJSRuntime(std::unique_ptr<HermesRuntime> runtime) : runtime_(std::move(runtime)) {} jsi::Runtime& getRuntime() noexcept override { return *runtime_; } jsinspector_modern::RuntimeTargetDelegate& getRuntimeTargetDelegate() override { if (!targetDelegate_) { targetDelegate_.emplace(runtime_); } return *targetDelegate_; } void unstable_initializeOnJsThread() override { runtime_->registerForProfiling(); } private: std::shared_ptr<HermesRuntime> runtime_; std::optional<jsinspector_modern::HermesRuntimeTargetDelegate> targetDelegate_; }; std::unique_ptr<JSRuntime> HermesInstance::createJSRuntime( std::shared_ptr<::hermes::vm::CrashManager> crashManager, std::shared_ptr<MessageQueueThread> msgQueueThread, bool allocInOldGenBeforeTTI) noexcept { assert(msgQueueThread != nullptr); auto gcConfig = ::hermes::vm::GCConfig::Builder() // Default to 3GB .withMaxHeapSize(3072 << 20) .withName("RNBridgeless"); if (allocInOldGenBeforeTTI) { // For the next two arguments: avoid GC before TTI // by initializing the runtime to allocate directly // in the old generation, but revert to normal // operation when we reach the (first) TTI point. gcConfig.withAllocInYoung(false).withRevertToYGAtTTI(true); } ::hermes::vm::RuntimeConfig::Builder runtimeConfigBuilder = ::hermes::vm::RuntimeConfig::Builder() .withGCConfig(gcConfig.build()) .withEnableSampleProfiling(true) .withMicrotaskQueue( ReactNativeFeatureFlags::enableBridgelessArchitecture()); if (crashManager) { runtimeConfigBuilder.withCrashMgr(crashManager); } std::unique_ptr<HermesRuntime> hermesRuntime = hermes::makeHermesRuntime(runtimeConfigBuilder.build()); auto errorPrototype = hermesRuntime->global() .getPropertyAsObject(*hermesRuntime, "Error") .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> decoratedRuntime = std::make_unique<DecoratedRuntime>( std::move(hermesRuntime), msgQueueThread); return std::make_unique<JSIRuntimeHolder>(std::move(decoratedRuntime)); } #else (void)msgQueueThread; #endif return std::make_unique<HermesJSRuntime>(std::move(hermesRuntime)); } } // namespace facebook::react