react-native-windows 0.71.26 → 0.71.28
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.
- package/Directory.Build.props +0 -5
- package/Microsoft.ReactNative/IReactDispatcher.cpp +0 -4
- package/Microsoft.ReactNative/IReactDispatcher.h +0 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +4 -2
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +11 -31
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +2 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +3 -3
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +2103 -0
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +73 -0
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +12 -43
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +6 -17
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.targets +1 -1
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.targets +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +4 -4
- package/PropertySheets/React.Cpp.props +0 -1
- package/PropertySheets/Warnings.props +0 -6
- package/ReactCommon/ReactCommon.vcxproj +1 -53
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +0 -36
- package/Shared/DevSupportManager.cpp +9 -2
- package/Shared/DevSupportManager.h +6 -2
- package/Shared/HermesRuntimeHolder.cpp +84 -344
- package/Shared/HermesRuntimeHolder.h +21 -32
- package/Shared/HermesSamplingProfiler.cpp +14 -66
- package/Shared/HermesSamplingProfiler.h +3 -5
- package/Shared/HermesShim.cpp +118 -0
- package/Shared/HermesShim.h +21 -0
- package/Shared/InspectorPackagerConnection.cpp +108 -62
- package/Shared/InspectorPackagerConnection.h +21 -9
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +209 -0
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +44 -0
- package/Shared/JSI/RuntimeHolder.h +2 -2
- package/Shared/JSI/ScriptStore.h +20 -18
- package/Shared/OInstance.cpp +45 -26
- package/Shared/Shared.vcxitems +8 -19
- package/Shared/Shared.vcxitems.filters +30 -23
- package/Shared/V8JSIRuntimeHolder.cpp +70 -0
- package/Shared/V8JSIRuntimeHolder.h +53 -0
- package/package.json +2 -2
- package/template/cs-app-WinAppSDK/proj/ExperimentalFeatures.props +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiLoader.cpp +0 -16
- package/ReactCommon/cgmanifest.json +0 -15
- package/Shared/JSI/V8RuntimeHolder.cpp +0 -260
- package/Shared/JSI/V8RuntimeHolder.h +0 -37
- package/Shared/SafeLoadLibrary.cpp +0 -41
- package/Shared/SafeLoadLibrary.h +0 -15
|
@@ -3,394 +3,134 @@
|
|
|
3
3
|
|
|
4
4
|
#include "pch.h"
|
|
5
5
|
|
|
6
|
-
#include
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <mutex>
|
|
7
8
|
|
|
8
|
-
#include <ApiLoaders/HermesApi.h>
|
|
9
9
|
#include <JSI/decorator.h>
|
|
10
|
-
#include <
|
|
11
|
-
#include <crash/verifyElseCrash.h>
|
|
10
|
+
#include <cxxreact/MessageQueueThread.h>
|
|
12
11
|
#include <cxxreact/SystraceSection.h>
|
|
13
|
-
#include <
|
|
14
|
-
#include
|
|
15
|
-
#include "
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
#if defined(HERMES_ENABLE_DEBUGGER)
|
|
17
|
+
#include <hermes/inspector/chrome/Registration.h>
|
|
18
|
+
#endif
|
|
22
19
|
|
|
23
|
-
using namespace
|
|
20
|
+
using namespace facebook;
|
|
21
|
+
using namespace Microsoft::ReactNative;
|
|
24
22
|
|
|
25
|
-
namespace
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
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
|
-
|
|
249
|
-
|
|
49
|
+
jsi::Runtime &getRuntime() override {
|
|
50
|
+
return *m_runtime;
|
|
250
51
|
}
|
|
251
52
|
|
|
252
|
-
|
|
253
|
-
|
|
53
|
+
facebook::hermes::debugger::Debugger &getDebugger() override {
|
|
54
|
+
return m_hermesRuntime.getDebugger();
|
|
254
55
|
}
|
|
255
56
|
|
|
256
|
-
void
|
|
257
|
-
|
|
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
|
-
|
|
262
|
-
|
|
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
|
-
|
|
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::
|
|
295
|
-
|
|
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::
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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
|
-
|
|
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<
|
|
352
|
-
std::call_once(
|
|
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
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
95
|
+
if (!m_hermesRuntime)
|
|
96
|
+
std::terminate();
|
|
364
97
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
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
|
-
|
|
377
|
-
|
|
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::
|
|
381
|
-
|
|
382
|
-
|
|
110
|
+
void HermesRuntimeHolder::initRuntime() noexcept {
|
|
111
|
+
auto devSettings = m_weakDevSettings.lock();
|
|
112
|
+
if (!devSettings)
|
|
113
|
+
std::terminate();
|
|
383
114
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
115
|
+
m_hermesRuntime = makeHermesRuntimeSystraced(devSettings->enableDefaultCrashHandler);
|
|
116
|
+
m_own_thread_id = std::this_thread::get_id();
|
|
387
117
|
|
|
388
|
-
|
|
389
|
-
|
|
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
|
-
|
|
393
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
43
|
+
} // namespace react
|
|
44
|
+
} // namespace facebook
|
|
@@ -3,51 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
#include "pch.h"
|
|
5
5
|
|
|
6
|
-
#include <hermes/
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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
|
-
|
|
39
|
+
HermesShim::enableSamplingProfiler();
|
|
81
40
|
}
|
|
82
41
|
|
|
83
42
|
co_return;
|
|
84
43
|
}
|
|
85
44
|
|
|
86
|
-
std::future<std::string> HermesSamplingProfiler::Stop(
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
95
|
-
|
|
49
|
+
HermesShim::disableSamplingProfiler();
|
|
96
50
|
s_lastTraceFilePath = co_await getTraceFilePath();
|
|
97
|
-
|
|
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
|
|
58
|
+
return s_isStarted;
|
|
111
59
|
}
|
|
112
60
|
|
|
113
61
|
} // namespace Microsoft::ReactNative
|