Wasm: fix async typed throws arguments mismatch trap - #89416
Merged
MaxDesiatov merged 2 commits intoMay 28, 2026
Conversation
Contributor
Author
|
@swift-ci smoke test |
This was referenced May 26, 2026
MaxDesiatov
commented
May 27, 2026
Co-authored-by: Max Desiatov <m_desiatov@apple.com>
kateinoigakukun
approved these changes
May 27, 2026
Contributor
Author
|
@swift-ci smoke test |
Member
|
Let me put my thoughts on this: This is very unfortunate and strictly speaking the problem is not specific to wasm but any target that doesn't support putting swiftself on a register (effectively wasm only today though). Having said that, the temporal workaround is valid and worth landing as a band-aid for now. We should consider placing |
MaxDesiatov
enabled auto-merge (squash)
May 27, 2026 15:25
Contributor
Author
|
@swift-ci test windows |
ktoso
added a commit
to mattmassicotte/swift
that referenced
this pull request
May 28, 2026
swiftlang#89416 was merged, so this should work now
MaxDesiatov
added a commit
that referenced
this pull request
May 29, 2026
Teemperor
pushed a commit
to Teemperor/swift-mono
that referenced
this pull request
May 29, 2026
…trap" (#89541) Reverts swiftlang/swift#89416
MaxDesiatov
added a commit
that referenced
this pull request
Jul 14, 2026
Follow up to currently-reverted #89416. On wasm32 the WebAssembly backend pads the `swiftself` and `swifterror` parameters, which left the indirect typed-error pointer and the `swiftself`/context slot at different LLVM-IR positions for Thin versus Thick async callers; caller and callee then disagreed on which trailing pointer held the typed-error slot and miscompiled async typed-throws calls (#89155: `Result.init(catching:) async` trapped in a value-witness copy on Wasm). With this change `SignatureExpansion::expandAsyncEntryType` now emits `addIndirectThrowingResult` before the `swiftself`/context slot, so the trailing pair is always `[ind_error, swiftself]` and Thin and Thick agree on the position regardless of parameter padding. The result-shape decision moves behind one gate, `hasTrailingAsyncErrorContextPair` (`GenCall.h`), consumed by the three sites that read these slots positionally: `AsyncCallEmission::setFromCallee`, `AsyncPartialApplicationForwarderEmission`, and `AsyncNativeCCEntryPointArgumentEmission::mapAsyncParameters` (the last also pre-extracts the witness-method Self/witness-table that trail the pair). Each consumer carries an assertion that fires if the gate ever diverges from the slots actually filled. Fixes #89320.
Teemperor
pushed a commit
to Teemperor/swift-mono
that referenced
this pull request
Jul 14, 2026
…R 89715) Follow up to currently-reverted swiftlang/swift#89416. On wasm32 the WebAssembly backend pads the `swiftself` and `swifterror` parameters, which left the indirect typed-error pointer and the `swiftself`/context slot at different LLVM-IR positions for Thin versus Thick async callers; caller and callee then disagreed on which trailing pointer held the typed-error slot and miscompiled async typed-throws calls (Issue/PR 89155: `Result.init(catching:) async` trapped in a value-witness copy on Wasm). With this change `SignatureExpansion::expandAsyncEntryType` now emits `addIndirectThrowingResult` before the `swiftself`/context slot, so the trailing pair is always `[ind_error, swiftself]` and Thin and Thick agree on the position regardless of parameter padding. The result-shape decision moves behind one gate, `hasTrailingAsyncErrorContextPair` (`GenCall.h`), consumed by the three sites that read these slots positionally: `AsyncCallEmission::setFromCallee`, `AsyncPartialApplicationForwarderEmission`, and `AsyncNativeCCEntryPointArgumentEmission::mapAsyncParameters` (the last also pre-extracts the witness-method Self/witness-table that trail the pair). Each consumer carries an assertion that fires if the gate ever diverges from the slots actually filled. Fixes Issue/PR 89320.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Workaround for issue #89320: a Wasm runtime trap when
asynctyped-throws closures are coerced viathin_to_thick_function. The WebAssembly backend pads swiftcc signatures with trailingswiftself/swifterrorplaceholders to aligncall_indirect. On thinasynctyped-throws callees the padding collides positionally with the trailingind_error_ptr, miscompiling calls from thick callers.This PR adds a mandatory SIL pass
WasmAsyncT2TLowering(gated onTriple::isWasm(), runs afterOwnershipModelEliminator) that rewrites the narrow bug shape (isAsync,hasIndirectErrorResult, non-polymorphic operand/result,FunctionRefBaseInstoperand, single-BB uses) into a zero-capturepartial_apply [callee_guaranteed] [on_stack]bracketed bydealloc_stack. Thepartial_applylowering emits matching caller and callee arg layouts at the LLVM level, sidestepping the backend padding mismatch.Resolves #89320
rdar://177615931