Skip to content

Commit 7f9094e

Browse files
Stop managing JSOneshotClosure by FinalizationRegistry
JSOneshotClosure manages its lifetime by itself, so it doesn't require nondeterministic FinalizationRegistry. Additionally, use of FinalizationRegistry was unsafe for the case: 1. JSOneshotClosure C1 is created 2. C1 is called, and destroyed 3. JSOneshotClosure C2 is created at the same address of C1 4. C1's finalizer callback is called
1 parent db3a6e2 commit 7f9094e

File tree

4 files changed

+29
-1
lines changed

4 files changed

+29
-1
lines changed

Plugins/PackageToJS/Templates/runtime.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,12 @@ class SwiftRuntime {
638638
(_a = this.closureDeallocator) === null || _a === void 0 ? void 0 : _a.track(func, host_func_id);
639639
return func_ref;
640640
},
641+
swjs_create_oneshot_function: (host_func_id, line, file) => {
642+
const fileString = this.memory.getObject(file);
643+
const func = (...args) => this.callHostFunction(host_func_id, line, fileString, args);
644+
const func_ref = this.memory.retain(func);
645+
return func_ref;
646+
},
641647
swjs_create_typed_array: (constructor_ref, elementsPtr, length) => {
642648
const ArrayType = this.memory.getObject(constructor_ref);
643649
if (length == 0) {

Runtime/src/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,18 @@ export class SwiftRuntime {
557557
return func_ref;
558558
},
559559

560+
swjs_create_oneshot_function: (
561+
host_func_id: number,
562+
line: number,
563+
file: ref
564+
) => {
565+
const fileString = this.memory.getObject(file) as string;
566+
const func = (...args: any[]) =>
567+
this.callHostFunction(host_func_id, line, fileString, args);
568+
const func_ref = this.memory.retain(func);
569+
return func_ref;
570+
},
571+
560572
swjs_create_typed_array: <T extends Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | BigInt64Array | BigUint64Array | Float32Array | Float64Array | Uint8ClampedArray>(
561573
constructor_ref: ref,
562574
elementsPtr: pointer,

Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class JSOneshotClosure: JSObject, JSClosureProtocol {
2525
// 2. Create a new JavaScript function which calls the given Swift function.
2626
hostFuncRef = JavaScriptHostFuncRef(bitPattern: ObjectIdentifier(self))
2727
_id = withExtendedLifetime(JSString(file)) { file in
28-
swjs_create_function(hostFuncRef, line, file.asInternalJSRef())
28+
swjs_create_oneshot_function(hostFuncRef, line, file.asInternalJSRef())
2929
}
3030

3131
// 3. Retain the given body in static storage by `funcRef`.

Sources/_CJavaScriptKit/include/_CJavaScriptKit.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ IMPORT_JS_FUNCTION(swjs_create_function, JavaScriptObjectRef, (const JavaScriptH
278278
unsigned int line,
279279
JavaScriptObjectRef file))
280280

281+
/// Creates a oneshot JavaScript thunk function that calls Swift side closure.
282+
///
283+
/// @param host_func_id The target Swift side function called by the created thunk function.
284+
/// @param line The line where the function is created. Will be used for diagnostics
285+
/// @param file The file name where the function is created. Will be used for diagnostics
286+
/// @returns A reference to the newly-created JavaScript thunk function
287+
IMPORT_JS_FUNCTION(swjs_create_oneshot_function, JavaScriptObjectRef, (const JavaScriptHostFuncRef host_func_id,
288+
unsigned int line,
289+
JavaScriptObjectRef file))
290+
281291
/// Instantiates a new `TypedArray` object with given elements
282292
/// This is used to provide an efficient way to create `TypedArray`.
283293
///

0 commit comments

Comments
 (0)