Tags: swiftwasm/JavaScriptKit
Tags
BridgeJS: Add `JSTypedClosure` API (#578) The new API allows managing JS closures converted from Swift closures from Swift side. It allows us to get the underlying `JSObject` and manage its lifetime manually from Swift. ```swift @js func makeIntToInt() throws(JSException) -> JSTypedClosure<(Int) -> Int> { return JSTypedClosure { x in return x + 1 } } @JSFunction func takeIntToInt(_ transform: JSTypedClosure<(Int) -> Int>) throws(JSException) let closure = JSTypedClosure<(Int) -> Int> { x in return x * 2 } defer { closure.release() } try takeIntToInt(closure) ``` Likewise to `JSClosure`, API users are responsible for "manually" releasing the closure when it's no longer needed by calling `release()`. After releasing, the closure becomes unusable and calling it will throw a JS exception (note that we will not segfault even if the closure is called after releasing). ```swift let closure = JSTypedClosure<(Int) -> Int> { x in return x * 2 } closure.release() try closure(10) // "JSException: Attempted to call a released JSTypedClosure created at <file>:<line>" ``` As a belt-and-suspenders measure, the underlying JS closure is also registered with a `FinalizationRegistry` to ensure that the Swift closure box is released when the JS closure is garbage collected, in case the API user forgets to call `release()`. However, relying on this mechanism is **not recommended** because the timing of garbage collection is non-deterministic and it's not guaranteed that it will happen in a timely manner. ---- On the top of the new API, this commit also fixes memory leak issues of closures exported to JS.
PreviousNext