Stream: git-wasmtime

Topic: wasmtime / issue #14346 Link host-side interface with can...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 00:25):

chenyan2002 opened issue #14346:

When -W component-model-canonical-names feature is enabled, the guest side component encodes interface names with canonical names, while the host-side bindgen is still using the full version. This causes the linking to fail.

NameMap currently supports matching a:b/c@0.2.1 with its alternate key a:b/c@0.2. But if the component is importing a:b/c@0.2, we cannot match it back with a:b/c@0.2.1. We need to refactor NameMap/alternate_lookup_key to be able to handle both canonical version and full version during the transition period.

Another fix is to add an option in the host side wit-bindgen to emit canonical names. But when the component is importing a full version, NameMap needs to know how to match it with the canonical name.

Raised from https://github.com/bytecodealliance/wasmtime/pull/14344#discussion_r4019873593

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 14:07):

alexcrichton added the wasm-proposal:component-model label to Issue #14346.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 14:19):

alexcrichton commented on issue #14346:

I haven't sat down to think through a full solution just yet, but the main property I think that should be upheld is that turning on and/or rolling out canonical names should not break any preexisting behaviors. For example turning on the CLI feature shouldn't cause any existing workflows to break. Additionally if this were a bindgen! feature then turning that on in wasmtime-wasi shouldn't cause any existing workflows to break. I think it's fine if the way this is configured opts-in to more behaviors or perhaps disallows some pretty edge-case-y behaviors but for big things like "instantiating a preexisting component using WASI not using canonical-names" should not break.

I'd probably personally lean towards not changing insertion into a linker and leave bindgen! dealing with full versions. Internally the NameMap would satisfy requests for 0.2 with 0.2.1 then, for example. I haven't fully thought this through, however.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 23 2026 at 05:13):

chenyan2002 commented on issue #14346:

Thinking a bit more, I think it makes more sense to keep the host side to use the full version. But there is a tricky corner case. Currently, host can import both a:b/c@0.2.0 and a:b/c@0.2.1, and have different host implementations. If we emit canonical version, this two interfaces somehow need to merge. I'm not sure if we want to merge them?

Asking the same question from the guest side, if guest imports a:b/c@0.2, does it get 0.2.0 or 0.2.1? Following alternate_lookups, we always get the highest version 0.2.1. But if the guest side has versionsuffix ".0", should we get 0.2.0 instead? Ideally, we should never look at versionsuffix in the lookup. Then that means 0.2.0 will never be linked, and thus need to be merged into 0.2.1?

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

alexcrichton commented on issue #14346:

If we keep the current behavior of NameMap which allows multiple versions to be defined, then we should probably mostly keep the same behavior it has today. Importing @0.2 would get the maximum version and @0.2 ... suffix .0 would import 0.2.0 if defined or otherwise the maximum.

Personally though that behavior of NameMap was mostly done out of necessity, and I'd be open to consider removing it to only allow one-implementation-per-semver-track

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

chenyan2002 commented on issue #14346:

For consistency, I think it's cleaner to merge the semver track on the host side, just like we do on the guest side. This will be a breaking change though. Do we want to gate it under a flag?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 23 2026 at 17:14):

alexcrichton commented on issue #14346:

I'm not personally aware of anyone actively leveraging the ability to define multiple versions, so in that sense I think it'd be ok to have a breaking change. Things like this that are so core often tend to pull people out of the woodwork, though, so this'll probably cause difficult-to-resolve breakage somewhere. That being said this is the direction we generally want to go in, so I think it's ok to do that.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 24 2026 at 01:06):

chenyan2002 commented on issue #14346:

The "one-implementation-per-semver-track" approach is likely to trigger many behavior changes. There are too many corner cases during the transition period: mixed use of canonical and non-canonical name in a component, some interfaces are semver merged, some are not...I think I would try to preserve the current NameMap semantics, storing everything using the full version, and rely on the alternate_lookup_key for canonical name matching.

For host APIs that define names (linker.instance("a:b/c@0.2.1")), currently it's using just string equality. Do we want to extend it to alternate_lookup_key if an alternative key exist? Do we want to support canonical version like instance("a:b/c@0.2")?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 24 2026 at 14:24):

alexcrichton commented on issue #14346:

That's ok with me yeah, but I'll also point out that in some sense this is kicking the can down the road because this transition period mostly isn't going to go away any time soon. Eventually Wasmtime will likely want to consider a behavioral change here and handle any fallout from that, but if you'd perfer to not take that on right now that's also ok.

You say that host APIs are just using string equality, but can you clarify what for? Insertion into NameMap happens at the full version, but querying uses the alternate key as well to see if something is present. The NameMap and Wasmtime are pretty agnostic to the strings that are inserted so I don't think there's anything preventing you from inserting @0.2 today and I don't think it's worth trying to specifically allow or disallow it. In general it's mostly geared towards getting idiomatic usage working

view this post on Zulip Wasmtime GitHub notifications bot (Sep 24 2026 at 16:47):

chenyan2002 commented on issue #14346:

I mean into_instance is using map.raw_get_mut for lookup, instead of map.get. So if you have a:b/c@0.1.1 in the map, into_instance("a:b/c@0.1.0") would create a new entry, instead of locating to 0.1.1. It's more about the semantics of instance name, is it purely a string, or it's semver aware.

Similarly, for Linker::define_unknown_imports_as_traps, it calls linker.instance. So if there is a a:b/c@0.1.1 on the host side, and the guest imports a:b/c@0.1.0, it will trap for this imports, instead of calling 0.1.1.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 24 2026 at 20:50):

alexcrichton commented on issue #14346:

Ah ok makes sense, although arguably both of those situations are bugs. a:b/c@0.1.1 satisfies a guest import for a:b/c@0.1.0 so define_unknown_Improts_as_traps arguably shouldn't do anything. For into_instance(...) that it's necessarily a bug that it yields a unique instance right now but I don't think it'd be overly problematic yielding the same instance


Last updated: Oct 11 2026 at 02:20 UTC