Stream: git-wasmtime

Topic: wasmtime / PR #14011 Remove the concept of concrete excep...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:22):

alexcrichton opened PR #14011 from alexcrichton:remove-exn-type to bytecodealliance:main:

This commit is a refactoring of the implementation of exceptions within Wasmtime to remove the concept of a concrete exception type from the hierarchy of types Wasmtime supports for guests. WebAssembly itself has no concept of concrete exception types meaning that Wasmtime's public API, which typically follows the WebAssembly specification, is misaligned in this respect. Specifically:

These properties have led to a good deal of implementation throughout Wasmtime's surface API itself, in addition to downstream APIs like the C and C++ APIs. Additionally as something that's not actually expressible in WebAssembly it means that these paths are not well tested or fuzzed, meaning that mistakes can leak through. Two known mistakes today are:

  1. When creating a host-defined Tag the internal ExnType is a stale index that is not properly rooted in a Store or Engine. This ends up not causing any issues, however, since the field isn't ever read.
  2. The TypeTrace for WasmHeapType implementation did not canonicalize the CanoncreteExn branch of the type. This was never expressible in WebAssembly, however, which meant that it ended up being benign at runtime.

Overall it seemed subjectively to me like it would be best to better align Wasmtime's public API with the WebAssembly type system in this respect, removing ExnType and various APIs that reference it.

Internally this necessitated some refactorings to avoid panics/unreachables when ConcreteExn appeared, so I've opted to entirely remove the ConcreteExn throughout as well. This permeated into the GC implementation where the layout for exceptions is now a struct with two leading fields as opposed to an object with a bigger header followed by a struct layout. Runtime-wise exceptions are still allocated in the same layout as before, only now the instance/tag fields are part of the struct layout as opposed to being implicitly part of the header computation. Internal methods were renamed to be more precise about what's being operated on.

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:22):

alexcrichton requested fitzgen for a review on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:22):

alexcrichton requested wasmtime-compiler-reviewers for a review on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:22):

alexcrichton requested wasmtime-fuzz-reviewers for a review on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:22):

alexcrichton requested wasmtime-core-reviewers for a review on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:26):

alexcrichton updated PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:33):

cfallin commented on PR #14011:

I'll add some historical context: in design discussions back when this was implemented, we explicitly chose to make "exception of tag T" a distinct type, and not a thin wrapper over a struct, because:

Basically: there were good reasons we did this; risks abound if we collapse the distinction; there have been a few bugs in the current approach but they can be easily fixed; I don't see sufficient data to relegislate the decision. Curious what @fitzgen thinks of course too.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 21:44):

alexcrichton commented on PR #14011:

I understand the knee-jerk reaction here, but I've done my best to not just barge in and change everything. To your points:

Exception unwinding needs to read out the tag from an exception object at runtime, and should not look up runtime type info to do so.

This is explicitly perserved. I consider it a bug as well that acquiring a layout requires runtime engine locks right now. That makes GC tracing that much slower. The Store should have quick and easy access to runtime layouts for tracing, and if it did so then the means by which I've preserved this would be even simpler.

The Wasm spec in essence has "too much implicitness" here: a functy can be used to refer to a signature, or can be used to refer to an exception layout.

I don't think this is true, though. A function type alone cannot be used to refer to an exception layout, but rather it needs to be explicitly wrapped up in a tag, and that's the delination for "here's the exception stuff" vs not. Regardless I don't think we should be in the business of providing an opinionated view of wasm's type system, to me Wasmtime should reflect wasm as-is.

A function signature and an exception object have different representations.

This remains so, a Tag is distinct from a TagType which is distinct from a FuncType. Do you have an example of something in this PR you'd like to change?

The host API does need something to represent "an exception of this type" for (i) fast allocation, and (ii) fast access to fields.

This is also explicitly preserved. There's still ExnRefPre, and we've never had fast access to fields on any GC type from the embedder because it always requires looking up the layout, and that behavior is additionally preserved. Like above I think this is something we should fix, but is orthogonal to the wasm type system mismatch here.

Basically: there were good reasons we did this; risks abound if we collapse the distinction; there have been a few bugs in the current approach but they can be easily fixed; I don't see sufficient data to relegislate the decision.

Do you have specific areas of this PR that you would not like to see land in Wasmtime, or would like to change? We routinely refactor core implementation details in response to implementation feedback, and to me the implementation feedback here is "the public API should match WebAssembly, not Wasmtime's own variant", and pushing that change back into the runtime results in this PR.

Put another way, do you disagree with the premise I have that Wasmtime's public API should reflect WebAssembly's type system? For example I don't think HeapType::ConcreteExn should exist because it doesn't exist in WebAssembly.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 22:01):

cfallin commented on PR #14011:

Do you have specific areas of this PR that you would not like to see land in Wasmtime, or would like to change? We routinely refactor core implementation details in response to implementation feedback, and to me the implementation feedback here is "the public API should match WebAssembly, not Wasmtime's own variant", and pushing that change back into the runtime results in this PR.

Sure, I think the main thing I don't like about it is that it creates a distributed and ad-hoc invariant between the struct layout code and the runtime: it expects that the tag reference fields (defining instance and defined-tag-index) come first in the layout. I appreciate that you added asserts here but it's still an example of how collapsing the concepts causes more entangled code than we otherwise would have.

I don't oppose refactoring as a concept (of course not!), we just spent a lot of time on this design decision and considered it carefully, and I still see risks here that I'm naming explicitly.

I don't think we should be in the business of providing an opinionated view of wasm's type system, to me Wasmtime should reflect wasm as-is.

For what it's worth I don't see the current design as "opinionated" or something like that: it names an implementation corner that already must exist implicitly (all exceptions with this layout). The Wasm surface language and semantics don't require that, so the spec doesn't have it, but a good implementation certainly does. Even this PR has it, just as a side-table with implicit invariants.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 23:03):

github-actions[bot] added the label wasmtime:c-api on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 23:03):

github-actions[bot] added the label fuzzing on PR #14011.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 23:03):

github-actions[bot] commented on PR #14011:

Subscribe to Label Action

cc @fitzgen

<details>
This issue or pull request has been labeled: "fuzzing", "wasmtime:c-api"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>


Last updated: Jul 29 2026 at 05:03 UTC