Skip to content

IRGen: fix async typed throws miscompiles on Wasm - #89715

Merged
MaxDesiatov merged 1 commit into
mainfrom
maxd/wasm-async-typed-throws2
Jul 14, 2026
Merged

IRGen: fix async typed throws miscompiles on Wasm#89715
MaxDesiatov merged 1 commit into
mainfrom
maxd/wasm-async-typed-throws2

Conversation

@MaxDesiatov

@MaxDesiatov MaxDesiatov commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

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.

@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch from 5ad9de1 to 259a442 Compare June 5, 2026 17:16
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test macos

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test linux

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test macos

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test windows

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test macos

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test windows

1 similar comment
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test windows

@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch from 866c136 to 9840b12 Compare June 15, 2026 14:31
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov
MaxDesiatov marked this pull request as ready for review June 16, 2026 12:30
@MaxDesiatov
MaxDesiatov requested review from a team and rjmccall as code owners June 16, 2026 12:30
@MaxDesiatov
MaxDesiatov marked this pull request as draft June 16, 2026 12:30
@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch from 9840b12 to 91ba7dd Compare June 16, 2026 12:43
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test

@MaxDesiatov
MaxDesiatov marked this pull request as ready for review June 18, 2026 20:01
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci build toolchain macos

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci build toolchain linux

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test macos arm64

@MaxDesiatov
MaxDesiatov requested review from hjyamauchi and removed request for aschwaighofer June 28, 2026 10:48

@drexin drexin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two nitpicks, rest LGTM

Comment thread lib/IRGen/GenCall.cpp Outdated
Comment thread lib/IRGen/GenCall.cpp Outdated
@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch from c467db0 to 18dde8d Compare June 30, 2026 22:35
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci build toolchain

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

Comment thread lib/IRGen/GenCall.cpp
Comment thread lib/IRGen/GenCall.cpp Outdated
@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch 2 times, most recently from 0fef043 to ec662d8 Compare July 1, 2026 14:07
@MaxDesiatov
MaxDesiatov requested a review from rjmccall July 1, 2026 14:08
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci build toolchain

@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@rjmccall rjmccall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks good. My only remaining comment is that you keep talking about ind_error in the comments when this AFAIK doesn't actually refer to anything specific; probably best to just talk about the indirect error slot normally in prose.

# Conflicts:
#	test/Interpreter/async_typed_throws_wasm.swift

# Conflicts:
#	test/stdlib/Result+asyncInit.swift
@MaxDesiatov
MaxDesiatov force-pushed the maxd/wasm-async-typed-throws2 branch from ec662d8 to 5732641 Compare July 5, 2026 20:43
@MaxDesiatov
MaxDesiatov requested a review from rjmccall July 5, 2026 20:44
@MaxDesiatov

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@MaxDesiatov
MaxDesiatov merged commit 4c99082 into main Jul 14, 2026
6 checks passed
@MaxDesiatov
MaxDesiatov deleted the maxd/wasm-async-typed-throws2 branch July 14, 2026 14:17
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Swift for Wasm Jul 14, 2026
MaxDesiatov added a commit that referenced this pull request Jul 23, 2026
Cherry-pick of #89715, merged as 4c99082

**Explanation**: 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).

**Scope**: IRGen async typed-throws lowering only; while resulting LLVM IR has different ordering of parameters, non-Wasm native codegen is unchanged.
**Risk**: Low. Non-Wasm codegen is unchanged (the reorder only moves IR operands; `swiftself`/`swifterror` stay register-pinned by attribute). The only calling-convention change is on Wasm, which was already miscompiling.
**Testing**:  New execution test reproduces #89155 on Wasm; IRGen tests updated to pin the new parameter order.
**Issue**: #89320, rdar://177615931
**Reviewed by**: @drexin @kateinoigakukun @rjmccall
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

async & await Feature → concurrency: asynchronous function aka the async/await pattern bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. typed throws Feature → error handling → throws & rethrows: Typed throws WebAssembly Platform: WebAssembly

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Crash with typed/untyped throwing async functions on Wasm

4 participants