react-native-windows 0.69.17 → 0.69.19

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.
@@ -67,7 +67,7 @@
67
67
 
68
68
  <PropertyGroup Label="NuGet" Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
69
69
  <!--See https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-target-->
70
- <RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</RestoreUseStaticGraphEvaluation>
70
+ <RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true' AND '$(DisableRestoreUseStaticGraphEvaluation)' != 'true'">true</RestoreUseStaticGraphEvaluation>
71
71
  </PropertyGroup>
72
72
 
73
73
  </Project>
@@ -124,4 +124,8 @@ void ReactDispatcher::InvokeElsePost(Mso::DispatchTask &&task) const noexcept {
124
124
  return jsThreadDispatcherProperty;
125
125
  }
126
126
 
127
+ /*static*/ IReactDispatcher ReactDispatcher::GetJSDispatcher(IReactPropertyBag const &properties) noexcept {
128
+ return properties.Get(JSDispatcherProperty()).try_as<IReactDispatcher>();
129
+ }
130
+
127
131
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -38,6 +38,7 @@ struct ReactDispatcher : implements<ReactDispatcher, IReactDispatcher, Mso::Reac
38
38
  static void SetUIThreadDispatcher(IReactPropertyBag const &properties) noexcept;
39
39
 
40
40
  static IReactPropertyName JSDispatcherProperty() noexcept;
41
+ static IReactDispatcher GetJSDispatcher(IReactPropertyBag const &properties) noexcept;
41
42
 
42
43
  void Post(Mso::DispatchTask &&task) const noexcept override;
43
44
  void InvokeElsePost(Mso::DispatchTask &&task) const noexcept override;
@@ -250,6 +250,7 @@ ReactInstanceWin::ReactInstanceWin(
250
250
  onDestroyed = m_options.OnInstanceDestroyed,
251
251
  reactContext = m_reactContext]() noexcept {
252
252
  whenLoaded.TryCancel(); // It only has an effect if whenLoaded was not set before
253
+ facebook::react::HermesRuntimeHolder::storeTo(ReactPropertyBag(reactContext->Properties()), nullptr);
253
254
  if (onDestroyed) {
254
255
  onDestroyed.Get()->Invoke(reactContext);
255
256
  }
@@ -463,10 +464,14 @@ void ReactInstanceWin::Initialize() noexcept {
463
464
  std::unique_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore = nullptr;
464
465
 
465
466
  switch (m_options.JsiEngine()) {
466
- case JSIEngine::Hermes:
467
- devSettings->jsiRuntimeHolder =
467
+ case JSIEngine::Hermes: {
468
+ auto hermesRuntimeHolder =
468
469
  std::make_shared<facebook::react::HermesRuntimeHolder>(devSettings, m_jsMessageThread.Load());
470
+ facebook::react::HermesRuntimeHolder::storeTo(
471
+ ReactPropertyBag(m_reactContext->Properties()), hermesRuntimeHolder);
472
+ devSettings->jsiRuntimeHolder = hermesRuntimeHolder;
469
473
  break;
474
+ }
470
475
  case JSIEngine::V8:
471
476
  #if defined(USE_V8)
472
477
  {
@@ -18,7 +18,7 @@ struct ReactId {
18
18
  };
19
19
 
20
20
  template <typename T>
21
- inline typename T asEnum(winrt::Microsoft::ReactNative::JSValue const &obj) {
21
+ inline T asEnum(winrt::Microsoft::ReactNative::JSValue const &obj) {
22
22
  return static_cast<T>(obj.AsInt64());
23
23
  }
24
24
 
@@ -82,16 +82,14 @@ bool ControlViewManager::UpdateProperty(
82
82
  }
83
83
  } else if (propertyName == "focusable") {
84
84
  if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
85
- IsFocusable(propertyValue.AsBoolean());
86
- control.IsTabStop(propertyValue.AsBoolean());
85
+ nodeToUpdate->IsFocusable(propertyValue.AsBoolean());
87
86
  } else if (propertyValue.IsNull()) {
88
- control.ClearValue(TAB_STOP_PROPERTY());
89
- IsFocusable(false);
87
+ nodeToUpdate->IsFocusable(false);
90
88
  }
91
89
  } else {
92
90
  if (propertyName == "accessible") {
93
91
  if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
94
- IsAccessible(propertyValue.AsBoolean());
92
+ nodeToUpdate->IsAccessible(propertyValue.AsBoolean());
95
93
  }
96
94
  }
97
95
  ret = Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue);
@@ -108,11 +106,13 @@ bool ControlViewManager::UpdateProperty(
108
106
  void ControlViewManager::OnPropertiesUpdated(ShadowNodeBase *node) {
109
107
  auto control(node->GetView().as<xaml::Controls::Control>());
110
108
 
111
- if (IsAccessible() != IsFocusable()) {
112
- control.IsTabStop(false);
113
- xaml::Automation::AutomationProperties::SetAccessibilityView(
114
- control, xaml::Automation::Peers::AccessibilityView::Raw);
115
- }
109
+ // If developer specifies either the accessible and focusable prop to be false
110
+ // remove accessibility and keyboard focus for component.
111
+ const auto isTabStop = (node->IsAccessible() && node->IsFocusable());
112
+ const auto accessibilityView =
113
+ isTabStop ? xaml::Automation::Peers::AccessibilityView::Content : xaml::Automation::Peers::AccessibilityView::Raw;
114
+ control.IsTabStop(isTabStop);
115
+ xaml::Automation::AutomationProperties::SetAccessibilityView(control, accessibilityView);
116
116
  }
117
117
 
118
118
  void ControlViewManager::OnViewCreated(XamlView view) {
@@ -123,17 +123,4 @@ void ControlViewManager::OnViewCreated(XamlView view) {
123
123
  }
124
124
  }
125
125
 
126
- void ControlViewManager::IsAccessible(bool accessible) {
127
- m_isAccessible = accessible;
128
- }
129
- bool ControlViewManager::IsAccessible() {
130
- return m_isAccessible;
131
- }
132
- void ControlViewManager::IsFocusable(bool focusable) {
133
- m_isFocusable = focusable;
134
- }
135
- bool ControlViewManager::IsFocusable() {
136
- return m_isFocusable;
137
- }
138
-
139
126
  } // namespace Microsoft::ReactNative
@@ -26,15 +26,6 @@ class REACTWINDOWS_EXPORT ControlViewManager : public FrameworkElementViewManage
26
26
  void OnViewCreated(XamlView view) override;
27
27
 
28
28
  void OnPropertiesUpdated(ShadowNodeBase *node) override;
29
-
30
- private:
31
- void IsAccessible(bool accessible);
32
- bool IsAccessible();
33
- void IsFocusable(bool focusable);
34
- bool IsFocusable();
35
-
36
- bool m_isAccessible = true;
37
- bool m_isFocusable = true;
38
29
  };
39
30
 
40
31
  } // namespace Microsoft::ReactNative
@@ -119,7 +119,7 @@ void DevMenuManager::CreateAndShowUI() noexcept {
119
119
 
120
120
  std::ostringstream os;
121
121
  if (Microsoft::ReactNative::HermesSamplingProfiler::IsStarted()) {
122
- os << "Hermes Sampling profiler is running.. !";
122
+ os << "Hermes Sampling profiler is running!";
123
123
  } else {
124
124
  os << "Click to start.";
125
125
  }
@@ -210,9 +210,9 @@ void DevMenuManager::CreateAndShowUI() noexcept {
210
210
  if (auto strongThis = wkThis.lock()) {
211
211
  strongThis->Hide();
212
212
  if (!Microsoft::ReactNative::HermesSamplingProfiler::IsStarted()) {
213
- Microsoft::ReactNative::HermesSamplingProfiler::Start();
213
+ Microsoft::ReactNative::HermesSamplingProfiler::Start(strongThis->m_context);
214
214
  } else {
215
- auto traceFilePath = co_await Microsoft::ReactNative::HermesSamplingProfiler::Stop();
215
+ auto traceFilePath = co_await Microsoft::ReactNative::HermesSamplingProfiler::Stop(strongThis->m_context);
216
216
  auto uiDispatcher =
217
217
  React::implementation::ReactDispatcher::GetUIDispatcher(strongThis->m_context->Properties());
218
218
  uiDispatcher.Post([traceFilePath]() {
@@ -166,4 +166,17 @@ void ShadowNodeBase::RedBox(const std::string &message) const noexcept {
166
166
  GetViewManager()->GetReactContext().CallJSFunction("RCTLog", "logToConsole", folly::dynamic::array("error", message));
167
167
  }
168
168
 
169
+ void ShadowNodeBase::IsAccessible(bool accessible) {
170
+ m_isAccessible = accessible;
171
+ }
172
+ bool ShadowNodeBase::IsAccessible() {
173
+ return m_isAccessible;
174
+ }
175
+ void ShadowNodeBase::IsFocusable(bool focusable) {
176
+ m_isFocusable = focusable;
177
+ }
178
+ bool ShadowNodeBase::IsFocusable() {
179
+ return m_isFocusable;
180
+ }
181
+
169
182
  } // namespace Microsoft::ReactNative
@@ -115,10 +115,17 @@ struct REACTWINDOWS_EXPORT ShadowNodeBase : public ShadowNode {
115
115
  return m_onMouseEnterRegistered || m_onMouseLeaveRegistered;
116
116
  }
117
117
 
118
+ void IsAccessible(bool accessible);
119
+ bool IsAccessible();
120
+ void IsFocusable(bool focusable);
121
+ bool IsFocusable();
122
+
118
123
  protected:
119
124
  XamlView m_view;
120
125
  bool m_updating = false;
121
126
  comp::CompositionPropertySet m_transformPS{nullptr};
127
+ bool m_isFocusable = true;
128
+ bool m_isAccessible = true;
122
129
 
123
130
  public:
124
131
  double m_padding[(int)ShadowEdges::CountEdges] = INIT_UNDEFINED_EDGES;
@@ -44,6 +44,8 @@ class ViewShadowNode : public ShadowNodeBase {
44
44
  Super::createView(props);
45
45
 
46
46
  auto panel = GetViewPanel();
47
+ IsAccessible(false);
48
+ IsFocusable(false);
47
49
 
48
50
  DynamicAutomationProperties::SetAccessibilityInvokeEventHandler(panel, [=]() {
49
51
  if (OnClick())
@@ -118,24 +120,6 @@ class ViewShadowNode : public ShadowNodeBase {
118
120
  m_onClick = isSet;
119
121
  }
120
122
 
121
- bool IsFocusable() const {
122
- return m_isFocusable;
123
- }
124
- void IsFocusable(bool isFocusable) {
125
- m_isFocusable = isFocusable;
126
-
127
- if (IsControl())
128
- GetControl().IsTabStop(m_isFocusable);
129
- }
130
-
131
- bool IsAccessible() const {
132
- return m_isAccessible;
133
- }
134
-
135
- void IsAccessible(bool isAccessible) {
136
- m_isAccessible = isAccessible;
137
- }
138
-
139
123
  bool IsHitTestBrushRequired() const {
140
124
  return IsRegisteredForMouseEvents();
141
125
  }
@@ -259,8 +243,6 @@ class ViewShadowNode : public ShadowNodeBase {
259
243
 
260
244
  bool m_enableFocusRing = true;
261
245
  bool m_onClick = false;
262
- bool m_isFocusable = false;
263
- bool m_isAccessible = false;
264
246
  int32_t m_tabIndex = std::numeric_limits<std::int32_t>::max();
265
247
 
266
248
  xaml::Controls::ContentControl::GotFocus_revoker m_contentControlGotFocusRevoker{};
@@ -408,20 +390,16 @@ bool ViewViewManager::UpdateProperty(
408
390
  UpdateCornerRadiusOnElement(nodeToUpdate, pPanel);
409
391
  } else if (TryUpdateMouseEvents(nodeToUpdate, propertyName, propertyValue)) {
410
392
  } else if (propertyName == "onClick") {
411
- pViewShadowNode->OnClick(!propertyValue.IsNull() && propertyValue.AsBoolean());
393
+ pViewShadowNode->OnClick(propertyValue.AsBoolean());
412
394
  } else if (propertyName == "overflow") {
413
395
  if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::String) {
414
396
  bool clipChildren = propertyValue.AsString() == "hidden";
415
397
  pPanel.ClipChildren(clipChildren);
416
398
  }
417
399
  } else if (propertyName == "focusable") {
418
- if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean)
419
- pViewShadowNode->IsFocusable(propertyValue.AsBoolean());
400
+ pViewShadowNode->IsFocusable(propertyValue.AsBoolean());
420
401
  } else if (propertyName == "enableFocusRing") {
421
- if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean)
422
- pViewShadowNode->EnableFocusRing(propertyValue.AsBoolean());
423
- else if (propertyValue.IsNull())
424
- pViewShadowNode->EnableFocusRing(false);
402
+ pViewShadowNode->EnableFocusRing(propertyValue.AsBoolean());
425
403
  } else if (propertyName == "tabIndex") {
426
404
  auto tabIndex = propertyValue.AsInt64();
427
405
  if (tabIndex == static_cast<int32_t>(tabIndex)) {
@@ -431,9 +409,7 @@ bool ViewViewManager::UpdateProperty(
431
409
  }
432
410
  } else {
433
411
  if (propertyName == "accessible") {
434
- if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
435
- pViewShadowNode->IsAccessible(propertyValue.AsBoolean());
436
- }
412
+ pViewShadowNode->IsAccessible(propertyValue.AsBoolean());
437
413
  }
438
414
  ret = Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue);
439
415
  }
@@ -458,7 +434,10 @@ void ViewViewManager::OnPropertiesUpdated(ShadowNodeBase *node) {
458
434
  // keep it around, so not adding that code (yet).
459
435
  }
460
436
 
461
- bool shouldBeControl = viewShadowNode->IsFocusable();
437
+ // If component is focusable, it should be a ViewControl.
438
+ // If component is a View with accessible set to true, the component should be focusable, thus we need a ViewControl.
439
+ bool shouldBeControl =
440
+ (viewShadowNode->IsFocusable() || (viewShadowNode->IsAccessible() && !viewShadowNode->OnClick()));
462
441
  if (auto view = viewShadowNode->GetView().try_as<xaml::UIElement>()) {
463
442
  // If we have DynamicAutomationProperties, we need a ViewControl with a
464
443
  // DynamicAutomationPeer
@@ -468,6 +447,7 @@ void ViewViewManager::OnPropertiesUpdated(ShadowNodeBase *node) {
468
447
  panel.FinalizeProperties();
469
448
 
470
449
  TryUpdateView(viewShadowNode, panel, shouldBeControl);
450
+ SyncFocusableAndAccessible(viewShadowNode, shouldBeControl);
471
451
  }
472
452
 
473
453
  void ViewViewManager::TryUpdateView(
@@ -578,11 +558,23 @@ void ViewViewManager::TryUpdateView(
578
558
 
579
559
  if (useControl)
580
560
  pViewShadowNode->GetControl().Content(visualRoot);
561
+ }
581
562
 
582
- if (useControl && pViewShadowNode->IsAccessible() != pViewShadowNode->IsFocusable()) {
583
- pViewShadowNode->GetControl().IsTabStop(false);
584
- xaml::Automation::AutomationProperties::SetAccessibilityView(
585
- pViewShadowNode->GetControl(), xaml::Automation::Peers::AccessibilityView::Raw);
563
+ void ViewViewManager::SyncFocusableAndAccessible(ViewShadowNode *pViewShadowNode, bool useControl) {
564
+ // If developer specifies either the accessible and focusable prop to be false
565
+ // remove accessibility and keyboard focus for component. Exception is made
566
+ // for case where a View with undefined onPress is specified, where
567
+ // component gains accessibility focus when either the accessible and focusable prop are true.
568
+ if (useControl) {
569
+ const auto isFocusable = pViewShadowNode->IsFocusable();
570
+ const auto isAccessible = pViewShadowNode->IsAccessible();
571
+ const auto isPressable = pViewShadowNode->OnClick();
572
+ const auto isTabStop =
573
+ (isPressable && isFocusable && isAccessible) || (!isPressable && (isFocusable || isAccessible));
574
+ const auto accessibilityView = isTabStop ? xaml::Automation::Peers::AccessibilityView::Content
575
+ : xaml::Automation::Peers::AccessibilityView::Raw;
576
+ pViewShadowNode->GetControl().IsTabStop(isTabStop);
577
+ xaml::Automation::AutomationProperties::SetAccessibilityView(pViewShadowNode->GetControl(), accessibilityView);
586
578
  }
587
579
  }
588
580
 
@@ -41,6 +41,7 @@ class ViewViewManager : public FrameworkElementViewManager {
41
41
 
42
42
  XamlView CreateViewCore(int64_t tag, const winrt::Microsoft::ReactNative::JSValueObject &) override;
43
43
  void TryUpdateView(ViewShadowNode *viewShadowNode, winrt::Microsoft::ReactNative::ViewPanel &pPanel, bool useControl);
44
+ void SyncFocusableAndAccessible(ViewShadowNode *viewShadowNode, bool useControl);
44
45
 
45
46
  xaml::Media::SolidColorBrush EnsureTransparentBrush();
46
47
 
@@ -24,11 +24,6 @@
24
24
  "Microsoft.SourceLink.Common": "1.0.0"
25
25
  }
26
26
  },
27
- "boost": {
28
- "type": "Transitive",
29
- "resolved": "1.76.0",
30
- "contentHash": "p+w3YvNdXL8Cu9Fzrmexssu0tZbWxuf6ywsQqHjDlKFE5ojXHof1HIyMC3zDLfLnh80dIeFcEUAuR2Asg/XHRA=="
31
- },
32
27
  "Microsoft.Build.Tasks.Git": {
33
28
  "type": "Transitive",
34
29
  "resolved": "1.0.0",
@@ -58,41 +53,21 @@
58
53
  "Microsoft.NETCore.Platforms": {
59
54
  "type": "Transitive",
60
55
  "resolved": "2.1.0",
61
- "contentHash": "GmkKfoyerqmsHMn7OZj0AKpcBabD+GaafqphvX2Mw406IwiJRy1pKcKqdCfKJfYmkRyJ6+e+RaUylgdJoDa1jQ=="
56
+ "contentHash": "ok+RPAtESz/9MUXeIEz6Lv5XAGQsaNmEYXMsgVALj4D7kqC8gveKWXWXbufLySR2fWrwZf8smyN5RmHu0e4BHA=="
62
57
  },
63
58
  "Microsoft.SourceLink.Common": {
64
59
  "type": "Transitive",
65
60
  "resolved": "1.0.0",
66
61
  "contentHash": "G8DuQY8/DK5NN+3jm5wcMcd9QYD90UV7MiLmdljSJixi3U/vNaeBKmmXUqI4DJCOeWizIUEh4ALhSt58mR+5eg=="
67
62
  },
68
- "Microsoft.UI.Xaml": {
69
- "type": "Transitive",
70
- "resolved": "2.7.0",
71
- "contentHash": "dB4im13tfmMgL/V3Ei+3kD2rUF+/lTxAmR4gjJ45l577eljHfdo/KUrxpq/3I1Vp6e5GCDG1evDaEGuDxypLMg=="
72
- },
73
- "Microsoft.Windows.CppWinRT": {
74
- "type": "Transitive",
75
- "resolved": "2.0.211028.7",
76
- "contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg=="
77
- },
78
- "Microsoft.Windows.SDK.BuildTools": {
79
- "type": "Transitive",
80
- "resolved": "10.0.22000.194",
81
- "contentHash": "4L0P3zqut466SIqT3VBeLTNUQTxCBDOrTRymRuROCRJKazcK7ibLz9yAO1nKWRt50ttCj39oAa2Iuz9ZTDmLlg=="
82
- },
83
63
  "NETStandard.Library": {
84
64
  "type": "Transitive",
85
65
  "resolved": "2.0.3",
86
- "contentHash": "548M6mnBSJWxsIlkQHfbzoYxpiYFXZZSL00p4GHYv8PkiqFBnnT68mW5mGEsA/ch9fDO9GkPgkFQpWiXZN7mAQ==",
66
+ "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
87
67
  "dependencies": {
88
68
  "Microsoft.NETCore.Platforms": "1.1.0"
89
69
  }
90
70
  },
91
- "ReactNative.Hermes.Windows": {
92
- "type": "Transitive",
93
- "resolved": "0.11.0-ms.6",
94
- "contentHash": "WAVLsSZBV4p/3hNC3W67su7xu3f/ZMSKxu0ON7g2GaKRbkJmH0Qyif1IlzcJwtvR48kuOdfgPu7Bgtz3AY+gqg=="
95
- },
96
71
  "runtime.win10-arm.Microsoft.Net.Native.Compiler": {
97
72
  "type": "Transitive",
98
73
  "resolved": "2.2.7-rel-27913-00",
@@ -160,31 +135,8 @@
160
135
  "resolved": "2.2.9",
161
136
  "contentHash": "qF6RRZKaflI+LR1YODNyWYjq5YoX8IJ2wx5y8O+AW2xO+1t/Q6Mm+jQ38zJbWnmXbrcOqUYofn7Y3/KC6lTLBQ=="
162
137
  },
163
- "common": {
164
- "type": "Project"
165
- },
166
- "fmt": {
167
- "type": "Project"
168
- },
169
- "folly": {
170
- "type": "Project",
171
- "dependencies": {
172
- "fmt": "1.0.0"
173
- }
174
- },
175
138
  "microsoft.reactnative": {
176
- "type": "Project",
177
- "dependencies": {
178
- "Common": "1.0.0",
179
- "Folly": "1.0.0",
180
- "ReactCommon": "1.0.0"
181
- }
182
- },
183
- "reactcommon": {
184
- "type": "Project",
185
- "dependencies": {
186
- "Folly": "1.0.0"
187
- }
139
+ "type": "Project"
188
140
  }
189
141
  },
190
142
  "UAP,Version=v10.0.16299/win10-arm": {
@@ -328,4 +280,4 @@
328
280
  }
329
281
  }
330
282
  }
331
- }
283
+ }
@@ -10,10 +10,10 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.69.17</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.69.19</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>69</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>17</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>19</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
18
  </PropertyGroup>
19
19
  </Project>
@@ -8,7 +8,7 @@
8
8
  <!-- Enabling this will (1) Include hermes glues in the Microsoft.ReactNative binaries AND (2) Make hermes the default engine -->
9
9
  <UseHermes Condition="'$(UseHermes)' == ''">false</UseHermes>
10
10
  <!-- 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 -->
11
- <HermesVersion Condition="'$(HermesVersion)' == ''">0.12.1</HermesVersion>
11
+ <HermesVersion Condition="'$(HermesVersion)' == ''">0.69.1</HermesVersion>
12
12
  <HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgReactNative_Hermes_Windows)')">$(PkgReactNative_Hermes_Windows)</HermesPackage>
13
13
  <HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\ReactNative.Hermes.Windows\$(HermesVersion)</HermesPackage>
14
14
  <EnableHermesInspectorInReleaseFlavor Condition="'$(EnableHermesInspectorInReleaseFlavor)' == ''">false</EnableHermesInspectorInReleaseFlavor>
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
- <!--
2
+ <!--
3
3
  Copyright (c) Microsoft Corporation. All rights reserved.
4
4
  Licensed under the MIT License.
5
5
 
@@ -10,7 +10,7 @@
10
10
  <PropertyGroup Label="NuGet">
11
11
  <!-- Should match entry in $(ReactNativeWindowsDir)vnext\Directory.Build.props -->
12
12
  <!--See https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-target-->
13
- <RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</RestoreUseStaticGraphEvaluation>
13
+ <RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true' AND '$(DisableRestoreUseStaticGraphEvaluation)' != 'true'">true</RestoreUseStaticGraphEvaluation>
14
14
 
15
15
  <!-- Ensure PackageReference compatibility for any consuming projects/apps -->
16
16
  <ResolveNuGetPackages>false</ResolveNuGetPackages>
@@ -3,38 +3,40 @@
3
3
 
4
4
  #include "pch.h"
5
5
 
6
- #include <memory>
7
- #include <mutex>
6
+ #include "HermesRuntimeHolder.h"
8
7
 
9
8
  #include <JSI/decorator.h>
9
+ #include <crash/verifyElseCrash.h>
10
10
  #include <cxxreact/MessageQueueThread.h>
11
11
  #include <cxxreact/SystraceSection.h>
12
12
  #include <hermes/hermes.h>
13
- #include "HermesRuntimeHolder.h"
14
13
  #include "HermesShim.h"
15
14
 
16
15
  #if defined(HERMES_ENABLE_DEBUGGER)
17
16
  #include <hermes/inspector/chrome/Registration.h>
18
17
  #endif
19
18
 
19
+ #include <memory>
20
+ #include <mutex>
21
+
20
22
  using namespace facebook;
21
23
  using namespace Microsoft::ReactNative;
22
24
 
23
- namespace facebook {
24
- namespace react {
25
+ namespace React {
26
+ using namespace winrt::Microsoft::ReactNative;
27
+ }
25
28
 
26
- namespace {
29
+ namespace facebook::react {
27
30
 
28
- std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntimeSystraced(bool enableDefaultCrashHandler) {
29
- SystraceSection s("HermesExecutorFactory::makeHermesRuntimeSystraced");
30
- if (enableDefaultCrashHandler) {
31
- return HermesShim::makeHermesRuntimeWithWER();
32
- } else {
33
- auto runtimeConfig = ::hermes::vm::RuntimeConfig();
34
- return HermesShim::makeHermesRuntime(runtimeConfig);
35
- }
31
+ React::ReactPropertyId<React::ReactNonAbiValue<std::shared_ptr<HermesRuntimeHolder>>>
32
+ HermesRuntimeHolderProperty() noexcept {
33
+ static React::ReactPropertyId<React::ReactNonAbiValue<std::shared_ptr<HermesRuntimeHolder>>> propId{
34
+ L"ReactNative.HermesRuntimeHolder", L"HermesRuntimeHolder"};
35
+ return propId;
36
36
  }
37
37
 
38
+ namespace {
39
+
38
40
  #ifdef HERMES_ENABLE_DEBUGGER
39
41
  class HermesExecutorRuntimeAdapter final : public facebook::hermes::inspector::RuntimeAdapter {
40
42
  public:
@@ -71,10 +73,19 @@ class HermesExecutorRuntimeAdapter final : public facebook::hermes::inspector::R
71
73
  };
72
74
  #endif
73
75
 
76
+ std::shared_ptr<HermesShim> makeHermesShimSystraced(bool enableDefaultCrashHandler) {
77
+ SystraceSection s("HermesExecutorFactory::makeHermesRuntimeSystraced");
78
+ if (enableDefaultCrashHandler) {
79
+ return HermesShim::makeWithWER();
80
+ } else {
81
+ return HermesShim::make();
82
+ }
83
+ }
84
+
74
85
  } // namespace
75
86
 
76
87
  void HermesRuntimeHolder::crashHandler(int fileDescriptor) noexcept {
77
- HermesShim::hermesCrashHandler(*m_hermesRuntime, fileDescriptor);
88
+ m_hermesShim->dumpCrashData(fileDescriptor);
78
89
  }
79
90
 
80
91
  void HermesRuntimeHolder::teardown() noexcept {
@@ -90,15 +101,9 @@ facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcep
90
101
  }
91
102
 
92
103
  std::shared_ptr<jsi::Runtime> HermesRuntimeHolder::getRuntime() noexcept {
93
- std::call_once(m_once_flag, [this]() { initRuntime(); });
94
-
95
- if (!m_hermesRuntime)
96
- std::terminate();
97
-
98
- // Make sure that the runtime instance is not consumed from multiple threads.
99
- if (m_own_thread_id != std::this_thread::get_id())
100
- std::terminate();
101
-
104
+ std::call_once(m_onceFlag, [this]() { initRuntime(); });
105
+ VerifyElseCrash(m_hermesRuntime);
106
+ VerifyElseCrashSz(m_ownThreadId == std::this_thread::get_id(), "Must be accessed from JS thread.");
102
107
  return m_hermesRuntime;
103
108
  }
104
109
 
@@ -109,11 +114,11 @@ HermesRuntimeHolder::HermesRuntimeHolder(
109
114
 
110
115
  void HermesRuntimeHolder::initRuntime() noexcept {
111
116
  auto devSettings = m_weakDevSettings.lock();
112
- if (!devSettings)
113
- std::terminate();
117
+ VerifyElseCrash(devSettings);
114
118
 
115
- m_hermesRuntime = makeHermesRuntimeSystraced(devSettings->enableDefaultCrashHandler);
116
- m_own_thread_id = std::this_thread::get_id();
119
+ m_hermesShim = makeHermesShimSystraced(devSettings->enableDefaultCrashHandler);
120
+ m_hermesRuntime = m_hermesShim->getRuntime();
121
+ m_ownThreadId = std::this_thread::get_id();
117
122
 
118
123
  #ifdef HERMES_ENABLE_DEBUGGER
119
124
  if (devSettings->useDirectDebugger) {
@@ -132,5 +137,23 @@ void HermesRuntimeHolder::initRuntime() noexcept {
132
137
  errorPrototype.setProperty(*m_hermesRuntime, "jsEngine", "hermes");
133
138
  }
134
139
 
135
- } // namespace react
136
- } // namespace facebook
140
+ std::shared_ptr<HermesRuntimeHolder> HermesRuntimeHolder::loadFrom(
141
+ React::ReactPropertyBag const &propertyBag) noexcept {
142
+ return *(propertyBag.Get(HermesRuntimeHolderProperty()));
143
+ }
144
+
145
+ void HermesRuntimeHolder::storeTo(
146
+ React::ReactPropertyBag const &propertyBag,
147
+ std::shared_ptr<HermesRuntimeHolder> const &holder) noexcept {
148
+ propertyBag.Set(HermesRuntimeHolderProperty(), holder);
149
+ }
150
+
151
+ void HermesRuntimeHolder::addToProfiling() const noexcept {
152
+ m_hermesShim->addToProfiling();
153
+ }
154
+
155
+ void HermesRuntimeHolder::removeFromProfiling() const noexcept {
156
+ m_hermesShim->removeFromProfiling();
157
+ }
158
+
159
+ } // namespace facebook::react
@@ -8,37 +8,52 @@
8
8
  #include <thread>
9
9
 
10
10
  #include <DevSettings.h>
11
+ #include <ReactPropertyBag.h>
11
12
 
12
13
  namespace facebook::hermes {
13
14
  class HermesRuntime;
14
15
  }
15
16
 
16
- namespace facebook {
17
- namespace react {
17
+ namespace Microsoft::ReactNative {
18
+ class HermesShim;
19
+ }
20
+
21
+ namespace facebook::react {
22
+
23
+ class MessageQueueThread;
18
24
 
19
25
  class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
20
- public:
26
+ public: // RuntimeHolderLazyInit implementation.
21
27
  std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
22
28
  facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
23
-
24
29
  void crashHandler(int fileDescriptor) noexcept override;
25
-
26
30
  void teardown() noexcept override;
27
31
 
32
+ public:
28
33
  HermesRuntimeHolder(
29
34
  std::shared_ptr<facebook::react::DevSettings> devSettings,
30
35
  std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept;
31
36
 
37
+ static std::shared_ptr<HermesRuntimeHolder> loadFrom(
38
+ winrt::Microsoft::ReactNative::ReactPropertyBag const &propertyBag) noexcept;
39
+
40
+ static void storeTo(
41
+ winrt::Microsoft::ReactNative::ReactPropertyBag const &propertyBag,
42
+ std::shared_ptr<HermesRuntimeHolder> const &holder) noexcept;
43
+
44
+ void addToProfiling() const noexcept;
45
+ void removeFromProfiling() const noexcept;
46
+
32
47
  private:
33
48
  void initRuntime() noexcept;
34
- std::shared_ptr<facebook::hermes::HermesRuntime> m_hermesRuntime;
35
-
36
- std::once_flag m_once_flag;
37
- std::thread::id m_own_thread_id;
38
49
 
50
+ private:
51
+ std::shared_ptr<Microsoft::ReactNative::HermesShim> m_hermesShim;
52
+ std::shared_ptr<facebook::hermes::HermesRuntime> m_hermesRuntime;
53
+ std::once_flag m_onceFlag{};
54
+ std::thread::id m_ownThreadId{};
39
55
  std::weak_ptr<facebook::react::DevSettings> m_weakDevSettings;
40
56
  std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
41
57
  };
42
58
 
43
- } // namespace react
44
- } // namespace facebook
59
+ } // namespace facebook::react
@@ -7,13 +7,46 @@
7
7
  #include <chrono>
8
8
  #include <future>
9
9
 
10
+ #include "HermesRuntimeHolder.h"
10
11
  #include "HermesSamplingProfiler.h"
11
12
  #include "HermesShim.h"
13
+ #include "IReactDispatcher.h"
14
+ #include "ReactPropertyBag.h"
12
15
  #include "Utils.h"
13
16
 
17
+ using namespace winrt::Microsoft::ReactNative;
18
+ using namespace facebook::react;
19
+
14
20
  namespace Microsoft::ReactNative {
15
21
 
16
22
  namespace {
23
+
24
+ // Implements an awaiter for Mso::DispatchQueue
25
+ auto resume_in_dispatcher(const IReactDispatcher &dispatcher) noexcept {
26
+ struct awaitable {
27
+ awaitable(const IReactDispatcher &dispatcher) noexcept : dispatcher_(dispatcher) {}
28
+
29
+ bool await_ready() const noexcept {
30
+ return false;
31
+ }
32
+
33
+ void await_resume() const noexcept {}
34
+
35
+ void await_suspend(std::experimental::coroutine_handle<> resume) noexcept {
36
+ callback_ = [context = resume.address()]() noexcept {
37
+ std::experimental::coroutine_handle<>::from_address(context)();
38
+ };
39
+ dispatcher_.Post(std::move(callback_));
40
+ }
41
+
42
+ private:
43
+ IReactDispatcher dispatcher_;
44
+ ReactDispatcherCallback callback_;
45
+ };
46
+
47
+ return awaitable{dispatcher};
48
+ }
49
+
17
50
  std::future<std::string> getTraceFilePath() noexcept {
18
51
  auto hermesDataPath = co_await Microsoft::React::getApplicationDataPath(L"Hermes");
19
52
  std::ostringstream os;
@@ -23,18 +56,27 @@ std::future<std::string> getTraceFilePath() noexcept {
23
56
  os << hermesDataPath << "\\cpu_" << now << ".cpuprofile";
24
57
  co_return os.str();
25
58
  }
59
+
26
60
  } // namespace
27
61
 
28
- bool HermesSamplingProfiler::s_isStarted = false;
62
+ std::atomic_bool HermesSamplingProfiler::s_isStarted{false};
29
63
  std::string HermesSamplingProfiler::s_lastTraceFilePath;
30
64
 
31
65
  std::string HermesSamplingProfiler::GetLastTraceFilePath() noexcept {
32
66
  return s_lastTraceFilePath;
33
67
  }
34
68
 
35
- winrt::fire_and_forget HermesSamplingProfiler::Start() noexcept {
36
- if (!s_isStarted) {
37
- s_isStarted = true;
69
+ winrt::fire_and_forget HermesSamplingProfiler::Start(
70
+ Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept {
71
+ bool expectedIsStarted = false;
72
+ if (s_isStarted.compare_exchange_strong(expectedIsStarted, true)) {
73
+ IReactDispatcher jsDispatcher = implementation::ReactDispatcher::GetJSDispatcher(reactContext->Properties());
74
+ ReactPropertyBag propertyBag = ReactPropertyBag(reactContext->Properties());
75
+
76
+ co_await resume_in_dispatcher(jsDispatcher);
77
+ std::shared_ptr<HermesRuntimeHolder> hermesRuntimeHolder = HermesRuntimeHolder::loadFrom(propertyBag);
78
+ hermesRuntimeHolder->addToProfiling();
79
+
38
80
  co_await winrt::resume_background();
39
81
  HermesShim::enableSamplingProfiler();
40
82
  }
@@ -42,20 +84,31 @@ winrt::fire_and_forget HermesSamplingProfiler::Start() noexcept {
42
84
  co_return;
43
85
  }
44
86
 
45
- std::future<std::string> HermesSamplingProfiler::Stop() noexcept {
46
- if (s_isStarted) {
47
- s_isStarted = false;
87
+ std::future<std::string> HermesSamplingProfiler::Stop(
88
+ Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept {
89
+ bool expectedIsStarted = true;
90
+ if (s_isStarted.compare_exchange_strong(expectedIsStarted, false)) {
91
+ IReactDispatcher jsDispatcher = implementation::ReactDispatcher::GetJSDispatcher(reactContext->Properties());
92
+ ReactPropertyBag propertyBag = ReactPropertyBag(reactContext->Properties());
93
+
48
94
  co_await winrt::resume_background();
49
95
  HermesShim::disableSamplingProfiler();
96
+
50
97
  s_lastTraceFilePath = co_await getTraceFilePath();
51
98
  HermesShim::dumpSampledTraceToFile(s_lastTraceFilePath);
99
+
100
+ co_await resume_in_dispatcher(jsDispatcher);
101
+ std::shared_ptr<HermesRuntimeHolder> hermesRuntimeHolder = HermesRuntimeHolder::loadFrom(propertyBag);
102
+ hermesRuntimeHolder->removeFromProfiling();
103
+
104
+ co_await winrt::resume_background();
52
105
  }
53
106
 
54
107
  co_return s_lastTraceFilePath;
55
108
  }
56
109
 
57
110
  bool HermesSamplingProfiler::IsStarted() noexcept {
58
- return s_isStarted;
111
+ return s_isStarted.load();
59
112
  }
60
113
 
61
114
  } // namespace Microsoft::ReactNative
@@ -3,19 +3,21 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ #include <ReactHost/React.h>
7
+ #include <atomic>
6
8
  #include <string>
7
9
 
8
10
  namespace Microsoft::ReactNative {
9
11
 
10
12
  class HermesSamplingProfiler final {
11
13
  public:
12
- static winrt::fire_and_forget Start() noexcept;
13
- static std::future<std::string> Stop() noexcept;
14
+ static winrt::fire_and_forget Start(Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept;
15
+ static std::future<std::string> Stop(Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept;
14
16
  static std::string GetLastTraceFilePath() noexcept;
15
17
  static bool IsStarted() noexcept;
16
18
 
17
19
  private:
18
- static bool s_isStarted;
20
+ static std::atomic_bool s_isStarted;
19
21
  static std::string s_lastTraceFilePath;
20
22
  };
21
23
 
@@ -4,115 +4,119 @@
4
4
  #include "HermesShim.h"
5
5
  #include "Crash.h"
6
6
 
7
- namespace Microsoft::ReactNative::HermesShim {
8
-
9
- static HMODULE s_hermesModule{nullptr};
10
- static decltype(&facebook::hermes::makeHermesRuntime) s_makeHermesRuntime{nullptr};
11
- static decltype(&facebook::hermes::HermesRuntime::enableSamplingProfiler) s_enableSamplingProfiler{nullptr};
12
- static decltype(&facebook::hermes::HermesRuntime::disableSamplingProfiler) s_disableSamplingProfiler{nullptr};
13
- static decltype(&facebook::hermes::HermesRuntime::dumpSampledTraceToFile) s_dumpSampledTraceToFile{nullptr};
14
- static decltype(&facebook::hermes::makeHermesRuntimeWithWER) s_makeHermesRuntimeWithWER{nullptr};
15
- static decltype(&facebook::hermes::hermesCrashHandler) s_hermesCrashHandler{nullptr};
16
-
17
- #if _M_X64
18
- constexpr const char *makeHermesRuntimeSymbol =
19
- "?makeHermesRuntime@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@AEBVRuntimeConfig@vm@1@@Z";
20
- constexpr const char *enableSamlingProfilerSymbol = "?enableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
21
- constexpr const char *disableSamlingProfilerSymbol = "?disableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
22
- constexpr const char *dumpSampledTraceToFileSymbol =
23
- "?dumpSampledTraceToFile@HermesRuntime@hermes@facebook@@SAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z";
24
- constexpr const char *makeHermesRuntimeWithWERSymbol =
25
- "?makeHermesRuntimeWithWER@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@XZ";
26
- constexpr const char *hermesCrashHandlerSymbol = "?hermesCrashHandler@hermes@facebook@@YAXAEAVHermesRuntime@12@H@Z";
27
- #endif
28
-
29
- #if _M_ARM64
30
- constexpr const char *makeHermesRuntimeSymbol =
31
- "?makeHermesRuntime@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@AEBVRuntimeConfig@vm@1@@Z";
32
- constexpr const char *enableSamlingProfilerSymbol = "?enableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
33
- constexpr const char *disableSamlingProfilerSymbol = "?disableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
34
- constexpr const char *dumpSampledTraceToFileSymbol =
35
- "?dumpSampledTraceToFile@HermesRuntime@hermes@facebook@@SAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z";
36
- constexpr const char *makeHermesRuntimeWithWERSymbol =
37
- "?makeHermesRuntimeWithWER@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@XZ";
38
- constexpr const char *hermesCrashHandlerSymbol = "?hermesCrashHandler@hermes@facebook@@YAXAEAVHermesRuntime@12@H@Z";
39
- #endif
40
-
41
- #if _M_IX86
42
- constexpr const char *makeHermesRuntimeSymbol =
43
- "?makeHermesRuntime@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@ABVRuntimeConfig@vm@1@@Z";
44
- constexpr const char *enableSamlingProfilerSymbol = "?enableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
45
- constexpr const char *disableSamlingProfilerSymbol = "?disableSamplingProfiler@HermesRuntime@hermes@facebook@@SAXXZ";
46
- constexpr const char *dumpSampledTraceToFileSymbol =
47
- "?dumpSampledTraceToFile@HermesRuntime@hermes@facebook@@SAXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z";
48
- constexpr const char *makeHermesRuntimeWithWERSymbol =
49
- "?makeHermesRuntimeWithWER@hermes@facebook@@YA?AV?$unique_ptr@VHermesRuntime@hermes@facebook@@U?$default_delete@VHermesRuntime@hermes@facebook@@@std@@@std@@XZ";
50
- constexpr const char *hermesCrashHandlerSymbol = "?hermesCrashHandler@hermes@facebook@@YAXAAVHermesRuntime@12@H@Z";
51
- #endif
52
-
53
- static std::once_flag s_hermesLoading;
54
-
55
- static void EnsureHermesLoaded() noexcept {
7
+ #define DECLARE_SYMBOL(symbol, importedSymbol) \
8
+ decltype(&importedSymbol) s_##symbol{}; \
9
+ constexpr const char symbol##Symbol[] = #importedSymbol;
10
+
11
+ #define INIT_SYMBOL(symbol) \
12
+ s_##symbol = reinterpret_cast<decltype(s_##symbol)>(GetProcAddress(s_hermesModule, symbol##Symbol)); \
13
+ VerifyElseCrash(s_##symbol);
14
+
15
+ #define CRASH_ON_ERROR(result) VerifyElseCrash(result == hermes_ok);
16
+
17
+ namespace Microsoft::ReactNative {
18
+
19
+ namespace {
20
+
21
+ DECLARE_SYMBOL(createRuntime, hermes_create_runtime);
22
+ DECLARE_SYMBOL(createRuntimeWithWER, hermes_create_runtime_with_wer);
23
+ DECLARE_SYMBOL(deleteRuntime, hermes_delete_runtime);
24
+ DECLARE_SYMBOL(getNonAbiSafeRuntime, hermes_get_non_abi_safe_runtime);
25
+ DECLARE_SYMBOL(dumpCrashData, hermes_dump_crash_data);
26
+ DECLARE_SYMBOL(samplingProfilerEnable, hermes_sampling_profiler_enable);
27
+ DECLARE_SYMBOL(samplingProfilerDisable, hermes_sampling_profiler_disable);
28
+ DECLARE_SYMBOL(samplingProfilerAdd, hermes_sampling_profiler_add);
29
+ DECLARE_SYMBOL(samplingProfilerRemove, hermes_sampling_profiler_remove);
30
+ DECLARE_SYMBOL(samplingProfilerDumpToFile, hermes_sampling_profiler_dump_to_file);
31
+
32
+ HMODULE s_hermesModule{};
33
+ std::once_flag s_hermesLoading;
34
+
35
+ void EnsureHermesLoaded() noexcept {
56
36
  std::call_once(s_hermesLoading, []() {
57
37
  VerifyElseCrashSz(!s_hermesModule, "Invalid state: \"hermes.dll\" being loaded again.");
58
38
 
59
39
  s_hermesModule = LoadLibrary(L"hermes.dll");
60
40
  VerifyElseCrashSz(s_hermesModule, "Could not load \"hermes.dll\"");
61
41
 
62
- s_makeHermesRuntime =
63
- reinterpret_cast<decltype(s_makeHermesRuntime)>(GetProcAddress(s_hermesModule, makeHermesRuntimeSymbol));
64
- VerifyElseCrash(s_makeHermesRuntime);
42
+ INIT_SYMBOL(createRuntime);
43
+ INIT_SYMBOL(createRuntimeWithWER);
44
+ INIT_SYMBOL(deleteRuntime);
45
+ INIT_SYMBOL(getNonAbiSafeRuntime);
46
+ INIT_SYMBOL(dumpCrashData);
47
+ INIT_SYMBOL(samplingProfilerEnable);
48
+ INIT_SYMBOL(samplingProfilerDisable);
49
+ INIT_SYMBOL(samplingProfilerAdd);
50
+ INIT_SYMBOL(samplingProfilerRemove);
51
+ INIT_SYMBOL(samplingProfilerDumpToFile);
52
+ });
53
+ }
54
+
55
+ struct RuntimeDeleter {
56
+ RuntimeDeleter(std::shared_ptr<const HermesShim> &&hermesShimPtr) noexcept
57
+ : hermesShimPtr_(std::move(hermesShimPtr)) {}
65
58
 
66
- s_enableSamplingProfiler = reinterpret_cast<decltype(s_enableSamplingProfiler)>(
67
- GetProcAddress(s_hermesModule, enableSamlingProfilerSymbol));
68
- VerifyElseCrash(s_enableSamplingProfiler);
59
+ void operator()(facebook::hermes::HermesRuntime * /*runtime*/) {
60
+ // Do nothing. Instead, we rely on the RuntimeDeleter destructor.
61
+ }
69
62
 
70
- s_disableSamplingProfiler = reinterpret_cast<decltype(s_disableSamplingProfiler)>(
71
- GetProcAddress(s_hermesModule, disableSamlingProfilerSymbol));
72
- VerifyElseCrash(s_disableSamplingProfiler);
63
+ private:
64
+ std::shared_ptr<const HermesShim> hermesShimPtr_;
65
+ };
73
66
 
74
- s_dumpSampledTraceToFile = reinterpret_cast<decltype(s_dumpSampledTraceToFile)>(
75
- GetProcAddress(s_hermesModule, dumpSampledTraceToFileSymbol));
76
- VerifyElseCrash(s_dumpSampledTraceToFile);
67
+ } // namespace
77
68
 
78
- s_makeHermesRuntimeWithWER = reinterpret_cast<decltype(s_makeHermesRuntimeWithWER)>(
79
- GetProcAddress(s_hermesModule, makeHermesRuntimeWithWERSymbol));
80
- VerifyElseCrash(s_makeHermesRuntimeWithWER);
69
+ HermesShim::HermesShim(hermes_runtime runtime) noexcept : runtime_(runtime) {
70
+ CRASH_ON_ERROR(s_getNonAbiSafeRuntime(runtime_, reinterpret_cast<void **>(&nonAbiSafeRuntime_)));
71
+ }
81
72
 
82
- s_hermesCrashHandler =
83
- reinterpret_cast<decltype(s_hermesCrashHandler)>(GetProcAddress(s_hermesModule, hermesCrashHandlerSymbol));
84
- VerifyElseCrash(s_hermesCrashHandler);
85
- });
73
+ HermesShim::~HermesShim() {
74
+ CRASH_ON_ERROR(s_deleteRuntime(runtime_));
86
75
  }
87
76
 
88
- std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntime(const hermes::vm::RuntimeConfig &runtimeConfig) {
77
+ /*static*/ std::shared_ptr<HermesShim> HermesShim::make() noexcept {
89
78
  EnsureHermesLoaded();
90
- return s_makeHermesRuntime(runtimeConfig);
79
+ hermes_runtime runtime{};
80
+ CRASH_ON_ERROR(s_createRuntime(&runtime));
81
+ return std::make_shared<HermesShim>(runtime);
91
82
  }
92
83
 
93
- void enableSamplingProfiler() {
84
+ /*static*/
85
+ std::shared_ptr<HermesShim> HermesShim::makeWithWER() noexcept {
94
86
  EnsureHermesLoaded();
95
- s_enableSamplingProfiler();
87
+ hermes_runtime runtime{};
88
+ CRASH_ON_ERROR(s_createRuntimeWithWER(&runtime));
89
+ return std::make_shared<HermesShim>(runtime);
96
90
  }
97
91
 
98
- void disableSamplingProfiler() {
99
- EnsureHermesLoaded();
100
- s_disableSamplingProfiler();
92
+ std::shared_ptr<facebook::hermes::HermesRuntime> HermesShim::getRuntime() const noexcept {
93
+ return std::shared_ptr<facebook::hermes::HermesRuntime>(nonAbiSafeRuntime_, RuntimeDeleter(shared_from_this()));
101
94
  }
102
95
 
103
- void dumpSampledTraceToFile(const std::string &fileName) {
96
+ void HermesShim::dumpCrashData(int fileDescriptor) const noexcept {
97
+ CRASH_ON_ERROR(s_dumpCrashData(runtime_, fileDescriptor));
98
+ }
99
+
100
+ /*static*/ void HermesShim::enableSamplingProfiler() noexcept {
104
101
  EnsureHermesLoaded();
105
- s_dumpSampledTraceToFile(fileName);
102
+ CRASH_ON_ERROR(s_samplingProfilerEnable());
106
103
  }
107
104
 
108
- std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntimeWithWER() {
105
+ /*static*/ void HermesShim::disableSamplingProfiler() noexcept {
109
106
  EnsureHermesLoaded();
110
- return s_makeHermesRuntimeWithWER();
107
+ CRASH_ON_ERROR(s_samplingProfilerDisable());
111
108
  }
112
109
 
113
- void hermesCrashHandler(facebook::hermes::HermesRuntime &runtime, int fileDescriptor) {
110
+ /*static*/ void HermesShim::dumpSampledTraceToFile(const std::string &fileName) noexcept {
114
111
  EnsureHermesLoaded();
115
- s_hermesCrashHandler(runtime, fileDescriptor);
112
+ CRASH_ON_ERROR(s_samplingProfilerDumpToFile(fileName.c_str()));
113
+ }
114
+ void HermesShim::addToProfiling() const noexcept {
115
+ CRASH_ON_ERROR(s_samplingProfilerAdd(runtime_));
116
+ }
117
+
118
+ void HermesShim::removeFromProfiling() const noexcept {
119
+ CRASH_ON_ERROR(s_samplingProfilerRemove(runtime_));
116
120
  }
117
121
 
118
- } // namespace Microsoft::ReactNative::HermesShim
122
+ } // namespace Microsoft::ReactNative
@@ -3,19 +3,39 @@
3
3
 
4
4
  #pragma once
5
5
 
6
- #include <hermes/hermes.h>
6
+ #include <hermes/hermes_win.h>
7
7
 
8
8
  //! We do not package hermes.dll for projects that do not require it. We cannot
9
9
  //! use pure delay-loading to achieve this, since WACK will detect the
10
10
  //! non-present DLL. Functions in this namespace shim to the Hermes DLL via
11
11
  //! GetProcAddress.
12
- namespace Microsoft::ReactNative::HermesShim {
12
+ namespace Microsoft::ReactNative {
13
13
 
14
- std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntime(const hermes::vm::RuntimeConfig &runtimeConfig);
15
- void enableSamplingProfiler();
16
- void disableSamplingProfiler();
17
- void dumpSampledTraceToFile(const std::string &fileName);
18
- std::unique_ptr<facebook::hermes::HermesRuntime> makeHermesRuntimeWithWER();
19
- void hermesCrashHandler(facebook::hermes::HermesRuntime &runtime, int fileDescriptor);
14
+ class HermesShim : public std::enable_shared_from_this<HermesShim> {
15
+ public:
16
+ HermesShim(hermes_runtime runtimeAbiPtr) noexcept;
17
+ ~HermesShim();
20
18
 
21
- } // namespace Microsoft::ReactNative::HermesShim
19
+ static std::shared_ptr<HermesShim> make() noexcept;
20
+ static std::shared_ptr<HermesShim> makeWithWER() noexcept;
21
+
22
+ std::shared_ptr<facebook::hermes::HermesRuntime> getRuntime() const noexcept;
23
+
24
+ void dumpCrashData(int fileDescriptor) const noexcept;
25
+
26
+ static void enableSamplingProfiler() noexcept;
27
+ static void disableSamplingProfiler() noexcept;
28
+ static void dumpSampledTraceToFile(const std::string &fileName) noexcept;
29
+ void addToProfiling() const noexcept;
30
+ void removeFromProfiling() const noexcept;
31
+
32
+ HermesShim(const HermesShim &) = delete;
33
+ HermesShim &operator=(const HermesShim &) = delete;
34
+
35
+ private:
36
+ // It must be a raw pointer to avoid circular reference.
37
+ facebook::hermes::HermesRuntime *nonAbiSafeRuntime_{};
38
+ hermes_runtime runtime_{};
39
+ };
40
+
41
+ } // namespace Microsoft::ReactNative
@@ -11,7 +11,7 @@ namespace Microsoft::JSI {
11
11
  // a. lazily create a JSI Runtime on the first call to getRuntime
12
12
  // b. subsequent calls to getRuntime should return the Runtime created in (a)
13
13
 
14
- // Note :: All calls to getRuntime() should happen on the same thread unless you are sure that
14
+ // Note: all calls to getRuntime() should happen on the same thread unless you are sure that
15
15
  // the underlying Runtime instance is thread safe.
16
16
 
17
17
  struct RuntimeHolderLazyInit {
@@ -21,7 +21,7 @@ struct RuntimeHolderLazyInit {
21
21
  virtual void teardown() noexcept {};
22
22
 
23
23
  // You can call this when a crash happens to attempt recording additional data
24
- // The fd supplied is a raw file stream an implementation might write JSON to
24
+ // The fileDescriptor supplied is a raw file stream an implementation might write JSON to.
25
25
  virtual void crashHandler(int fileDescriptor) noexcept {};
26
26
  };
27
27
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <functional>
7
7
  #include <map>
8
+ #include <memory>
8
9
  #include <string>
9
10
  #include <vector>
10
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.69.17",
3
+ "version": "0.69.19",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "@react-native-community/cli": "^8.0.0",
27
27
  "@react-native-community/cli-platform-android": "^8.0.0",
28
28
  "@react-native-community/cli-platform-ios": "^8.0.0",
29
- "@react-native-windows/cli": "0.69.5",
29
+ "@react-native-windows/cli": "0.69.6",
30
30
  "@react-native-windows/virtualized-list": "0.69.1",
31
31
  "@react-native/assets": "1.0.0",
32
32
  "@react-native/normalize-color": "2.0.0",