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.
- package/Directory.Build.props +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.cpp +169 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggerUIIsland.h +42 -0
- package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +60 -33
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +68 -1
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +9 -0
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +5 -3
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +6 -1
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +14 -1
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.cpp +75 -24
- package/Microsoft.ReactNative/Fabric/platform/react/threading/TaskDispatchThread.h +4 -25
- package/Microsoft.ReactNative/JsiApi.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +3 -0
- package/Microsoft.ReactNative/ReactHost/DebuggerNotifications.h +54 -0
- package/Microsoft.ReactNative/ReactHost/React.h +11 -4
- package/Microsoft.ReactNative/ReactHost/ReactHost.cpp +195 -29
- package/Microsoft.ReactNative/ReactHost/ReactHost.h +22 -4
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +24 -5
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
- package/Microsoft.ReactNative/ReactRootView.cpp +108 -0
- package/Microsoft.ReactNative/ReactRootView.h +6 -0
- package/Microsoft.ReactNative/Views/DevMenu.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/JSEngine.props +1 -1
- package/PropertySheets/React.Cpp.props +2 -2
- package/ReactCommon/ReactCommon.vcxproj +18 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +1 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +4 -4
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.cpp +23 -9
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsinspector-modern/NetworkIOAgent.h +16 -0
- package/ReactCommon/cgmanifest.json +1 -1
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -0
- package/Shared/DevServerHelper.h +13 -3
- package/Shared/DevSettings.h +7 -0
- package/Shared/DevSupportManager.cpp +79 -20
- package/Shared/DevSupportManager.h +7 -19
- package/Shared/Hermes/HermesRuntimeAgentDelegate.cpp +99 -0
- package/Shared/Hermes/HermesRuntimeAgentDelegate.h +81 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.cpp +263 -0
- package/Shared/Hermes/HermesRuntimeTargetDelegate.h +77 -0
- package/Shared/HermesRuntimeHolder.cpp +29 -111
- package/Shared/HermesRuntimeHolder.h +214 -32
- package/Shared/IDevSupportManager.h +5 -2
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.cpp +108 -0
- package/Shared/Inspector/ReactInspectorPackagerConnectionDelegate.h +19 -0
- package/Shared/Inspector/ReactInspectorThread.h +18 -0
- package/Shared/JSI/RuntimeHolder.h +5 -2
- package/Shared/OInstance.cpp +44 -27
- package/Shared/Shared.vcxitems +27 -17
- package/Shared/Shared.vcxitems.filters +33 -15
- package/package.json +4 -4
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.cpp +0 -79
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.h +0 -51
- package/Microsoft.ReactNative.Cxx/ApiLoaders/JSRuntimeApi.inc +0 -50
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.cpp +0 -41
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.h +0 -127
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi.inc +0 -125
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_posix.cpp +0 -16
- package/Microsoft.ReactNative.Cxx/ApiLoaders/NodeApi_win.cpp +0 -23
- package/Microsoft.ReactNative.Cxx/JSI/decorator.h +0 -1054
- package/Microsoft.ReactNative.Cxx/JSI/instrumentation.h +0 -145
- package/Microsoft.ReactNative.Cxx/JSI/jsi-inl.h +0 -372
- package/Microsoft.ReactNative.Cxx/JSI/jsi.cpp +0 -797
- package/Microsoft.ReactNative.Cxx/JSI/jsi.h +0 -1799
- package/Microsoft.ReactNative.Cxx/JSI/threadsafe.h +0 -79
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.cpp +0 -3531
- package/Microsoft.ReactNative.Cxx/NodeApiJsiRuntime.h +0 -38
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api.h +0 -614
- package/Microsoft.ReactNative.Cxx/node-api/js_native_api_types.h +0 -212
- package/Microsoft.ReactNative.Cxx/node-api/js_runtime_api.h +0 -199
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +0 -78
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.h +0 -196
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jserrorhandler/JsErrorHandler.cpp +0 -429
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.cpp +0 -45
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsitooling/react/runtime/JSRuntimeFactory.h +0 -91
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +0 -670
- package/Shared/InspectorPackagerConnection.cpp +0 -232
- package/Shared/InspectorPackagerConnection.h +0 -61
- /package/Shared/{HermesSamplingProfiler.cpp → Hermes/HermesSamplingProfiler.cpp} +0 -0
- /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
|