react-native-windows 0.73.0-preview.3 → 0.73.0-preview.4

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.
@@ -121,6 +121,42 @@ bool ReactSettingsSnapshot::UseDeveloperSupport() const noexcept {
121
121
  return false;
122
122
  }
123
123
 
124
+ struct WeakRefPropertyBag : winrt::implements<WeakRefPropertyBag, winrt::Microsoft::ReactNative::IReactPropertyBag> {
125
+ WeakRefPropertyBag(winrt::Microsoft::ReactNative::IReactPropertyBag propertyBag) : m_wkPropBag(propertyBag) {}
126
+
127
+ IInspectable Get(winrt::Microsoft::ReactNative::IReactPropertyName const &name) noexcept {
128
+ if (auto propBag = m_wkPropBag.get()) {
129
+ return propBag.Get(name);
130
+ }
131
+ return nullptr;
132
+ }
133
+
134
+ IInspectable GetOrCreate(
135
+ winrt::Microsoft::ReactNative::IReactPropertyName const &name,
136
+ winrt::Microsoft::ReactNative::ReactCreatePropertyValue const &createValue) noexcept {
137
+ if (auto propBag = m_wkPropBag.get()) {
138
+ return propBag.GetOrCreate(name, createValue);
139
+ }
140
+ return nullptr;
141
+ }
142
+
143
+ IInspectable Set(winrt::Microsoft::ReactNative::IReactPropertyName const &name, IInspectable const &value) noexcept {
144
+ if (auto propBag = m_wkPropBag.get()) {
145
+ return propBag.Set(name, value);
146
+ }
147
+ return nullptr;
148
+ }
149
+
150
+ void CopyFrom(winrt::Microsoft::ReactNative::IReactPropertyBag const &value) noexcept {
151
+ if (auto propBag = m_wkPropBag.get()) {
152
+ return propBag.CopyFrom(value);
153
+ }
154
+ }
155
+
156
+ private:
157
+ winrt::weak_ref<winrt::Microsoft::ReactNative::IReactPropertyBag> m_wkPropBag;
158
+ };
159
+
124
160
  //=============================================================================================
125
161
  // ReactContext implementation
126
162
  //=============================================================================================
@@ -131,7 +167,7 @@ ReactContext::ReactContext(
131
167
  winrt::Microsoft::ReactNative::IReactNotificationService const &notifications) noexcept
132
168
  : m_reactInstance{std::move(reactInstance)},
133
169
  m_settings{Mso::Make<ReactSettingsSnapshot>(Mso::Copy(m_reactInstance))},
134
- m_properties{properties},
170
+ m_properties{winrt::make<WeakRefPropertyBag>(properties)},
135
171
  m_notifications{notifications} {}
136
172
 
137
173
  void ReactContext::Destroy() noexcept {
@@ -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"
@@ -253,6 +255,11 @@ ReactInstanceWin::ReactInstanceWin(
253
255
  m_whenDestroyedResult =
254
256
  m_whenDestroyed.AsFuture().Then<Mso::Executors::Inline>([whenLoaded = m_whenLoaded,
255
257
  onDestroyed = m_options.OnInstanceDestroyed,
258
+ // instance might be the only thing keeping
259
+ // the propertyBag alive.
260
+ // We want it to remain alive for the
261
+ // InstanceDestroyed callbacks
262
+ propBag = m_options.Properties,
256
263
  reactContext = m_reactContext]() noexcept {
257
264
  whenLoaded.TryCancel(); // It only has an effect if whenLoaded was not set before
258
265
  Microsoft::ReactNative::HermesRuntimeHolder::storeTo(ReactPropertyBag(reactContext->Properties()), nullptr);
@@ -491,7 +498,6 @@ void ReactInstanceWin::Initialize() noexcept {
491
498
 
492
499
  switch (m_options.JsiEngine()) {
493
500
  case JSIEngine::Hermes: {
494
- // TODO: Should we use UwpPreparedScriptStore?
495
501
  if (Microsoft::ReactNative::HasPackageIdentity()) {
496
502
  preparedScriptStore =
497
503
  std::make_unique<facebook::react::BasePreparedScriptStoreImpl>(getApplicationTempFolder());
@@ -529,8 +535,18 @@ void ReactInstanceWin::Initialize() noexcept {
529
535
  enableMultiThreadSupport = Microsoft::ReactNative::IsFabricEnabled(m_reactContext->Properties());
530
536
  #endif // USE_FABRIC
531
537
 
532
- devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
533
- devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
538
+ if (m_options.JsiEngineV8NodeApi()) {
539
+ devSettings->jsiRuntimeHolder = std::make_shared<Microsoft::ReactNative::V8RuntimeHolder>(
540
+ devSettings, m_jsMessageThread.Load(), std::move(preparedScriptStore), enableMultiThreadSupport);
541
+ } else {
542
+ devSettings->jsiRuntimeHolder = std::make_shared<facebook::react::V8JSIRuntimeHolder>(
543
+ devSettings,
544
+ m_jsMessageThread.Load(),
545
+ std::move(scriptStore),
546
+ std::move(preparedScriptStore),
547
+ enableMultiThreadSupport);
548
+ }
549
+
534
550
  break;
535
551
  }
536
552
  #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>
@@ -8,5 +8,13 @@
8
8
  Do not make any changes here unless it applies to ALL such projects.
9
9
  -->
10
10
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
11
+ <Target Name="EnsureUseHermes" BeforeTargets="PrepareForBuild" Condition="'$(UseHermes)' == 'false'">
12
+ <Warning Text="Property 'UseHermes' was set to 'false'. Projects built against Microsoft.ReactNative.Composition require Hermes and it will be set to true." />
13
+ </Target>
14
+
15
+ <PropertyGroup>
16
+ <UseHermes>true</UseHermes>
17
+ </PropertyGroup>
18
+
11
19
  <Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Common.props" />
12
20
  </Project>
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.73.0-preview.3</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.73.0-preview.4</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>73</ReactNativeWindowsMinor>
16
16
  <ReactNativeWindowsPatch>0</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>727387f5fd3b039d39d3b58d600b08204690b6e7</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>cbdae1dd7cb7fd0ce521e3812e81d8c646d9ca6a</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -12,7 +12,7 @@
12
12
  <PropertyGroup>
13
13
  <JsEnginePropsDefined>true</JsEnginePropsDefined>
14
14
  <!-- Enabling this will (1) Include hermes glues in the Microsoft.ReactNative binaries AND (2) Make hermes the default engine -->
15
- <UseHermes Condition="'$(UseHermes)' == ''">false</UseHermes>
15
+ <UseHermes Condition="'$(UseHermes)' == ''">true</UseHermes>
16
16
  <!-- This will be true if (1) the client want to use hermes by setting UseHermes to true OR (2) We are building for UWP where dynamic switching is enabled -->
17
17
  <HermesVersion Condition="'$(HermesVersion)' == ''">0.1.15</HermesVersion>
18
18
  <HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgMicrosoft_JavaScript_Hermes)')">$(PkgMicrosoft_JavaScript_Hermes)</HermesPackage>
@@ -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
 
@@ -241,8 +241,8 @@
241
241
  <!-- Reenable this task if we need to temporarily replace any folly files for fixes, while we wait for PRs to land in folly -->
242
242
  <Target Name="ApplyReactCommonTemporaryPatch" BeforeTargets="PrepareForBuild" DependsOnTargets="UnzipNodeApiJsi">
243
243
  <ItemGroup>
244
- <NodeApiJsiFiles Include="$([MSBuild]::NormalizePath($(NodeApiJsiDir)..))\jsi\**\*.*" />
245
- </ItemGroup>
244
+ <NodeApiJsiFiles Include="$([MSBuild]::NormalizePath($(NodeApiJsiDir)))\jsi\**\*.*" />
245
+ </ItemGroup>
246
246
  <Copy DestinationFiles="@(NodeApiJsiFiles->'$(ReactNativeDir)\ReactCommon\jsi\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(NodeApiJsiFiles)" />
247
247
  <Copy DestinationFiles="@(TemporaryReactCommonPatchFiles->'$(ReactNativeDir)\ReactCommon\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(TemporaryReactCommonPatchFiles)" />
248
248
  </Target>
@@ -650,10 +650,10 @@ jsi::Value UIManagerBinding::get(
650
650
 
651
651
  onSuccessFunction.call(
652
652
  runtime,
653
- {jsi::Value{runtime, (double)frame.origin.x},
654
- jsi::Value{runtime, (double)frame.origin.y},
655
- jsi::Value{runtime, (double)frame.size.width},
656
- jsi::Value{runtime, (double)frame.size.height}});
653
+ {jsi::Value{(double)frame.origin.x},
654
+ jsi::Value{(double)frame.origin.y},
655
+ jsi::Value{(double)frame.size.width},
656
+ jsi::Value{(double)frame.size.height}});
657
657
  return jsi::Value::undefined();
658
658
  });
659
659
  }
@@ -695,12 +695,12 @@ jsi::Value UIManagerBinding::get(
695
695
  auto frame = layoutMetrics.frame;
696
696
  onSuccessFunction.call(
697
697
  runtime,
698
- {jsi::Value{runtime, (double)originRelativeToParent.x},
699
- jsi::Value{runtime, (double)originRelativeToParent.y},
700
- jsi::Value{runtime, (double)frame.size.width},
701
- jsi::Value{runtime, (double)frame.size.height},
702
- jsi::Value{runtime, (double)frame.origin.x},
703
- jsi::Value{runtime, (double)frame.origin.y}});
698
+ {jsi::Value{(double)originRelativeToParent.x},
699
+ jsi::Value{(double)originRelativeToParent.y},
700
+ jsi::Value{(double)frame.size.width},
701
+ jsi::Value{(double)frame.size.height},
702
+ jsi::Value{(double)frame.origin.x},
703
+ jsi::Value{(double)frame.origin.y}});
704
704
  return jsi::Value::undefined();
705
705
  });
706
706
  }
@@ -736,10 +736,10 @@ jsi::Value UIManagerBinding::get(
736
736
  auto frame = layoutMetrics.frame;
737
737
  onSuccessFunction.call(
738
738
  runtime,
739
- {jsi::Value{runtime, (double)frame.origin.x},
740
- jsi::Value{runtime, (double)frame.origin.y},
741
- jsi::Value{runtime, (double)frame.size.width},
742
- jsi::Value{runtime, (double)frame.size.height}});
739
+ {jsi::Value{(double)frame.origin.x},
740
+ jsi::Value{(double)frame.origin.y},
741
+ jsi::Value{(double)frame.size.width},
742
+ jsi::Value{(double)frame.size.height}});
743
743
  return jsi::Value::undefined();
744
744
  });
745
745
  }
@@ -886,10 +886,10 @@ jsi::Value UIManagerBinding::get(
886
886
  auto frame = layoutMetrics.frame;
887
887
  return jsi::Array::createWithElements(
888
888
  runtime,
889
- jsi::Value{runtime, (double)frame.origin.x},
890
- jsi::Value{runtime, (double)frame.origin.y},
891
- jsi::Value{runtime, (double)frame.size.width},
892
- jsi::Value{runtime, (double)frame.size.height});
889
+ jsi::Value{(double)frame.origin.x},
890
+ jsi::Value{(double)frame.origin.y},
891
+ jsi::Value{(double)frame.size.width},
892
+ jsi::Value{(double)frame.size.height});
893
893
  });
894
894
  }
895
895
 
@@ -1150,8 +1150,8 @@ jsi::Value UIManagerBinding::get(
1150
1150
  return jsi::Array::createWithElements(
1151
1151
  runtime,
1152
1152
  (*newestParentOfShadowNode).getInstanceHandle(runtime),
1153
- jsi::Value{runtime, (double)offsetTop},
1154
- jsi::Value{runtime, (double)offsetLeft});
1153
+ jsi::Value{(double)offsetTop},
1154
+ jsi::Value{(double)offsetLeft});
1155
1155
  });
1156
1156
  }
1157
1157
 
@@ -1217,12 +1217,8 @@ jsi::Value UIManagerBinding::get(
1217
1217
 
1218
1218
  return jsi::Array::createWithElements(
1219
1219
  runtime,
1220
- jsi::Value{
1221
- runtime,
1222
- scrollPosition.x == 0 ? 0 : (double)-scrollPosition.x},
1223
- jsi::Value{
1224
- runtime,
1225
- scrollPosition.y == 0 ? 0 : (double)-scrollPosition.y});
1220
+ jsi::Value{scrollPosition.x == 0 ? 0 : (double)-scrollPosition.x},
1221
+ jsi::Value{scrollPosition.y == 0 ? 0 : (double)-scrollPosition.y});
1226
1222
  });
1227
1223
  }
1228
1224
 
@@ -1291,8 +1287,8 @@ jsi::Value UIManagerBinding::get(
1291
1287
 
1292
1288
  return jsi::Array::createWithElements(
1293
1289
  runtime,
1294
- jsi::Value{runtime, std::round(scrollSize.width)},
1295
- jsi::Value{runtime, std::round(scrollSize.height)});
1290
+ jsi::Value{(double)std::round(scrollSize.width)},
1291
+ jsi::Value{(double)std::round(scrollSize.height)});
1296
1292
  });
1297
1293
  }
1298
1294
 
@@ -1343,8 +1339,8 @@ jsi::Value UIManagerBinding::get(
1343
1339
 
1344
1340
  return jsi::Array::createWithElements(
1345
1341
  runtime,
1346
- jsi::Value{runtime, std::round(paddingFrame.size.width)},
1347
- jsi::Value{runtime, std::round(paddingFrame.size.height)});
1342
+ jsi::Value{(double)std::round(paddingFrame.size.width)},
1343
+ jsi::Value{(double)std::round(paddingFrame.size.height)});
1348
1344
  });
1349
1345
  }
1350
1346
 
@@ -1395,10 +1391,10 @@ jsi::Value UIManagerBinding::get(
1395
1391
 
1396
1392
  return jsi::Array::createWithElements(
1397
1393
  runtime,
1398
- jsi::Value{runtime, std::round(layoutMetrics.borderWidth.top)},
1399
- jsi::Value{runtime, std::round(layoutMetrics.borderWidth.right)},
1400
- jsi::Value{runtime, std::round(layoutMetrics.borderWidth.bottom)},
1401
- jsi::Value{runtime, std::round(layoutMetrics.borderWidth.left)});
1394
+ jsi::Value{(double)std::round(layoutMetrics.borderWidth.top)},
1395
+ jsi::Value{(double)std::round(layoutMetrics.borderWidth.right)},
1396
+ jsi::Value{(double)std::round(layoutMetrics.borderWidth.bottom)},
1397
+ jsi::Value{(double)std::round(layoutMetrics.borderWidth.left)});
1402
1398
  });
1403
1399
  }
1404
1400
 
@@ -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));
@@ -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));
@@ -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
@@ -223,6 +223,9 @@
223
223
  <ClCompile Include="$(MSBuildThisFileDirectory)TurboModuleManager.cpp" />
224
224
  <ClCompile Include="$(MSBuildThisFileDirectory)Utils.cpp" />
225
225
  <ClCompile Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.cpp" />
226
+ <ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp">
227
+ <ExcludedFromBuild Condition="'$(UseV8)' != 'true'">true</ExcludedFromBuild>
228
+ </ClCompile>
226
229
  </ItemGroup>
227
230
  <ItemGroup>
228
231
  <ClInclude Include="$(MSBuildThisFileDirectory)..\codegen\react\components\rnwcore\EventEmitters.h" />
@@ -396,6 +399,7 @@
396
399
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils.h" />
397
400
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils\CppWinrtLessExceptions.h" />
398
401
  <ClInclude Include="$(MSBuildThisFileDirectory)Utils\WinRTConversions.h" />
402
+ <ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
399
403
  <ClInclude Include="$(MSBuildThisFileDirectory)WebSocketJSExecutorFactory.h" />
400
404
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Modules\DevSettingsModule.cpp" />
401
405
  <ClCompile Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\Modules\ReactRootViewTagGenerator.cpp" />
@@ -270,6 +270,7 @@
270
270
  <ClCompile Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.cpp" />
271
271
  <ClCompile Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.cpp" />
272
272
  <ClCompile Include="$(MSBuildThisFileDirectory)Hasher.cpp" />
273
+ <ClCompile Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.cpp" />
273
274
  <ClCompile Include="$(MSBuildThisFileDirectory)Networking\DefaultBlobResource.cpp">
274
275
  <Filter>Source Files\Networking</Filter>
275
276
  </ClCompile>
@@ -331,6 +332,9 @@
331
332
  <Filter Include="Source Files\Networking">
332
333
  <UniqueIdentifier>{71196e04-aca0-48d6-99e4-f418c957b50f}</UniqueIdentifier>
333
334
  </Filter>
335
+ <Filter Include="Hermes">
336
+ <UniqueIdentifier>{b32590e6-ae3d-4388-ab98-767345ce38c9}</UniqueIdentifier>
337
+ </Filter>
334
338
  <Filter Include="Header Files\Fabric">
335
339
  <UniqueIdentifier>{e045612e-bca3-4844-bce8-e75f83e89e05}</UniqueIdentifier>
336
340
  </Filter>
@@ -728,17 +732,6 @@
728
732
  <ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\platform\react\renderer\core\graphicsConversions.h">
729
733
  <Filter>Header Files\Fabric\platform\react\renderer\core</Filter>
730
734
  </ClInclude>
731
- <ClInclude Include="$(MSBuildThisFileDirectory)HermesRuntimeHolder.h">
732
- <Filter>Hermes</Filter>
733
- </ClInclude>
734
- <ClInclude Include="$(MSBuildThisFileDirectory)HermesSamplingProfiler.h">
735
- <Filter>Hermes</Filter>
736
- </ClInclude>
737
- <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.h" />
738
- <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.inc" />
739
- <ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\JsiApi.h" />
740
- <ClInclude Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.h" />
741
- <ClInclude Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.h" />
742
735
  <ClInclude Include="$(MSBuildThisFileDirectory)Modules\WebSocketTurboModule.h">
743
736
  <Filter>Header Files\Modules</Filter>
744
737
  </ClInclude>
@@ -756,6 +749,18 @@
756
749
  <ClInclude Include="$(MSBuildThisFileDirectory)Modules\BlobCollector.h">
757
750
  <Filter>Header Files\Modules</Filter>
758
751
  </ClInclude>
752
+ <ClInclude Include="$(MSBuildThisFileDirectory)HermesRuntimeHolder.h">
753
+ <Filter>Hermes</Filter>
754
+ </ClInclude>
755
+ <ClInclude Include="$(MSBuildThisFileDirectory)HermesSamplingProfiler.h">
756
+ <Filter>Hermes</Filter>
757
+ </ClInclude>
758
+ <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.h" />
759
+ <ClInclude Include="$(NodeApiJsiDir)src\ApiLoaders\HermesApi.inc" />
760
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\JsiApi.h" />
761
+ <ClInclude Include="$(MSBuildThisFileDirectory)JSI\V8RuntimeHolder.h" />
762
+ <ClInclude Include="$(MSBuildThisFileDirectory)SafeLoadLibrary.h" />
763
+ <ClInclude Include="$(MSBuildThisFileDirectory)V8JSIRuntimeHolder.h" />
759
764
  </ItemGroup>
760
765
  <ItemGroup>
761
766
  <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/metro.config.js CHANGED
@@ -19,4 +19,4 @@ if (
19
19
  }
20
20
 
21
21
  const {makeMetroConfig} = require('@rnw-scripts/metro-dev-config');
22
- module.exports = makeMetroConfig();
22
+ module.exports = makeMetroConfig({projectRoot: __dirname});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.73.0-preview.3",
3
+ "version": "0.73.0-preview.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "@react-native-community/cli": "12.0.0-alpha.17",
27
27
  "@react-native-community/cli-platform-android": "12.0.0-alpha.17",
28
28
  "@react-native-community/cli-platform-ios": "12.0.0-alpha.17",
29
- "@react-native-windows/cli": "0.73.0-preview.1",
29
+ "@react-native-windows/cli": "0.73.0-preview.2",
30
30
  "@react-native/assets": "1.0.0",
31
31
  "@react-native/assets-registry": "^0.73.1",
32
32
  "@react-native/codegen": "^0.73.1",
@@ -2,7 +2,6 @@
2
2
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
3
 
4
4
  <PropertyGroup Label="Microsoft.ReactNative Experimental Features">
5
- <UseHermes>true</UseHermes>
6
5
  <UseFabric>true</UseFabric>
7
6
  <UseWinUI3>false</UseWinUI3>
8
7
 
@@ -20,7 +20,7 @@ function makeGenerateWindowsWrapper(
20
20
  })`
21
21
  : `React Native Windows Application (Old Arch, UWP, ${
22
22
  language === 'cs' ? 'C#' : 'C++'
23
- }, Chakra)`;
23
+ }, Hermes)`;
24
24
  const description =
25
25
  projectType === 'lib'
26
26
  ? `A RNW module written in ${
@@ -28,7 +28,7 @@ function makeGenerateWindowsWrapper(
28
28
  }, targeting UWP and RN's old architecture.`
29
29
  : `A RNW app written in ${
30
30
  language === 'cs' ? 'C#' : 'C++'
31
- }, targeting UWP and RN's old architecture, with the Chakra JS engine.`;
31
+ }, targeting UWP and RN's old architecture, with the Hermes JS engine.`;
32
32
 
33
33
  const postInstall = async (config = {}, options = {}) => {
34
34
  const experimentalFeatures = config?.project?.windows?.experimentalFeatures;
@@ -40,7 +40,7 @@ function makeGenerateWindowsWrapper(
40
40
  experimentalNuGetDependency:
41
41
  experimentalFeatures?.UseExperimentalNuget ?? false,
42
42
  useWinUI3: experimentalFeatures?.UseWinUI3 ?? false,
43
- useHermes: experimentalFeatures?.UseHermes ?? false,
43
+ useHermes: experimentalFeatures?.UseHermes ?? true,
44
44
  useDevMode: false,
45
45
  verbose: !!options.logging,
46
46
  telemetry: !!options.telemetry,
@@ -12,4 +12,4 @@
12
12
 
13
13
  const {makeGenerateWindowsWrapper} = require('../generateWrapper');
14
14
 
15
- module.exports = makeGenerateWindowsWrapper('cpp', 'lib', false);
15
+ module.exports = makeGenerateWindowsWrapper('cpp', 'lib');