Skip to content

Encode the exception channel in the thin Wasm IR (EH-01..EH-04) - #150

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

biuld merged 1 commit into
masterfrom
slice/eh-encoding

Conversation

@biuld

@biuld biuld commented Oct 18, 2026

Copy link
Copy Markdown
Owner

What lands

Slice 1 of the exception-handling adoption (rows EH-01..EH-04 of docs/implementation/backend/exception-handling.md), implementing the merged design (PR #149):

  • Thin IR (wasm/mod.rs): Op::Try { body, clauses } (leaf opcodes stay wasm_encoder::Instruction), CatchClause = Catch { tag, label } | CatchAll { label } (labels depth-relative at the try_table's emission point, not counting its internal label), TagDef, the distinct TagIndex domain, Module::tags. The one lowering construction site emits no tags yet.
  • Verifier (wasm/verify/{mod.rs,body.rs}): module-level tag checks; the body walk now tracks active-label result types and rejects out-of-range raw/catch-clause tag indices, unresolved clause label depths, and clause labels whose result type disagrees with the delivered payload; the try_table's internal label is counted in branch-depth simulation.
  • Encoder (wasm/encode.rs): the tag section (id 13) between memory and global, emitted only when a tag is defined.
  • Profile gate tests (EH-03): the profile-derived validator gates the encoding; no profile default touched.

Evidence (wasmtime 48.0.1 CLI, PSRS_REQUIRE_WASMTIME=1)

  • named_catch_delivers_the_tag_payload — exit 0, stdout 7
  • catch_all_observes_a_payload_less_throw — exit 0, stdout 42
  • throw_unwinds_through_nested_call_frames — exit 0, stdout 5
  • traps_are_not_exceptions — trap not caught, non-zero exit

wasmparser validation under an explicitly exceptions-enabled profile; disabled-profile rejection and no-tag-section regression tests included. Checklist rows EH-01..04 moved to Verified with the evidence record; D-04 untouched (its BC-08 status claim lands at EH-17 with board evidence).

Validation (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 ok, 0 failed (coordinator re-run). Files ≤500 lines (two were converted to module directories with content preserved).

Slice 1 of the exception-handling adoption (DEC-23): the structured
encoding gains the channel's region shape while the MIR lowering and the
structurer stay untouched — every fixture in this slice builds the thin
IR directly.

- wasm/mod.rs: Op::Try { body, clauses }, CatchClause (Catch/CatchAll),
  TagDef, the TagIndex index domain, and Module::tags.
- encode.rs: the tag section (id 13) between the memory and global
  sections, emitted only when the module defines a tag; try_table
  emission with an empty block type.
- verify/: module-level tag-definition checks and a structured-body walk
  that tracks active-label result types; the verifier now rejects
  out-of-range throw/catch tag indices, unresolved clause label depths
  (resolved at the try_table's emission point, not counting its own
  internal label), and clause labels whose result type disagrees with the
  delivered payload.
- capability gate: the profile-derived validator already gates assembled
  binaries; tests prove a tag-using module is rejected while exceptions
  is disabled and accepted when enabled, with no other feature enabled
  implicitly. The default profile keeps exceptions disabled.
- driver fixtures (PSRS_REQUIRE_WASMTIME=1, wasmtime 48.0.1): a named
  catch delivering an i32 payload, catch_all observing a payload-less
  throw, a throw unwinding through two nested call frames, and a trap
  inside a protected region staying uncatchable.

wasm/tests.rs and wasm/verify.rs grew past the 500-line limit and became
module directories with their content preserved. The checklist records
EH-01..EH-04 as Verified with the exact tests, commands, and engine
version.
@biuld
biuld merged commit 56773ae into master Oct 18, 2026
1 check passed
@biuld
biuld deleted the slice/eh-encoding branch October 18, 2026 10:15
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