Skip to content

[Wasm RyuJit] EH, Unwind, and unwindable frames#127043

Merged
AndyAyersMS merged 8 commits intodotnet:mainfrom
AndyAyersMS:WasmUnwindInfo
Apr 23, 2026
Merged

[Wasm RyuJit] EH, Unwind, and unwindable frames#127043
AndyAyersMS merged 8 commits intodotnet:mainfrom
AndyAyersMS:WasmUnwindInfo

Conversation

@AndyAyersMS
Copy link
Copy Markdown
Member

Implement the codegen changes necessary for EH and unwind reporting and for making frames unwindable by the runtime:

  • Add a new phase that assigns Virtual IP ranges to each try, handler, and filter, and a distinct Virtual IP for each call. Call Virtual IPs lie within the range of their enclosing EH region. Region ranges lie within the range of their enclosing region.
  • Add codegen to the method to ensure the Virtual IP slot is at the bottom of the fixed part of the stack frame, and is updated before each call.
  • Adjust the localloc codegen so that for variable-sized frames there is a special marker at the bottom of the stack, and a pointer to the bottom of the fixed portion of the stack just above this.
  • Report unwind data to the host. For Wasm this is just the size of the fixed portion of the frame.
  • Report EH info to the host. For Wasm these are the Virtual IP ranges for the EH regions as noted above.
  • Change throw helpers so there is one per EH region (instead of one per EH handler region), so the throw helper calls have a well defined Virtual IP.
  • Catch funclets now return a value to the runtime, though not the actual resume IP (resume IPs are in a different "IP space" than the virtual IP, and are not meaningful except to codegen).

We are currently somewhat generous in handing out Virtual IPs; likely we could compress their range a bit more.

Still to do:

  • Use the Virtual IPs for GC reporting
  • Host side handling (in particular funclet extraction)
  • Runtime stack walking and EH processing.

Implement the codegen changes necessary for EH and unwind reporting
and for making frames unwindable by the runtime:

* Add a new phase that assigns Virtual IP ranges to each try, handler,
and filter, and a distinct Virtual IP for each call. Call Virtual IPs
lie within the range of their enclosing EH region. Region ranges lie
within the range of their enclosing region.
* Add codegen to the method to ensure the Virtual IP slot is at the
bottom of the fixed part of the stack frame, and is updated before
each call.
* Adjust the localloc codegen so that for variable-sized frames there
is a special marker at the bottom of the stack, and a pointer to the
bottom of the fixed portion of the stack just above this.
* Report unwind data to the host. For Wasm this is just the size of
the fixed portion of the frame.
* Report EH info to the host. For Wasm these are the Virtual IP ranges
for the EH regions as noted above.
* Change throw helpers so there is one per EH region (instead of one
per EH handler region), so the throw helper calls have a well defined
Virtual IP.
* Catch funclets now return a value to the runtime, though not the actual
resume IP (resume IPs are in a different "IP space" than the virtual IP,
and are not meaningful except to codegen).

We are currently somewhat generous in handing out Virtual IPs;
likely we could compress their range a bit more.

Still to do:
* Use the Virtual IPs for GC reporting
* Host side handling (in particular funclet extraction)
* Runtime stack walking and EH processing.
Copilot AI review requested due to automatic review settings April 17, 2026 02:34
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 17, 2026
@AndyAyersMS
Copy link
Copy Markdown
Member Author

FYI @dotnet/wasm-contrib

See the revised unwind proposal here: #121651 (comment)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the CoreCLR JIT’s Wasm backend to support unwind reporting and EH region mapping using a “Virtual IP” scheme, laying groundwork for runtime stack walking/EH processing on Wasm.

Changes:

  • Add a new Wasm JIT phase to assign Virtual IP ranges to EH regions and a distinct Virtual IP at each call site, and inject code to update the Virtual IP prior to calls.
  • Track and report per-func (root + funclets) Wasm unwind info (currently: fixed frame size) and report EH clause data to the VM for Wasm.
  • Update Wasm frame layout/codegen to place new unwind/EH-related slots at stable positions and adjust localloc handling to keep variable-sized frames unwindable.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/coreclr/jit/unwindwasm.cpp Implement Wasm unwind reservation/emission and track per-func frame size.
src/coreclr/jit/lclvars.cpp Ensure Wasm VirtualIP/ResumeIP/FunctionIndex locals are allocated last in the frame layout; add frame diagrams.
src/coreclr/jit/jit.h Include win64unwind.h on TARGET_WASM to get UNWIND_INFO definition.
src/coreclr/jit/flowgraph.cpp Adjust throw helper placement logic for Wasm to allow try-region association.
src/coreclr/jit/fgwasm.h Update Wasm successor enumeration to treat try-beg blocks as region entry points.
src/coreclr/jit/fgwasm.cpp Add fgWasmVirtualIP phase: compute EH Virtual IP ranges, inject Virtual IP stores before calls, mark funcs needing unwindable frames.
src/coreclr/jit/compphases.h Add PHASE_WASM_VIRTUAL_IP.
src/coreclr/jit/compmemkind.h Add WasmEH allocator kind used for EH clause info storage.
src/coreclr/jit/compiler.h Add Wasm-specific locals + per-func fields (frame size, unwindable flag) and store fgWasmEHInfo.
src/coreclr/jit/compiler.cpp Schedule PHASE_WASM_VIRTUAL_IP after lowering and before FinalizeEH/RA.
src/coreclr/jit/codegenwasm.cpp Record unwind stack allocation, create unwindable funclet prolog slots, adjust localloc unwind markers, return a value from catch funclets, and report EH clauses from precomputed data.
src/coreclr/jit/codegeninterface.h Promote EHClauseInfo to a shared type.
src/coreclr/jit/codegencommon.cpp Refactor EH reporting to a shared genReportEHClauses helper callable by Wasm codegen.
src/coreclr/jit/codegen.h Declare genReportEHClauses.
src/coreclr/inc/win64unwind.h Define a Wasm-specific UNWIND_INFO payload (FrameSize).
src/coreclr/inc/clrnt.h Include win64unwind.h for Wasm unwind type definitions.

Comment thread src/coreclr/jit/codegenwasm.cpp Outdated
Comment thread src/coreclr/jit/codegenwasm.cpp
Comment thread src/coreclr/jit/codegenwasm.cpp
Comment thread src/coreclr/jit/unwindwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/inc/clrnt.h Outdated
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp
Comment thread src/coreclr/inc/win64unwind.h Outdated
Comment thread src/coreclr/jit/lclvars.cpp
Comment thread src/coreclr/jit/unwindwasm.cpp
Copy link
Copy Markdown
Member

@kg kg left a comment

Choose a reason for hiding this comment

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

LGTM, but a second pair of eyes would be good

Comment thread src/coreclr/jit/codegenwasm.cpp
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/lclvars.cpp Outdated
Emit just one Virtual IP update per (non-empty) block. Track whether
funclets need unwindable frames in codegen. Simplfy the Wasm stack
layout charts.
Copilot AI review requested due to automatic review settings April 21, 2026 01:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp
Comment thread src/coreclr/jit/fgwasm.cpp Outdated
Comment thread src/coreclr/jit/unwindwasm.cpp Outdated
@AndyAyersMS
Copy link
Copy Markdown
Member Author

We are going to need to iterate a bit on the Virtual IP approach, but this at least gives us a plausible start and unblocks the work we need to do for funclet extraction and implementing unwiunding.

Various factors/constraints:

  • We are setting up Virtual IPs before fgWasmControlFlow, because that phase does not guarantee EH regions remain contiguous, so it's the "last time" we have a view of the code where the linear order of code properly respects EH nesting rules. We could try and change that and force Wasm linear codegen to also respect EH nesting... not clear how hard that might be.
  • We want to keep the range of Virtual IPs relatively compact since their values must be materialized in code.
  • We could perhaps do something like what we do for span dependent branches in the emitter (that is, once we've made it through codegen we know the set of materialized Virtual IP values, so we could compress that sparse set down to a dense set, and emit the dense encoding.
  • Because we're introducing them before codegen (and possibly before GC) we need to anticipate what those might need. Ideally we'd only modify the VIP when the EH or GC needs require a change -- eg if we have untracked reporting (or conservative scanning) we'd only need changes driven by EH.

Comment thread src/coreclr/jit/unwindwasm.cpp Outdated
Copilot AI review requested due to automatic review settings April 21, 2026 20:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment thread src/coreclr/jit/codegenwasm.cpp Outdated
Comment thread src/coreclr/jit/fgwasm.cpp
Comment thread src/coreclr/jit/codegenwasm.cpp Outdated
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@AndyAyersMS
Copy link
Copy Markdown
Member Author

/ba-g Wasm only JIT change, not testable in CI yet.

@AndyAyersMS AndyAyersMS merged commit a28fe52 into dotnet:main Apr 23, 2026
128 of 146 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants