Skip to content

Commit 539b8f3

Browse files
committed
BridgeJS: Guard FinalizationRegistry deinit callback against Wasm teardown
1 parent bbdf7d5 commit 539b8f3

27 files changed

+199
-47
lines changed

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,19 @@ public struct BridgeJSLink {
5050
}
5151
"""
5252

53+
// Both the FinalizationRegistry callback and release() wrap state.deinit() in try/catch
54+
// because either can fire during process shutdown after the Wasm instance is already torn
55+
// down. Calling into Wasm at that point throws RuntimeError (memory access / table index
56+
// out of bounds). There's nothing to do but swallow it - the process is exiting anyway.
5357
let swiftHeapObjectClassJs = """
5458
const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => {
5559
if (state.hasReleased) {
5660
return;
5761
}
5862
state.hasReleased = true;
59-
state.deinit(state.pointer);
63+
try {
64+
state.deinit(state.pointer);
65+
} catch {}
6066
});
6167
6268
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -77,7 +83,9 @@ public struct BridgeJSLink {
7783
}
7884
state.hasReleased = true;
7985
swiftHeapObjectFinalizationRegistry.unregister(state);
80-
state.deinit(state.pointer);
86+
try {
87+
state.deinit(state.pointer);
88+
} catch {}
8189
}
8290
}
8391
"""

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,9 @@ export async function createInstantiator(options, swift) {
340340
return;
341341
}
342342
state.hasReleased = true;
343-
state.deinit(state.pointer);
343+
try {
344+
state.deinit(state.pointer);
345+
} catch {}
344346
});
345347

346348
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -361,7 +363,9 @@ export async function createInstantiator(options, swift) {
361363
}
362364
state.hasReleased = true;
363365
swiftHeapObjectFinalizationRegistry.unregister(state);
364-
state.deinit(state.pointer);
366+
try {
367+
state.deinit(state.pointer);
368+
} catch {}
365369
}
366370
}
367371
class Item extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ export async function createInstantiator(options, swift) {
277277
return;
278278
}
279279
state.hasReleased = true;
280-
state.deinit(state.pointer);
280+
try {
281+
state.deinit(state.pointer);
282+
} catch {}
281283
});
282284

283285
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -298,7 +300,9 @@ export async function createInstantiator(options, swift) {
298300
}
299301
state.hasReleased = true;
300302
swiftHeapObjectFinalizationRegistry.unregister(state);
301-
state.deinit(state.pointer);
303+
try {
304+
state.deinit(state.pointer);
305+
} catch {}
302306
}
303307
}
304308
class DefaultGreeter extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ export async function createInstantiator(options, swift) {
235235
return;
236236
}
237237
state.hasReleased = true;
238-
state.deinit(state.pointer);
238+
try {
239+
state.deinit(state.pointer);
240+
} catch {}
239241
});
240242

241243
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -256,7 +258,9 @@ export async function createInstantiator(options, swift) {
256258
}
257259
state.hasReleased = true;
258260
swiftHeapObjectFinalizationRegistry.unregister(state);
259-
state.deinit(state.pointer);
261+
try {
262+
state.deinit(state.pointer);
263+
} catch {}
260264
}
261265
}
262266
class Box extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,9 @@ export async function createInstantiator(options, swift) {
972972
return;
973973
}
974974
state.hasReleased = true;
975-
state.deinit(state.pointer);
975+
try {
976+
state.deinit(state.pointer);
977+
} catch {}
976978
});
977979

978980
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -993,7 +995,9 @@ export async function createInstantiator(options, swift) {
993995
}
994996
state.hasReleased = true;
995997
swiftHeapObjectFinalizationRegistry.unregister(state);
996-
state.deinit(state.pointer);
998+
try {
999+
state.deinit(state.pointer);
1000+
} catch {}
9971001
}
9981002
}
9991003
class User extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,9 @@ export async function createInstantiator(options, swift) {
261261
return;
262262
}
263263
state.hasReleased = true;
264-
state.deinit(state.pointer);
264+
try {
265+
state.deinit(state.pointer);
266+
} catch {}
265267
});
266268

267269
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -282,7 +284,9 @@ export async function createInstantiator(options, swift) {
282284
}
283285
state.hasReleased = true;
284286
swiftHeapObjectFinalizationRegistry.unregister(state);
285-
state.deinit(state.pointer);
287+
try {
288+
state.deinit(state.pointer);
289+
} catch {}
286290
}
287291
}
288292
class Converter extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ export async function createInstantiator(options, swift) {
242242
return;
243243
}
244244
state.hasReleased = true;
245-
state.deinit(state.pointer);
245+
try {
246+
state.deinit(state.pointer);
247+
} catch {}
246248
});
247249

248250
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -263,7 +265,9 @@ export async function createInstantiator(options, swift) {
263265
}
264266
state.hasReleased = true;
265267
swiftHeapObjectFinalizationRegistry.unregister(state);
266-
state.deinit(state.pointer);
268+
try {
269+
state.deinit(state.pointer);
270+
} catch {}
267271
}
268272
}
269273
class Converter extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,9 @@ export async function createInstantiator(options, swift) {
336336
return;
337337
}
338338
state.hasReleased = true;
339-
state.deinit(state.pointer);
339+
try {
340+
state.deinit(state.pointer);
341+
} catch {}
340342
});
341343

342344
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -357,7 +359,9 @@ export async function createInstantiator(options, swift) {
357359
}
358360
state.hasReleased = true;
359361
swiftHeapObjectFinalizationRegistry.unregister(state);
360-
state.deinit(state.pointer);
362+
try {
363+
state.deinit(state.pointer);
364+
} catch {}
361365
}
362366
}
363367
class JSValueHolder extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,9 @@ export async function createInstantiator(options, swift) {
209209
return;
210210
}
211211
state.hasReleased = true;
212-
state.deinit(state.pointer);
212+
try {
213+
state.deinit(state.pointer);
214+
} catch {}
213215
});
214216

215217
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -230,7 +232,9 @@ export async function createInstantiator(options, swift) {
230232
}
231233
state.hasReleased = true;
232234
swiftHeapObjectFinalizationRegistry.unregister(state);
233-
state.deinit(state.pointer);
235+
try {
236+
state.deinit(state.pointer);
237+
} catch {}
234238
}
235239
}
236240
class GlobalClass extends SwiftHeapObject {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,9 @@ export async function createInstantiator(options, swift) {
217217
return;
218218
}
219219
state.hasReleased = true;
220-
state.deinit(state.pointer);
220+
try {
221+
state.deinit(state.pointer);
222+
} catch {}
221223
});
222224

223225
/// Represents a Swift heap object like a class instance or an actor instance.
@@ -238,7 +240,9 @@ export async function createInstantiator(options, swift) {
238240
}
239241
state.hasReleased = true;
240242
swiftHeapObjectFinalizationRegistry.unregister(state);
241-
state.deinit(state.pointer);
243+
try {
244+
state.deinit(state.pointer);
245+
} catch {}
242246
}
243247
}
244248
class GlobalClass extends SwiftHeapObject {

0 commit comments

Comments
 (0)