Skip to content

Commit d978c95

Browse files
BridgeJS: Use JSIntrinsicRegistry to emit closure helpers on demand
1 parent 6d24178 commit d978c95

40 files changed

+54
-967
lines changed

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -259,32 +259,6 @@ public struct BridgeJSLink {
259259
"let \(JSGlueVariableScope.reservedTmpStructCleanups) = [];",
260260
"const \(JSGlueVariableScope.reservedEnumHelpers) = {};",
261261
"const \(JSGlueVariableScope.reservedStructHelpers) = {};",
262-
"const \(JSGlueVariableScope.reservedSwiftClosureEntries) = new Map();",
263-
"const \(JSGlueVariableScope.reservedSwiftClosureRegistry) = (typeof FinalizationRegistry === \"undefined\") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {",
264-
" \(JSGlueVariableScope.reservedSwiftClosureEntries).delete(funcRef);",
265-
" \(JSGlueVariableScope.reservedSwift).memory.release(funcRef);",
266-
" \(JSGlueVariableScope.reservedInstance)?.exports?.bjs_release_swift_closure(pointer);",
267-
"});",
268-
"const \(JSGlueVariableScope.reservedRegisterSwiftClosure) = (func, pointer) => {",
269-
" const funcRef = \(JSGlueVariableScope.reservedSwift).memory.retain(func);",
270-
" const token = \(JSGlueVariableScope.reservedSwiftClosureRegistry) ? {} : null;",
271-
" if (\(JSGlueVariableScope.reservedSwiftClosureRegistry)) {",
272-
" \(JSGlueVariableScope.reservedSwiftClosureRegistry).register(func, { pointer, funcRef }, token);",
273-
" }",
274-
" \(JSGlueVariableScope.reservedSwiftClosureEntries).set(funcRef, { pointer, token });",
275-
" return { func, funcRef };",
276-
"};",
277-
"const \(JSGlueVariableScope.reservedReleaseSwiftClosure) = (funcRef, pointer) => {",
278-
" const entry = \(JSGlueVariableScope.reservedSwiftClosureEntries).get(funcRef);",
279-
" if (!entry) { return; }",
280-
" \(JSGlueVariableScope.reservedSwiftClosureEntries).delete(funcRef);",
281-
" if (entry.token && \(JSGlueVariableScope.reservedSwiftClosureRegistry)) {",
282-
" \(JSGlueVariableScope.reservedSwiftClosureRegistry).unregister(entry.token);",
283-
" }",
284-
" \(JSGlueVariableScope.reservedSwift).memory.release(funcRef);",
285-
" (\(JSGlueVariableScope.reservedInstance)?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));",
286-
"};",
287-
"",
288262
"let _exports = null;",
289263
"let bjs = null;",
290264
]
@@ -644,6 +618,56 @@ public struct BridgeJSLink {
644618

645619
guard !closureSignatures.isEmpty else { continue }
646620

621+
intrinsicRegistry.register(name: "swiftClosureHelpers") { helperPrinter in
622+
helperPrinter.write("const \(JSGlueVariableScope.reservedSwiftClosureEntries) = new Map();")
623+
helperPrinter.write(
624+
"const \(JSGlueVariableScope.reservedSwiftClosureRegistry) = (typeof FinalizationRegistry === \"undefined\") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {"
625+
)
626+
helperPrinter.indent {
627+
helperPrinter.write("\(JSGlueVariableScope.reservedSwiftClosureEntries).delete(funcRef);")
628+
helperPrinter.write("\(JSGlueVariableScope.reservedSwift).memory.release(funcRef);")
629+
helperPrinter.write(
630+
"\(JSGlueVariableScope.reservedInstance)?.exports?.bjs_release_swift_closure(pointer);"
631+
)
632+
}
633+
helperPrinter.write("});")
634+
helperPrinter.write("const \(JSGlueVariableScope.reservedRegisterSwiftClosure) = (func, pointer) => {")
635+
helperPrinter.indent {
636+
helperPrinter.write("const funcRef = \(JSGlueVariableScope.reservedSwift).memory.retain(func);")
637+
helperPrinter.write("const token = \(JSGlueVariableScope.reservedSwiftClosureRegistry) ? {} : null;")
638+
helperPrinter.write("if (\(JSGlueVariableScope.reservedSwiftClosureRegistry)) {")
639+
helperPrinter.indent {
640+
helperPrinter.write(
641+
"\(JSGlueVariableScope.reservedSwiftClosureRegistry).register(func, { pointer, funcRef }, token);"
642+
)
643+
}
644+
helperPrinter.write("}")
645+
helperPrinter.write(
646+
"\(JSGlueVariableScope.reservedSwiftClosureEntries).set(funcRef, { pointer, token });"
647+
)
648+
helperPrinter.write("return { func, funcRef };")
649+
}
650+
helperPrinter.write("};")
651+
helperPrinter.write("const \(JSGlueVariableScope.reservedReleaseSwiftClosure) = (funcRef, pointer) => {")
652+
helperPrinter.indent {
653+
helperPrinter.write("const entry = \(JSGlueVariableScope.reservedSwiftClosureEntries).get(funcRef);")
654+
helperPrinter.write("if (!entry) { return; }")
655+
helperPrinter.write("\(JSGlueVariableScope.reservedSwiftClosureEntries).delete(funcRef);")
656+
helperPrinter.write("if (entry.token && \(JSGlueVariableScope.reservedSwiftClosureRegistry)) {")
657+
helperPrinter.indent {
658+
helperPrinter.write(
659+
"\(JSGlueVariableScope.reservedSwiftClosureRegistry).unregister(entry.token);"
660+
)
661+
}
662+
helperPrinter.write("}")
663+
helperPrinter.write("\(JSGlueVariableScope.reservedSwift).memory.release(funcRef);")
664+
helperPrinter.write(
665+
"(\(JSGlueVariableScope.reservedInstance)?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));"
666+
)
667+
}
668+
helperPrinter.write("};")
669+
}
670+
647671
for signature in closureSignatures.sorted(by: { $0.mangleName < $1.mangleName }) {
648672
let invokeFuncName = "invoke_js_callback_\(moduleName)_\(signature.mangleName)"
649673
printer.write(

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,32 +44,6 @@ export async function createInstantiator(options, swift) {
4444
let tmpStructCleanups = [];
4545
const enumHelpers = {};
4646
const structHelpers = {};
47-
const swiftClosureEntries = new Map();
48-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
49-
swiftClosureEntries.delete(funcRef);
50-
swift.memory.release(funcRef);
51-
instance?.exports?.bjs_release_swift_closure(pointer);
52-
});
53-
const registerSwiftClosure = (func, pointer) => {
54-
const funcRef = swift.memory.retain(func);
55-
const token = swiftClosureRegistry ? {} : null;
56-
if (swiftClosureRegistry) {
57-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
58-
}
59-
swiftClosureEntries.set(funcRef, { pointer, token });
60-
return { func, funcRef };
61-
};
62-
const releaseSwiftClosure = (funcRef, pointer) => {
63-
const entry = swiftClosureEntries.get(funcRef);
64-
if (!entry) { return; }
65-
swiftClosureEntries.delete(funcRef);
66-
if (entry.token && swiftClosureRegistry) {
67-
swiftClosureRegistry.unregister(entry.token);
68-
}
69-
swift.memory.release(funcRef);
70-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
71-
};
72-
7347
let _exports = null;
7448
let bjs = null;
7549
const __bjs_createPointHelpers = () => {

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,6 @@ export async function createInstantiator(options, swift) {
3131
let tmpStructCleanups = [];
3232
const enumHelpers = {};
3333
const structHelpers = {};
34-
const swiftClosureEntries = new Map();
35-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
36-
swiftClosureEntries.delete(funcRef);
37-
swift.memory.release(funcRef);
38-
instance?.exports?.bjs_release_swift_closure(pointer);
39-
});
40-
const registerSwiftClosure = (func, pointer) => {
41-
const funcRef = swift.memory.retain(func);
42-
const token = swiftClosureRegistry ? {} : null;
43-
if (swiftClosureRegistry) {
44-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
45-
}
46-
swiftClosureEntries.set(funcRef, { pointer, token });
47-
return { func, funcRef };
48-
};
49-
const releaseSwiftClosure = (funcRef, pointer) => {
50-
const entry = swiftClosureEntries.get(funcRef);
51-
if (!entry) { return; }
52-
swiftClosureEntries.delete(funcRef);
53-
if (entry.token && swiftClosureRegistry) {
54-
swiftClosureRegistry.unregister(entry.token);
55-
}
56-
swift.memory.release(funcRef);
57-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
58-
};
59-
6034
let _exports = null;
6135
let bjs = null;
6236

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,6 @@ export async function createInstantiator(options, swift) {
3737
let tmpStructCleanups = [];
3838
const enumHelpers = {};
3939
const structHelpers = {};
40-
const swiftClosureEntries = new Map();
41-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
42-
swiftClosureEntries.delete(funcRef);
43-
swift.memory.release(funcRef);
44-
instance?.exports?.bjs_release_swift_closure(pointer);
45-
});
46-
const registerSwiftClosure = (func, pointer) => {
47-
const funcRef = swift.memory.retain(func);
48-
const token = swiftClosureRegistry ? {} : null;
49-
if (swiftClosureRegistry) {
50-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
51-
}
52-
swiftClosureEntries.set(funcRef, { pointer, token });
53-
return { func, funcRef };
54-
};
55-
const releaseSwiftClosure = (funcRef, pointer) => {
56-
const entry = swiftClosureEntries.get(funcRef);
57-
if (!entry) { return; }
58-
swiftClosureEntries.delete(funcRef);
59-
if (entry.token && swiftClosureRegistry) {
60-
swiftClosureRegistry.unregister(entry.token);
61-
}
62-
swift.memory.release(funcRef);
63-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
64-
};
65-
6640
let _exports = null;
6741
let bjs = null;
6842
const __bjs_createConfigHelpers = () => {

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -506,32 +506,6 @@ export async function createInstantiator(options, swift) {
506506
let tmpStructCleanups = [];
507507
const enumHelpers = {};
508508
const structHelpers = {};
509-
const swiftClosureEntries = new Map();
510-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
511-
swiftClosureEntries.delete(funcRef);
512-
swift.memory.release(funcRef);
513-
instance?.exports?.bjs_release_swift_closure(pointer);
514-
});
515-
const registerSwiftClosure = (func, pointer) => {
516-
const funcRef = swift.memory.retain(func);
517-
const token = swiftClosureRegistry ? {} : null;
518-
if (swiftClosureRegistry) {
519-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
520-
}
521-
swiftClosureEntries.set(funcRef, { pointer, token });
522-
return { func, funcRef };
523-
};
524-
const releaseSwiftClosure = (funcRef, pointer) => {
525-
const entry = swiftClosureEntries.get(funcRef);
526-
if (!entry) { return; }
527-
swiftClosureEntries.delete(funcRef);
528-
if (entry.token && swiftClosureRegistry) {
529-
swiftClosureRegistry.unregister(entry.token);
530-
}
531-
swift.memory.release(funcRef);
532-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
533-
};
534-
535509
let _exports = null;
536510
let bjs = null;
537511

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,32 +55,6 @@ export async function createInstantiator(options, swift) {
5555
let tmpStructCleanups = [];
5656
const enumHelpers = {};
5757
const structHelpers = {};
58-
const swiftClosureEntries = new Map();
59-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
60-
swiftClosureEntries.delete(funcRef);
61-
swift.memory.release(funcRef);
62-
instance?.exports?.bjs_release_swift_closure(pointer);
63-
});
64-
const registerSwiftClosure = (func, pointer) => {
65-
const funcRef = swift.memory.retain(func);
66-
const token = swiftClosureRegistry ? {} : null;
67-
if (swiftClosureRegistry) {
68-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
69-
}
70-
swiftClosureEntries.set(funcRef, { pointer, token });
71-
return { func, funcRef };
72-
};
73-
const releaseSwiftClosure = (funcRef, pointer) => {
74-
const entry = swiftClosureEntries.get(funcRef);
75-
if (!entry) { return; }
76-
swiftClosureEntries.delete(funcRef);
77-
if (entry.token && swiftClosureRegistry) {
78-
swiftClosureRegistry.unregister(entry.token);
79-
}
80-
swift.memory.release(funcRef);
81-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
82-
};
83-
8458
let _exports = null;
8559
let bjs = null;
8660

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -75,32 +75,6 @@ export async function createInstantiator(options, swift) {
7575
let tmpStructCleanups = [];
7676
const enumHelpers = {};
7777
const structHelpers = {};
78-
const swiftClosureEntries = new Map();
79-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
80-
swiftClosureEntries.delete(funcRef);
81-
swift.memory.release(funcRef);
82-
instance?.exports?.bjs_release_swift_closure(pointer);
83-
});
84-
const registerSwiftClosure = (func, pointer) => {
85-
const funcRef = swift.memory.retain(func);
86-
const token = swiftClosureRegistry ? {} : null;
87-
if (swiftClosureRegistry) {
88-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
89-
}
90-
swiftClosureEntries.set(funcRef, { pointer, token });
91-
return { func, funcRef };
92-
};
93-
const releaseSwiftClosure = (funcRef, pointer) => {
94-
const entry = swiftClosureEntries.get(funcRef);
95-
if (!entry) { return; }
96-
swiftClosureEntries.delete(funcRef);
97-
if (entry.token && swiftClosureRegistry) {
98-
swiftClosureRegistry.unregister(entry.token);
99-
}
100-
swift.memory.release(funcRef);
101-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
102-
};
103-
10478
let _exports = null;
10579
let bjs = null;
10680

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,32 +56,6 @@ export async function createInstantiator(options, swift) {
5656
let tmpStructCleanups = [];
5757
const enumHelpers = {};
5858
const structHelpers = {};
59-
const swiftClosureEntries = new Map();
60-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
61-
swiftClosureEntries.delete(funcRef);
62-
swift.memory.release(funcRef);
63-
instance?.exports?.bjs_release_swift_closure(pointer);
64-
});
65-
const registerSwiftClosure = (func, pointer) => {
66-
const funcRef = swift.memory.retain(func);
67-
const token = swiftClosureRegistry ? {} : null;
68-
if (swiftClosureRegistry) {
69-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
70-
}
71-
swiftClosureEntries.set(funcRef, { pointer, token });
72-
return { func, funcRef };
73-
};
74-
const releaseSwiftClosure = (funcRef, pointer) => {
75-
const entry = swiftClosureEntries.get(funcRef);
76-
if (!entry) { return; }
77-
swiftClosureEntries.delete(funcRef);
78-
if (entry.token && swiftClosureRegistry) {
79-
swiftClosureRegistry.unregister(entry.token);
80-
}
81-
swift.memory.release(funcRef);
82-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
83-
};
84-
8559
let _exports = null;
8660
let bjs = null;
8761

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -106,32 +106,6 @@ export async function createInstantiator(options, swift) {
106106
let tmpStructCleanups = [];
107107
const enumHelpers = {};
108108
const structHelpers = {};
109-
const swiftClosureEntries = new Map();
110-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
111-
swiftClosureEntries.delete(funcRef);
112-
swift.memory.release(funcRef);
113-
instance?.exports?.bjs_release_swift_closure(pointer);
114-
});
115-
const registerSwiftClosure = (func, pointer) => {
116-
const funcRef = swift.memory.retain(func);
117-
const token = swiftClosureRegistry ? {} : null;
118-
if (swiftClosureRegistry) {
119-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
120-
}
121-
swiftClosureEntries.set(funcRef, { pointer, token });
122-
return { func, funcRef };
123-
};
124-
const releaseSwiftClosure = (funcRef, pointer) => {
125-
const entry = swiftClosureEntries.get(funcRef);
126-
if (!entry) { return; }
127-
swiftClosureEntries.delete(funcRef);
128-
if (entry.token && swiftClosureRegistry) {
129-
swiftClosureRegistry.unregister(entry.token);
130-
}
131-
swift.memory.release(funcRef);
132-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
133-
};
134-
135109
let _exports = null;
136110
let bjs = null;
137111

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,6 @@ export async function createInstantiator(options, swift) {
3131
let tmpStructCleanups = [];
3232
const enumHelpers = {};
3333
const structHelpers = {};
34-
const swiftClosureEntries = new Map();
35-
const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry(({ pointer, funcRef }) => {
36-
swiftClosureEntries.delete(funcRef);
37-
swift.memory.release(funcRef);
38-
instance?.exports?.bjs_release_swift_closure(pointer);
39-
});
40-
const registerSwiftClosure = (func, pointer) => {
41-
const funcRef = swift.memory.retain(func);
42-
const token = swiftClosureRegistry ? {} : null;
43-
if (swiftClosureRegistry) {
44-
swiftClosureRegistry.register(func, { pointer, funcRef }, token);
45-
}
46-
swiftClosureEntries.set(funcRef, { pointer, token });
47-
return { func, funcRef };
48-
};
49-
const releaseSwiftClosure = (funcRef, pointer) => {
50-
const entry = swiftClosureEntries.get(funcRef);
51-
if (!entry) { return; }
52-
swiftClosureEntries.delete(funcRef);
53-
if (entry.token && swiftClosureRegistry) {
54-
swiftClosureRegistry.unregister(entry.token);
55-
}
56-
swift.memory.release(funcRef);
57-
(instance?.exports?.bjs_release_swift_closure(pointer ?? entry.pointer));
58-
};
59-
6034
let _exports = null;
6135
let bjs = null;
6236

0 commit comments

Comments
 (0)