[0.71] Switch between V8 JSI and V8 Node-API (#12211)

* Switch between V8 JSI and V8 Node-API

* Change files

* Format code
This commit is contained in:
Vladimir Morozov 2023-10-06 10:38:12 -07:00 коммит произвёл GitHub
Родитель 707cdea8a9
Коммит 75b42021db
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 192 добавлений и 3 удалений

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Switch between V8 JSI and V8 Node-API",
"packageName": "react-native-windows",
"email": "vmorozov@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -275,6 +275,9 @@ struct ReactOptions {
winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
JSIEngine value) noexcept;
bool JsiEngineV8NodeApi() const noexcept;
static bool JsiEngineV8NodeApi(winrt::Microsoft::ReactNative::IReactPropertyBag const &properties) noexcept;
//! Enable live reload to load the source bundle from the React Native packager.
//! When the file is saved, the packager will trigger reloading.
void SetUseLiveReload(bool enable) noexcept;

Просмотреть файл

@ -3,6 +3,7 @@
#include "ReactHost.h"
#include <Future/FutureWait.h>
#include <ReactPropertyBag.h>
#include <winrt/Windows.Foundation.h>
namespace Mso::React {
@ -35,6 +36,12 @@ winrt::Microsoft::ReactNative::IReactPropertyName JSIEngineProperty() noexcept {
return propName;
}
winrt::Microsoft::ReactNative::ReactPropertyId<bool> JSIEngineV8NodeApiProperty() noexcept {
static winrt::Microsoft::ReactNative::ReactPropertyId<bool> propId{
L"ReactNative.ReactOptions", L"JSIEngineV8NodeApi"};
return propId;
}
winrt::Microsoft::ReactNative::IReactPropertyName LiveReloadEnabledProperty() noexcept {
static winrt::Microsoft::ReactNative::IReactPropertyName propName =
winrt::Microsoft::ReactNative::ReactPropertyBagHelper::GetName(
@ -137,6 +144,15 @@ void ReactOptions::SetJsiEngine(JSIEngine value) noexcept {
properties.Set(JSIEngineProperty(), winrt::box_value(static_cast<uint32_t>(value)));
}
/*static*/ bool ReactOptions::JsiEngineV8NodeApi(
winrt::Microsoft::ReactNative::IReactPropertyBag const &properties) noexcept {
return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(JSIEngineV8NodeApiProperty()).value_or(false);
}
bool ReactOptions::JsiEngineV8NodeApi() const noexcept {
return JsiEngineV8NodeApi(Properties);
}
/*static*/ void ReactOptions::SetUseFastRefresh(
winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
bool value) noexcept {

Просмотреть файл

@ -68,7 +68,9 @@
#if defined(USE_V8)
#include <winrt/Windows.Storage.h>
#include "BaseScriptStoreImpl.h"
#include "JSI/V8RuntimeHolder.h"
#include "V8JSIRuntimeHolder.h"
#endif // USE_V8
#include "RedBox.h"
@ -509,8 +511,18 @@ void ReactInstanceWin::Initialize() noexcept {
enableMultiThreadSupport = Microsoft::ReactNative::IsFabricEnabled(m_reactContext->Properties());
#endif // USE_FABRIC
devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
if (m_options.JsiEngineV8NodeApi()) {
devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
} else {
devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
devSettings,
m_jsMessageThread.Load(),
std::move(scriptStore),
std::move(preparedScriptStore),
enableMultiThreadSupport);
}
break;
}
#endif // USE_V8

Просмотреть файл

@ -52,6 +52,7 @@
#if defined(USE_V8)
#include <JSI/V8RuntimeHolder.h>
#include "V8JSIRuntimeHolder.h"
#endif
#include <ReactCommon/CallInvoker.h>
#include <ReactCommon/TurboModuleBinding.h>
@ -319,7 +320,24 @@ InstanceImpl::InstanceImpl(
m_devSettings, m_jsThread, std::move(preparedScriptStore));
break;
}
case JSIEngineOverride::V8:
case JSIEngineOverride::V8: {
#if defined(USE_V8)
std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore;
wchar_t tempPath[MAX_PATH];
if (GetTempPathW(MAX_PATH, tempPath)) {
preparedScriptStore =
std::make_shared<facebook::react::BasePreparedScriptStoreImpl>(winrt::to_string(tempPath));
}
m_devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
m_devSettings, m_jsThread, nullptr, std::move(preparedScriptStore), /*multithreading*/ false);
break;
#else
assert(false); // V8 is not available in this build, fallthrough
[[fallthrough]];
#endif
}
case JSIEngineOverride::V8NodeApi: {
#if defined(USE_V8)
std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore;

Просмотреть файл

@ -74,6 +74,9 @@
<ClCompile Include="$(MSBuildThisFileDirectory)TurboModuleManager.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Utils.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp">
<ExcludedFromBuild Condition="'$(UseV8)' != 'true'">true</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)..\include\Shared\cdebug.h" />
@ -165,6 +168,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)Utils.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)Utils\CppWinrtLessExceptions.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)WebSocketJSExecutorFactory.h" />
<ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Modules\ReactRootViewTagGenerator.cpp" />
<ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Utils\ImageUtils.cpp" />

Просмотреть файл

@ -157,6 +157,7 @@
<ClCompile Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="Source Files">
@ -485,6 +486,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\JsiApi.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)tracing\rnw.wprp">

Просмотреть файл

@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include <V8JsiRuntime.h>
#include "V8JSIRuntimeHolder.h"
#include <atomic>
#include <queue>
using namespace facebook;
using namespace facebook::react;
namespace facebook {
namespace react {
class TaskRunnerAdapter : public v8runtime::JSITaskRunner {
public:
TaskRunnerAdapter(std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) : jsQueue_(std::move(jsQueue)) {}
void postTask(std::unique_ptr<v8runtime::JSITask> task) override {
std::shared_ptr<v8runtime::JSITask> shared_task(task.release());
jsQueue_->runOnQueue([shared_task2 = std::move(shared_task)]() { shared_task2->run(); });
}
private:
TaskRunnerAdapter(const TaskRunnerAdapter &) = delete;
TaskRunnerAdapter &operator=(const TaskRunnerAdapter &) = delete;
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue_;
};
facebook::react::JSIEngineOverride V8JSIRuntimeHolder::getRuntimeType() noexcept {
return facebook::react::JSIEngineOverride::V8;
}
std::shared_ptr<facebook::jsi::Runtime> V8JSIRuntimeHolder::getRuntime() noexcept {
std::call_once(once_flag_, [this]() { initRuntime(); });
if (!runtime_)
std::terminate();
// V8JsiRuntime is not thread safe as of now.
if (own_thread_id_ != std::this_thread::get_id())
std::terminate();
return runtime_;
}
void V8JSIRuntimeHolder::initRuntime() noexcept {
v8runtime::V8RuntimeArgs args{};
if (debuggerPort_ > 0)
args.inspectorPort = debuggerPort_;
args.flags.enableInspector = useDirectDebugger_;
args.flags.waitForDebugger = debuggerBreakOnNextLine_;
args.debuggerRuntimeName = debuggerRuntimeName_;
args.foreground_task_runner = std::make_shared<TaskRunnerAdapter>(jsQueue_);
args.preparedScriptStore = std::move(preparedScriptStore_);
args.flags.enableMultiThread = enableMultiThreadingSupport_;
runtime_ = v8runtime::makeV8Runtime(std::move(args));
own_thread_id_ = std::this_thread::get_id();
}
} // namespace react
} // namespace facebook

Просмотреть файл

@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include <DevSettings.h>
#include <JSI/RuntimeHolder.h>
#include <JSI/ScriptStore.h>
#include <Logging.h>
namespace facebook {
namespace react {
class V8JSIRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
public:
std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
V8JSIRuntimeHolder(
std::shared_ptr<facebook::react::DevSettings> devSettings,
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
std::unique_ptr<facebook::jsi::ScriptStore> &&scriptStore,
std::shared_ptr<facebook::jsi::PreparedScriptStore> &&preparedScriptStore,
bool enableMultiThreadingSupport) noexcept
: useDirectDebugger_(devSettings->useDirectDebugger),
debuggerBreakOnNextLine_(devSettings->debuggerBreakOnNextLine),
debuggerPort_(devSettings->debuggerPort),
debuggerRuntimeName_(devSettings->debuggerRuntimeName),
jsQueue_(std::move(jsQueue)),
scriptStore_(std::move(scriptStore)),
preparedScriptStore_(std::move(preparedScriptStore)),
enableMultiThreadingSupport_(enableMultiThreadingSupport) {}
private:
void initRuntime() noexcept;
std::shared_ptr<facebook::jsi::Runtime> runtime_;
std::shared_ptr<facebook::react::MessageQueueThread> jsQueue_;
std::unique_ptr<facebook::jsi::ScriptStore> scriptStore_;
std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore_;
std::once_flag once_flag_;
std::thread::id own_thread_id_;
uint16_t debuggerPort_;
bool useDirectDebugger_;
bool debuggerBreakOnNextLine_;
std::string debuggerRuntimeName_;
bool enableMultiThreadingSupport_;
};
} // namespace react
} // namespace facebook