Stream: wasm-tools

Topic: Naming convention for canon abi in core wasm


view this post on Zulip Zihang Ye (Sep 10 2025 at 07:57):

When handling wit-bindgen, I'm aware that import / export follow some specific naming convention. I did see some explanations for common interfaces, but I wonder where's the naming convention for the canon abi, such as resource.new? As far as what I've seen from the tests of spec repository, they could be defined as import "" "R1.resource.new", but the validation of wasm-tools require them to be named with prefix [resource-new]xxx, and, I presume, the module need to be [export]xxx.

If I understand correctly, the naming of the original import / export could be arbitrary as long as there's the (canon resource.new $R1' (core func $R1.resource.new)) exists to point out that the function in core wasm is calling the canon abi. Which means that the restriction on the naming convention is imposed by wasm-tools to figure out which abi it refers to. If that's the case, I wonder if there's some documentation on how they are defined? Or could that be determined in some embedded metadata?

Repository for design and specification of the Component Model - WebAssembly/component-model
CLI and Rust libraries for low-level manipulation of WebAssembly modules - bytecodealliance/wasm-tools

view this post on Zulip Zihang Ye (Sep 10 2025 at 09:30):

Reading through the comments, I wonder why the future-read and future-write needs to be indexed?

view this post on Zulip Christof Petig (Sep 10 2025 at 12:07):

I believe this https://github.com/WebAssembly/component-model/pull/378 could answer some of your questions (I had the same question sind time ago)

This PR adds BuildTargets.md to define this new concept of "build targets" as presented in both CG-06 and WASI-06-12, which itself was a revision of the earlier "wasit2" idea th...

view this post on Zulip Alex Crichton (Sep 10 2025 at 14:36):

At a high level you're correct the names don't actually matter here. Once you have a component the names are purely informational and the runtime just follows the links. The problem that wasm-tools is solving is that LLVM today doesn't emit a component, it emits a core module. The process of going from a core module to a component requires some form of convention for naming these imports so tooling can know what connects to what. The naming chosen by wasm-tools today is not standard and nor will it ever be, it's just a loose toolchain convention. The PR @Christof Petig linked to is intended to be the standard way to import things and a defined target for compilers to use (as opposed to whatever wasm-tools does)

view this post on Zulip Zihang Ye (Sep 11 2025 at 04:48):

I see, thank you for pointing the PR. I assume that it will be the new naming convention soon?

But the PR doesn't cover async yet. @Alex Crichton Would you mind explaining why the future-read/writeand drop-readable/writable need to be indexed per function as "[{kind}-drop-readable-{index}]{func_name}" or is there any PR that I can check on?

view this post on Zulip Alex Crichton (Sep 11 2025 at 14:34):

I forget if there's comments interspersed throughout the codebase but the original PR would require some digging now.

Basically the problem is that the future/stream read/write intrinsics take a type parameter for what kind of future/stream they're operating on. Somehow wit-component needs to synthesize that which means we have to go from a string module and a string field to a type somehow. The solution we settled on was an indexing approach where we enumerate all the futures/streams in a function type signature and then you say "this is the read/write for the Nth type in that list"

view this post on Zulip Alex Crichton (Sep 11 2025 at 14:34):

It's not a great solution IMO but it's sufficient for now. It's also one where we're definitely able to change it in the future as necessary

view this post on Zulip Zihang Ye (Sep 12 2025 at 01:56):

I see, thank you for your explanation. @BigOrangeQWQ is trying to add wasip3 support in wit-bindgen for MoonBit, and we started following the existing wit-bindgen for C impl. So we are curious to see why something like drop-readable which is supposed to be the same for a same type has different imports in different function / field.

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:39):

ah yeah that's true, you only need to pick 1 and any one will suffice

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:40):

and it's also true that the current scheme means you can import stream<u8> things through any API that has stream<u8> in its signature

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:40):

Rust I believe ends up just picking the first

view this post on Zulip Alex Crichton (Sep 12 2025 at 14:40):

regardless bindgen is indeed a bit awkward

view this post on Zulip Zihang Ye (Sep 15 2025 at 02:02):

I see. So I think it might be more proper to have the naming as <package> [{kind}-drop-readable]{type}?

view this post on Zulip Alex Crichton (Sep 15 2025 at 14:02):

In theory yeah, but the hard part about that is parsing {type}. I'd personally prefer to avoid trying to specify WIT type parsing in another place

view this post on Zulip Zihang Ye (Sep 16 2025 at 02:14):

Sorry but I didn't quite follow. I was thinking about how the resource types were handled. For example, the resource.drop for output-stream was : (import "wasi:io/streams@0.2.3" "[resource-drop]output-stream" (func xxx))

So in anaglous to it, I thought the future would be (import "my:test/i" "[future-drop-readable][async][future]u32 or (import "$root" "[future-drop-readable][async]u32 since u32 is primitive.
Did you mean the hard part was to figure out the whose future type it is, for example it could be a complicated type such as future<(u32, u32)>?

view this post on Zulip Alex Crichton (Sep 16 2025 at 13:15):

Right yeah, resource is a "flat" type with no recursion so naming is pretty easy, but the type parameter on futures makes this much more difficult

view this post on Zulip Zihang Ye (Sep 17 2025 at 02:03):

I see, thank you.

view this post on Zulip Zihang Ye (Sep 29 2025 at 08:29):

Just one question, what will happen if there's a type such as future<stream<u8>>, how will we be able to refer to stream<u8> with index? or is that out of consideration at the moment?

view this post on Zulip Alex Crichton (Sep 29 2025 at 14:20):

IIRC if future<stream<u8>> is index N then stream<u8> is index N+1

view this post on Zulip Alex Crichton (Sep 29 2025 at 14:20):

the ordering implementation is here

CLI and Rust libraries for low-level manipulation of WebAssembly modules - bytecodealliance/wasm-tools

view this post on Zulip Zihang Ye (Sep 30 2025 at 08:37):

Thank you very much


Last updated: Dec 06 2025 at 06:05 UTC