react-native-windows 0.69.18 → 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.
@@ -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
 
@@ -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]() {
@@ -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.18</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.69.19</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>69</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>18</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>
@@ -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.18",
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",