You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0919be8
Browse filesBrowse the repository at this point in the historyBrowse files
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.
0 commit comments