react-native-windows 0.71.35 → 0.71.37

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.
Files changed (48) hide show
  1. package/Directory.Build.props +0 -5
  2. package/Microsoft.ReactNative/IReactDispatcher.cpp +0 -4
  3. package/Microsoft.ReactNative/IReactDispatcher.h +0 -1
  4. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +4 -2
  5. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +23 -36
  6. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +2 -0
  7. package/Microsoft.ReactNative/Views/DevMenu.cpp +3 -3
  8. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +2103 -0
  9. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +73 -0
  10. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +12 -43
  11. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +6 -17
  12. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
  13. package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
  14. package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
  15. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  16. package/PropertySheets/JSEngine.props +4 -4
  17. package/PropertySheets/React.Cpp.props +0 -1
  18. package/PropertySheets/Warnings.props +0 -6
  19. package/ReactCommon/ReactCommon.vcxproj +1 -53
  20. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +0 -36
  21. package/Shared/DevSettings.h +3 -0
  22. package/Shared/DevSupportManager.cpp +9 -2
  23. package/Shared/DevSupportManager.h +6 -2
  24. package/Shared/HermesRuntimeHolder.cpp +84 -344
  25. package/Shared/HermesRuntimeHolder.h +21 -32
  26. package/Shared/HermesSamplingProfiler.cpp +14 -66
  27. package/Shared/HermesSamplingProfiler.h +3 -5
  28. package/Shared/HermesShim.cpp +118 -0
  29. package/Shared/HermesShim.h +21 -0
  30. package/Shared/InspectorPackagerConnection.cpp +108 -62
  31. package/Shared/InspectorPackagerConnection.h +21 -9
  32. package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +209 -0
  33. package/Shared/JSI/NapiJsiV8RuntimeHolder.h +44 -0
  34. package/Shared/JSI/RuntimeHolder.h +2 -2
  35. package/Shared/JSI/ScriptStore.h +20 -18
  36. package/Shared/OInstance.cpp +56 -41
  37. package/Shared/Shared.vcxitems +8 -19
  38. package/Shared/Shared.vcxitems.filters +30 -23
  39. package/Shared/V8JSIRuntimeHolder.cpp +70 -0
  40. package/Shared/V8JSIRuntimeHolder.h +53 -0
  41. package/package.json +2 -2
  42. package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
  43. package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +0 -16
  44. package/ReactCommon/cgmanifest.json +0 -15
  45. package/Shared/JSI/V8RuntimeHolder.cpp +0 -260
  46. package/Shared/JSI/V8RuntimeHolder.h +0 -37
  47. package/Shared/SafeLoadLibrary.cpp +0 -77
  48. package/Shared/SafeLoadLibrary.h +0 -19
@@ -3,394 +3,134 @@
3
3
 
4
4
  #include "pch.h"
5
5
 
6
- #include "HermesRuntimeHolder.h"
6
+ #include <memory>
7
+ #include <mutex>
7
8
 
8
- #include <ApiLoaders/HermesApi.h>
9
9
  #include <JSI/decorator.h>
10
- #include <NodeApiJsiRuntime.h>
11
- #include <crash/verifyElseCrash.h>
10
+ #include <cxxreact/MessageQueueThread.h>
12
11
  #include <cxxreact/SystraceSection.h>
13
- #include <jsinspector/InspectorInterfaces.h>
14
- #include <mutex>
15
- #include "SafeLoadLibrary.h"
16
-
17
- #define CRASH_ON_ERROR(result) VerifyElseCrash(result == napi_ok);
12
+ #include <hermes/hermes.h>
13
+ #include "HermesRuntimeHolder.h"
14
+ #include "HermesShim.h"
18
15
 
19
- namespace React {
20
- using namespace winrt::Microsoft::ReactNative;
21
- }
16
+ #if defined(HERMES_ENABLE_DEBUGGER)
17
+ #include <hermes/inspector/chrome/Registration.h>
18
+ #endif
22
19
 
23
- using namespace Microsoft::NodeApiJsi;
20
+ using namespace facebook;
21
+ using namespace Microsoft::ReactNative;
24
22
 
25
- namespace Microsoft::ReactNative {
26
-
27
- React::ReactPropertyId<React::ReactNonAbiValue<std::shared_ptr<HermesRuntimeHolder>>>
28
- HermesRuntimeHolderProperty() noexcept {
29
- static React::ReactPropertyId<React::ReactNonAbiValue<std::shared_ptr<HermesRuntimeHolder>>> propId{
30
- L"ReactNative.HermesRuntimeHolder", L"HermesRuntimeHolder"};
31
- return propId;
32
- }
23
+ namespace facebook {
24
+ namespace react {
33
25
 
34
26
  namespace {
35
27
 
36
- int32_t NAPI_CDECL addInspectorPage(const char *title, const char *vm, void *connectFunc) noexcept;
37
- void NAPI_CDECL removeInspectorPage(int32_t pageId) noexcept;
38
-
39
- class HermesFuncResolver : public IFuncResolver {
40
- public:
41
- HermesFuncResolver() : libHandle_(LoadLibraryAsPeerFirst(L"hermes.dll")) {}
42
-
43
- FuncPtr getFuncPtr(const char *funcName) override {
44
- return reinterpret_cast<FuncPtr>(GetProcAddress(libHandle_, funcName));
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);
45
35
  }
46
-
47
- private:
48
- HMODULE libHandle_;
49
- };
50
-
51
- HermesApi &initHermesApi() noexcept {
52
- static HermesFuncResolver funcResolver;
53
- static HermesApi s_hermesApi(&funcResolver);
54
- HermesApi::setCurrent(&s_hermesApi);
55
- CRASH_ON_ERROR(s_hermesApi.hermes_set_inspector(&addInspectorPage, &removeInspectorPage));
56
- return s_hermesApi;
57
- }
58
-
59
- HermesApi &getHermesApi() noexcept {
60
- static HermesApi &s_hermesApi = initHermesApi();
61
- return s_hermesApi;
62
36
  }
63
37
 
64
- class HermesTask {
65
- public:
66
- HermesTask(
67
- void *taskData,
68
- jsr_task_run_cb taskRunCallback,
69
- jsr_data_delete_cb taskDataDeleteCallback,
70
- void *deleterData)
71
- : taskData_(taskData),
72
- taskRunCallback_(taskRunCallback),
73
- taskDataDeleteCallback_(taskDataDeleteCallback),
74
- deleterData_(deleterData) {}
75
-
76
- HermesTask(const HermesTask &other) = delete;
77
- HermesTask &operator=(const HermesTask &other) = delete;
78
-
79
- ~HermesTask() {
80
- if (taskDataDeleteCallback_ != nullptr) {
81
- taskDataDeleteCallback_(taskData_, deleterData_);
82
- }
83
- }
84
-
85
- void Run() const {
86
- if (taskRunCallback_ != nullptr) {
87
- taskRunCallback_(taskData_);
88
- }
89
- }
90
-
91
- private:
92
- void *taskData_;
93
- jsr_task_run_cb taskRunCallback_;
94
- jsr_data_delete_cb taskDataDeleteCallback_;
95
- void *deleterData_;
96
- };
97
-
98
- class HermesTaskRunner {
99
- public:
100
- static void Create(jsr_config config, std::shared_ptr<facebook::react::MessageQueueThread> queue) {
101
- CRASH_ON_ERROR(getHermesApi().jsr_config_set_task_runner(
102
- config, new HermesTaskRunner(std::move(queue)), &PostTask, &Delete, nullptr));
103
- }
104
-
105
- private:
106
- HermesTaskRunner(std::shared_ptr<facebook::react::MessageQueueThread> queue) : queue_(std::move(queue)) {}
107
-
108
- static void NAPI_CDECL PostTask(
109
- void *taskRunnerData,
110
- void *taskData,
111
- jsr_task_run_cb taskRunCallback,
112
- jsr_data_delete_cb taskDataDeleteCallback,
113
- void *deleterData) {
114
- auto task = std::make_shared<HermesTask>(taskData, taskRunCallback, taskDataDeleteCallback, deleterData);
115
- reinterpret_cast<HermesTaskRunner *>(taskRunnerData)->queue_->runOnQueue([task = std::move(task)] { task->Run(); });
116
- }
117
-
118
- static void NAPI_CDECL Delete(void *taskRunner, void * /*deleterData*/) {
119
- delete reinterpret_cast<HermesTaskRunner *>(taskRunner);
120
- }
121
-
122
- private:
123
- std::shared_ptr<facebook::react::MessageQueueThread> queue_;
124
- };
125
-
126
- struct HermesJsiBuffer : facebook::jsi::Buffer {
127
- static std::shared_ptr<const facebook::jsi::Buffer>
128
- Create(const uint8_t *buffer, size_t bufferSize, jsr_data_delete_cb bufferDeleteCallback, void *deleterData) {
129
- return std::shared_ptr<const facebook::jsi::Buffer>(
130
- new HermesJsiBuffer(buffer, bufferSize, bufferDeleteCallback, deleterData));
131
- }
132
-
133
- HermesJsiBuffer(
134
- const uint8_t *buffer,
135
- size_t bufferSize,
136
- jsr_data_delete_cb bufferDeleteCallback,
137
- void *deleterData) noexcept
138
- : buffer_(buffer),
139
- bufferSize_(bufferSize),
140
- bufferDeleteCallback_(bufferDeleteCallback),
141
- deleterData_(deleterData) {}
142
-
143
- ~HermesJsiBuffer() override {
144
- if (bufferDeleteCallback_) {
145
- bufferDeleteCallback_(const_cast<uint8_t *>(buffer_), deleterData_);
146
- }
147
- }
148
-
149
- const uint8_t *data() const override {
150
- return buffer_;
151
- }
152
-
153
- size_t size() const override {
154
- return bufferSize_;
155
- }
156
-
157
- private:
158
- const uint8_t *buffer_;
159
- size_t bufferSize_;
160
- jsr_data_delete_cb bufferDeleteCallback_;
161
- void *deleterData_;
162
- };
163
-
164
- class HermesScriptCache {
38
+ #ifdef HERMES_ENABLE_DEBUGGER
39
+ class HermesExecutorRuntimeAdapter final : public facebook::hermes::inspector::RuntimeAdapter {
165
40
  public:
166
- static void Create(jsr_config config, std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore) {
167
- CRASH_ON_ERROR(getHermesApi().jsr_config_set_script_cache(
168
- config, new HermesScriptCache(std::move(scriptStore)), &LoadScript, &StoreScript, &Delete, nullptr));
169
- }
41
+ HermesExecutorRuntimeAdapter(
42
+ std::shared_ptr<jsi::Runtime> runtime,
43
+ facebook::hermes::HermesRuntime &hermesRuntime,
44
+ std::shared_ptr<MessageQueueThread> thread)
45
+ : m_runtime(runtime), m_hermesRuntime(hermesRuntime), m_thread(std::move(thread)) {}
170
46
 
171
- private:
172
- HermesScriptCache(std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore)
173
- : scriptStore_(std::move(scriptStore)) {}
174
-
175
- static void NAPI_CDECL LoadScript(
176
- void *scriptCache,
177
- const char *sourceUrl,
178
- uint64_t sourceHash,
179
- const char *runtimeName,
180
- uint64_t runtimeVersion,
181
- const char *cacheTag,
182
- const uint8_t **buffer,
183
- size_t *bufferSize,
184
- jsr_data_delete_cb *bufferDeleteCallback,
185
- void **deleterData) {
186
- auto &scriptStore = reinterpret_cast<HermesScriptCache *>(scriptCache)->scriptStore_;
187
- std::shared_ptr<const facebook::jsi::Buffer> preparedScript = scriptStore->tryGetPreparedScript(
188
- facebook::jsi::ScriptSignature{sourceUrl, sourceHash},
189
- facebook::jsi::JSRuntimeSignature{runtimeName, runtimeVersion},
190
- cacheTag);
191
- if (preparedScript) {
192
- *buffer = preparedScript->data();
193
- *bufferSize = preparedScript->size();
194
- *bufferDeleteCallback = [](void * /*data*/, void *deleterData) noexcept {
195
- delete reinterpret_cast<std::shared_ptr<const facebook::jsi::Buffer> *>(deleterData);
196
- };
197
- *deleterData = new std::shared_ptr<const facebook::jsi::Buffer>(std::move(preparedScript));
198
- } else {
199
- *buffer = nullptr;
200
- *bufferSize = 0;
201
- *bufferDeleteCallback = nullptr;
202
- *deleterData = nullptr;
203
- }
204
- }
205
-
206
- static void NAPI_CDECL StoreScript(
207
- void *scriptCache,
208
- const char *sourceUrl,
209
- uint64_t sourceHash,
210
- const char *runtimeName,
211
- uint64_t runtimeVersion,
212
- const char *cacheTag,
213
- const uint8_t *buffer,
214
- size_t bufferSize,
215
- jsr_data_delete_cb bufferDeleteCallback,
216
- void *deleterData) {
217
- auto &scriptStore = reinterpret_cast<HermesScriptCache *>(scriptCache)->scriptStore_;
218
- scriptStore->persistPreparedScript(
219
- HermesJsiBuffer::Create(buffer, bufferSize, bufferDeleteCallback, deleterData),
220
- facebook::jsi::ScriptSignature{sourceUrl, sourceHash},
221
- facebook::jsi::JSRuntimeSignature{runtimeName, runtimeVersion},
222
- cacheTag);
223
- }
224
-
225
- static void NAPI_CDECL Delete(void *scriptCache, void * /*deleterData*/) {
226
- delete reinterpret_cast<HermesScriptCache *>(scriptCache);
227
- }
228
-
229
- private:
230
- std::shared_ptr<facebook::jsi::PreparedScriptStore> scriptStore_;
231
- };
232
-
233
- class HermesLocalConnection : public facebook::react::ILocalConnection {
234
- public:
235
- HermesLocalConnection(
236
- std::unique_ptr<facebook::react::IRemoteConnection> remoteConneciton,
237
- void *connectFunc) noexcept {
238
- CRASH_ON_ERROR(getHermesApi().hermes_create_local_connection(
239
- connectFunc,
240
- reinterpret_cast<hermes_remote_connection>(remoteConneciton.release()),
241
- &OnRemoteConnectionSendMessage,
242
- &OnRemoteConnectionDisconnect,
243
- &OnRemoteConnectionDelete,
244
- nullptr,
245
- &localConnection_));
246
- }
47
+ virtual ~HermesExecutorRuntimeAdapter() = default;
247
48
 
248
- ~HermesLocalConnection() override {
249
- CRASH_ON_ERROR(getHermesApi().hermes_delete_local_connection(localConnection_));
49
+ jsi::Runtime &getRuntime() override {
50
+ return *m_runtime;
250
51
  }
251
52
 
252
- void sendMessage(std::string message) {
253
- CRASH_ON_ERROR(getHermesApi().hermes_local_connection_send_message(localConnection_, message.c_str()));
53
+ facebook::hermes::debugger::Debugger &getDebugger() override {
54
+ return m_hermesRuntime.getDebugger();
254
55
  }
255
56
 
256
- void disconnect() {
257
- CRASH_ON_ERROR(getHermesApi().hermes_local_connection_disconnect(localConnection_));
57
+ void tickleJs() override {
58
+ // The queue will ensure that runtime_ is still valid when this
59
+ // gets invoked.
60
+ m_thread->runOnQueue([&runtime = m_runtime]() {
61
+ auto func = runtime->global().getPropertyAsFunction(*runtime, "__tickleJs");
62
+ func.call(*runtime);
63
+ });
258
64
  }
259
65
 
260
66
  private:
261
- static void NAPI_CDECL OnRemoteConnectionSendMessage(hermes_remote_connection remoteConnection, const char *message) {
262
- reinterpret_cast<facebook::react::IRemoteConnection *>(remoteConnection)->onMessage(message);
263
- }
264
-
265
- static void NAPI_CDECL OnRemoteConnectionDisconnect(hermes_remote_connection remoteConnection) {
266
- reinterpret_cast<facebook::react::IRemoteConnection *>(remoteConnection)->onDisconnect();
267
- }
67
+ std::shared_ptr<jsi::Runtime> m_runtime;
68
+ facebook::hermes::HermesRuntime &m_hermesRuntime;
268
69
 
269
- static void NAPI_CDECL OnRemoteConnectionDelete(void *remoteConnection, void * /*deleterData*/) {
270
- delete reinterpret_cast<facebook::react::IRemoteConnection *>(remoteConnection);
271
- }
272
-
273
- private:
274
- hermes_local_connection localConnection_{};
70
+ std::shared_ptr<MessageQueueThread> m_thread;
275
71
  };
276
-
277
- int32_t NAPI_CDECL addInspectorPage(const char *title, const char *vm, void *connectFunc) noexcept {
278
- return facebook::react::getInspectorInstance().addPage(
279
- title,
280
- vm,
281
- [connectFunc,
282
- hermesApi = HermesApi::current()](std::unique_ptr<facebook::react::IRemoteConnection> remoteConneciton) {
283
- HermesApi::Scope apiScope(hermesApi);
284
- return std::make_unique<HermesLocalConnection>(std::move(remoteConneciton), connectFunc);
285
- });
286
- }
287
-
288
- void NAPI_CDECL removeInspectorPage(int32_t pageId) noexcept {
289
- facebook::react::getInspectorInstance().removePage(pageId);
290
- }
72
+ #endif
291
73
 
292
74
  } // namespace
293
75
 
294
- HermesRuntimeHolder::HermesRuntimeHolder(
295
- std::shared_ptr<facebook::react::DevSettings> devSettings,
296
- std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
297
- std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore) noexcept
298
- : m_weakDevSettings(devSettings),
299
- m_jsQueue(std::move(jsQueue)),
300
- m_preparedScriptStore(std::move(preparedScriptStore)) {}
301
-
302
- HermesRuntimeHolder::~HermesRuntimeHolder() {
303
- if (m_runtime) {
304
- CRASH_ON_ERROR(getHermesApi().jsr_delete_runtime(m_runtime));
305
- }
76
+ void HermesRuntimeHolder::crashHandler(int fileDescriptor) noexcept {
77
+ HermesShim::hermesCrashHandler(*m_hermesRuntime, fileDescriptor);
306
78
  }
307
79
 
308
- void HermesRuntimeHolder::initRuntime() noexcept {
309
- facebook::react::SystraceSection s("HermesExecutorFactory::makeHermesRuntimeSystraced");
310
- std::shared_ptr<facebook::react::DevSettings> devSettings = m_weakDevSettings.lock();
311
- VerifyElseCrash(devSettings);
312
-
313
- HermesApi &api = getHermesApi();
314
- HermesApi::setCurrent(&api);
315
- jsr_config config{};
316
- CRASH_ON_ERROR(api.jsr_create_config(&config));
317
- CRASH_ON_ERROR(api.hermes_config_enable_default_crash_handler(config, devSettings->enableDefaultCrashHandler));
318
- CRASH_ON_ERROR(api.jsr_config_enable_inspector(config, devSettings->useDirectDebugger));
319
- CRASH_ON_ERROR(api.jsr_config_set_inspector_runtime_name(config, devSettings->debuggerRuntimeName.c_str()));
320
- CRASH_ON_ERROR(api.jsr_config_set_inspector_port(config, devSettings->debuggerPort));
321
- CRASH_ON_ERROR(api.jsr_config_set_inspector_break_on_start(config, devSettings->debuggerBreakOnNextLine));
322
- if (m_jsQueue) {
323
- HermesTaskRunner::Create(config, m_jsQueue);
324
- }
325
- if (m_preparedScriptStore) {
326
- HermesScriptCache::Create(config, m_preparedScriptStore);
80
+ void HermesRuntimeHolder::teardown() noexcept {
81
+ #ifdef HERMES_ENABLE_DEBUGGER
82
+ if (auto devSettings = m_weakDevSettings.lock(); devSettings && devSettings->useDirectDebugger) {
83
+ facebook::hermes::inspector::chrome::disableDebugging(*m_hermesRuntime);
327
84
  }
328
- jsr_runtime runtime{};
329
- CRASH_ON_ERROR(api.jsr_create_runtime(config, &runtime));
330
- CRASH_ON_ERROR(api.jsr_delete_config(config));
331
-
332
- napi_env env{};
333
- CRASH_ON_ERROR(api.jsr_runtime_get_node_api_env(runtime, &env));
334
-
335
- m_jsiRuntime = makeNodeApiJsiRuntime(
336
- env, &api, [runtime]() { CRASH_ON_ERROR(HermesApi::current()->jsr_delete_runtime(runtime)); });
337
- m_ownThreadId = std::this_thread::get_id();
338
-
339
- // Add JS engine information to Error.prototype so in error reporting we
340
- // can send this information.
341
- auto errorPrototype = m_jsiRuntime->global()
342
- .getPropertyAsObject(*m_jsiRuntime, "Error")
343
- .getPropertyAsObject(*m_jsiRuntime, "prototype");
344
- errorPrototype.setProperty(*m_jsiRuntime, "jsEngine", "hermes");
85
+ #endif
345
86
  }
346
87
 
347
88
  facebook::react::JSIEngineOverride HermesRuntimeHolder::getRuntimeType() noexcept {
348
89
  return facebook::react::JSIEngineOverride::Hermes;
349
90
  }
350
91
 
351
- std::shared_ptr<facebook::jsi::Runtime> HermesRuntimeHolder::getRuntime() noexcept {
352
- std::call_once(m_onceFlag, [this]() { initRuntime(); });
353
- VerifyElseCrash(m_jsiRuntime);
354
- return m_jsiRuntime;
355
- }
356
-
357
- void HermesRuntimeHolder::crashHandler(int fileDescriptor) noexcept {
358
- CRASH_ON_ERROR(getHermesApi().hermes_dump_crash_data(m_runtime, fileDescriptor));
359
- }
92
+ std::shared_ptr<jsi::Runtime> HermesRuntimeHolder::getRuntime() noexcept {
93
+ std::call_once(m_once_flag, [this]() { initRuntime(); });
360
94
 
361
- void HermesRuntimeHolder::teardown() noexcept {
362
- // TODO: (vmoroz) Implement
363
- }
95
+ if (!m_hermesRuntime)
96
+ std::terminate();
364
97
 
365
- std::shared_ptr<HermesRuntimeHolder> HermesRuntimeHolder::loadFrom(
366
- React::ReactPropertyBag const &propertyBag) noexcept {
367
- return *(propertyBag.Get(HermesRuntimeHolderProperty()));
368
- }
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();
369
101
 
370
- void HermesRuntimeHolder::storeTo(
371
- React::ReactPropertyBag const &propertyBag,
372
- std::shared_ptr<HermesRuntimeHolder> const &holder) noexcept {
373
- propertyBag.Set(HermesRuntimeHolderProperty(), holder);
102
+ return m_hermesRuntime;
374
103
  }
375
104
 
376
- void HermesRuntimeHolder::addToProfiling() const noexcept {
377
- CRASH_ON_ERROR(getHermesApi().hermes_sampling_profiler_add(m_runtime));
378
- }
105
+ HermesRuntimeHolder::HermesRuntimeHolder(
106
+ std::shared_ptr<facebook::react::DevSettings> devSettings,
107
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept
108
+ : m_weakDevSettings(devSettings), m_jsQueue(std::move(jsQueue)) {}
379
109
 
380
- void HermesRuntimeHolder::removeFromProfiling() const noexcept {
381
- CRASH_ON_ERROR(getHermesApi().hermes_sampling_profiler_remove(m_runtime));
382
- }
110
+ void HermesRuntimeHolder::initRuntime() noexcept {
111
+ auto devSettings = m_weakDevSettings.lock();
112
+ if (!devSettings)
113
+ std::terminate();
383
114
 
384
- /*static*/ void HermesRuntimeHolder::enableSamplingProfiler() noexcept {
385
- CRASH_ON_ERROR(getHermesApi().hermes_sampling_profiler_enable());
386
- }
115
+ m_hermesRuntime = makeHermesRuntimeSystraced(devSettings->enableDefaultCrashHandler);
116
+ m_own_thread_id = std::this_thread::get_id();
387
117
 
388
- /*static*/ void HermesRuntimeHolder::disableSamplingProfiler() noexcept {
389
- CRASH_ON_ERROR(getHermesApi().hermes_sampling_profiler_disable());
390
- }
118
+ #ifdef HERMES_ENABLE_DEBUGGER
119
+ if (devSettings->useDirectDebugger) {
120
+ auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(m_hermesRuntime, *m_hermesRuntime, m_jsQueue);
121
+ facebook::hermes::inspector::chrome::enableDebugging(
122
+ std::move(adapter),
123
+ devSettings->debuggerRuntimeName.empty() ? "Hermes React Native" : devSettings->debuggerRuntimeName);
124
+ }
125
+ #endif
391
126
 
392
- /*static*/ void HermesRuntimeHolder::dumpSampledTraceToFile(const std::string &fileName) noexcept {
393
- CRASH_ON_ERROR(getHermesApi().hermes_sampling_profiler_dump_to_file(fileName.c_str()));
127
+ // Add js engine information to Error.prototype so in error reporting we
128
+ // can send this information.
129
+ auto errorPrototype = m_hermesRuntime->global()
130
+ .getPropertyAsObject(*m_hermesRuntime, "Error")
131
+ .getPropertyAsObject(*m_hermesRuntime, "prototype");
132
+ errorPrototype.setProperty(*m_hermesRuntime, "jsEngine", "hermes");
394
133
  }
395
134
 
396
- } // namespace Microsoft::ReactNative
135
+ } // namespace react
136
+ } // namespace facebook
@@ -2,54 +2,43 @@
2
2
  // Licensed under the MIT License.
3
3
 
4
4
  #pragma once
5
- #include <DevSettings.h>
6
5
  #include <JSI/RuntimeHolder.h>
7
- #include <JSI/ScriptStore.h>
8
- #include <ReactPropertyBag.h>
9
- #include <cxxreact/MessageQueueThread.h>
10
- #include <hermes/hermes_api.h>
11
6
 
12
- namespace Microsoft::ReactNative {
7
+ #include <jsi/jsi.h>
8
+ #include <thread>
9
+
10
+ #include <DevSettings.h>
11
+
12
+ namespace facebook::hermes {
13
+ class HermesRuntime;
14
+ }
15
+
16
+ namespace facebook {
17
+ namespace react {
13
18
 
14
19
  class HermesRuntimeHolder : public Microsoft::JSI::RuntimeHolderLazyInit {
15
- public: // RuntimeHolderLazyInit implementation.
20
+ public:
16
21
  std::shared_ptr<facebook::jsi::Runtime> getRuntime() noexcept override;
17
22
  facebook::react::JSIEngineOverride getRuntimeType() noexcept override;
23
+
18
24
  void crashHandler(int fileDescriptor) noexcept override;
25
+
19
26
  void teardown() noexcept override;
20
27
 
21
- public:
22
28
  HermesRuntimeHolder(
23
29
  std::shared_ptr<facebook::react::DevSettings> devSettings,
24
- std::shared_ptr<facebook::react::MessageQueueThread> jsQueue,
25
- std::shared_ptr<facebook::jsi::PreparedScriptStore> preparedScriptStore) noexcept;
26
- ~HermesRuntimeHolder();
27
-
28
- static std::shared_ptr<HermesRuntimeHolder> loadFrom(
29
- winrt::Microsoft::ReactNative::ReactPropertyBag const &propertyBag) noexcept;
30
-
31
- static void storeTo(
32
- winrt::Microsoft::ReactNative::ReactPropertyBag const &propertyBag,
33
- std::shared_ptr<HermesRuntimeHolder> const &holder) noexcept;
34
-
35
- void addToProfiling() const noexcept;
36
- void removeFromProfiling() const noexcept;
37
-
38
- static void enableSamplingProfiler() noexcept;
39
- static void disableSamplingProfiler() noexcept;
40
- static void dumpSampledTraceToFile(const std::string &fileName) noexcept;
30
+ std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) noexcept;
41
31
 
42
32
  private:
43
33
  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;
44
38
 
45
- private:
46
- jsr_runtime m_runtime{};
47
- std::shared_ptr<facebook::jsi::Runtime> m_jsiRuntime;
48
- std::once_flag m_onceFlag{};
49
- std::thread::id m_ownThreadId{};
50
39
  std::weak_ptr<facebook::react::DevSettings> m_weakDevSettings;
51
40
  std::shared_ptr<facebook::react::MessageQueueThread> m_jsQueue;
52
- std::shared_ptr<facebook::jsi::PreparedScriptStore> m_preparedScriptStore;
53
41
  };
54
42
 
55
- } // namespace Microsoft::ReactNative
43
+ } // namespace react
44
+ } // namespace facebook
@@ -3,51 +3,19 @@
3
3
 
4
4
  #include "pch.h"
5
5
 
6
- #include <hermes/hermes_api.h>
6
+ #include <hermes/hermes.h>
7
7
  #include <chrono>
8
8
  #include <future>
9
9
 
10
- #include "HermesRuntimeHolder.h"
11
10
  #include "HermesSamplingProfiler.h"
12
- #include "IReactDispatcher.h"
13
- #include "ReactPropertyBag.h"
11
+ #include "HermesShim.h"
14
12
  #include "Utils.h"
15
13
 
16
- using namespace winrt::Microsoft::ReactNative;
17
- using namespace facebook::react;
18
-
19
14
  namespace Microsoft::ReactNative {
20
15
 
21
16
  namespace {
22
-
23
- // Implements an awaiter for Mso::DispatchQueue
24
- auto resume_in_dispatcher(const IReactDispatcher &dispatcher) noexcept {
25
- struct awaitable {
26
- awaitable(const IReactDispatcher &dispatcher) noexcept : dispatcher_(dispatcher) {}
27
-
28
- bool await_ready() const noexcept {
29
- return false;
30
- }
31
-
32
- void await_resume() const noexcept {}
33
-
34
- void await_suspend(std::experimental::coroutine_handle<> resume) noexcept {
35
- callback_ = [context = resume.address()]() noexcept {
36
- std::experimental::coroutine_handle<>::from_address(context)();
37
- };
38
- dispatcher_.Post(std::move(callback_));
39
- }
40
-
41
- private:
42
- IReactDispatcher dispatcher_;
43
- ReactDispatcherCallback callback_;
44
- };
45
-
46
- return awaitable{dispatcher};
47
- }
48
-
49
17
  std::future<std::string> getTraceFilePath() noexcept {
50
- std::string hermesDataPath = co_await Microsoft::React::getApplicationDataPath(L"Hermes");
18
+ auto hermesDataPath = co_await Microsoft::React::getApplicationDataPath(L"Hermes");
51
19
  std::ostringstream os;
52
20
  auto now = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch())
53
21
  .count();
@@ -55,59 +23,39 @@ std::future<std::string> getTraceFilePath() noexcept {
55
23
  os << hermesDataPath << "\\cpu_" << now << ".cpuprofile";
56
24
  co_return os.str();
57
25
  }
58
-
59
26
  } // namespace
60
27
 
61
- std::atomic_bool HermesSamplingProfiler::s_isStarted{false};
28
+ bool HermesSamplingProfiler::s_isStarted = false;
62
29
  std::string HermesSamplingProfiler::s_lastTraceFilePath;
63
30
 
64
31
  std::string HermesSamplingProfiler::GetLastTraceFilePath() noexcept {
65
32
  return s_lastTraceFilePath;
66
33
  }
67
34
 
68
- winrt::fire_and_forget HermesSamplingProfiler::Start(
69
- Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept {
70
- bool expectedIsStarted = false;
71
- if (s_isStarted.compare_exchange_strong(expectedIsStarted, true)) {
72
- IReactDispatcher jsDispatcher = implementation::ReactDispatcher::GetJSDispatcher(reactContext->Properties());
73
- ReactPropertyBag propertyBag = ReactPropertyBag(reactContext->Properties());
74
-
75
- co_await resume_in_dispatcher(jsDispatcher);
76
- std::shared_ptr<HermesRuntimeHolder> hermesRuntimeHolder = HermesRuntimeHolder::loadFrom(propertyBag);
77
- hermesRuntimeHolder->addToProfiling();
78
-
35
+ winrt::fire_and_forget HermesSamplingProfiler::Start() noexcept {
36
+ if (!s_isStarted) {
37
+ s_isStarted = true;
79
38
  co_await winrt::resume_background();
80
- HermesRuntimeHolder::enableSamplingProfiler();
39
+ HermesShim::enableSamplingProfiler();
81
40
  }
82
41
 
83
42
  co_return;
84
43
  }
85
44
 
86
- std::future<std::string> HermesSamplingProfiler::Stop(
87
- Mso::CntPtr<Mso::React::IReactContext> const &reactContext) noexcept {
88
- bool expectedIsStarted = true;
89
- if (s_isStarted.compare_exchange_strong(expectedIsStarted, false)) {
90
- IReactDispatcher jsDispatcher = implementation::ReactDispatcher::GetJSDispatcher(reactContext->Properties());
91
- ReactPropertyBag propertyBag = ReactPropertyBag(reactContext->Properties());
92
-
45
+ std::future<std::string> HermesSamplingProfiler::Stop() noexcept {
46
+ if (s_isStarted) {
47
+ s_isStarted = false;
93
48
  co_await winrt::resume_background();
94
- HermesRuntimeHolder::disableSamplingProfiler();
95
-
49
+ HermesShim::disableSamplingProfiler();
96
50
  s_lastTraceFilePath = co_await getTraceFilePath();
97
- HermesRuntimeHolder::dumpSampledTraceToFile(s_lastTraceFilePath);
98
-
99
- co_await resume_in_dispatcher(jsDispatcher);
100
- std::shared_ptr<HermesRuntimeHolder> hermesRuntimeHolder = HermesRuntimeHolder::loadFrom(propertyBag);
101
- hermesRuntimeHolder->removeFromProfiling();
102
-
103
- co_await winrt::resume_background();
51
+ HermesShim::dumpSampledTraceToFile(s_lastTraceFilePath);
104
52
  }
105
53
 
106
54
  co_return s_lastTraceFilePath;
107
55
  }
108
56
 
109
57
  bool HermesSamplingProfiler::IsStarted() noexcept {
110
- return s_isStarted.load();
58
+ return s_isStarted;
111
59
  }
112
60
 
113
61
  } // namespace Microsoft::ReactNative