Skip to content

Commit 9ad174a

Browse files
committed
BridgeJS: Fix retain leak on identity cache hit and namespace deinit reference
Each boundary crossing calls passRetained on the Swift side. On cache hit, the wrapper is returned without creating a new FinalizationRegistry entry, leaving the retain unbalanced. Call deinit(pointer) on cache hit to immediately release the extra retain. Also fix deinit reference for namespaced classes to use abiName instead of short class name.
1 parent 012bb85 commit 9ad174a

24 files changed

Lines changed: 45 additions & 21 deletions

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public struct BridgeJSLink {
118118
119119
const cached = identityCache.get(pointer)?.deref();
120120
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
121+
deinit(pointer);
121122
return cached;
122123
}
123124
if (!cached) {
@@ -2000,7 +2001,7 @@ extension BridgeJSLink {
20002001
jsPrinter.write("static __construct(ptr) {")
20012002
jsPrinter.indent {
20022003
jsPrinter.write(
2003-
"return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_\(klass.name)_deinit, \(klass.name).prototype, \(klass.name).__identityCache);"
2004+
"return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_\(klass.abiName)_deinit, \(klass.name).prototype, \(klass.name).__identityCache);"
20042005
)
20052006
}
20062007
jsPrinter.write("}")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ export async function createInstantiator(options, swift) {
377377

378378
const cached = identityCache.get(pointer)?.deref();
379379
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
380+
deinit(pointer);
380381
return cached;
381382
}
382383
if (!cached) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ export async function createInstantiator(options, swift) {
308308

309309
const cached = identityCache.get(pointer)?.deref();
310310
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
311+
deinit(pointer);
311312
return cached;
312313
}
313314
if (!cached) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ export async function createInstantiator(options, swift) {
317317

318318
const cached = identityCache.get(pointer)?.deref();
319319
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
320+
deinit(pointer);
320321
return cached;
321322
}
322323
if (!cached) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ export async function createInstantiator(options, swift) {
984984

985985
const cached = identityCache.get(pointer)?.deref();
986986
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
987+
deinit(pointer);
987988
return cached;
988989
}
989990
if (!cached) {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ export async function createInstantiator(options, swift) {
300300

301301
const cached = identityCache.get(pointer)?.deref();
302302
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
303+
deinit(pointer);
303304
return cached;
304305
}
305306
if (!cached) {
@@ -324,7 +325,7 @@ export async function createInstantiator(options, swift) {
324325
static __identityCache = new Map();
325326

326327
static __construct(ptr) {
327-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype, Converter.__identityCache);
328+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Utils_Converter_deinit, Converter.prototype, Converter.__identityCache);
328329
}
329330

330331
constructor() {
@@ -349,7 +350,7 @@ export async function createInstantiator(options, swift) {
349350
static __identityCache = new Map();
350351

351352
static __construct(ptr) {
352-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_HTTPServer_deinit, HTTPServer.prototype, HTTPServer.__identityCache);
353+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Networking_API_HTTPServer_deinit, HTTPServer.prototype, HTTPServer.__identityCache);
353354
}
354355

355356
constructor() {
@@ -364,7 +365,7 @@ export async function createInstantiator(options, swift) {
364365
static __identityCache = new Map();
365366

366367
static __construct(ptr) {
367-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_TestServer_deinit, TestServer.prototype, TestServer.__identityCache);
368+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Networking_APIV2_Internal_TestServer_deinit, TestServer.prototype, TestServer.__identityCache);
368369
}
369370

370371
constructor() {
@@ -379,7 +380,7 @@ export async function createInstantiator(options, swift) {
379380
static __identityCache = new Map();
380381

381382
static __construct(ptr) {
382-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype, Converter.__identityCache);
383+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Formatting_Converter_deinit, Converter.prototype, Converter.__identityCache);
383384
}
384385

385386
constructor() {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ export async function createInstantiator(options, swift) {
281281

282282
const cached = identityCache.get(pointer)?.deref();
283283
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
284+
deinit(pointer);
284285
return cached;
285286
}
286287
if (!cached) {
@@ -305,7 +306,7 @@ export async function createInstantiator(options, swift) {
305306
static __identityCache = new Map();
306307

307308
static __construct(ptr) {
308-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype, Converter.__identityCache);
309+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Utils_Converter_deinit, Converter.prototype, Converter.__identityCache);
309310
}
310311

311312
constructor() {
@@ -330,7 +331,7 @@ export async function createInstantiator(options, swift) {
330331
static __identityCache = new Map();
331332

332333
static __construct(ptr) {
333-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_HTTPServer_deinit, HTTPServer.prototype, HTTPServer.__identityCache);
334+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Networking_API_HTTPServer_deinit, HTTPServer.prototype, HTTPServer.__identityCache);
334335
}
335336

336337
constructor() {
@@ -345,7 +346,7 @@ export async function createInstantiator(options, swift) {
345346
static __identityCache = new Map();
346347

347348
static __construct(ptr) {
348-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_TestServer_deinit, TestServer.prototype, TestServer.__identityCache);
349+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Networking_APIV2_Internal_TestServer_deinit, TestServer.prototype, TestServer.__identityCache);
349350
}
350351

351352
constructor() {
@@ -360,7 +361,7 @@ export async function createInstantiator(options, swift) {
360361
static __identityCache = new Map();
361362

362363
static __construct(ptr) {
363-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype, Converter.__identityCache);
364+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Formatting_Converter_deinit, Converter.prototype, Converter.__identityCache);
364365
}
365366

366367
constructor() {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ export async function createInstantiator(options, swift) {
371371

372372
const cached = identityCache.get(pointer)?.deref();
373373
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
374+
deinit(pointer);
374375
return cached;
375376
}
376377
if (!cached) {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ export async function createInstantiator(options, swift) {
244244

245245
const cached = identityCache.get(pointer)?.deref();
246246
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
247+
deinit(pointer);
247248
return cached;
248249
}
249250
if (!cached) {
@@ -268,7 +269,7 @@ export async function createInstantiator(options, swift) {
268269
static __identityCache = new Map();
269270

270271
static __construct(ptr) {
271-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalClass_deinit, GlobalClass.prototype, GlobalClass.__identityCache);
272+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalAPI_GlobalClass_deinit, GlobalClass.prototype, GlobalClass.__identityCache);
272273
}
273274

274275
constructor() {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ export async function createInstantiator(options, swift) {
252252

253253
const cached = identityCache.get(pointer)?.deref();
254254
if (cached && !cached.__swiftHeapObjectState.hasReleased) {
255+
deinit(pointer);
255256
return cached;
256257
}
257258
if (!cached) {
@@ -276,7 +277,7 @@ export async function createInstantiator(options, swift) {
276277
static __identityCache = new Map();
277278

278279
static __construct(ptr) {
279-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalClass_deinit, GlobalClass.prototype, GlobalClass.__identityCache);
280+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalAPI_GlobalClass_deinit, GlobalClass.prototype, GlobalClass.__identityCache);
280281
}
281282

282283
constructor() {
@@ -294,7 +295,7 @@ export async function createInstantiator(options, swift) {
294295
static __identityCache = new Map();
295296

296297
static __construct(ptr) {
297-
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_PrivateClass_deinit, PrivateClass.prototype, PrivateClass.__identityCache);
298+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_PrivateAPI_PrivateClass_deinit, PrivateClass.prototype, PrivateClass.__identityCache);
298299
}
299300

300301
constructor() {

0 commit comments

Comments
 (0)