react-native-windows 0.80.1 → 0.80.5

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 (83) hide show
  1. package/Directory.Build.props +1 -1
  2. package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.cpp +169 -0
  3. package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.h +42 -0
  4. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
  5. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +60 -33
  6. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +68 -1
  7. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
  8. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +5 -3
  9. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
  10. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
  11. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
  12. package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
  13. package/Microsoft.ReactNative/JsiApi.cpp +1 -1
  14. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
  15. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
  16. package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
  17. package/Microsoft.ReactNative/ReactHost/React.h +11 -4
  18. package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
  19. package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
  20. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
  21. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  22. package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
  23. package/Microsoft.ReactNative/ReactRootView.h +6 -0
  24. package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
  25. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
  26. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  27. package/PropertySheets/JSEngine.props +1 -1
  28. package/PropertySheets/React.Cpp.props +2 -2
  29. package/ReactCommon/ReactCommon.vcxproj +18 -1
  30. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
  31. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
  32. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
  33. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
  34. package/ReactCommon/cgmanifest.json +1 -1
  35. package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
  36. package/Shared/DevServerHelper.h +13 -3
  37. package/Shared/DevSettings.h +7 -0
  38. package/Shared/DevSupportManager.cpp +79 -20
  39. package/Shared/DevSupportManager.h +7 -19
  40. package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
  41. package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
  42. package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
  43. package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
  44. package/Shared/HermesRuntimeHolder.cpp +29 -111
  45. package/Shared/HermesRuntimeHolder.h +214 -32
  46. package/Shared/IDevSupportManager.h +5 -2
  47. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
  48. package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
  49. package/Shared/Inspector/ReactInspectorThread.h +18 -0
  50. package/Shared/JSI/RuntimeHolder.h +5 -2
  51. package/Shared/OInstance.cpp +44 -27
  52. package/Shared/Shared.vcxitems +27 -17
  53. package/Shared/Shared.vcxitems.filters +33 -15
  54. package/package.json +4 -4
  55. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +0 -79
  56. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.h +0 -51
  57. package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +0 -50
  58. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.cpp +0 -41
  59. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.h +0 -127
  60. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.inc +0 -125
  61. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +0 -16
  62. package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_win.cpp +0 -23
  63. package/Microsoft.ReactNative.Cxx/JSI/decorator.h +0 -1054
  64. package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +0 -145
  65. package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +0 -372
  66. package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +0 -797
  67. package/Microsoft.ReactNative.Cxx/JSI/jsi.h +0 -1799
  68. package/Microsoft.ReactNative.Cxx/JSI/threadsafe.h +0 -79
  69. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +0 -3531
  70. package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +0 -38
  71. package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +0 -614
  72. package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +0 -212
  73. package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +0 -199
  74. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
  75. package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
  76. package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
  77. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
  78. package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
  79. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
  80. package/Shared/InspectorPackagerConnection.cpp +0 -232
  81. package/Shared/InspectorPackagerConnection.h +0 -61
  82. /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
  83. /package/Shared/{HermesSamplingProfiler.h → Hermes/HermesSamplingProfiler.h} +0 -0
@@ -1,670 +0,0 @@
1
- /*
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
-
8
- #include "ReactInstance.h"
9
-
10
- #include <ReactCommon/RuntimeExecutor.h>
11
- #include <cxxreact/ErrorUtils.h>
12
- #include <cxxreact/JSBigString.h>
13
- #include <cxxreact/JSExecutor.h>
14
- #include <cxxreact/ReactMarker.h>
15
- #include <cxxreact/TraceSection.h>
16
- #include <glog/logging.h>
17
- #include <jsi/JSIDynamic.h>
18
- #include <jsi/instrumentation.h>
19
- #include <jsinspector-modern/HostTarget.h>
20
- #include <jsireact/JSIExecutor.h>
21
- #include <react/featureflags/ReactNativeFeatureFlags.h>
22
- #include <react/renderer/core/ShadowNode.h>
23
- #include <react/renderer/runtimescheduler/RuntimeSchedulerBinding.h>
24
- #include <react/utils/jsi-utils.h>
25
- #include <iostream>
26
- #include <memory>
27
- #include <utility>
28
-
29
- namespace facebook::react {
30
-
31
- namespace {
32
-
33
- std::shared_ptr<RuntimeScheduler> createRuntimeScheduler(
34
- RuntimeExecutor runtimeExecutor,
35
- RuntimeSchedulerTaskErrorHandler taskErrorHandler) {
36
- std::shared_ptr<RuntimeScheduler> scheduler =
37
- std::make_shared<RuntimeScheduler>(
38
- runtimeExecutor, RuntimeSchedulerClock::now, taskErrorHandler);
39
- scheduler->setPerformanceEntryReporter(
40
- // FIXME: Move creation of PerformanceEntryReporter to here and
41
- // guarantee that its lifetime is the same as the runtime.
42
- PerformanceEntryReporter::getInstance().get());
43
-
44
- return scheduler;
45
- }
46
-
47
- } // namespace
48
-
49
- ReactInstance::ReactInstance(
50
- std::unique_ptr<JSRuntime> runtime,
51
- std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
52
- std::shared_ptr<TimerManager> timerManager,
53
- JsErrorHandler::OnJsError onJsError,
54
- jsinspector_modern::HostTarget* parentInspectorTarget)
55
- : runtime_(std::move(runtime)),
56
- jsMessageQueueThread_(jsMessageQueueThread),
57
- timerManager_(std::move(timerManager)),
58
- jsErrorHandler_(std::make_shared<JsErrorHandler>(std::move(onJsError))),
59
- parentInspectorTarget_(parentInspectorTarget) {
60
- RuntimeExecutor runtimeExecutor =
61
- [weakRuntime = std::weak_ptr(runtime_),
62
- weakTimerManager = std::weak_ptr(timerManager_),
63
- weakJsThread = std::weak_ptr(jsMessageQueueThread_),
64
- jsErrorHandler = jsErrorHandler_](auto callback) {
65
- if (weakRuntime.expired()) {
66
- return;
67
- }
68
-
69
- if (auto jsThread = weakJsThread.lock()) {
70
- jsThread->runOnQueue([jsErrorHandler,
71
- weakRuntime,
72
- weakTimerManager,
73
- callback = std::move(callback)]() {
74
- auto runtime = weakRuntime.lock();
75
- if (!runtime) {
76
- return;
77
- }
78
-
79
- jsi::Runtime& jsiRuntime = runtime->getRuntime();
80
- TraceSection s("ReactInstance::_runtimeExecutor[Callback]");
81
- try {
82
- ShadowNode::setUseRuntimeShadowNodeReferenceUpdateOnThread(true);
83
- callback(jsiRuntime);
84
- } catch (jsi::JSError& originalError) {
85
- jsErrorHandler->handleError(jsiRuntime, originalError, true);
86
- } catch (std::exception& ex) {
87
- jsi::JSError error(
88
- jsiRuntime, std::string("Non-js exception: ") + ex.what());
89
- jsErrorHandler->handleError(jsiRuntime, error, true);
90
- }
91
- });
92
- }
93
- };
94
-
95
- if (parentInspectorTarget_) {
96
- auto executor = parentInspectorTarget_->executorFromThis();
97
-
98
- auto bufferedRuntimeExecutorThatWaitsForInspectorSetup =
99
- std::make_shared<BufferedRuntimeExecutor>(runtimeExecutor);
100
- auto runtimeExecutorThatExecutesAfterInspectorSetup =
101
- [bufferedRuntimeExecutorThatWaitsForInspectorSetup](
102
- std::function<void(jsi::Runtime & runtime)>&& callback) {
103
- bufferedRuntimeExecutorThatWaitsForInspectorSetup->execute(
104
- std::move(callback));
105
- };
106
-
107
- runtimeScheduler_ = createRuntimeScheduler(
108
- runtimeExecutorThatExecutesAfterInspectorSetup,
109
- [jsErrorHandler = jsErrorHandler_](
110
- jsi::Runtime& runtime, jsi::JSError& error) {
111
- jsErrorHandler->handleError(runtime, error, true);
112
- });
113
-
114
- auto runtimeExecutorThatGoesThroughRuntimeScheduler =
115
- [runtimeScheduler = runtimeScheduler_.get()](
116
- std::function<void(jsi::Runtime & runtime)>&& callback) {
117
- runtimeScheduler->scheduleWork(std::move(callback));
118
- };
119
-
120
- // This code can execute from any thread, so we need to make sure we set up
121
- // the inspector logic in the right one. The callback executes immediately
122
- // if we are already in the right thread.
123
- executor([this,
124
- runtimeExecutorThatGoesThroughRuntimeScheduler,
125
- bufferedRuntimeExecutorThatWaitsForInspectorSetup](
126
- jsinspector_modern::HostTarget& hostTarget) {
127
- // Callbacks scheduled through the page target executor are generally
128
- // not guaranteed to run (e.g.: if the page target is destroyed)
129
- // but in this case it is because the page target cannot be destroyed
130
- // before the instance finishes its setup:
131
- // * On iOS it's because we do the setup synchronously.
132
- // * On Android it's because we explicitly wait for the instance
133
- // creation task to finish before starting the destruction.
134
- inspectorTarget_ = &hostTarget.registerInstance(*this);
135
- runtimeInspectorTarget_ =
136
- &inspectorTarget_->registerRuntime(*runtime_, runtimeExecutorThatGoesThroughRuntimeScheduler); // [Windows #13172]
137
- bufferedRuntimeExecutorThatWaitsForInspectorSetup->flush();
138
- });
139
- } else {
140
- runtimeScheduler_ = createRuntimeScheduler(
141
- runtimeExecutor,
142
- [jsErrorHandler = jsErrorHandler_](
143
- jsi::Runtime& runtime, jsi::JSError& error) {
144
- jsErrorHandler->handleError(runtime, error, true);
145
- });
146
- }
147
-
148
- bufferedRuntimeExecutor_ = std::make_shared<BufferedRuntimeExecutor>(
149
- [runtimeScheduler = runtimeScheduler_.get()](
150
- std::function<void(jsi::Runtime & runtime)>&& callback) {
151
- runtimeScheduler->scheduleWork(std::move(callback));
152
- });
153
- }
154
-
155
- void ReactInstance::unregisterFromInspector() {
156
- if (inspectorTarget_) {
157
- assert(runtimeInspectorTarget_);
158
- inspectorTarget_->unregisterRuntime(*runtimeInspectorTarget_);
159
-
160
- assert(parentInspectorTarget_);
161
- parentInspectorTarget_->unregisterInstance(*inspectorTarget_);
162
-
163
- inspectorTarget_ = nullptr;
164
- }
165
- }
166
-
167
- RuntimeExecutor ReactInstance::getUnbufferedRuntimeExecutor() noexcept {
168
- return [runtimeScheduler = runtimeScheduler_.get()](
169
- std::function<void(jsi::Runtime & runtime)>&& callback) {
170
- runtimeScheduler->scheduleWork(std::move(callback));
171
- };
172
- }
173
-
174
- // This BufferedRuntimeExecutor ensures that the main JS bundle finished
175
- // execution before any JS queued into it from C++ are executed. Use
176
- // getUnbufferedRuntimeExecutor() instead if you do not need the main JS bundle
177
- // to have finished. e.g. setting global variables into JS runtime.
178
- RuntimeExecutor ReactInstance::getBufferedRuntimeExecutor() noexcept {
179
- return [weakBufferedRuntimeExecutor_ =
180
- std::weak_ptr<BufferedRuntimeExecutor>(bufferedRuntimeExecutor_)](
181
- std::function<void(jsi::Runtime & runtime)>&& callback) {
182
- if (auto strongBufferedRuntimeExecutor_ =
183
- weakBufferedRuntimeExecutor_.lock()) {
184
- strongBufferedRuntimeExecutor_->execute(std::move(callback));
185
- }
186
- };
187
- }
188
-
189
- // TODO(T184010230): Should the RuntimeScheduler returned from this method be
190
- // buffered?
191
- std::shared_ptr<RuntimeScheduler>
192
- ReactInstance::getRuntimeScheduler() noexcept {
193
- return runtimeScheduler_;
194
- }
195
-
196
- namespace {
197
-
198
- // Copied from JSIExecutor.cpp
199
- // basename_r isn't in all iOS SDKs, so use this simple version instead.
200
- std::string simpleBasename(const std::string& path) {
201
- size_t pos = path.rfind("/");
202
- return (pos != std::string::npos) ? path.substr(pos) : path;
203
- }
204
-
205
- } // namespace
206
-
207
- /**
208
- * Load the JS bundle and flush buffered JS calls, future JS calls won't be
209
- * buffered after calling this.
210
- * Note that this method is asynchronous. However, a completion callback
211
- * isn't needed because all calls into JS should be dispatched to the JSThread,
212
- * preferably via the runtimeExecutor_.
213
- */
214
- void ReactInstance::loadScript(
215
- std::unique_ptr<const JSBigString> script,
216
- const std::string& sourceURL,
217
- std::function<void(jsi::Runtime& runtime)>&& beforeLoad,
218
- std::function<void(jsi::Runtime& runtime)>&& afterLoad) {
219
- auto buffer = std::make_shared<BigStringBuffer>(std::move(script));
220
- std::string scriptName = simpleBasename(sourceURL);
221
-
222
- runtimeScheduler_->scheduleWork([this,
223
- scriptName,
224
- sourceURL,
225
- buffer = std::move(buffer),
226
- weakBufferedRuntimeExecuter =
227
- std::weak_ptr<BufferedRuntimeExecutor>(
228
- bufferedRuntimeExecutor_),
229
- beforeLoad,
230
- afterLoad](jsi::Runtime& runtime) {
231
- if (beforeLoad) {
232
- beforeLoad(runtime);
233
- }
234
- TraceSection s("ReactInstance::loadScript");
235
- bool hasLogger(ReactMarker::logTaggedMarkerBridgelessImpl);
236
- if (hasLogger) {
237
- ReactMarker::logTaggedMarkerBridgeless(
238
- ReactMarker::RUN_JS_BUNDLE_START, scriptName.c_str());
239
- }
240
-
241
- runtime.evaluateJavaScript(buffer, sourceURL);
242
-
243
- /**
244
- * TODO(T183610671): We need a safe/reliable way to enable the js
245
- * pipeline from javascript. Remove this after we figure that out, or
246
- * after we just remove the js pipeline.
247
- */
248
- if (!jsErrorHandler_->hasHandledFatalError()) {
249
- jsErrorHandler_->setRuntimeReady();
250
- }
251
-
252
- if (hasLogger) {
253
- ReactMarker::logTaggedMarkerBridgeless(
254
- ReactMarker::RUN_JS_BUNDLE_STOP, scriptName.c_str());
255
- ReactMarker::logMarkerBridgeless(ReactMarker::INIT_REACT_RUNTIME_STOP);
256
- ReactMarker::logMarkerBridgeless(ReactMarker::APP_STARTUP_STOP);
257
- }
258
- if (auto strongBufferedRuntimeExecuter =
259
- weakBufferedRuntimeExecuter.lock()) {
260
- strongBufferedRuntimeExecuter->flush();
261
- }
262
- if (afterLoad) {
263
- afterLoad(runtime);
264
- }
265
- });
266
- }
267
-
268
- /*
269
- * Calls a method on a JS module that has been registered with
270
- * `registerCallableModule`. Used to invoke a JS function from platform code.
271
- */
272
- void ReactInstance::callFunctionOnModule(
273
- const std::string& moduleName,
274
- const std::string& methodName,
275
- folly::dynamic&& args) {
276
- if (bufferedRuntimeExecutor_ == nullptr) {
277
- LOG(ERROR)
278
- << "Calling callFunctionOnModule with null BufferedRuntimeExecutor";
279
- return;
280
- }
281
-
282
- bufferedRuntimeExecutor_->execute([this,
283
- moduleName = moduleName,
284
- methodName = methodName,
285
- args = std::move(args)](
286
- jsi::Runtime& runtime) {
287
- TraceSection s(
288
- "ReactInstance::callFunctionOnModule",
289
- "moduleName",
290
- moduleName,
291
- "methodName",
292
- methodName);
293
- auto it = callableModules_.find(moduleName);
294
- if (it == callableModules_.end()) {
295
- std::ostringstream knownModules;
296
- int i = 0;
297
- for (it = callableModules_.begin(); it != callableModules_.end();
298
- it++, i++) {
299
- const char* space = (i > 0 ? ", " : " ");
300
- knownModules << space << it->first;
301
- }
302
- throw jsi::JSError(
303
- runtime,
304
- "Failed to call into JavaScript module method " + moduleName + "." +
305
- methodName +
306
- "(). Module has not been registered as callable. Registered callable JavaScript modules (n = " +
307
- std::to_string(callableModules_.size()) +
308
- "):" + knownModules.str() +
309
- ". Did you forget to call `registerCallableModule`?");
310
- }
311
-
312
- if (std::holds_alternative<jsi::Function>(it->second)) {
313
- auto module =
314
- std::get<jsi::Function>(it->second).call(runtime).asObject(runtime);
315
- it->second = std::move(module);
316
- }
317
-
318
- auto& module = std::get<jsi::Object>(it->second);
319
- auto method = module.getPropertyAsFunction(runtime, methodName.c_str());
320
-
321
- std::vector<jsi::Value> jsArgs;
322
- for (auto& arg : args) {
323
- jsArgs.push_back(jsi::valueFromDynamic(runtime, arg));
324
- }
325
- method.callWithThis(
326
- runtime, module, (const jsi::Value*)jsArgs.data(), jsArgs.size());
327
- });
328
- }
329
-
330
- void ReactInstance::registerSegment(
331
- uint32_t segmentId,
332
- const std::string& segmentPath) {
333
- LOG(WARNING) << "Starting to run ReactInstance::registerSegment with segment "
334
- << segmentId;
335
- runtimeScheduler_->scheduleWork([=](jsi::Runtime& runtime) {
336
- TraceSection s("ReactInstance::registerSegment");
337
- auto tag = std::to_string(segmentId);
338
- auto script = JSBigFileString::fromPath(segmentPath);
339
- if (script->size() == 0) {
340
- throw std::invalid_argument(
341
- "Empty segment registered with ID " + tag + " from " + segmentPath);
342
- }
343
- auto buffer = std::make_shared<BigStringBuffer>(std::move(script));
344
-
345
- bool hasLogger(ReactMarker::logTaggedMarkerBridgelessImpl);
346
- if (hasLogger) {
347
- ReactMarker::logTaggedMarkerBridgeless(
348
- ReactMarker::REGISTER_JS_SEGMENT_START, tag.c_str());
349
- }
350
- LOG(WARNING) << "Starting to evaluate segment " << segmentId
351
- << " in ReactInstance::registerSegment";
352
- runtime.evaluateJavaScript(
353
- buffer, JSExecutor::getSyntheticBundlePath(segmentId, segmentPath));
354
- LOG(WARNING) << "Finished evaluating segment " << segmentId
355
- << " in ReactInstance::registerSegment";
356
- if (hasLogger) {
357
- ReactMarker::logTaggedMarkerBridgeless(
358
- ReactMarker::REGISTER_JS_SEGMENT_STOP, tag.c_str());
359
- }
360
- });
361
- }
362
-
363
- namespace {
364
- void defineReactInstanceFlags(
365
- jsi::Runtime& runtime,
366
- ReactInstance::JSRuntimeFlags options) noexcept {
367
- defineReadOnlyGlobal(runtime, "RN$Bridgeless", jsi::Value(true));
368
-
369
- if (options.isProfiling) {
370
- defineReadOnlyGlobal(runtime, "__RCTProfileIsProfiling", jsi::Value(true));
371
- }
372
-
373
- if (options.runtimeDiagnosticFlags.length() > 0) {
374
- defineReadOnlyGlobal(
375
- runtime,
376
- "RN$DiagnosticFlags",
377
- jsi::String::createFromUtf8(runtime, options.runtimeDiagnosticFlags));
378
- }
379
- }
380
-
381
- bool isTruthy(jsi::Runtime& runtime, const jsi::Value& value) {
382
- auto Boolean = runtime.global().getPropertyAsFunction(runtime, "Boolean");
383
- return Boolean.call(runtime, value).getBool();
384
- }
385
-
386
- } // namespace
387
-
388
- void ReactInstance::initializeRuntime(
389
- JSRuntimeFlags options,
390
- BindingsInstallFunc bindingsInstallFunc) noexcept {
391
- runtimeScheduler_->scheduleWork([this, options, bindingsInstallFunc](
392
- jsi::Runtime& runtime) {
393
- TraceSection s("ReactInstance::initializeRuntime");
394
-
395
- bindNativePerformanceNow(runtime);
396
-
397
- RuntimeSchedulerBinding::createAndInstallIfNeeded(
398
- runtime, runtimeScheduler_);
399
-
400
- runtime_->unstable_initializeOnJsThread();
401
-
402
- defineReactInstanceFlags(runtime, options);
403
-
404
- defineReadOnlyGlobal(
405
- runtime,
406
- "RN$useAlwaysAvailableJSErrorHandling",
407
- jsi::Value(
408
- ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling()));
409
-
410
- defineReadOnlyGlobal(
411
- runtime,
412
- "RN$isRuntimeReady",
413
- jsi::Function::createFromHostFunction(
414
- runtime,
415
- jsi::PropNameID::forAscii(runtime, "isRuntimeReady"),
416
- 0,
417
- [jsErrorHandler = jsErrorHandler_](
418
- jsi::Runtime& /*runtime*/,
419
- const jsi::Value& /*unused*/,
420
- const jsi::Value* /*args*/,
421
- size_t /*count*/) {
422
- return jsErrorHandler->isRuntimeReady();
423
- }));
424
-
425
- defineReadOnlyGlobal(
426
- runtime,
427
- "RN$hasHandledFatalException",
428
- jsi::Function::createFromHostFunction(
429
- runtime,
430
- jsi::PropNameID::forAscii(runtime, "hasHandledFatalException"),
431
- 0,
432
- [jsErrorHandler = jsErrorHandler_](
433
- jsi::Runtime& /*runtime*/,
434
- const jsi::Value& /*unused*/,
435
- const jsi::Value* /*args*/,
436
- size_t /*count*/) {
437
- return jsErrorHandler->hasHandledFatalError();
438
- }));
439
-
440
- defineReadOnlyGlobal(
441
- runtime,
442
- "RN$notifyOfFatalException",
443
- jsi::Function::createFromHostFunction(
444
- runtime,
445
- jsi::PropNameID::forAscii(runtime, "notifyOfFatalException"),
446
- 0,
447
- [jsErrorHandler = jsErrorHandler_](
448
- jsi::Runtime& /*runtime*/,
449
- const jsi::Value& /*unused*/,
450
- const jsi::Value* /*args*/,
451
- size_t /*count*/) {
452
- jsErrorHandler->notifyOfFatalError();
453
- return jsi::Value::undefined();
454
- }));
455
-
456
- defineReadOnlyGlobal(
457
- runtime,
458
- "RN$inExceptionHandler",
459
- jsi::Function::createFromHostFunction(
460
- runtime,
461
- jsi::PropNameID::forAscii(runtime, "inExceptionHandler"),
462
- 0,
463
- [jsErrorHandler = jsErrorHandler_](
464
- jsi::Runtime& /*runtime*/,
465
- const jsi::Value& /*unused*/,
466
- const jsi::Value* /*args*/,
467
- size_t /*count*/) {
468
- return jsErrorHandler->inErrorHandler();
469
- }));
470
-
471
- // TODO(T196834299): We should really use a C++ turbomodule for this
472
- defineReadOnlyGlobal(
473
- runtime,
474
- "RN$handleException",
475
- jsi::Function::createFromHostFunction(
476
- runtime,
477
- jsi::PropNameID::forAscii(runtime, "handleException"),
478
- 3,
479
- [jsErrorHandler = jsErrorHandler_](
480
- jsi::Runtime& runtime,
481
- const jsi::Value& /*unused*/,
482
- const jsi::Value* args,
483
- size_t count) {
484
- if (count < 2) {
485
- throw jsi::JSError(
486
- runtime,
487
- "handleException requires 3 arguments: error, isFatal, logToConsole (optional)");
488
- }
489
-
490
- auto isFatal = isTruthy(runtime, args[1]);
491
-
492
- if (!ReactNativeFeatureFlags::
493
- useAlwaysAvailableJSErrorHandling()) {
494
- if (jsErrorHandler->isRuntimeReady()) {
495
- return jsi::Value(false);
496
- }
497
- }
498
-
499
- auto jsError =
500
- jsi::JSError(runtime, jsi::Value(runtime, args[0]));
501
-
502
- if (count == 2) {
503
- jsErrorHandler->handleError(runtime, jsError, isFatal);
504
- } else {
505
- auto logToConsole = isTruthy(runtime, args[2]);
506
- jsErrorHandler->handleError(
507
- runtime, jsError, isFatal, logToConsole);
508
- }
509
-
510
- return jsi::Value(true);
511
- }));
512
-
513
- defineReadOnlyGlobal(
514
- runtime,
515
- "RN$registerExceptionListener",
516
- jsi::Function::createFromHostFunction(
517
- runtime,
518
- jsi::PropNameID::forAscii(runtime, "registerExceptionListener"),
519
- 1,
520
- [errorListeners = std::vector<std::shared_ptr<jsi::Function>>(),
521
- jsErrorHandler = jsErrorHandler_](
522
- jsi::Runtime& runtime,
523
- const jsi::Value& /*unused*/,
524
- const jsi::Value* args,
525
- size_t count) mutable {
526
- if (count < 1) {
527
- throw jsi::JSError(
528
- runtime,
529
- "registerExceptionListener: requires 1 argument: fn");
530
- }
531
-
532
- if (!args[0].isObject() ||
533
- !args[0].getObject(runtime).isFunction(runtime)) {
534
- throw jsi::JSError(
535
- runtime,
536
- "registerExceptionListener: The first argument must be a function");
537
- }
538
-
539
- auto errorListener = std::make_shared<jsi::Function>(
540
- args[0].getObject(runtime).getFunction(runtime));
541
- errorListeners.emplace_back(errorListener);
542
-
543
- jsErrorHandler->registerErrorListener(
544
- [weakErrorListener = std::weak_ptr<jsi::Function>(
545
- errorListener)](jsi::Runtime& runtime, jsi::Value data) {
546
- if (auto strongErrorListener = weakErrorListener.lock()) {
547
- strongErrorListener->call(runtime, data);
548
- }
549
- });
550
-
551
- return jsi::Value::undefined();
552
- }));
553
-
554
- defineReadOnlyGlobal(
555
- runtime,
556
- "RN$registerCallableModule",
557
- jsi::Function::createFromHostFunction(
558
- runtime,
559
- jsi::PropNameID::forAscii(runtime, "registerCallableModule"),
560
- 2,
561
- [this](
562
- jsi::Runtime& runtime,
563
- const jsi::Value& /*unused*/,
564
- const jsi::Value* args,
565
- size_t count) {
566
- if (count != 2) {
567
- throw jsi::JSError(
568
- runtime,
569
- "registerCallableModule requires exactly 2 arguments");
570
- }
571
- if (!args[0].isString()) {
572
- throw jsi::JSError(
573
- runtime,
574
- "The first argument to registerCallableModule must be a string (the name of the JS module).");
575
- }
576
- auto name = args[0].asString(runtime).utf8(runtime);
577
- if (!args[1].isObject() ||
578
- !args[1].getObject(runtime).isFunction(runtime)) {
579
- throw jsi::JSError(
580
- runtime,
581
- "The second argument to registerCallableModule must be a function that returns the JS module.");
582
- }
583
- callableModules_.emplace(
584
- std::move(name),
585
- args[1].getObject(runtime).getFunction(runtime));
586
- return jsi::Value::undefined();
587
- }));
588
-
589
- timerManager_->attachGlobals(runtime);
590
-
591
- bindingsInstallFunc(runtime);
592
- });
593
- }
594
-
595
- void ReactInstance::handleMemoryPressureJs(int pressureLevel) {
596
- // The level is an enum value passed by the Android OS to an onTrimMemory
597
- // event callback. Defined in ComponentCallbacks2.
598
- enum AndroidMemoryPressure {
599
- TRIM_MEMORY_BACKGROUND = 40,
600
- TRIM_MEMORY_COMPLETE = 80,
601
- TRIM_MEMORY_MODERATE = 60,
602
- TRIM_MEMORY_RUNNING_CRITICAL = 15,
603
- TRIM_MEMORY_RUNNING_LOW = 10,
604
- TRIM_MEMORY_RUNNING_MODERATE = 5,
605
- TRIM_MEMORY_UI_HIDDEN = 20,
606
- };
607
- const char* levelName;
608
- switch (pressureLevel) {
609
- case TRIM_MEMORY_BACKGROUND:
610
- levelName = "TRIM_MEMORY_BACKGROUND";
611
- break;
612
- case TRIM_MEMORY_COMPLETE:
613
- levelName = "TRIM_MEMORY_COMPLETE";
614
- break;
615
- case TRIM_MEMORY_MODERATE:
616
- levelName = "TRIM_MEMORY_MODERATE";
617
- break;
618
- case TRIM_MEMORY_RUNNING_CRITICAL:
619
- levelName = "TRIM_MEMORY_RUNNING_CRITICAL";
620
- break;
621
- case TRIM_MEMORY_RUNNING_LOW:
622
- levelName = "TRIM_MEMORY_RUNNING_LOW";
623
- break;
624
- case TRIM_MEMORY_RUNNING_MODERATE:
625
- levelName = "TRIM_MEMORY_RUNNING_MODERATE";
626
- break;
627
- case TRIM_MEMORY_UI_HIDDEN:
628
- levelName = "TRIM_MEMORY_UI_HIDDEN";
629
- break;
630
- default:
631
- levelName = "UNKNOWN";
632
- break;
633
- }
634
-
635
- switch (pressureLevel) {
636
- case TRIM_MEMORY_RUNNING_LOW:
637
- case TRIM_MEMORY_RUNNING_MODERATE:
638
- case TRIM_MEMORY_UI_HIDDEN:
639
- // For non-severe memory trims, do nothing.
640
- LOG(INFO) << "Memory warning (pressure level: " << levelName
641
- << ") received by JS VM, ignoring because it's non-severe";
642
- break;
643
- case TRIM_MEMORY_BACKGROUND:
644
- case TRIM_MEMORY_COMPLETE:
645
- case TRIM_MEMORY_MODERATE:
646
- case TRIM_MEMORY_RUNNING_CRITICAL:
647
- // For now, pressureLevel is unused by collectGarbage.
648
- // This may change in the future if the JS GC has different styles of
649
- // collections.
650
- LOG(INFO) << "Memory warning (pressure level: " << levelName
651
- << ") received by JS VM, running a GC";
652
- runtimeScheduler_->scheduleWork([=](jsi::Runtime& runtime) {
653
- TraceSection s("ReactInstance::handleMemoryPressure");
654
- runtime.instrumentation().collectGarbage(levelName);
655
- });
656
- break;
657
- default:
658
- // Use the raw number instead of the name here since the name is
659
- // meaningless.
660
- LOG(WARNING) << "Memory warning (pressure level: " << pressureLevel
661
- << ") received by JS VM, unrecognized pressure level";
662
- break;
663
- }
664
- }
665
-
666
- void* ReactInstance::getJavaScriptContext() {
667
- return &runtime_->getRuntime();
668
- }
669
-
670
- } // namespace facebook::react