Skip to content

Represent the exception channel in MIR (EH-05..EH-08) - #151

Merged
biuld merged 1 commit into
masterfrom
slice/eh-mir
Oct 18, 2026
Merged

biuld merged 1 commit into
masterfrom
slice/eh-mir

Conversation

@biuld

@biuld biuld commented Oct 18, 2026

Copy link
Copy Markdown
Owner

What lands

Slice 2 of the exception-handling adoption (rows EH-05..EH-08), implementing the design from PR #149:

  • mir/tag.rs — TagId (module-local) and Tag { name, payload, span } (≤1 payload value, multi-payload rejected).
  • mir/mod.rs — Terminator::Throw { tag, arguments, handler, span } and Terminator::Try { protected, catches, catch_all, span }; Module::tags.
  • mir/try_region.rs — the shared try-region partition (dominance-carved protected regions, handler owners, conflicts), one definition consumed by the verifier, mark_tail, and (next slice) the structurer.
  • mir/verify/exception.rs — tag checks and unwind-edge rules: a throw's landing handler is the innermost enclosing region that catches its tag (matching Wasm's dynamic clause-matching semantics); handler-block throws resolve outward from their owning try's block (the try_table is disarmed on its own catch path); handler blocks have no normal predecessors and one owner; no back edge targets a try block. Negative fixture per rule, span-carrying diagnostics.
  • mir/lower/tail.rs — mark_tail skips calls in protected blocks (a return_call pops the caller's frame and would silently discard armed handlers); loopification inside regions stays active.
  • mir/verify/capability.rs — exceptions joins the required set; disabled profile rejects with a source-associated diagnostic; wasmtime_wasi_0_2() unchanged.
  • Downstream: wasm/lower/structure rejects yet-unlowered exception terminators loudly at their span; the optimizer treats handlers as reachable-from-handlers, throws as non-total, and try/throw blocks as opaque for simplification.

Validation (coordinator re-run on the final committed state)

cargo fmt --all --check ✅ · cargo clippy --workspace --all-targets -- -D warnings ✅ · PSRS_STDLIB_ROOT=… PSRS_REQUIRE_WASMTIME=1 cargo test --workspace ✅ 71 suites, 2168 passed, 0 failed. Checklist rows EH-05..08 → Verified with evidence; D-04 untouched; profile default unchanged. mir/mod.rs is exactly at the 500-line limit (flagged for the next slice).

MIR gains the module-local tag table and the two channel terminators, and
the verifier checks their unwind edges. The protected-region partition is
one shared analysis (mir/try_region.rs) that the verifier, tail-call
marking, and the structuring slice all consume.

- mir/tag.rs, mir/mod.rs: Tag/TagId, Module::tags, Terminator::Throw with
  the documented fields (tag, arguments, handler, span) and
  Terminator::Try (protected, catches, catch_all, span); a tag has at
  most one payload value, rejected with an explicit diagnostic.
- mir/try_region.rs: the dominance-carved protected region (blocks
  dominated by the protected entry, minus inner tries' claims, minus
  handler blocks), the nesting-or-disjoint check, and the no-back-edge-
  into-a-try-block check; handler ownership with conflict recording.
- mir/verify/exception.rs: clause-tag resolution, handler parameters
  typed as the caught payload, no normal predecessors, single-owner
  handler, Throw handler resolution (the innermost enclosing region that
  catches the tag; a handler block resolves from its owning try, whose
  try_table is disarmed on its own catch path), and no forced
  ReturnCall/ReturnCallRef inside a protected region.
- mir/lower/tail.rs: mark_tail computes the shared partition and keeps
  protected blocks' calls ordinary; self-call loopification stays active
  inside regions.
- mir/verify/capability.rs: RequiredCapabilities.exceptions, set by a
  declared tag or a Throw/Try terminator, rejected under a disabled
  profile at module.span; wasmtime_wasi_0_2() unchanged.
- Wasm structuring and the dispatcher reject the terminators they cannot
  lower yet ('MIR exception-channel terminators are not lowered to Wasm
  yet'); the optimizer keeps handler blocks that normal reachability
  would prune.

Checklist rows EH-05..EH-08 verified with direct-MIR fixtures.
@biuld
biuld merged commit b5d1879 into master Oct 18, 2026
1 check passed
@biuld
biuld deleted the slice/eh-mir branch October 18, 2026 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant