@@ -10,12 +10,16 @@ import BridgeJSUtilities
1010public struct BridgeJSLink {
1111 var skeletons : [ BridgeJSSkeleton ] = [ ]
1212 let sharedMemory : Bool
13+ /// Whether to track the lifetime of Swift objects.
14+ ///
15+ /// This is useful for debugging memory issues.
16+ let enableLifetimeTracking : Bool = false
1317 private let namespaceBuilder = NamespaceBuilder ( )
1418 private let intrinsicRegistry = JSIntrinsicRegistry ( )
1519
1620 public init (
1721 skeletons: [ BridgeJSSkeleton ] = [ ] ,
18- sharedMemory: Bool
22+ sharedMemory: Bool = false
1923 ) {
2024 self . skeletons = skeletons
2125 self . sharedMemory = sharedMemory
@@ -50,8 +54,33 @@ public struct BridgeJSLink {
5054 }
5155 """
5256
53- let swiftHeapObjectClassJs = """
57+ let lifetimeTrackingClassJs = """
58+ const TRACKING = {
59+ wrap: (pointer, deinit, prototype, state) => {
60+ console.log(JSON.stringify({ DEBUG: true, event: " WRP " , class: prototype.constructor.name, state }));
61+ },
62+ release: (obj) => {
63+ console.log(JSON.stringify({ DEBUG: true, event: " REL " , class: obj.constructor.name, state: obj.__swiftHeapObjectState }));
64+ },
65+ finalization: (state) => {
66+ console.log(JSON.stringify({ DEBUG: true, event: " FIN " , state }));
67+ }
68+ };
69+ """
70+
71+ var swiftHeapObjectClassJs : String {
72+ var output = " "
73+ if enableLifetimeTracking {
74+ output += lifetimeTrackingClassJs + " \n "
75+ }
76+ output += """
5477 const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === " undefined " ) ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
78+
79+ """
80+ if enableLifetimeTracking {
81+ output += " TRACKING.finalization(state); \n "
82+ }
83+ output += """
5584 if (state.hasReleased) {
5685 return;
5786 }
@@ -64,13 +93,25 @@ public struct BridgeJSLink {
6493 static __wrap(pointer, deinit, prototype) {
6594 const obj = Object.create(prototype);
6695 const state = { pointer, deinit, hasReleased: false };
96+
97+ """
98+ if enableLifetimeTracking {
99+ output += " TRACKING.wrap(pointer, deinit, prototype, state); \n "
100+ }
101+ output += """
67102 obj.pointer = pointer;
68103 obj.__swiftHeapObjectState = state;
69104 swiftHeapObjectFinalizationRegistry.register(obj, state, state);
70105 return obj;
71106 }
72107
73108 release() {
109+
110+ """
111+ if enableLifetimeTracking {
112+ output += " TRACKING.release(this); \n "
113+ }
114+ output += """
74115 const state = this.__swiftHeapObjectState;
75116 if (state.hasReleased) {
76117 return;
@@ -81,6 +122,8 @@ public struct BridgeJSLink {
81122 }
82123 }
83124 """
125+ return output
126+ }
84127
85128 fileprivate struct LinkData {
86129 var exportsLines : [ String ] = [ ]
0 commit comments