Skip to content

Commit df960e6

Browse files
committed
fix: Restore FinalizationRegistry polyfill and clean up formatting noise
Restore the no-op polyfill pattern for environments without FinalizationRegistry instead of null, matching the upstream convention. Remove finalizer parameter from makeFresh since the polyfill is always callable. Use has() guard before stale WeakRef cleanup. Remove formatting-only changes from instantiate.d.ts.
1 parent a865a00 commit df960e6

25 files changed

Lines changed: 240 additions & 302 deletions

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public struct BridgeJSLink {
7474
output += lifetimeTrackingClassJs + "\n"
7575
}
7676
output += """
77-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
77+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
7878
7979
"""
8080
if enableLifetimeTracking {
@@ -92,9 +92,9 @@ public struct BridgeJSLink {
9292
/// Represents a Swift heap object like a class instance or an actor instance.
9393
class SwiftHeapObject {
9494
static __wrap(pointer, deinit, prototype, identityCache) {
95-
const makeFresh = (identityMap, finalizer) => {
95+
const makeFresh = (identityMap) => {
9696
const obj = Object.create(prototype);
97-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
97+
const state = { pointer, deinit, hasReleased: false, identityMap };
9898
9999
"""
100100
if enableLifetimeTracking {
@@ -103,29 +103,27 @@ public struct BridgeJSLink {
103103
output += """
104104
obj.pointer = pointer;
105105
obj.__swiftHeapObjectState = state;
106-
if (finalizer) {
107-
finalizer.register(obj, state, state);
108-
}
106+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
109107
if (identityMap) {
110108
identityMap.set(pointer, new WeakRef(obj));
111109
}
112110
return obj;
113111
};
114112
115113
if (!shouldUseIdentityMap) {
116-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
114+
return makeFresh(null);
117115
}
118116
119117
const cached = identityCache.get(pointer)?.deref();
120118
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
121119
deinit(pointer);
122120
return cached;
123121
}
124-
if (!cached) {
122+
if (identityCache.has(pointer)) {
125123
identityCache.delete(pointer);
126124
}
127125
128-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
126+
return makeFresh(identityCache);
129127
}
130128
131129
release() {
@@ -140,7 +138,7 @@ public struct BridgeJSLink {
140138
return;
141139
}
142140
state.hasReleased = true;
143-
state.finalizer?.unregister(state);
141+
swiftHeapObjectFinalizationRegistry.unregister(state);
144142
state.identityMap?.delete(state.pointer);
145143
state.deinit(state.pointer);
146144
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ export async function createInstantiator(options, swift) {
345345
/** @param {WebAssembly.Instance} instance */
346346
createExports: (instance) => {
347347
const js = swift.memory.heap;
348-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
348+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
349349
if (state.hasReleased) {
350350
return;
351351
}
@@ -357,34 +357,32 @@ export async function createInstantiator(options, swift) {
357357
/// Represents a Swift heap object like a class instance or an actor instance.
358358
class SwiftHeapObject {
359359
static __wrap(pointer, deinit, prototype, identityCache) {
360-
const makeFresh = (identityMap, finalizer) => {
360+
const makeFresh = (identityMap) => {
361361
const obj = Object.create(prototype);
362-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
362+
const state = { pointer, deinit, hasReleased: false, identityMap };
363363
obj.pointer = pointer;
364364
obj.__swiftHeapObjectState = state;
365-
if (finalizer) {
366-
finalizer.register(obj, state, state);
367-
}
365+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
368366
if (identityMap) {
369367
identityMap.set(pointer, new WeakRef(obj));
370368
}
371369
return obj;
372370
};
373371

374372
if (!shouldUseIdentityMap) {
375-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
373+
return makeFresh(null);
376374
}
377375

378376
const cached = identityCache.get(pointer)?.deref();
379377
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
380378
deinit(pointer);
381379
return cached;
382380
}
383-
if (!cached) {
381+
if (identityCache.has(pointer)) {
384382
identityCache.delete(pointer);
385383
}
386384

387-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
385+
return makeFresh(identityCache);
388386
}
389387

390388
release() {
@@ -393,7 +391,7 @@ export async function createInstantiator(options, swift) {
393391
return;
394392
}
395393
state.hasReleased = true;
396-
state.finalizer?.unregister(state);
394+
swiftHeapObjectFinalizationRegistry.unregister(state);
397395
state.identityMap?.delete(state.pointer);
398396
state.deinit(state.pointer);
399397
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ export async function createInstantiator(options, swift) {
276276
/** @param {WebAssembly.Instance} instance */
277277
createExports: (instance) => {
278278
const js = swift.memory.heap;
279-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
279+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
280280
if (state.hasReleased) {
281281
return;
282282
}
@@ -288,34 +288,32 @@ export async function createInstantiator(options, swift) {
288288
/// Represents a Swift heap object like a class instance or an actor instance.
289289
class SwiftHeapObject {
290290
static __wrap(pointer, deinit, prototype, identityCache) {
291-
const makeFresh = (identityMap, finalizer) => {
291+
const makeFresh = (identityMap) => {
292292
const obj = Object.create(prototype);
293-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
293+
const state = { pointer, deinit, hasReleased: false, identityMap };
294294
obj.pointer = pointer;
295295
obj.__swiftHeapObjectState = state;
296-
if (finalizer) {
297-
finalizer.register(obj, state, state);
298-
}
296+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
299297
if (identityMap) {
300298
identityMap.set(pointer, new WeakRef(obj));
301299
}
302300
return obj;
303301
};
304302

305303
if (!shouldUseIdentityMap) {
306-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
304+
return makeFresh(null);
307305
}
308306

309307
const cached = identityCache.get(pointer)?.deref();
310308
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
311309
deinit(pointer);
312310
return cached;
313311
}
314-
if (!cached) {
312+
if (identityCache.has(pointer)) {
315313
identityCache.delete(pointer);
316314
}
317315

318-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
316+
return makeFresh(identityCache);
319317
}
320318

321319
release() {
@@ -324,7 +322,7 @@ export async function createInstantiator(options, swift) {
324322
return;
325323
}
326324
state.hasReleased = true;
327-
state.finalizer?.unregister(state);
325+
swiftHeapObjectFinalizationRegistry.unregister(state);
328326
state.identityMap?.delete(state.pointer);
329327
state.deinit(state.pointer);
330328
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ export async function createInstantiator(options, swift) {
285285
/** @param {WebAssembly.Instance} instance */
286286
createExports: (instance) => {
287287
const js = swift.memory.heap;
288-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
288+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
289289
if (state.hasReleased) {
290290
return;
291291
}
@@ -297,34 +297,32 @@ export async function createInstantiator(options, swift) {
297297
/// Represents a Swift heap object like a class instance or an actor instance.
298298
class SwiftHeapObject {
299299
static __wrap(pointer, deinit, prototype, identityCache) {
300-
const makeFresh = (identityMap, finalizer) => {
300+
const makeFresh = (identityMap) => {
301301
const obj = Object.create(prototype);
302-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
302+
const state = { pointer, deinit, hasReleased: false, identityMap };
303303
obj.pointer = pointer;
304304
obj.__swiftHeapObjectState = state;
305-
if (finalizer) {
306-
finalizer.register(obj, state, state);
307-
}
305+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
308306
if (identityMap) {
309307
identityMap.set(pointer, new WeakRef(obj));
310308
}
311309
return obj;
312310
};
313311

314312
if (!shouldUseIdentityMap) {
315-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
313+
return makeFresh(null);
316314
}
317315

318316
const cached = identityCache.get(pointer)?.deref();
319317
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
320318
deinit(pointer);
321319
return cached;
322320
}
323-
if (!cached) {
321+
if (identityCache.has(pointer)) {
324322
identityCache.delete(pointer);
325323
}
326324

327-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
325+
return makeFresh(identityCache);
328326
}
329327

330328
release() {
@@ -333,7 +331,7 @@ export async function createInstantiator(options, swift) {
333331
return;
334332
}
335333
state.hasReleased = true;
336-
state.finalizer?.unregister(state);
334+
swiftHeapObjectFinalizationRegistry.unregister(state);
337335
state.identityMap?.delete(state.pointer);
338336
state.deinit(state.pointer);
339337
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ export async function createInstantiator(options, swift) {
952952
/** @param {WebAssembly.Instance} instance */
953953
createExports: (instance) => {
954954
const js = swift.memory.heap;
955-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
955+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
956956
if (state.hasReleased) {
957957
return;
958958
}
@@ -964,34 +964,32 @@ export async function createInstantiator(options, swift) {
964964
/// Represents a Swift heap object like a class instance or an actor instance.
965965
class SwiftHeapObject {
966966
static __wrap(pointer, deinit, prototype, identityCache) {
967-
const makeFresh = (identityMap, finalizer) => {
967+
const makeFresh = (identityMap) => {
968968
const obj = Object.create(prototype);
969-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
969+
const state = { pointer, deinit, hasReleased: false, identityMap };
970970
obj.pointer = pointer;
971971
obj.__swiftHeapObjectState = state;
972-
if (finalizer) {
973-
finalizer.register(obj, state, state);
974-
}
972+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
975973
if (identityMap) {
976974
identityMap.set(pointer, new WeakRef(obj));
977975
}
978976
return obj;
979977
};
980978

981979
if (!shouldUseIdentityMap) {
982-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
980+
return makeFresh(null);
983981
}
984982

985983
const cached = identityCache.get(pointer)?.deref();
986984
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
987985
deinit(pointer);
988986
return cached;
989987
}
990-
if (!cached) {
988+
if (identityCache.has(pointer)) {
991989
identityCache.delete(pointer);
992990
}
993991

994-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
992+
return makeFresh(identityCache);
995993
}
996994

997995
release() {
@@ -1000,7 +998,7 @@ export async function createInstantiator(options, swift) {
1000998
return;
1001999
}
10021000
state.hasReleased = true;
1003-
state.finalizer?.unregister(state);
1001+
swiftHeapObjectFinalizationRegistry.unregister(state);
10041002
state.identityMap?.delete(state.pointer);
10051003
state.deinit(state.pointer);
10061004
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export async function createInstantiator(options, swift) {
268268
/** @param {WebAssembly.Instance} instance */
269269
createExports: (instance) => {
270270
const js = swift.memory.heap;
271-
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? null : new FinalizationRegistry((state) => {
271+
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
272272
if (state.hasReleased) {
273273
return;
274274
}
@@ -280,34 +280,32 @@ export async function createInstantiator(options, swift) {
280280
/// Represents a Swift heap object like a class instance or an actor instance.
281281
class SwiftHeapObject {
282282
static __wrap(pointer, deinit, prototype, identityCache) {
283-
const makeFresh = (identityMap, finalizer) => {
283+
const makeFresh = (identityMap) => {
284284
const obj = Object.create(prototype);
285-
const state = { pointer, deinit, hasReleased: false, identityMap, finalizer };
285+
const state = { pointer, deinit, hasReleased: false, identityMap };
286286
obj.pointer = pointer;
287287
obj.__swiftHeapObjectState = state;
288-
if (finalizer) {
289-
finalizer.register(obj, state, state);
290-
}
288+
swiftHeapObjectFinalizationRegistry.register(obj, state, state);
291289
if (identityMap) {
292290
identityMap.set(pointer, new WeakRef(obj));
293291
}
294292
return obj;
295293
};
296294

297295
if (!shouldUseIdentityMap) {
298-
return makeFresh(null, swiftHeapObjectFinalizationRegistry);
296+
return makeFresh(null);
299297
}
300298

301299
const cached = identityCache.get(pointer)?.deref();
302300
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
303301
deinit(pointer);
304302
return cached;
305303
}
306-
if (!cached) {
304+
if (identityCache.has(pointer)) {
307305
identityCache.delete(pointer);
308306
}
309307

310-
return makeFresh(identityCache, swiftHeapObjectFinalizationRegistry);
308+
return makeFresh(identityCache);
311309
}
312310

313311
release() {
@@ -316,7 +314,7 @@ export async function createInstantiator(options, swift) {
316314
return;
317315
}
318316
state.hasReleased = true;
319-
state.finalizer?.unregister(state);
317+
swiftHeapObjectFinalizationRegistry.unregister(state);
320318
state.identityMap?.delete(state.pointer);
321319
state.deinit(state.pointer);
322320
}

0 commit comments

Comments
 (0)