JIT: don't fall through from a Wasm callfinally across a try_table end - #134758
Merged
Merged
Conversation
genCallFinally omitted the branch to the continuation whenever it was the lexically next block. On Wasm, closing a Try interval between the BBJ_CALLFINALLYRET and its continuation emits a validation 'unreachable' after the try_table 'end', so the fall-through trapped at runtime. Use CanRemoveJumpToTarget, which already handles this for BBJ_ALWAYS/BBJ_COND. Re-enable WebSocketReceiveErrorMessageTests on Wasm R2R. Fixes #134264 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add a JIT regression test for the Wasm callfinally fall-through trap: an async method ending in a user try/catch/finally whose finally is too large to clone, plus a nested try/finally-in-try/catch variant. Add a DEBUG check in fgWasmControlFlow that every adjacent forward edge that cannot fall through because a Try/ExnRefWrapper ends at its target has an enclosing Block interval to branch to. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 6 pipeline(s). 10 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Contributor
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
This was referenced Sep 28, 2026
Member
Author
|
cc @dotnet/wasm-contrib |
adamperlin
reviewed
Sep 29, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
adamperlin
approved these changes
Sep 29, 2026
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.
On Wasm,
genCallFinallyomitted the branch to the callfinally continuation whenever it was the lexically next block. When atry_tableinterval ends between theBBJ_CALLFINALLYRETand its continuation, codegen emits a validationunreachableafter thetry_tableend, so the fall-through traps at runtime withRuntimeError: unreachable.This hit
ManagedWebSocket.<WaitForServerToCloseConnectionAsync>d__64.MoveNextunder browser-wasm R2R. Disassembly showed the normal path calling the finally funclet and then falling into thetry_tableend, while other paths to the same continuation usedcall finally; br N.Changes
genCallFinallynow usesBasicBlock::CanRemoveJumpToTarget, which already refuses fall-through across a Try/ExnRefWrapper end forBBJ_ALWAYSandBBJ_COND(JIT: fix wasm conditional fallthrough #133528). Its assert is widened to acceptBBJ_CALLFINALLYRET.fgWasmControlFlowasserts that every adjacent forward edge that cannot fall through because a Try/ExnRefWrapper ends at its target has an enclosing Block interval, so the explicit branch has a label.JIT/Regression_2/Runtime_134264. The bug needs an async method ending in a user try/catch/finally whose finally is too large to be cloned; a nested try/finally-in-try/catch variant is included.WebSocketReceiveErrorMessageTestson Wasm R2R.Validation
System.Net.WebSockets.Tests, browser-wasm CoreCLR, trimmed R2R on Chrome: before the fix, reproduces the trap; after, 278 run, 0 failed, including the 4 re-enabled tests.Runtime_134264viasrc/tests/run.sh wasm --runcrossgen2tests(browser): passes with the fix; with the pre-fix JIT it traps withRuntimeError: unreachableinTryCatchFinallyAsync_d__2.MoveNext.jitformat.pyclean.JIT/Regression_2is not yet in the curated WASI runtime-test trees; #133265 adds the WASI R2R lane and should include-tree:JIT/Regression_2to cover this test there.Resolves #134264
Note
This PR description was generated with GitHub Copilot.