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
Tracks removal of the JSException storage boxing introduced in #766.
Context
swiftlang/swift#89320 miscompiles Wasm calls to captureless async throws(JSException) closure values when the typed error exceeds the direct error convention: the thrown error is corrupted across the async unwind, so the rejected Promise receives garbage. JSException (~36 bytes) always took the affected indirect-error path.
#766 works around this at the library level by boxing JSException's stored properties (thrownValue, description, stack) into a private final class, shrinking the struct to a single stored reference so it travels in the direct error convention and the broken path is never taken. The public API is unchanged; the cost is one heap allocation per thrown exception. The original exploration is in PassiveLogic#13.
The codegen-level counterpart for zero-parameter async throwing exports is tracked separately in #761.
What to do once the compiler fix ships
The proper fix is swiftlang/swift#89715 (IRGen: fix async typed throws miscompiles on Wasm). Once it is available in the oldest Swift toolchain JavaScriptKit supports:
Move thrownValue, description, and stack back to stored properties on JSException and delete the Storage class. This is a library-internal layout change only, not a breaking API change.
Keep the async closure reject end-to-end tests as the regression guard that the reject path still works without the boxing.
Tracks removal of the
JSExceptionstorage boxing introduced in #766.Context
swiftlang/swift#89320 miscompiles Wasm calls to captureless
async throws(JSException)closure values when the typed error exceeds the direct error convention: the thrown error is corrupted across the async unwind, so the rejectedPromisereceives garbage.JSException(~36 bytes) always took the affected indirect-error path.#766 works around this at the library level by boxing
JSException's stored properties (thrownValue,description,stack) into a private final class, shrinking the struct to a single stored reference so it travels in the direct error convention and the broken path is never taken. The public API is unchanged; the cost is one heap allocation per thrown exception. The original exploration is in PassiveLogic#13.The codegen-level counterpart for zero-parameter async throwing exports is tracked separately in #761.
What to do once the compiler fix ships
The proper fix is swiftlang/swift#89715 (IRGen: fix async typed throws miscompiles on Wasm). Once it is available in the oldest Swift toolchain JavaScriptKit supports:
thrownValue,description, andstackback to stored properties onJSExceptionand delete theStorageclass. This is a library-internal layout change only, not a breaking API change.