react-native-windows 0.72.11 → 0.72.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -275,6 +275,9 @@ struct ReactOptions {
275
275
  winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
276
276
  JSIEngine value) noexcept;
277
277
 
278
+ bool JsiEngineV8NodeApi() const noexcept;
279
+ static bool JsiEngineV8NodeApi(winrt::Microsoft::ReactNative::IReactPropertyBag const &properties) noexcept;
280
+
278
281
  //! Enable live reload to load the source bundle from the React Native packager.
279
282
  //! When the file is saved, the packager will trigger reloading.
280
283
  void SetUseLiveReload(bool enable) noexcept;
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "ReactHost.h"
5
5
  #include <Future/FutureWait.h>
6
+ #include <ReactPropertyBag.h>
6
7
  #include <winrt/Windows.Foundation.h>
7
8
 
8
9
  namespace Mso::React {
@@ -35,6 +36,12 @@ winrt::Microsoft::ReactNative::IReactPropertyName JSIEngineProperty() noexcept {
35
36
  return propName;
36
37
  }
37
38
 
39
+ winrt::Microsoft::ReactNative::ReactPropertyId<bool> JSIEngineV8NodeApiProperty() noexcept {
40
+ static winrt::Microsoft::ReactNative::ReactPropertyId<bool> propId{
41
+ L"ReactNative.ReactOptions", L"JSIEngineV8NodeApi"};
42
+ return propId;
43
+ }
44
+
38
45
  winrt::Microsoft::ReactNative::IReactPropertyName LiveReloadEnabledProperty() noexcept {
39
46
  static winrt::Microsoft::ReactNative::IReactPropertyName propName =
40
47
  winrt::Microsoft::ReactNative::ReactPropertyBagHelper::GetName(
@@ -137,6 +144,15 @@ void ReactOptions::SetJsiEngine(JSIEngine value) noexcept {
137
144
  properties.Set(JSIEngineProperty(), winrt::box_value(static_cast<uint32_t>(value)));
138
145
  }
139
146
 
147
+ /*static*/ bool ReactOptions::JsiEngineV8NodeApi(
148
+ winrt::Microsoft::ReactNative::IReactPropertyBag const &properties) noexcept {
149
+ return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(JSIEngineV8NodeApiProperty()).value_or(false);
150
+ }
151
+
152
+ bool ReactOptions::JsiEngineV8NodeApi() const noexcept {
153
+ return JsiEngineV8NodeApi(Properties);
154
+ }
155
+
140
156
  /*static*/ void ReactOptions::SetUseFastRefresh(
141
157
  winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
142
158
  bool value) noexcept {
@@ -76,7 +76,9 @@
76
76
 
77
77
  #if defined(USE_V8)
78
78
  #include <winrt/Windows.Storage.h>
79
+ #include "BaseScriptStoreImpl.h"
79
80
  #include "JSI/V8RuntimeHolder.h"
81
+ #include "V8JSIRuntimeHolder.h"
80
82
  #endif // USE_V8
81
83
 
82
84
  #include "RedBox.h"
@@ -491,7 +493,6 @@ void ReactInstanceWin::Initialize() noexcept {
491
493
 
492
494
  switch (m_options.JsiEngine()) {
493
495
  case JSIEngine::Hermes: {
494
- // TODO: Should we use UwpPreparedScriptStore?
495
496
  if (Microsoft::ReactNative::HasPackageIdentity()) {
496
497
  preparedScriptStore =
497
498
  std::make_unique<facebook::react::BasePreparedScriptStoreImpl>(getApplicationTempFolder());
@@ -529,8 +530,18 @@ void ReactInstanceWin::Initialize() noexcept {
529
530
  enableMultiThreadSupport = Microsoft::ReactNative::IsFabricEnabled(m_reactContext->Properties());
530
531
  #endif // USE_FABRIC
531
532
 
532
- devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
533
- devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
533
+ if (m_options.JsiEngineV8NodeApi()) {
534
+ devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
535
+ devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
536
+ } else {
537
+ devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
538
+ devSettings,
539
+ m_jsMessageThread.Load(),
540
+ std::move(scriptStore),
541
+ std::move(preparedScriptStore),
542
+ enableMultiThreadSupport);
543
+ }
544
+
534
545
  break;
535
546
  }
536
547
  #endif // USE_V8
@@ -36,6 +36,7 @@
36
36
  $(NodeApiJsiSrcDir);
37
37
  %(AdditionalIncludeDirectories)
38
38
  </AdditionalIncludeDirectories>
39
+ <PreprocessorDefinitions>JSI_VERSION=10;%(PreprocessorDefinitions)</PreprocessorDefinitions>
39
40
  </ClCompile>
40
41
  <Midl>
41
42
  <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.72.11</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.72.13</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>72</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>11</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>13</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>2255827c0902a9740b9e029ce22f02fb445093e1</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>78f5a3de444b20d8e5826348ee3d18ffba19c89d</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -24,9 +24,10 @@
24
24
  <EnableDevServerHBCBundles Condition="'$(EnableDevServerHBCBundles)' == ''">false</EnableDevServerHBCBundles>
25
25
 
26
26
  <UseV8 Condition="'$(UseV8)' == ''">false</UseV8>
27
- <V8Version Condition="'$(V8Version)' == ''">0.71.5</V8Version>
27
+ <V8Version Condition="'$(V8Version)' == ''">0.71.8</V8Version>
28
28
  <V8PackageName>ReactNative.V8Jsi.Windows</V8PackageName>
29
29
  <V8PackageName Condition="'$(V8AppPlatform)' != 'win32'">$(V8PackageName).UWP</V8PackageName>
30
+ <V8Package>$(NuGetPackageRoot)\$(V8PackageName).$(V8Version)</V8Package>
30
31
  </PropertyGroup>
31
32
 
32
33
  </Project>
@@ -56,6 +56,7 @@
56
56
  <PreprocessorDefinitions Condition="'$(EnableDevServerHBCBundles)'=='true'">ENABLE_DEVSERVER_HBCBUNDLES;%(PreprocessorDefinitions)</PreprocessorDefinitions>
57
57
  <PreprocessorDefinitions Condition="'$(UseV8)'=='true'">USE_V8;%(PreprocessorDefinitions)</PreprocessorDefinitions>
58
58
  <PreprocessorDefinitions Condition="'$(UseFabric)'=='true'">USE_FABRIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
59
+ <PreprocessorDefinitions>JSI_VERSION=10;%(PreprocessorDefinitions)</PreprocessorDefinitions>
59
60
  </ClCompile>
60
61
  </ItemDefinitionGroup>
61
62
 
@@ -235,8 +235,8 @@
235
235
  <!-- Reenable this task if we need to temporarily replace any folly files for fixes, while we wait for PRs to land in folly -->
236
236
  <Target Name="ApplyReactCommonTemporaryPatch" BeforeTargets="PrepareForBuild" DependsOnTargets="UnzipNodeApiJsi">
237
237
  <ItemGroup>
238
- <NodeApiJsiFiles Include="$([MSBuild]::NormalizePath($(NodeApiJsiDir)..))\jsi\**\*.*" />
239
- </ItemGroup>
238
+ <NodeApiJsiFiles Include="$([MSBuild]::NormalizePath($(NodeApiJsiDir)))\jsi\**\*.*" />
239
+ </ItemGroup>
240
240
  <Copy DestinationFiles="@(NodeApiJsiFiles->'$(ReactNativeDir)\ReactCommon\jsi\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(NodeApiJsiFiles)" />
241
241
  <Copy DestinationFiles="@(TemporaryReactCommonPatchFiles->'$(ReactNativeDir)\ReactCommon\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(TemporaryReactCommonPatchFiles)" />
242
242
  </Target>
@@ -38,7 +38,7 @@ void NAPI_CDECL removeInspectorPage(int32_t pageId) noexcept;
38
38
 
39
39
  class HermesFuncResolver : public IFuncResolver {
40
40
  public:
41
- HermesFuncResolver() : libHandle_(SafeLoadLibrary(L"hermes.dll")) {}
41
+ HermesFuncResolver() : libHandle_(LoadLibraryAsPeerFirst(L"hermes.dll")) {}
42
42
 
43
43
  FuncPtr getFuncPtr(const char *funcName) override {
44
44
  return reinterpret_cast<FuncPtr>(GetProcAddress(libHandle_, funcName));
@@ -18,8 +18,8 @@ class InspectorPackagerConnection final : public std::enable_shared_from_this<In
18
18
  bool m_isLastDownloadSuccess;
19
19
  int64_t m_updateTimestamp = -1;
20
20
 
21
- BundleStatus(bool isLastDownloadSucess, long updateTimestamp)
22
- : m_isLastDownloadSuccess(isLastDownloadSucess), m_updateTimestamp(updateTimestamp) {}
21
+ BundleStatus(bool isLastDownloadSuccess, long updateTimestamp)
22
+ : m_isLastDownloadSuccess(isLastDownloadSuccess), m_updateTimestamp(updateTimestamp) {}
23
23
  BundleStatus() : m_isLastDownloadSuccess(false), m_updateTimestamp(-1) {}
24
24
  };
25
25
 
@@ -16,7 +16,7 @@ namespace {
16
16
 
17
17
  class V8FuncResolver : public IFuncResolver {
18
18
  public:
19
- V8FuncResolver() : libHandle_(SafeLoadLibrary(L"v8jsi.dll")) {}
19
+ V8FuncResolver() : libHandle_(LoadLibraryAsPeerFirst(L"v8jsi.dll")) {}
20
20
 
21
21
  FuncPtr getFuncPtr(const char *funcName) override {
22
22
  return reinterpret_cast<FuncPtr>(GetProcAddress(libHandle_, funcName));
@@ -239,8 +239,6 @@ void V8RuntimeHolder::initRuntime() noexcept {
239
239
  CRASH_ON_ERROR(api.jsr_create_runtime(config, &runtime));
240
240
  CRASH_ON_ERROR(api.jsr_delete_config(config));
241
241
 
242
- CRASH_ON_ERROR(api.jsr_create_runtime(config, &runtime));
243
-
244
242
  napi_env env{};
245
243
  CRASH_ON_ERROR(api.jsr_runtime_get_node_api_env(runtime, &env));
246
244
 
@@ -52,6 +52,9 @@ using Microsoft::React::Networking::IWebSocketResource;
52
52
 
53
53
  constexpr char s_moduleName[] = "WebSocketModule";
54
54
  constexpr wchar_t s_moduleNameW[] = L"WebSocketModule";
55
+ constexpr wchar_t s_proxyNameW[] = L"WebSocketModule.Proxy";
56
+ constexpr wchar_t s_sharedStateNameW[] = L"WebSocketModule.SharedState";
57
+ constexpr wchar_t s_contentHandlerNameW[] = L"BlobModule.ContentHandler";
55
58
 
56
59
  msrn::ReactModuleProvider s_moduleProvider = msrn::MakeTurboModuleProvider<Microsoft::React::WebSocketTurboModule>();
57
60
 
@@ -119,7 +122,7 @@ GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedS
119
122
  auto args = msrn::JSValueObject{{"id", id}, {"type", isBinary ? "binary" : "text"}};
120
123
  shared_ptr<Microsoft::React::IWebSocketModuleContentHandler> contentHandler;
121
124
  auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<Microsoft::React::IWebSocketModuleContentHandler>>>{
122
- L"BlobModule.ContentHandler"};
125
+ s_contentHandlerNameW};
123
126
  if (auto prop = propBag.Get(propId))
124
127
  contentHandler = prop.Value().lock();
125
128
 
@@ -171,11 +174,11 @@ WebSocketModule::WebSocketModule(winrt::Windows::Foundation::IInspectable const
171
174
 
172
175
  auto propBag = ReactPropertyBag{m_sharedState->InspectableProps.try_as<IReactPropertyBag>()};
173
176
 
174
- auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{L"WebSocketModule.Proxy"};
177
+ auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{s_proxyNameW};
175
178
  auto proxy = weak_ptr<IWebSocketModuleProxy>{m_proxy};
176
179
  propBag.Set(proxyPropId, std::move(proxy));
177
180
 
178
- auto statePropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<SharedState>>>{L"WebSocketModule.SharedState"};
181
+ auto statePropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<SharedState>>>{s_sharedStateNameW};
179
182
  auto state = weak_ptr<SharedState>{m_sharedState};
180
183
  propBag.Set(statePropId, std::move(state));
181
184
  }
@@ -309,10 +312,9 @@ vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMethods()
309
312
  WebSocketModuleProxy::WebSocketModuleProxy(IInspectable const &inspectableProperties) noexcept
310
313
  : m_inspectableProps{inspectableProperties} {}
311
314
 
312
- void WebSocketModuleProxy::SendBinary(std::string &&base64String, int64_t id) noexcept /*override*/ {
315
+ void WebSocketModuleProxy::SendBinary(string &&base64String, int64_t id) noexcept /*override*/ {
313
316
  auto propBag = ReactPropertyBag{m_inspectableProps.try_as<IReactPropertyBag>()};
314
- auto sharedPropId =
315
- ReactPropertyId<ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>>{L"WebSocketModule.SharedState"};
317
+ auto sharedPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>>{s_sharedStateNameW};
316
318
  auto state = propBag.Get(sharedPropId).Value();
317
319
 
318
320
  weak_ptr weakWs = GetOrCreateWebSocket(id, {}, std::move(state));
@@ -353,8 +355,7 @@ shared_ptr<IWebSocketResource> WebSocketTurboModule::CreateResource(int64_t id,
353
355
  rc->SetOnMessage([id, context = m_context](size_t length, const string &message, bool isBinary) {
354
356
  auto args = msrn::JSValueObject{{"id", id}, {"type", isBinary ? "binary" : "text"}};
355
357
  shared_ptr<IWebSocketModuleContentHandler> contentHandler;
356
- auto propId =
357
- ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{L"BlobModule.ContentHandler"};
358
+ auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{s_contentHandlerNameW};
358
359
  auto propBag = context.Properties();
359
360
  if (auto prop = propBag.Get(propId))
360
361
  contentHandler = prop.Value().lock();
@@ -396,6 +397,11 @@ shared_ptr<IWebSocketResource> WebSocketTurboModule::CreateResource(int64_t id,
396
397
 
397
398
  void WebSocketTurboModule::Initialize(msrn::ReactContext const &reactContext) noexcept {
398
399
  m_context = reactContext.Handle();
400
+ m_proxy = std::make_shared<WebSocketTurboModuleProxy>(m_resourceMap);
401
+
402
+ auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{s_proxyNameW};
403
+ auto proxy = weak_ptr<IWebSocketModuleProxy>{m_proxy};
404
+ m_context.Properties().Set(proxyPropId, std::move(proxy));
399
405
  }
400
406
 
401
407
  void WebSocketTurboModule::Connect(
@@ -487,6 +493,29 @@ void WebSocketTurboModule::RemoveListeners(double /*count*/) noexcept {}
487
493
 
488
494
  #pragma endregion WebSocketTurboModule
489
495
 
496
+ #pragma region WebSocketTurboModuleProxy
497
+
498
+ WebSocketTurboModuleProxy::WebSocketTurboModuleProxy(
499
+ std::unordered_map<double, shared_ptr<IWebSocketResource>> &resourceMap) noexcept
500
+ : m_resourceMap{resourceMap} {}
501
+
502
+ #pragma endregion WebSocketTurboModuleProxy
503
+
504
+ void WebSocketTurboModuleProxy::SendBinary(string &&base64String, int64_t id) noexcept /*override*/
505
+ {
506
+ auto rcItr = m_resourceMap.find(static_cast<double>(id));
507
+ if (rcItr == m_resourceMap.cend()) {
508
+ return;
509
+ }
510
+
511
+ weak_ptr<IWebSocketResource> weakRc = (*rcItr).second;
512
+ if (auto rc = weakRc.lock()) {
513
+ rc->SendBinary(std::move(base64String));
514
+ }
515
+ }
516
+
517
+ #pragma region WebSocketTurboModule
518
+
490
519
  /*extern*/ const char *GetWebSocketModuleName() noexcept {
491
520
  return s_moduleName;
492
521
  }
@@ -10,6 +10,20 @@
10
10
 
11
11
  namespace Microsoft::React {
12
12
 
13
+ class WebSocketTurboModuleProxy final : public IWebSocketModuleProxy {
14
+ std::unordered_map<double, std::shared_ptr<Networking::IWebSocketResource>> &m_resourceMap;
15
+
16
+ public:
17
+ WebSocketTurboModuleProxy(
18
+ std::unordered_map<double, std::shared_ptr<Networking::IWebSocketResource>> &resourceMap) noexcept;
19
+
20
+ #pragma region IWebSocketModuleProxy
21
+
22
+ void SendBinary(std::string &&base64String, int64_t id) noexcept override;
23
+
24
+ #pragma endregion
25
+ };
26
+
13
27
  REACT_MODULE(WebSocketTurboModule, L"WebSocketModule")
14
28
  struct WebSocketTurboModule {
15
29
  using ModuleSpec = ReactNativeSpecs::WebSocketModuleSpec;
@@ -47,6 +61,11 @@ struct WebSocketTurboModule {
47
61
 
48
62
  winrt::Microsoft::ReactNative::ReactContext m_context;
49
63
  std::unordered_map<double, std::shared_ptr<Networking::IWebSocketResource>> m_resourceMap;
64
+
65
+ /// <summary>
66
+ /// Exposes a subset of the module's methods.
67
+ /// </summary>
68
+ std::shared_ptr<IWebSocketModuleProxy> m_proxy;
50
69
  };
51
70
 
52
71
  } // namespace Microsoft::React
@@ -52,6 +52,7 @@
52
52
 
53
53
  #if defined(USE_V8)
54
54
  #include <JSI/V8RuntimeHolder.h>
55
+ #include "V8JSIRuntimeHolder.h"
55
56
  #endif
56
57
  #include <ReactCommon/CallInvoker.h>
57
58
  #include <ReactCommon/TurboModuleBinding.h>
@@ -319,7 +320,24 @@ InstanceImpl::InstanceImpl(
319
320
  m_devSettings, m_jsThread, std::move(preparedScriptStore));
320
321
  break;
321
322
  }
322
- case JSIEngineOverride::V8:
323
+ case JSIEngineOverride::V8: {
324
+ #if defined(USE_V8)
325
+ std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore;
326
+
327
+ wchar_t tempPath[MAX_PATH];
328
+ if (GetTempPathW(MAX_PATH, tempPath)) {
329
+ preparedScriptStore =
330
+ std::make_shared<facebook::react::BasePreparedScriptStoreImpl>(winrt::to_string(tempPath));
331
+ }
332
+
333
+ m_devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
334
+ m_devSettings, m_jsThread, nullptr, std::move(preparedScriptStore), /*multithreading*/ false);
335
+ break;
336
+ #else
337
+ assert(false); // V8 is not available in this build, fallthrough
338
+ [[fallthrough]];
339
+ #endif
340
+ }
323
341
  case JSIEngineOverride::V8NodeApi: {
324
342
  #if defined(USE_V8)
325
343
  std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore;
@@ -2,19 +2,22 @@
2
2
  // Licensed under the MIT License.
3
3
 
4
4
  #include "SafeLoadLibrary.h"
5
+ #include "PathCch.h"
6
+
7
+ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
5
8
 
6
9
  namespace Microsoft::ReactNative {
7
10
 
8
11
  // Unsafe calls to LoadLibrary/LoadLibraryEx.
9
12
  // The default behavior of LoadLibrary, or LoadLibraryEx without flags, is to try and find the dependency by iterating
10
13
  // through a search order. This search order contains the current working directory. In the classic attack, a malicious
11
- // DLL is dropped in the likely - controllable current working directory.The malicious DLL has the same name as a
12
- // missing dependency or dependency that is not in the same directory as the executable.When the call to LoadLibrary is
13
- // reached, the malicious DLL is loaded preferentially, and code execution occurs.
14
+ // DLL is dropped in the likely - controllable current working directory. The malicious DLL has the same name as a
15
+ // missing dependency or dependency that is not in the same directory as the executable. When the call to LoadLibrary
16
+ // is reached, the malicious DLL is loaded preferentially, and code execution occurs.
14
17
  //
15
18
  // The SafeLoadLibrary is the preferred ways to manually load dependencies.
16
19
  // The API does not search the current working directory when resolving dependencies.
17
- // It is "borrowed" from Office Mso code.
20
+ // The implementation is "borrowed" from Office MsoSafeLoadLibrary.
18
21
 
19
22
  /**
20
23
  List of new flags that control where to search for DLLs. Requires KB2533623.
@@ -22,20 +25,53 @@ namespace Microsoft::ReactNative {
22
25
  const DWORD SafeLoadLibraryFlags = LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
23
26
  LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS;
24
27
 
25
- HMODULE SafeLoadLibrary(const wchar_t *wzFileName, HANDLE hFile, DWORD dwFlags) noexcept {
28
+ HMODULE SafeLoadLibrary(const wchar_t *fileName, DWORD dwFlags) noexcept {
26
29
  // When calling LoadLibrary, OR in LOAD_LIBRARY_SEARCH_DEFAULT_DIRS which enables all of the
27
30
  // safe behaviors. Note that this flag is not compatible with LOAD_WITH_ALTERED_SEARCH_PATH.
31
+ #pragma push_macro("LoadLibraryExW")
32
+ #undef LoadLibraryExW
28
33
  HMODULE module =
29
- LoadLibraryExW(wzFileName, hFile, (dwFlags | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) & ~LOAD_WITH_ALTERED_SEARCH_PATH);
34
+ ::LoadLibraryExW(fileName, 0, (dwFlags | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) & ~LOAD_WITH_ALTERED_SEARCH_PATH);
30
35
  if (module == nullptr && GetLastError() == ERROR_INVALID_PARAMETER) {
31
36
  // Could have failed with actual bad parameters or an unpatched OS without KB2533623.
32
- if (GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "AddDllDirectory") == nullptr) {
37
+ if (::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "AddDllDirectory") == nullptr) {
33
38
  // Unpatched OS, remove all new flags.
34
- module = LoadLibraryExW(wzFileName, hFile, dwFlags & ~SafeLoadLibraryFlags);
39
+ module = ::LoadLibraryExW(fileName, 0, dwFlags & ~SafeLoadLibraryFlags);
35
40
  }
36
41
  }
42
+ #pragma pop_macro("LoadLibraryExW")
37
43
 
38
44
  return module;
39
45
  }
40
46
 
47
+ // Gets the full file name in the same directory as the current DLL.
48
+ // It returns nullptr if we cannot create the full file name.
49
+ wchar_t *GePeerFullFileName(const wchar_t *fileName, wchar_t *buffer, size_t bufferSize) {
50
+ size_t nameSize =
51
+ ::GetModuleFileNameW(reinterpret_cast<HINSTANCE>(&__ImageBase), buffer, static_cast<DWORD>(bufferSize));
52
+ if (nameSize == 0 || nameSize == bufferSize)
53
+ return nullptr;
54
+
55
+ if (::PathCchRemoveFileSpec(buffer, bufferSize) != S_OK)
56
+ return nullptr;
57
+ if (::PathCchCombineEx(buffer, bufferSize, buffer, fileName, PATHCCH_ALLOW_LONG_PATHS) != S_OK)
58
+ return nullptr;
59
+
60
+ return buffer;
61
+ }
62
+
63
+ HMODULE LoadLibraryAsPeerFirst(const wchar_t *fileName) noexcept {
64
+ HMODULE lib{nullptr};
65
+ constexpr size_t nameBufferSize = 4096;
66
+ wchar_t nameBuffer[nameBufferSize] = L"";
67
+
68
+ if (wchar_t *fullFileName = GePeerFullFileName(fileName, nameBuffer, nameBufferSize))
69
+ lib = SafeLoadLibrary(fullFileName);
70
+
71
+ if (!lib)
72
+ lib = SafeLoadLibrary(fileName);
73
+
74
+ return lib;
75
+ }
76
+
41
77
  } // namespace Microsoft::ReactNative
@@ -10,6 +10,10 @@
10
10
  namespace Microsoft::ReactNative {
11
11
 
12
12
  // Safe LoadLibraryEx wrapper that must be used instead of LoadLibrary.
13
- extern HMODULE SafeLoadLibrary(const wchar_t *wzFileName, HANDLE hFile = nullptr, DWORD dwFlags = 0) noexcept;
13
+ extern HMODULE SafeLoadLibrary(const wchar_t *fileName, DWORD flags = 0) noexcept;
14
+
15
+ // Try to load the dll from the same folder as the current DLL first,
16
+ // and if it is not found, then use the SafeLoadLibrary.
17
+ extern HMODULE LoadLibraryAsPeerFirst(const wchar_t *fileName) noexcept;
14
18
 
15
19
  } // namespace Microsoft::ReactNative
@@ -196,6 +196,9 @@
196
196
  <ClCompile Include="$(MSBuildThisFileDirectory)TurboModuleManager.cpp" />
197
197
  <ClCompile Include="$(MSBuildThisFileDirectory)Utils.cpp" />
198
198
  <ClCompile Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.cpp" />
199
+ <ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp">
200
+ <ExcludedFromBuild Condition="'$(UseV8)' != 'true'">true</ExcludedFromBuild>
201
+ </ClCompile>
199
202
  </ItemGroup>
200
203
  <ItemGroup>
201
204
  <ClInclude Include="$(MSBuildThisFileDirectory)..\codegen\react\components\rnwcore\EventEmitters.h" />
@@ -365,6 +368,7 @@
365
368
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils.h" />
366
369
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils\CppWinrtLessExceptions.h" />
367
370
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.h" />
371
+ <ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
368
372
  <ClInclude Include="$(MSBuildThisFileDirectory)WebSocketJSExecutorFactory.h" />
369
373
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Modules\DevSettingsModule.cpp" />
370
374
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Modules\ReactRootViewTagGenerator.cpp" />
@@ -266,6 +266,7 @@
266
266
  <ClCompile Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.cpp" />
267
267
  <ClCompile Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.cpp" />
268
268
  <ClCompile Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.cpp" />
269
+ <ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp" />
269
270
  <ClCompile Include="$(MSBuildThisFileDirectory)Networking\DefaultBlobResource.cpp">
270
271
  <Filter>Source Files\Networking</Filter>
271
272
  </ClCompile>
@@ -322,6 +323,9 @@
322
323
  <Filter Include="Source Files\Networking">
323
324
  <UniqueIdentifier>{71196e04-aca0-48d6-99e4-f418c957b50f}</UniqueIdentifier>
324
325
  </Filter>
326
+ <Filter Include="Hermes">
327
+ <UniqueIdentifier>{b32590e6-ae3d-4388-ab98-767345ce38c9}</UniqueIdentifier>
328
+ </Filter>
325
329
  <Filter Include="Header Files\Fabric">
326
330
  <UniqueIdentifier>{e045612e-bca3-4844-bce8-e75f83e89e05}</UniqueIdentifier>
327
331
  </Filter>
@@ -713,17 +717,6 @@
713
717
  <ClInclude Include="$(MSBuildThisFileDirectory)BaseFileReaderResource.h">
714
718
  <Filter>Header Files</Filter>
715
719
  </ClInclude>
716
- <ClInclude Include="$(MSBuildThisFileDirectory)HermesRuntimeHolder.h">
717
- <Filter>Hermes</Filter>
718
- </ClInclude>
719
- <ClInclude Include="$(MSBuildThisFileDirectory)HermesSamplingProfiler.h">
720
- <Filter>Hermes</Filter>
721
- </ClInclude>
722
- <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.h" />
723
- <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.inc" />
724
- <ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\JsiApi.h" />
725
- <ClInclude Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.h" />
726
- <ClInclude Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.h" />
727
720
  <ClInclude Include="$(MSBuildThisFileDirectory)Modules\WebSocketTurboModule.h">
728
721
  <Filter>Header Files\Modules</Filter>
729
722
  </ClInclude>
@@ -736,6 +729,18 @@
736
729
  <ClInclude Include="$(MSBuildThisFileDirectory)IBlobPersistor.h">
737
730
  <Filter>Header Files</Filter>
738
731
  </ClInclude>
732
+ <ClInclude Include="$(MSBuildThisFileDirectory)HermesRuntimeHolder.h">
733
+ <Filter>Hermes</Filter>
734
+ </ClInclude>
735
+ <ClInclude Include="$(MSBuildThisFileDirectory)HermesSamplingProfiler.h">
736
+ <Filter>Hermes</Filter>
737
+ </ClInclude>
738
+ <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.h" />
739
+ <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.inc" />
740
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\JsiApi.h" />
741
+ <ClInclude Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.h" />
742
+ <ClInclude Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.h" />
743
+ <ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
739
744
  </ItemGroup>
740
745
  <ItemGroup>
741
746
  <None Include="$(MSBuildThisFileDirectory)tracing\rnw.wprp">
@@ -0,0 +1,71 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+
6
+ #include <V8JsiRuntime.h>
7
+ #include "V8JSIRuntimeHolder.h"
8
+
9
+ #include <atomic>
10
+ #include <queue>
11
+
12
+ using namespace facebook;
13
+ using namespace facebook::react;
14
+
15
+ namespace facebook {
16
+ namespace react {
17
+
18
+ class TaskRunnerAdapter : public v8runtime::JSITaskRunner {
19
+ public:
20
+ TaskRunnerAdapter(std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) : jsQueue_(std::move(jsQueue)) {}
21
+
22
+ void postTask(std::unique_ptr<v8runtime::JSITask> task) override {
23
+ std::shared_ptr<v8runtime::JSITask> shared_task(task.release());
24
+ jsQueue_->runOnQueue([shared_task2 = std::move(shared_task)]() { shared_task2->run(); });
25
+ }
26
+
27
+ private:
28
+ TaskRunnerAdapter(const TaskRunnerAdapter &) = delete;
29
+ TaskRunnerAdapter &operator=(const TaskRunnerAdapter &) = delete;
30
+
31
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue_;
32
+ };
33
+
34
+ facebook::react::JSIEngineOverride V8JSIRuntimeHolder::getRuntimeType() noexcept {
35
+ return facebook::react::JSIEngineOverride::V8;
36
+ }
37
+
38
+ std::shared_ptr<facebook::jsi::Runtime> V8JSIRuntimeHolder::getRuntime() noexcept {
39
+ std::call_once(once_flag_, [this]() { initRuntime(); });
40
+
41
+ if (!runtime_)
42
+ std::terminate();
43
+
44
+ // V8JsiRuntime is not thread safe as of now.
45
+ if (own_thread_id_ != std::this_thread::get_id())
46
+ std::terminate();
47
+
48
+ return runtime_;
49
+ }
50
+
51
+ void V8JSIRuntimeHolder::initRuntime() noexcept {
52
+ v8runtime::V8RuntimeArgs args{};
53
+
54
+ if (debuggerPort_ > 0)
55
+ args.inspectorPort = debuggerPort_;
56
+
57
+ args.flags.enableInspector = useDirectDebugger_;
58
+ args.flags.waitForDebugger = debuggerBreakOnNextLine_;
59
+ args.debuggerRuntimeName = debuggerRuntimeName_;
60
+
61
+ args.foreground_task_runner = std::make_shared<TaskRunnerAdapter>(jsQueue_);
62
+ args.preparedScriptStore = std::move(preparedScriptStore_);
63
+ args.flags.enableMultiThread = enableMultiThreadingSupport_;
64
+
65
+ runtime_ = v8runtime::makeV8Runtime(std::move(args));
66
+
67
+ own_thread_id_ = std::this_thread::get_id();
68
+ }
69
+
70
+ } // namespace react
71
+ } // namespace facebook
@@ -0,0 +1,56 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <DevSettings.h>
7
+
8
+ #include <JSI/RuntimeHolder.h>
9
+ #include <JSI/ScriptStore.h>
10
+
11
+ #include <Logging.h>
12
+
13
+ namespace facebook {
14
+ namespace react {
15
+
16
+ class V8JSIRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
17
+ public:
18
+ std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
19
+ facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
20
+
21
+ V8JSIRuntimeHolder(
22
+ std::shared_ptr<facebook::react::DevSettings> devSettings,
23
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
24
+ std::unique_ptr<facebook::jsi::ScriptStore> &&scriptStore,
25
+ std::shared_ptr<facebook::jsi::PreparedScriptStore> &&preparedScriptStore,
26
+ bool enableMultiThreadingSupport) noexcept
27
+ : useDirectDebugger_(devSettings->useDirectDebugger),
28
+ debuggerBreakOnNextLine_(devSettings->debuggerBreakOnNextLine),
29
+ debuggerPort_(devSettings->debuggerPort),
30
+ debuggerRuntimeName_(devSettings->debuggerRuntimeName),
31
+ jsQueue_(std::move(jsQueue)),
32
+ scriptStore_(std::move(scriptStore)),
33
+ preparedScriptStore_(std::move(preparedScriptStore)),
34
+ enableMultiThreadingSupport_(enableMultiThreadingSupport) {}
35
+
36
+ private:
37
+ void initRuntime() noexcept;
38
+
39
+ std::shared_ptr<facebook::jsi::Runtime> runtime_;
40
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue_;
41
+
42
+ std::unique_ptr<facebook::jsi::ScriptStore> scriptStore_;
43
+ std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore_;
44
+
45
+ std::once_flag once_flag_;
46
+ std::thread::id own_thread_id_;
47
+
48
+ uint16_t debuggerPort_;
49
+ bool useDirectDebugger_;
50
+ bool debuggerBreakOnNextLine_;
51
+ std::string debuggerRuntimeName_;
52
+ bool enableMultiThreadingSupport_;
53
+ };
54
+
55
+ } // namespace react
56
+ } // namespace facebook
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.72.11",
3
+ "version": "0.72.13",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",