Skip to content

Commit db3a6e2

Browse files
Fix wrong deallocation management for JSClosure with FinalizationRegistry
In FinalizationRegistry mode, the `swjs_free_host_function` should be called with the Swift heap object ID, not the JS closure object ID. The wrong argument was causing: - Swift closures to be leaked, because FinalizationRegistry attempted to release a JS object ID that was never registered as a Swift closure. - Unintended deallocation of unrelated closures when a reused JS object ID happened to match a valid Swift closure ID by coincidence. This eventually led to crashes with `The JSClosure has been already released by Swift side.`
1 parent 825f947 commit db3a6e2

File tree

2 files changed

+2
-2
lines changed

2 files changed

+2
-2
lines changed

Plugins/PackageToJS/Templates/runtime.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ class SwiftRuntime {
635635
const fileString = this.memory.getObject(file);
636636
const func = (...args) => this.callHostFunction(host_func_id, line, fileString, args);
637637
const func_ref = this.memory.retain(func);
638-
(_a = this.closureDeallocator) === null || _a === void 0 ? void 0 : _a.track(func, func_ref);
638+
(_a = this.closureDeallocator) === null || _a === void 0 ? void 0 : _a.track(func, host_func_id);
639639
return func_ref;
640640
},
641641
swjs_create_typed_array: (constructor_ref, elementsPtr, length) => {

Runtime/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ export class SwiftRuntime {
553553
const func = (...args: any[]) =>
554554
this.callHostFunction(host_func_id, line, fileString, args);
555555
const func_ref = this.memory.retain(func);
556-
this.closureDeallocator?.track(func, func_ref);
556+
this.closureDeallocator?.track(func, host_func_id);
557557
return func_ref;
558558
},
559559

0 commit comments

Comments
 (0)