Skip to content

Commit 7d7a3ee

Browse files
RSNarafacebook-github-bot
authored andcommitted
[skip ci] Fabric: Export shadow node family to javascript (facebook#51146)
Summary: InteresectionObserver caches shadow nodes in javascript. This is hazardous: caching shadow nodes could lead to memory leaks. Therefore, this diff exports shadow node families to javascript via fabric ui manager. This way, we don't have to cache the shadow nodes in js. Changelog: [ Reviewed By: yungsters Differential Revision: D74262805
1 parent 4cc8a67 commit 7d7a3ee

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

packages/react-native/Libraries/ReactNative/FabricUIManager.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import defineLazyObjectProperty from '../Utilities/defineLazyObjectProperty';
2727

2828
export type NodeSet = Array<Node>;
2929
export type NodeProps = {...};
30+
export opaque type ShadowNodeFamilyReference = mixed;
3031
export interface Spec {
3132
+createNode: (
3233
reactTag: number,
@@ -40,6 +41,7 @@ export interface Spec {
4041
+cloneNodeWithNewProps: (node: Node, newProps: NodeProps) => Node;
4142
+cloneNodeWithNewChildrenAndProps: (node: Node, newProps: NodeProps) => Node;
4243
+createChildSet: (rootTag: RootTag) => NodeSet;
44+
+createShadowNodeFamilyReference: (node: Node) => ShadowNodeFamilyReference;
4345
+appendChild: (parentNode: Node, child: Node) => Node;
4446
+appendChildToSet: (childSet: NodeSet, child: Node) => void;
4547
+completeRoot: (rootTag: RootTag, childSet: NodeSet) => void;
@@ -111,6 +113,7 @@ const CACHED_PROPERTIES = [
111113
'cloneNodeWithNewProps',
112114
'cloneNodeWithNewChildrenAndProps',
113115
'createChildSet',
116+
'createShadowNodeFamilyReference',
114117
'appendChild',
115118
'appendChildToSet',
116119
'completeRoot',

packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFamily.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct ShadowNodeFamilyFragment {
3939
* Represents all things that shadow nodes from the same family have in common.
4040
* To be used inside `ShadowNode` class *only*.
4141
*/
42-
class ShadowNodeFamily final {
42+
class ShadowNodeFamily final : public jsi::NativeState {
4343
public:
4444
using Shared = std::shared_ptr<const ShadowNodeFamily>;
4545
using Weak = std::weak_ptr<const ShadowNodeFamily>;

packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,24 @@ jsi::Value UIManagerBinding::get(
235235
});
236236
}
237237

238+
if (methodName == "createShadowNodeFamilyReference") {
239+
auto paramCount = 1;
240+
return jsi::Function::createFromHostFunction(
241+
runtime,
242+
name,
243+
paramCount,
244+
[methodName, paramCount](
245+
jsi::Runtime& runtime,
246+
const jsi::Value& /*thisValue*/,
247+
const jsi::Value* arguments,
248+
size_t count) {
249+
validateArgumentCount(runtime, methodName, paramCount, count);
250+
251+
auto node = shadowNodeFromValue(runtime, arguments[0]);
252+
return valueFromShadowNodeFamily(runtime, node->getFamilyShared());
253+
});
254+
}
255+
238256
if (methodName == "setIsJSResponder") {
239257
auto paramCount = 3;
240258
return jsi::Function::createFromHostFunction(

packages/react-native/ReactCommon/react/renderer/uimanager/primitives.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ inline static ShadowNode::Shared shadowNodeFromValue(
4242
->shadowNode;
4343
}
4444

45+
inline static ShadowNodeFamily::Shared shadowNodeFamilyFromValue(
46+
jsi::Runtime& runtime,
47+
const jsi::Value& value) {
48+
if (value.isNull()) {
49+
return nullptr;
50+
}
51+
52+
return value.getObject(runtime).getNativeState<ShadowNodeFamily>(runtime);
53+
}
54+
4555
inline static jsi::Value valueFromShadowNode(
4656
jsi::Runtime& runtime,
4757
ShadowNode::Shared shadowNode,
@@ -60,6 +70,17 @@ inline static jsi::Value valueFromShadowNode(
6070
return obj;
6171
}
6272

73+
inline static jsi::Value valueFromShadowNodeFamily(
74+
jsi::Runtime& runtime,
75+
ShadowNodeFamily::Shared shadowNodeFamily) {
76+
jsi::Object obj(runtime);
77+
// Need to const_cast since JSI only allows non-const pointees
78+
obj.setNativeState(
79+
runtime,
80+
std::const_pointer_cast<ShadowNodeFamily>(std::move(shadowNodeFamily)));
81+
return obj;
82+
}
83+
6384
// TODO: once we no longer need to mutate the return value (appendChildToSet)
6485
// make this a SharedListOfShared
6586
inline static ShadowNode::UnsharedListOfShared shadowNodeListFromValue(

0 commit comments

Comments
 (0)