Skip to content

Conversation

cfallin
Copy link
Member

@cfallin cfallin commented Jun 4, 2025

This commit introduces the next major piece of machinery (after the previously-landed try_call support) that we will eventually use to implement Wasm exceptions in Wasmtime. In particular, it implements a generic unwinder as a new crate that supports (i) walking a stack produced by Cranelift code, (ii) serializing Cranelift exception metadata to compact tables (in a way very similar to address maps in Wasmtime, so they will be mappable directly from disk), (iii) using these serialized tables to find handlers during a stack-walk, and (iv) jumping to handlers (i.e., actually unwinding). This crate is currently used in the filetests runner, and will next be used in Wasmtime.

The commit first performs code-motion: it moves stack-walking code from Wasmtime to cranelift-unwinder. This itself has no functional effect, but isolates the code that understands contiguous sequences of Cranelift frames ("activations") from that which is specific to Wasmtime's activation delimiters and metadata.

It then implements a compact exception-table format. This format uses the object crate's mechanisms for directly referencing in-memory arrays of little-endian u32s in a way that will allow us to find handlers when mapping exception metadata directly from an ELF section in a .cwasm (for example). The format consists of four sorted u32 arrays in a way that allows us to look up a callsite first, then search its sorted array of handler offsets by tags.

It next implements the actual unwind control flow: it contains an assembly stub for each supported architecture that transfers control to a PC, SP, and FP value "up the stack", with payload values placed in the payload registers we have defined per our exception ABI in Cranelift.

Finally, it puts these pieces together in the filetest runner. Note that the runtest does a lot "by hand": we don't have entry and exit trampolines as we do in Wasmtime, so the filetest contains three functions, with the middle one invoking the "throw hostcall" and entry and exit trampolines around it grabbing the appropriate entry/exit FPs and exit PC. The dance to call back to host code is also somewhat delicate, as we haven't done this before. The JITModule's linking + relocation support does not seem sufficient to properly define a symbol, so instead we scan for func_addr instructions referencing a well-known name (__cranelift_throw) and replace them with iconsts with the function address at runtime, baking it in. This is somewhat ugly, but it works. All of these filetest-specific details will be handled much more nicely in the Wasmtime version of this functionality, as we have proper abstractions for entry/exit trampolines and hostcalls.

@cfallin cfallin requested review from a team as code owners June 4, 2025 05:50
@cfallin cfallin requested review from abrown, dicej and fitzgen and removed request for a team, abrown and dicej June 4, 2025 05:50
@cfallin cfallin force-pushed the lets-kick-back-and-unwind-a-bit branch from c29d873 to 24b71a8 Compare June 4, 2025 05:53
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator wasmtime:api Related to the API of the `wasmtime` crate itself labels Jun 4, 2025
@bjorn3
Copy link
Contributor

bjorn3 commented Jun 4, 2025

By the way why is the unwind info format defined in the cranelift-unwinder crate? It is Wasmtime specific and I would assume that Winch and Pulley will reuse the same format.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

r=me with things we discussed in the cranelift meeting

@cfallin cfallin force-pushed the lets-kick-back-and-unwind-a-bit branch 6 times, most recently from 12673ed to 2ed32f9 Compare June 4, 2025 20:20
@cfallin cfallin force-pushed the lets-kick-back-and-unwind-a-bit branch 2 times, most recently from 1006ae6 to d624489 Compare June 4, 2025 20:58
@cfallin
Copy link
Member Author

cfallin commented Jun 5, 2025

Wow, CI really does not like this PR -- network error here downloading CMake.

@cfallin cfallin added this pull request to the merge queue Jun 5, 2025
Merged via the queue into bytecodealliance:main with commit efa236e Jun 5, 2025
71 checks passed
@cfallin cfallin deleted the lets-kick-back-and-unwind-a-bit branch June 5, 2025 02:00
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 25, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those. It is currently stacked on top of bytecodealliance#11321.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those. It is currently stacked on top of bytecodealliance#11321.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those. It is currently stacked on top of bytecodealliance#11321.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those. It is currently stacked on top of bytecodealliance#11321.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those. It is currently stacked on top of bytecodealliance#11321.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Jul 26, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 12, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 12, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

This PR does not yet provide host-boundary-crossing exceptions;
exceptions that are not caught in a given Wasm activation become traps
at the host boundary. That support will come in a subsequent PR.

Because exceptions do not yet cross the host boundary, this also does
not yet enable the `assert_exception` wast directive, and so cannot yet
support the spec-tests. That will also come in a subsequent PR.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 15, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 15, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 19, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 19, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 19, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 19, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/

prtest:full
cfallin added a commit to cfallin/wasmtime that referenced this pull request Aug 20, 2025
This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/

prtest:full
github-merge-queue bot pushed a commit that referenced this pull request Aug 21, 2025
* WebAssembly exception-handling support.

This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in #10510 for Cranelift-level
exception support, #10919 for an unwinder, and #11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/

prtest:full

* Permit UnwindToWasm to have unused fields in Pulley builds (for now).

* Resolve miri-caught reborrowing issue.

* Ignore exceptions tests in miri for now (Pulley not supported).

* Use wasmtime_test on exceptions tests.

* Get tests passing on pulley platforms

* Add a check to `supports_host` for the generated test and assert
  failure also when that is false.
* Remove `pulley_unsupported` test as it falls out of `#[wasmtime_test]`
* Remove `exceptions_store` helper as it falls out of `#[wasmtime_test]`
* Remove miri annotations as they fall out of `#[wasmtime_test]`

* Remove dead import

* Skip some unsupported tests entirely in `#[wasmtime_test]`

If the selected compiler doesn't support the host at all then there's no
need to run it. Actually running it could misinterpret `CraneliftNative`
as "run with pulley" otherwise, so avoid such false negatives.

* Cranelift: dynamic contexts: account for outgoing-args area.

---------

Co-authored-by: Alex Crichton <[email protected]>
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
…tests. (bytecodealliance#10919)

This commit introduces the next major piece of machinery (after the
previously-landed `try_call` support) that we will eventually use to
implement Wasm exceptions in Wasmtime. In particular, it implements a
generic unwinder as a new crate that supports (i) walking a stack
produced by Cranelift code, (ii) serializing Cranelift exception
metadata to compact tables (in a way very similar to address maps in
Wasmtime, so they will be mappable directly from disk), (iii) using
these serialized tables to find handlers during a stack-walk, and (iv)
jumping to handlers (i.e., actually unwinding). This crate is currently
used in the filetests runner, and will next be used in Wasmtime.

The commit first performs code-motion: it moves stack-walking code from
Wasmtime to `cranelift-unwinder`. This itself has no functional effect,
but isolates the code that understands contiguous sequences of Cranelift
frames ("activations") from that which is specific to Wasmtime's
activation delimiters and metadata.

It then implements a compact exception-table format. This format uses
the `object` crate's mechanisms for directly referencing in-memory
arrays of little-endian `u32`s in a way that will allow us to find
handlers when mapping exception metadata directly from an ELF section in
a `.cwasm` (for example). The format consists of four sorted `u32`
arrays in a way that allows us to look up a callsite first, then search
its sorted array of handler offsets by tags.

It next implements the actual unwind control flow: it contains an
assembly stub for each supported architecture that transfers control to
a PC, SP, and FP value "up the stack", with payload values placed in the
payload registers we have defined per our exception ABI in Cranelift.

Finally, it puts these pieces together in the filetest runner. Note that
the runtest does a lot "by hand": we don't have entry and exit
trampolines as we do in Wasmtime, so the filetest contains three
functions, with the middle one invoking the "throw hostcall" and entry
and exit trampolines around it grabbing the appropriate entry/exit FPs
and exit PC. The dance to call back to host code is also somewhat
delicate, as we haven't done this before. The `JITModule`'s linking +
relocation support does not seem sufficient to properly define a symbol,
so instead we scan for `func_addr` instructions referencing a well-known
name (`__cranelift_throw`) and replace them with `iconst`s with the
function address at runtime, baking it in. This is somewhat ugly, but it
works. All of these filetest-specific details will be handled much more
nicely in the Wasmtime version of this functionality, as we have proper
abstractions for entry/exit trampolines and hostcalls.
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
* WebAssembly exception-handling support.

This PR introduces support for the [Wasm exception-handling proposal],
which introduces a conventional try/catch mechanism to WebAssembly. The
PR supports modules that use `try_table` to register handlers for a
lexical scope; and provides `throw` and `throw_ref` that allocate (in
the first case) and throw exception objects.

This PR builds on top of the work in bytecodealliance#10510 for Cranelift-level
exception support, bytecodealliance#10919 for an unwinder, and bytecodealliance#11230 for exception
objects built on top of GC, in addition a bunch of smaller fix and
enabling PRs around those.

[Wasm exception-handling proposal]: https://github.com/WebAssembly/exception-handling/

prtest:full

* Permit UnwindToWasm to have unused fields in Pulley builds (for now).

* Resolve miri-caught reborrowing issue.

* Ignore exceptions tests in miri for now (Pulley not supported).

* Use wasmtime_test on exceptions tests.

* Get tests passing on pulley platforms

* Add a check to `supports_host` for the generated test and assert
  failure also when that is false.
* Remove `pulley_unsupported` test as it falls out of `#[wasmtime_test]`
* Remove `exceptions_store` helper as it falls out of `#[wasmtime_test]`
* Remove miri annotations as they fall out of `#[wasmtime_test]`

* Remove dead import

* Skip some unsupported tests entirely in `#[wasmtime_test]`

If the selected compiler doesn't support the host at all then there's no
need to run it. Actually running it could misinterpret `CraneliftNative`
as "run with pulley" otherwise, so avoid such false negatives.

* Cranelift: dynamic contexts: account for outgoing-args area.

---------

Co-authored-by: Alex Crichton <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift Issues related to the Cranelift code generator wasmtime:api Related to the API of the `wasmtime` crate itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants