@react-native-ohos/react-native-reanimated 3.18.2 → 3.18.3-beta.2

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 (94) hide show
  1. package/LICENSE +21 -21
  2. package/README.OpenSource +10 -10
  3. package/README.md +10 -10
  4. package/harmony/reanimated/BuildProfile.ets +1 -1
  5. package/harmony/reanimated/build-profile.json5 +11 -11
  6. package/harmony/reanimated/oh-package-lock.json5 +29 -0
  7. package/harmony/reanimated/oh-package.json5 +11 -11
  8. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.cpp +86 -86
  9. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/AnimatedSensor/AnimatedSensorModule.h +47 -47
  10. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/PropsRegistry.cpp +68 -68
  11. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/PropsRegistry.h +73 -68
  12. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.cpp +101 -101
  13. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitHook.h +51 -51
  14. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedCommitShadowNode.h +49 -49
  15. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.cpp +96 -96
  16. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ReanimatedMountHook.h +33 -33
  17. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.cpp +95 -95
  18. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Fabric/ShadowTreeCloner.h +29 -29
  19. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationType.h +9 -9
  20. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.cpp +232 -232
  21. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsManager.h +90 -90
  22. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.cpp +870 -870
  23. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsProxy.h +147 -147
  24. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.cpp +91 -91
  25. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/LayoutAnimations/LayoutAnimationsUtils.h +176 -176
  26. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp +971 -971
  27. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h +252 -254
  28. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.cpp +231 -231
  29. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxySpec.h +109 -109
  30. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.cpp +56 -56
  31. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/RNRuntimeDecorator.h +20 -20
  32. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.cpp +70 -70
  33. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/RuntimeDecorators/UIRuntimeDecorator.h +35 -35
  34. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/CollectionUtils.h +14 -14
  35. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeaturesConfig.cpp +5 -5
  36. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/FeaturesConfig.h +19 -19
  37. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/PlatformDepMethodsHolder.h +98 -98
  38. package/harmony/reanimated/src/main/cpp/Common/cpp/reanimated/Tools/ReanimatedSystraceSection.h +135 -135
  39. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.cpp +47 -47
  40. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxy.h +59 -59
  41. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.cpp +27 -27
  42. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/NativeModules/WorkletsModuleProxySpec.h +25 -25
  43. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/EventHandlerRegistry.cpp +94 -94
  44. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/EventHandlerRegistry.h +49 -49
  45. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.cpp +8 -8
  46. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Registries/WorkletRuntimeRegistry.h +39 -39
  47. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/SharedItems/Shareables.cpp +326 -326
  48. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/SharedItems/Shareables.h +345 -345
  49. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/AsyncQueue.cpp +52 -52
  50. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/AsyncQueue.h +35 -35
  51. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/Defs.h +10 -10
  52. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSISerializer.cpp +342 -342
  53. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSISerializer.h +47 -47
  54. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSLogger.cpp +16 -16
  55. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSLogger.h +20 -20
  56. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSScheduler.cpp +20 -20
  57. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/JSScheduler.h +29 -29
  58. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/PlatformLogger.h +16 -16
  59. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedJSIUtils.cpp +26 -26
  60. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedJSIUtils.h +199 -199
  61. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedVersion.cpp +95 -95
  62. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ReanimatedVersion.h +19 -19
  63. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/SingleInstanceChecker.h +72 -72
  64. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/ThreadSafeQueue.h +49 -49
  65. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/UIScheduler.cpp +20 -20
  66. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/UIScheduler.h +22 -22
  67. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/WorkletEventHandler.cpp +29 -29
  68. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/Tools/WorkletEventHandler.h +41 -41
  69. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.cpp +16 -16
  70. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h +19 -19
  71. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedHermesRuntime.cpp +112 -112
  72. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedHermesRuntime.h +127 -127
  73. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedRuntime.cpp +53 -53
  74. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/ReanimatedRuntime.h +22 -22
  75. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/RuntimeInitialization.md +191 -191
  76. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.cpp +173 -173
  77. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntime.h +90 -90
  78. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeCollector.h +36 -36
  79. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.cpp +189 -189
  80. package/harmony/reanimated/src/main/cpp/Common/cpp/worklets/WorkletRuntime/WorkletRuntimeDecorator.h +22 -22
  81. package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +4 -6
  82. package/harmony/reanimated/src/main/cpp/WorkletsModule.cpp +60 -60
  83. package/harmony/reanimated/src/main/cpp/patches/AnimatedSensor/AnimatedSensorModule.cpp +89 -89
  84. package/harmony/reanimated/src/main/cpp/patches/NativeModules/ReanimatedModuleProxy.cpp +22 -4
  85. package/harmony/reanimated/src/main/ets/ReanimatedModule.ts +88 -13
  86. package/harmony/reanimated/src/main/module.json5 +12 -12
  87. package/harmony/reanimated/src/main/resources/base/element/color.json +7 -7
  88. package/harmony/reanimated/src/main/resources/base/element/string.json +15 -15
  89. package/harmony/reanimated/src/main/resources/base/profile/main_pages.json +5 -5
  90. package/harmony/reanimated/src/main/resources/en_US/element/string.json +15 -15
  91. package/harmony/reanimated/src/main/resources/zh_CN/element/string.json +15 -15
  92. package/harmony/reanimated/ts.ts +6 -6
  93. package/harmony/reanimated.har +0 -0
  94. package/package.json +51 -50
@@ -1,326 +1,326 @@
1
- #include <worklets/SharedItems/Shareables.h>
2
-
3
- using namespace facebook;
4
-
5
- namespace worklets {
6
-
7
- jsi::Function getValueUnpacker(jsi::Runtime &rt) {
8
- auto valueUnpacker = rt.global().getProperty(rt, "__valueUnpacker");
9
- assert(valueUnpacker.isObject() && "valueUnpacker not found");
10
- return valueUnpacker.asObject(rt).asFunction(rt);
11
- }
12
-
13
- #ifndef NDEBUG
14
-
15
- static const auto callGuardLambda = [](facebook::jsi::Runtime &rt,
16
- const facebook::jsi::Value &thisVal,
17
- const facebook::jsi::Value *args,
18
- size_t count) {
19
- return args[0].asObject(rt).asFunction(rt).call(rt, args + 1, count - 1);
20
- };
21
-
22
- jsi::Function getCallGuard(jsi::Runtime &rt) {
23
- auto callGuard = rt.global().getProperty(rt, "__callGuardDEV");
24
- if (callGuard.isObject()) {
25
- // Use JS implementation if `__callGuardDEV` has already been installed.
26
- // This is the desired behavior.
27
- return callGuard.asObject(rt).asFunction(rt);
28
- }
29
-
30
- // Otherwise, fallback to C++ JSI implementation. This is necessary so that we
31
- // can install `__callGuardDEV` itself and should happen only once. Note that
32
- // the C++ implementation doesn't intercept errors and simply throws them as
33
- // C++ exceptions which crashes the app. We assume that installing the guard
34
- // doesn't throw any errors.
35
- return jsi::Function::createFromHostFunction(
36
- rt, jsi::PropNameID::forAscii(rt, "callGuard"), 1, callGuardLambda);
37
- }
38
-
39
- #endif // NDEBUG
40
-
41
- jsi::Value makeShareableClone(
42
- jsi::Runtime &rt,
43
- const jsi::Value &value,
44
- const jsi::Value &shouldRetainRemote,
45
- const jsi::Value &nativeStateSource) {
46
- std::shared_ptr<Shareable> shareable;
47
- if (value.isObject()) {
48
- auto object = value.asObject(rt);
49
- if (!object.getProperty(rt, "__workletHash").isUndefined()) {
50
- if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
51
- shareable =
52
- std::make_shared<RetainingShareable<ShareableWorklet>>(rt, object);
53
- } else {
54
- shareable = std::make_shared<ShareableWorklet>(rt, object);
55
- }
56
- } else if (!object.getProperty(rt, "__init").isUndefined()) {
57
- shareable = std::make_shared<ShareableHandle>(rt, object);
58
- } else if (object.isFunction(rt)) {
59
- auto function = object.asFunction(rt);
60
- if (function.isHostFunction(rt)) {
61
- shareable =
62
- std::make_shared<ShareableHostFunction>(rt, std::move(function));
63
- } else {
64
- shareable =
65
- std::make_shared<ShareableRemoteFunction>(rt, std::move(function));
66
- }
67
- } else if (object.isArray(rt)) {
68
- if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
69
- shareable = std::make_shared<RetainingShareable<ShareableArray>>(
70
- rt, object.asArray(rt));
71
- } else {
72
- shareable = std::make_shared<ShareableArray>(rt, object.asArray(rt));
73
- }
74
- } else if (object.isArrayBuffer(rt)) {
75
- shareable =
76
- std::make_shared<ShareableArrayBuffer>(rt, object.getArrayBuffer(rt));
77
- } else if (object.isHostObject(rt)) {
78
- if (object.isHostObject<ShareableJSRef>(rt)) {
79
- return object;
80
- }
81
- shareable =
82
- std::make_shared<ShareableHostObject>(rt, object.getHostObject(rt));
83
- } else {
84
- if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
85
- shareable = std::make_shared<RetainingShareable<ShareableObject>>(
86
- rt, object, nativeStateSource);
87
- } else {
88
- shareable =
89
- std::make_shared<ShareableObject>(rt, object, nativeStateSource);
90
- }
91
- }
92
- } else if (value.isString()) {
93
- shareable = std::make_shared<ShareableString>(value.asString(rt).utf8(rt));
94
- } else if (value.isUndefined()) {
95
- shareable = std::make_shared<ShareableScalar>();
96
- } else if (value.isNull()) {
97
- shareable = std::make_shared<ShareableScalar>(nullptr);
98
- } else if (value.isBool()) {
99
- shareable = std::make_shared<ShareableScalar>(value.getBool());
100
- } else if (value.isNumber()) {
101
- shareable = std::make_shared<ShareableScalar>(value.getNumber());
102
- } else if (value.isBigInt()) {
103
- shareable = std::make_shared<ShareableBigInt>(rt, value.getBigInt(rt));
104
- } else if (value.isSymbol()) {
105
- // TODO: this is only a placeholder implementation, here we replace symbols
106
- // with strings in order to make certain objects to be captured. There isn't
107
- // yet any usecase for using symbols on the UI runtime so it is fine to keep
108
- // it like this for now.
109
- shareable =
110
- std::make_shared<ShareableString>(value.getSymbol(rt).toString(rt));
111
- } else {
112
- throw std::runtime_error(
113
- "[Reanimated] Attempted to convert an unsupported value type.");
114
- }
115
- return ShareableJSRef::newHostObject(rt, shareable);
116
- }
117
-
118
- std::shared_ptr<Shareable> extractShareableOrThrow(
119
- jsi::Runtime &rt,
120
- const jsi::Value &maybeShareableValue,
121
- const std::string &errorMessage) {
122
- if (maybeShareableValue.isObject()) {
123
- auto object = maybeShareableValue.asObject(rt);
124
- if (object.isHostObject<ShareableJSRef>(rt)) {
125
- return object.getHostObject<ShareableJSRef>(rt)->value();
126
- }
127
- throw std::runtime_error(
128
- "[Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.");
129
- } else if (maybeShareableValue.isUndefined()) {
130
- return Shareable::undefined();
131
- }
132
- throw std::runtime_error(errorMessage);
133
- }
134
-
135
- Shareable::~Shareable() {}
136
-
137
- std::shared_ptr<Shareable> Shareable::undefined() {
138
- static auto undefined = std::make_shared<ShareableScalar>();
139
- return undefined;
140
- }
141
-
142
- template <typename BaseClass>
143
- jsi::Value RetainingShareable<BaseClass>::toJSValue(jsi::Runtime &rt) {
144
- if (&rt == primaryRuntime_) {
145
- // TODO: it is suboptimal to generate new object every time getJS is
146
- // called on host runtime – the objects we are generating already exists
147
- // and we should possibly just grab a hold of such object and use it here
148
- // instead of creating a new JS representation. As far as I understand the
149
- // only case where it can be realistically called this way is when a
150
- // shared value is created and then accessed on the same runtime
151
- return BaseClass::toJSValue(rt);
152
- }
153
- if (secondaryValue_ == nullptr) {
154
- auto value = BaseClass::toJSValue(rt);
155
- secondaryValue_ = std::make_unique<jsi::Value>(rt, value);
156
- secondaryRuntime_ = &rt;
157
- return value;
158
- }
159
- if (&rt == secondaryRuntime_) {
160
- return jsi::Value(rt, *secondaryValue_);
161
- }
162
- return BaseClass::toJSValue(rt);
163
- }
164
-
165
- ShareableJSRef::~ShareableJSRef() {}
166
-
167
- ShareableArray::ShareableArray(jsi::Runtime &rt, const jsi::Array &array)
168
- : Shareable(ArrayType) {
169
- auto size = array.size(rt);
170
- data_.reserve(size);
171
- for (size_t i = 0; i < size; i++) {
172
- data_.push_back(extractShareableOrThrow(rt, array.getValueAtIndex(rt, i)));
173
- }
174
- }
175
-
176
- jsi::Value ShareableArray::toJSValue(jsi::Runtime &rt) {
177
- auto size = data_.size();
178
- auto ary = jsi::Array(rt, size);
179
- for (size_t i = 0; i < size; i++) {
180
- ary.setValueAtIndex(rt, i, data_[i]->toJSValue(rt));
181
- }
182
- return ary;
183
- }
184
-
185
- jsi::Value ShareableArrayBuffer::toJSValue(jsi::Runtime &rt) {
186
- auto size = static_cast<int>(data_.size());
187
- auto arrayBuffer = rt.global()
188
- .getPropertyAsFunction(rt, "ArrayBuffer")
189
- .callAsConstructor(rt, size)
190
- .getObject(rt)
191
- .getArrayBuffer(rt);
192
- memcpy(arrayBuffer.data(rt), data_.data(), size);
193
- return arrayBuffer;
194
- }
195
-
196
- ShareableObject::ShareableObject(jsi::Runtime &rt, const jsi::Object &object)
197
- : Shareable(ObjectType) {
198
- auto propertyNames = object.getPropertyNames(rt);
199
- auto size = propertyNames.size(rt);
200
- data_.reserve(size);
201
- for (size_t i = 0; i < size; i++) {
202
- auto key = propertyNames.getValueAtIndex(rt, i).asString(rt);
203
- auto value = extractShareableOrThrow(rt, object.getProperty(rt, key));
204
- data_.emplace_back(key.utf8(rt), value);
205
- }
206
- if (object.hasNativeState(rt)) {
207
- nativeState_ = object.getNativeState(rt);
208
- }
209
- }
210
-
211
- ShareableObject::ShareableObject(
212
- jsi::Runtime &rt,
213
- const jsi::Object &object,
214
- const jsi::Value &nativeStateSource)
215
- : ShareableObject(rt, object) {
216
- if (nativeStateSource.isObject() &&
217
- nativeStateSource.asObject(rt).hasNativeState(rt)) {
218
- nativeState_ = nativeStateSource.asObject(rt).getNativeState(rt);
219
- }
220
- }
221
-
222
- jsi::Value ShareableObject::toJSValue(jsi::Runtime &rt) {
223
- auto obj = jsi::Object(rt);
224
- for (size_t i = 0, size = data_.size(); i < size; i++) {
225
- obj.setProperty(
226
- rt,
227
- jsi::String::createFromUtf8(rt, data_[i].first),
228
- data_[i].second->toJSValue(rt));
229
- }
230
- if (nativeState_ != nullptr) {
231
- obj.setNativeState(rt, nativeState_);
232
- }
233
- return obj;
234
- }
235
-
236
- jsi::Value ShareableHostObject::toJSValue(jsi::Runtime &rt) {
237
- return jsi::Object::createFromHostObject(rt, hostObject_);
238
- }
239
-
240
- jsi::Value ShareableHostFunction::toJSValue(jsi::Runtime &rt) {
241
- return jsi::Function::createFromHostFunction(
242
- rt, jsi::PropNameID::forUtf8(rt, name_), paramCount_, hostFunction_);
243
- }
244
-
245
- jsi::Value ShareableWorklet::toJSValue(jsi::Runtime &rt) {
246
- assert(
247
- std::any_of(
248
- data_.cbegin(),
249
- data_.cend(),
250
- [](const auto &item) { return item.first == "__workletHash"; }) &&
251
- "ShareableWorklet doesn't have `__workletHash` property");
252
- jsi::Value obj = ShareableObject::toJSValue(rt);
253
- return getValueUnpacker(rt).call(
254
- rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
255
- }
256
-
257
- jsi::Value ShareableRemoteFunction::toJSValue(jsi::Runtime &rt) {
258
- if (&rt == runtime_) {
259
- return jsi::Value(rt, *function_);
260
- } else {
261
- #ifndef NDEBUG
262
- return getValueUnpacker(rt).call(
263
- rt,
264
- ShareableJSRef::newHostObject(rt, shared_from_this()),
265
- jsi::String::createFromAscii(rt, "RemoteFunction"),
266
- jsi::String::createFromUtf8(rt, name_));
267
- #else
268
- return ShareableJSRef::newHostObject(rt, shared_from_this());
269
- #endif
270
- }
271
- }
272
-
273
- jsi::Value ShareableHandle::toJSValue(jsi::Runtime &rt) {
274
- if (remoteValue_ == nullptr) {
275
- auto initObj = initializer_->toJSValue(rt);
276
- auto value = std::make_unique<jsi::Value>(getValueUnpacker(rt).call(
277
- rt, initObj, jsi::String::createFromAscii(rt, "Handle")));
278
-
279
- // We are locking the initialization here since the thread that is
280
- // initalizing can be pre-empted on runtime lock. E.g.
281
- // UI thread can be pre-empted on initialization of a shared value and then
282
- // JS thread can try to access the shared value, locking the whole runtime.
283
- // If we put the lock on `getValueUnpacker` part (basically any part that
284
- // requires runtime) we would get a deadlock since UI thread would never
285
- // release it.
286
- std::unique_lock<std::mutex> lock(initializationMutex_);
287
- if (remoteValue_ == nullptr) {
288
- remoteValue_ = std::move(value);
289
- remoteRuntime_ = &rt;
290
- }
291
- }
292
- if (&rt == remoteRuntime_) {
293
- return jsi::Value(rt, *remoteValue_);
294
- }
295
- auto initObj = initializer_->toJSValue(rt);
296
- return getValueUnpacker(rt).call(
297
- rt, initObj, jsi::String::createFromAscii(rt, "Handle"));
298
- }
299
-
300
- jsi::Value ShareableString::toJSValue(jsi::Runtime &rt) {
301
- return jsi::String::createFromUtf8(rt, data_);
302
- }
303
-
304
- jsi::Value ShareableBigInt::toJSValue(jsi::Runtime &rt) {
305
- return rt.global()
306
- .getPropertyAsFunction(rt, "BigInt")
307
- .call(rt, jsi::String::createFromUtf8(rt, string_));
308
- }
309
-
310
- jsi::Value ShareableScalar::toJSValue(jsi::Runtime &) {
311
- switch (valueType_) {
312
- case Shareable::UndefinedType:
313
- return jsi::Value();
314
- case Shareable::NullType:
315
- return jsi::Value(nullptr);
316
- case Shareable::BooleanType:
317
- return jsi::Value(data_.boolean);
318
- case Shareable::NumberType:
319
- return jsi::Value(data_.number);
320
- default:
321
- throw std::runtime_error(
322
- "[Reanimated] Attempted to convert object that's not of a scalar type.");
323
- }
324
- }
325
-
326
- } // namespace worklets
1
+ #include <worklets/SharedItems/Shareables.h>
2
+
3
+ using namespace facebook;
4
+
5
+ namespace worklets {
6
+
7
+ jsi::Function getValueUnpacker(jsi::Runtime &rt) {
8
+ auto valueUnpacker = rt.global().getProperty(rt, "__valueUnpacker");
9
+ assert(valueUnpacker.isObject() && "valueUnpacker not found");
10
+ return valueUnpacker.asObject(rt).asFunction(rt);
11
+ }
12
+
13
+ #ifndef NDEBUG
14
+
15
+ static const auto callGuardLambda = [](facebook::jsi::Runtime &rt,
16
+ const facebook::jsi::Value &thisVal,
17
+ const facebook::jsi::Value *args,
18
+ size_t count) {
19
+ return args[0].asObject(rt).asFunction(rt).call(rt, args + 1, count - 1);
20
+ };
21
+
22
+ jsi::Function getCallGuard(jsi::Runtime &rt) {
23
+ auto callGuard = rt.global().getProperty(rt, "__callGuardDEV");
24
+ if (callGuard.isObject()) {
25
+ // Use JS implementation if `__callGuardDEV` has already been installed.
26
+ // This is the desired behavior.
27
+ return callGuard.asObject(rt).asFunction(rt);
28
+ }
29
+
30
+ // Otherwise, fallback to C++ JSI implementation. This is necessary so that we
31
+ // can install `__callGuardDEV` itself and should happen only once. Note that
32
+ // the C++ implementation doesn't intercept errors and simply throws them as
33
+ // C++ exceptions which crashes the app. We assume that installing the guard
34
+ // doesn't throw any errors.
35
+ return jsi::Function::createFromHostFunction(
36
+ rt, jsi::PropNameID::forAscii(rt, "callGuard"), 1, callGuardLambda);
37
+ }
38
+
39
+ #endif // NDEBUG
40
+
41
+ jsi::Value makeShareableClone(
42
+ jsi::Runtime &rt,
43
+ const jsi::Value &value,
44
+ const jsi::Value &shouldRetainRemote,
45
+ const jsi::Value &nativeStateSource) {
46
+ std::shared_ptr<Shareable> shareable;
47
+ if (value.isObject()) {
48
+ auto object = value.asObject(rt);
49
+ if (!object.getProperty(rt, "__workletHash").isUndefined()) {
50
+ if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
51
+ shareable =
52
+ std::make_shared<RetainingShareable<ShareableWorklet>>(rt, object);
53
+ } else {
54
+ shareable = std::make_shared<ShareableWorklet>(rt, object);
55
+ }
56
+ } else if (!object.getProperty(rt, "__init").isUndefined()) {
57
+ shareable = std::make_shared<ShareableHandle>(rt, object);
58
+ } else if (object.isFunction(rt)) {
59
+ auto function = object.asFunction(rt);
60
+ if (function.isHostFunction(rt)) {
61
+ shareable =
62
+ std::make_shared<ShareableHostFunction>(rt, std::move(function));
63
+ } else {
64
+ shareable =
65
+ std::make_shared<ShareableRemoteFunction>(rt, std::move(function));
66
+ }
67
+ } else if (object.isArray(rt)) {
68
+ if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
69
+ shareable = std::make_shared<RetainingShareable<ShareableArray>>(
70
+ rt, object.asArray(rt));
71
+ } else {
72
+ shareable = std::make_shared<ShareableArray>(rt, object.asArray(rt));
73
+ }
74
+ } else if (object.isArrayBuffer(rt)) {
75
+ shareable =
76
+ std::make_shared<ShareableArrayBuffer>(rt, object.getArrayBuffer(rt));
77
+ } else if (object.isHostObject(rt)) {
78
+ if (object.isHostObject<ShareableJSRef>(rt)) {
79
+ return object;
80
+ }
81
+ shareable =
82
+ std::make_shared<ShareableHostObject>(rt, object.getHostObject(rt));
83
+ } else {
84
+ if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
85
+ shareable = std::make_shared<RetainingShareable<ShareableObject>>(
86
+ rt, object, nativeStateSource);
87
+ } else {
88
+ shareable =
89
+ std::make_shared<ShareableObject>(rt, object, nativeStateSource);
90
+ }
91
+ }
92
+ } else if (value.isString()) {
93
+ shareable = std::make_shared<ShareableString>(value.asString(rt).utf8(rt));
94
+ } else if (value.isUndefined()) {
95
+ shareable = std::make_shared<ShareableScalar>();
96
+ } else if (value.isNull()) {
97
+ shareable = std::make_shared<ShareableScalar>(nullptr);
98
+ } else if (value.isBool()) {
99
+ shareable = std::make_shared<ShareableScalar>(value.getBool());
100
+ } else if (value.isNumber()) {
101
+ shareable = std::make_shared<ShareableScalar>(value.getNumber());
102
+ } else if (value.isBigInt()) {
103
+ shareable = std::make_shared<ShareableBigInt>(rt, value.getBigInt(rt));
104
+ } else if (value.isSymbol()) {
105
+ // TODO: this is only a placeholder implementation, here we replace symbols
106
+ // with strings in order to make certain objects to be captured. There isn't
107
+ // yet any usecase for using symbols on the UI runtime so it is fine to keep
108
+ // it like this for now.
109
+ shareable =
110
+ std::make_shared<ShareableString>(value.getSymbol(rt).toString(rt));
111
+ } else {
112
+ throw std::runtime_error(
113
+ "[Reanimated] Attempted to convert an unsupported value type.");
114
+ }
115
+ return ShareableJSRef::newHostObject(rt, shareable);
116
+ }
117
+
118
+ std::shared_ptr<Shareable> extractShareableOrThrow(
119
+ jsi::Runtime &rt,
120
+ const jsi::Value &maybeShareableValue,
121
+ const std::string &errorMessage) {
122
+ if (maybeShareableValue.isObject()) {
123
+ auto object = maybeShareableValue.asObject(rt);
124
+ if (object.isHostObject<ShareableJSRef>(rt)) {
125
+ return object.getHostObject<ShareableJSRef>(rt)->value();
126
+ }
127
+ throw std::runtime_error(
128
+ "[Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.");
129
+ } else if (maybeShareableValue.isUndefined()) {
130
+ return Shareable::undefined();
131
+ }
132
+ throw std::runtime_error(errorMessage);
133
+ }
134
+
135
+ Shareable::~Shareable() {}
136
+
137
+ std::shared_ptr<Shareable> Shareable::undefined() {
138
+ static auto undefined = std::make_shared<ShareableScalar>();
139
+ return undefined;
140
+ }
141
+
142
+ template <typename BaseClass>
143
+ jsi::Value RetainingShareable<BaseClass>::toJSValue(jsi::Runtime &rt) {
144
+ if (&rt == primaryRuntime_) {
145
+ // TODO: it is suboptimal to generate new object every time getJS is
146
+ // called on host runtime – the objects we are generating already exists
147
+ // and we should possibly just grab a hold of such object and use it here
148
+ // instead of creating a new JS representation. As far as I understand the
149
+ // only case where it can be realistically called this way is when a
150
+ // shared value is created and then accessed on the same runtime
151
+ return BaseClass::toJSValue(rt);
152
+ }
153
+ if (secondaryValue_ == nullptr) {
154
+ auto value = BaseClass::toJSValue(rt);
155
+ secondaryValue_ = std::make_unique<jsi::Value>(rt, value);
156
+ secondaryRuntime_ = &rt;
157
+ return value;
158
+ }
159
+ if (&rt == secondaryRuntime_) {
160
+ return jsi::Value(rt, *secondaryValue_);
161
+ }
162
+ return BaseClass::toJSValue(rt);
163
+ }
164
+
165
+ ShareableJSRef::~ShareableJSRef() {}
166
+
167
+ ShareableArray::ShareableArray(jsi::Runtime &rt, const jsi::Array &array)
168
+ : Shareable(ArrayType) {
169
+ auto size = array.size(rt);
170
+ data_.reserve(size);
171
+ for (size_t i = 0; i < size; i++) {
172
+ data_.push_back(extractShareableOrThrow(rt, array.getValueAtIndex(rt, i)));
173
+ }
174
+ }
175
+
176
+ jsi::Value ShareableArray::toJSValue(jsi::Runtime &rt) {
177
+ auto size = data_.size();
178
+ auto ary = jsi::Array(rt, size);
179
+ for (size_t i = 0; i < size; i++) {
180
+ ary.setValueAtIndex(rt, i, data_[i]->toJSValue(rt));
181
+ }
182
+ return ary;
183
+ }
184
+
185
+ jsi::Value ShareableArrayBuffer::toJSValue(jsi::Runtime &rt) {
186
+ auto size = static_cast<int>(data_.size());
187
+ auto arrayBuffer = rt.global()
188
+ .getPropertyAsFunction(rt, "ArrayBuffer")
189
+ .callAsConstructor(rt, size)
190
+ .getObject(rt)
191
+ .getArrayBuffer(rt);
192
+ memcpy(arrayBuffer.data(rt), data_.data(), size);
193
+ return arrayBuffer;
194
+ }
195
+
196
+ ShareableObject::ShareableObject(jsi::Runtime &rt, const jsi::Object &object)
197
+ : Shareable(ObjectType) {
198
+ auto propertyNames = object.getPropertyNames(rt);
199
+ auto size = propertyNames.size(rt);
200
+ data_.reserve(size);
201
+ for (size_t i = 0; i < size; i++) {
202
+ auto key = propertyNames.getValueAtIndex(rt, i).asString(rt);
203
+ auto value = extractShareableOrThrow(rt, object.getProperty(rt, key));
204
+ data_.emplace_back(key.utf8(rt), value);
205
+ }
206
+ if (object.hasNativeState(rt)) {
207
+ nativeState_ = object.getNativeState(rt);
208
+ }
209
+ }
210
+
211
+ ShareableObject::ShareableObject(
212
+ jsi::Runtime &rt,
213
+ const jsi::Object &object,
214
+ const jsi::Value &nativeStateSource)
215
+ : ShareableObject(rt, object) {
216
+ if (nativeStateSource.isObject() &&
217
+ nativeStateSource.asObject(rt).hasNativeState(rt)) {
218
+ nativeState_ = nativeStateSource.asObject(rt).getNativeState(rt);
219
+ }
220
+ }
221
+
222
+ jsi::Value ShareableObject::toJSValue(jsi::Runtime &rt) {
223
+ auto obj = jsi::Object(rt);
224
+ for (size_t i = 0, size = data_.size(); i < size; i++) {
225
+ obj.setProperty(
226
+ rt,
227
+ jsi::String::createFromUtf8(rt, data_[i].first),
228
+ data_[i].second->toJSValue(rt));
229
+ }
230
+ if (nativeState_ != nullptr) {
231
+ obj.setNativeState(rt, nativeState_);
232
+ }
233
+ return obj;
234
+ }
235
+
236
+ jsi::Value ShareableHostObject::toJSValue(jsi::Runtime &rt) {
237
+ return jsi::Object::createFromHostObject(rt, hostObject_);
238
+ }
239
+
240
+ jsi::Value ShareableHostFunction::toJSValue(jsi::Runtime &rt) {
241
+ return jsi::Function::createFromHostFunction(
242
+ rt, jsi::PropNameID::forUtf8(rt, name_), paramCount_, hostFunction_);
243
+ }
244
+
245
+ jsi::Value ShareableWorklet::toJSValue(jsi::Runtime &rt) {
246
+ assert(
247
+ std::any_of(
248
+ data_.cbegin(),
249
+ data_.cend(),
250
+ [](const auto &item) { return item.first == "__workletHash"; }) &&
251
+ "ShareableWorklet doesn't have `__workletHash` property");
252
+ jsi::Value obj = ShareableObject::toJSValue(rt);
253
+ return getValueUnpacker(rt).call(
254
+ rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
255
+ }
256
+
257
+ jsi::Value ShareableRemoteFunction::toJSValue(jsi::Runtime &rt) {
258
+ if (&rt == runtime_) {
259
+ return jsi::Value(rt, *function_);
260
+ } else {
261
+ #ifndef NDEBUG
262
+ return getValueUnpacker(rt).call(
263
+ rt,
264
+ ShareableJSRef::newHostObject(rt, shared_from_this()),
265
+ jsi::String::createFromAscii(rt, "RemoteFunction"),
266
+ jsi::String::createFromUtf8(rt, name_));
267
+ #else
268
+ return ShareableJSRef::newHostObject(rt, shared_from_this());
269
+ #endif
270
+ }
271
+ }
272
+
273
+ jsi::Value ShareableHandle::toJSValue(jsi::Runtime &rt) {
274
+ if (remoteValue_ == nullptr) {
275
+ auto initObj = initializer_->toJSValue(rt);
276
+ auto value = std::make_unique<jsi::Value>(getValueUnpacker(rt).call(
277
+ rt, initObj, jsi::String::createFromAscii(rt, "Handle")));
278
+
279
+ // We are locking the initialization here since the thread that is
280
+ // initalizing can be pre-empted on runtime lock. E.g.
281
+ // UI thread can be pre-empted on initialization of a shared value and then
282
+ // JS thread can try to access the shared value, locking the whole runtime.
283
+ // If we put the lock on `getValueUnpacker` part (basically any part that
284
+ // requires runtime) we would get a deadlock since UI thread would never
285
+ // release it.
286
+ std::unique_lock<std::mutex> lock(initializationMutex_);
287
+ if (remoteValue_ == nullptr) {
288
+ remoteValue_ = std::move(value);
289
+ remoteRuntime_ = &rt;
290
+ }
291
+ }
292
+ if (&rt == remoteRuntime_) {
293
+ return jsi::Value(rt, *remoteValue_);
294
+ }
295
+ auto initObj = initializer_->toJSValue(rt);
296
+ return getValueUnpacker(rt).call(
297
+ rt, initObj, jsi::String::createFromAscii(rt, "Handle"));
298
+ }
299
+
300
+ jsi::Value ShareableString::toJSValue(jsi::Runtime &rt) {
301
+ return jsi::String::createFromUtf8(rt, data_);
302
+ }
303
+
304
+ jsi::Value ShareableBigInt::toJSValue(jsi::Runtime &rt) {
305
+ return rt.global()
306
+ .getPropertyAsFunction(rt, "BigInt")
307
+ .call(rt, jsi::String::createFromUtf8(rt, string_));
308
+ }
309
+
310
+ jsi::Value ShareableScalar::toJSValue(jsi::Runtime &) {
311
+ switch (valueType_) {
312
+ case Shareable::UndefinedType:
313
+ return jsi::Value();
314
+ case Shareable::NullType:
315
+ return jsi::Value(nullptr);
316
+ case Shareable::BooleanType:
317
+ return jsi::Value(data_.boolean);
318
+ case Shareable::NumberType:
319
+ return jsi::Value(data_.number);
320
+ default:
321
+ throw std::runtime_error(
322
+ "[Reanimated] Attempted to convert object that's not of a scalar type.");
323
+ }
324
+ }
325
+
326
+ } // namespace worklets