Stream: git-wasmtime

Topic: wasmtime / PR #13613 Component model: catch exceptions at...


view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:35):

cfallin opened PR #13613 from cfallin:keep-your-exceptions-to-yourself to bytecodealliance:main:

Per the [Canonical ABI], an exception thrown in one component must not cross component boundaries; instead, it must become a trap. (Thanks to fitzgen for realizing this and raising the issue to me!)

This PR updates the adapter compiler (FACT) to wrap adapters in a try_table, with a catch_all clause that raises a trap, when exceptions are enabled in the engine Wasm feature configuration. This is a clean and simple catch-all: because FACT-compiled adapters are Wasm modules, we can use Wasm exception handling itself and be assured that we will tie into the necessary runtime infra without having to change the internal throw logic to be component-aware at all.

[Canonical ABI]: https://github.com/WebAssembly/component-model/blob/823aa133c2d94a328269da25fd9712bccc142d49/design/mvp/CanonicalABI.md?plain=1#L3768

<!--
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 (Jun 11 2026 at 20:35):

cfallin requested pchickey for a review on PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:35):

cfallin requested wasmtime-core-reviewers for a review on PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:38):

alexcrichton edited PR #13613:

Per the [Canonical ABI], an exception thrown in one component must not cross component boundaries; instead, it must become a trap. (Thanks to fitzgen for realizing this and raising the issue to me!)

This PR updates the adapter compiler (FACT) to wrap adapters in a try_table, with a catch_all clause that raises a trap, when exceptions are enabled in the engine Wasm feature configuration. This is a clean and simple catch-all: because FACT-compiled adapters are Wasm modules, we can use Wasm exception handling itself and be assured that we will tie into the necessary runtime infra without having to change the internal throw logic to be component-aware at all.

[Canonical ABI]: https://github.com/WebAssembly/component-model/blob/823aa133c2d94a328269da25fd9712bccc142d49/design/mvp/CanonicalABI.md?plain=1#L3768

Closes #13614

<!--
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 (Jun 11 2026 at 20:42):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:53):

:memo: alexcrichton submitted PR review:

I think we'll want to expand out the test here to be more exhaustive since there are other locations this may need to get integrated. For example realloc, post-return, and various async-related features I'm not sure will be caught by this current block/injection. I'll try to write up a test.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:53):

:speech_balloon: alexcrichton created PR review comment:

Could this be plumbed as WasmFeatures rather than a bool to help make ti a bit more self-documenting in case more params are grown here?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:53):

:speech_balloon: alexcrichton created PR review comment:

I'm wary about the non-local behavior of return here w.r.t. how everything else right now is structured as a relatively self-contained method in this compiler. Could this instead have the "didn't throw" case jump to an outermost block which continues execution past this? Something like:

block $ok (result ...)
  block $uncaught-exception
    try_table (catch_all $uncaught-exception)
        call $the-thing
        br $ok
    end
   unreachable
  end
end
;; ... rest of the translation ...

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:53):

:speech_balloon: alexcrichton created PR review comment:

Could this test be modeled as *.wast?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 20:53):

:speech_balloon: alexcrichton created PR review comment:

Do you know where this try_call_indirect is coming from? Is this perhaps a libcall invocation, and if so we probably want an issue about avoiding try_call_* with libcalls because they can't raise exceptions.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:00):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:00):

:speech_balloon: cfallin created PR review comment:

Ah, yeah, this is general inlining logic I think: if we inline at a try_call and in the inlinee, we have a call_indirect, it will turn into a try_call_indirect, because Cranelift doesn't know anything about callees' throws. That's required for soundness with the current IR, a Big Project to change (effect system in Cranelift signatures?) and I'm not sure there's a smaller point-fix...

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:01):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:01):

:speech_balloon: cfallin created PR review comment:

(More precisely, this requires something like checked exceptions and a whole-program analysis: the original call_indirect could still indirectly call something that throws, per CLIF semantics. We'd need a separate "call that never even indirectly invokes a throw" instruction, i.e., a call with a checked-exception null set, and then somehow interprocedurally typecheck that.)

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:01):

:speech_balloon: cfallin edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:speech_balloon: cfallin created PR review comment:

Converted!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:speech_balloon: cfallin created PR review comment:

Done!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:memo: cfallin submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:42):

:speech_balloon: cfallin created PR review comment:

Switched!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:43):

cfallin commented on PR #13613:

Thanks! Updated and added tests for realloc and post-return throwing as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 21:43):

cfallin updated PR #13613.

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

:memo: alexcrichton submitted PR review.

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

:speech_balloon: alexcrichton created PR review comment:

Ah ok yeah that makes sense, yeah. Taking a leaf out of Rust's book what I'd imagine is that a solution for this would be a bool on an ABI as to whether it could unwind or not, and that way try_call-ing a nounwind ABI by definition can become a call instead (or something like that). That's definitely out of scope for this PR though

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:03):

:thumbs_up: alexcrichton submitted PR review:

er, meant for that to be this

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:24):

alexcrichton commented on PR #13613:

Ok I tried to write up some more parts of a test case here, and what I've found is:

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:41):

cfallin requested fitzgen for a review on PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:41):

cfallin requested wasmtime-compiler-reviewers for a review on PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:41):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:42):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:43):

cfallin commented on PR #13613:

Updated, thanks! For resource.drop, uncovered from new test, since that's a call emitted from the component compiler directly, that also needs a separate try_call_indirect.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:43):

cfallin has enabled auto merge for PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 22:44):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 23:00):

cfallin added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 23:24):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 23:31):

cfallin added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 11 2026 at 23:55):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 00:09):

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

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 03:20):

alexcrichton added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 03:44):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 03:54):

alexcrichton added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 04:27):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 04:36):

alexcrichton added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 05:00):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 05:02):

alexcrichton commented on PR #13613:

Hm ok given how consistently this is failing on s390x this may not actually be spurious (e.g. #10000). Mind double-checking locally @cfallin and seeing if you can reproduce the fault?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 15:40):

cfallin commented on PR #13613:

Yep, I can sometimes (nondeterministically) reproduce locally -- digging in.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:03):

cfallin updated PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:04):

cfallin commented on PR #13613:

@alexcrichton fixed as I missed the non-signals-based-trap case for the resource.drop trap, which was a bit I added late above. Mind taking another look before merging?

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:06):

cfallin commented on PR #13613:

(PR CI failing is crates.io being inaccessible from GitHub, as usual on a day ending in -day)

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:13):

:thumbs_up: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:13):

alexcrichton has enabled auto merge for PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 16:23):

alexcrichton added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 17:11):

github-merge-queue[bot] removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 18:27):

alexcrichton added PR #13613 Component model: catch exceptions at component barriers and turn into traps. to the merge queue

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 19:15):

:check: alexcrichton merged PR #13613.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2026 at 19:15):

alexcrichton removed PR #13613 Component model: catch exceptions at component barriers and turn into traps. from the merge queue


Last updated: Jul 29 2026 at 05:03 UTC