Stream: wasi

Topic: list of functions a Wasm engine should implement


view this post on Zulip a (Jul 21 2026 at 14:36):

Hi,

I'm writing a Wasm engine and I'd like to implement WASI 0.2. I want to focus on core Wasm and I don't want to deal with WIT, Component model or anything similar. I couldn't find a list of the core Wasm functions I'd need to implement in my engine. How am I supposed to do it?

view this post on Zulip Alex Crichton (Jul 21 2026 at 14:46):

It's worth pointing out that WASI 0.2 is fundamentally defined in terms of WIT, the Component Model, and similar things. You probably won't get too far implementing this while ignoring all of those details because they're fundamental to at least understand. For example the list of core wasm functions you're supposed to implement isn't actually written down anywhere strictly speaking because the list of functions are defined in WIT. You'll need to understand how component model and core functions layer to understand what your engine needs to implement.

There is, at this time, no standard naming scheme by which core modules are expected to import/export to satisfy WIT interfaces. One is being proposed in this PR but that's not finalized yet. That's the closest equivalent for "core wasm provides this and components can hook up into it".

Overall, though, if your attitude is "get all the component stuff away from me" then WASI 0.2 probably isn't for you.

view this post on Zulip a (Jul 21 2026 at 14:48):

I know, but I'm not writing a compiler to Wasm, I'm writing a runtime for core Wasm whose goal is to analyze programs. All of the WIT things is lowered by the C/C++/Rust/TinyGo/Haskell/Zig compiler way before reaching my interpreter.

view this post on Zulip a (Jul 21 2026 at 14:49):

Said otherwise, if I want to write an interpreter that can run Wasm modules produced by the Rust compiler + WASI 2.0, how am I supposed to find the list of functions this program might import and should be implemented in my interpreter ?

view this post on Zulip Chris Fallin (Jul 21 2026 at 14:55):

Alex's answer is still the answer to your question. The short answer to "how do I get the list of functions" is "take the WITs and map them through the canonical ABI". But it's not quite that simple because the canonical ABI involves some back-and-forth handshakes (e.g. allocator calls) and some host state (e.g. resource tables). You really do need to work at that level to implement the thing; WASI 0.2 is built on the component-model platform.

view this post on Zulip a (Jul 21 2026 at 15:03):

But how come such a list is not available somewhere? IIUC, there's only one such possible list, because of the canonical ABI being... well, the canonical one. Right? I want to implement this incrementally, I really would like to avoid having to reimplement WIT in my language, and then, understand all of https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md before being able to run anything...

view this post on Zulip a (Jul 21 2026 at 15:06):

the canonical ABI involves some back-and-forth handshakes (e.g. allocator calls) and some host state (e.g. resource tables)

But couldn't all of this be lowered to core Wasm? With some contract, or pre/post-conditions on the imported host functions that the runtime should respect?

view this post on Zulip Pat Hickey (Jul 21 2026 at 15:07):

Yes, the canonical ABI is the description of how you lower a component model call into core wasm.

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:07):

The list is available: in the WIT. For the same reason that e.g. C libraries do not specify their interfaces in terms of machine registers on x86-64, but instead in terms of C signatures, the WASI APIs are defined in terms of WIT, and there are well-understood lowerings to lower abstraction layers.

view this post on Zulip Pat Hickey (Jul 21 2026 at 15:08):

The reason there's not a single description is that the canonical ABI has various options for how you lower it, to make it flexible for different users and guest languages. So there is no single "ABI". The component model docs go into the way canonical abi options and etc work in great detail, you should go and read them

view this post on Zulip a (Jul 21 2026 at 15:08):

The list is available: in the WIT. For the same reason that e.g. C libraries do not specify their interfaces in terms of machine registers on x86-64, but instead in terms of C signatures, the WASI APIs are defined in terms of WIT, and there are well-understood lowerings to lower abstraction layers.

Yes but, x86-64 processors do not have to know the C interface to be implemented...

view this post on Zulip a (Jul 21 2026 at 15:09):

Pat Hickey said:

The reason there's not a single description is that the canonical ABI has various options for how you lower it, to make it flexible for different users and guest languages. So there is no single "ABI". The component model docs go into the way canonical abi options and etc work in great detail, you should go and read them

OK, that's what I was afraid of.

view this post on Zulip Pat Hickey (Jul 21 2026 at 15:10):

I'm afraid of different things, like systems where there are no docs and nobody is trying to help you

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:11):

@a that's taking the analogy too far: a processor vendor isn't implementing the operating system (which is what WASI is). You can very well implement the core Wasm opcode execution without understanding WIT, but the OS interface is specified in terms of it.

You've asked, we've answered -- there are a lot of docs on this and you need to read them. Best of luck.

view this post on Zulip a (Jul 21 2026 at 15:11):

So, IIUC, depending on the source language, even when using the same WASI interface, we might end-up with imported host functions with different signatures in the core Wasm module ?

view this post on Zulip Pat Hickey (Jul 21 2026 at 15:12):

its not dependent on the source language, its dependent on the canonical abi options. the options exist so that different languages and use cases can be accomodated.

view this post on Zulip a (Jul 21 2026 at 15:13):

Yes but if each source language use different options for the Canonical ABI, the problem is the same, right?

view this post on Zulip Pat Hickey (Jul 21 2026 at 15:13):

when a component describes its import and export functions, those imports and exports contain lift and lower descriptions that contain the canonical abi options

view this post on Zulip a (Jul 21 2026 at 15:15):

You can very well implement the core Wasm opcode execution without understanding WIT

Yes, that's what I'd like to achieve. But, is it really possible? Or does the imported Wasm functions might change depending on the options used to lower it?

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:16):

@a you're missing the distinction I made: you can implement core Wasm opcode execution, but you cannot implement WASI 0.2(+) without understanding WIT.

view this post on Zulip a (Jul 21 2026 at 15:19):

I think the issue is rather : you can't implement WASI without implementing WIT, rather than understanding WIT.

view this post on Zulip a (Jul 21 2026 at 15:19):

I think it's a shame.

view this post on Zulip a (Jul 21 2026 at 15:19):

Is there some document somewhere where these design decisions are explained?

view this post on Zulip Alex Crichton (Jul 21 2026 at 15:21):

Well, yes, but it's in the documentation that you don't want to read: https://github.com/webassembly/component-model

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:21):

Well, the path of interface description languages (IDLs) to offer a higher abstraction level for defining APIs is well-trodden. It shouldn't be too surprising that we have this in the Wasm world too.

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:22):

There's nothing weird or out-there about "we don't want to define high-level APIs in terms of low-level details"

view this post on Zulip a (Jul 21 2026 at 15:25):

@Alex Crichton can you point me to the part of the doc explaining why things are done this way? And why it wasn't a goal to make sure WASI can be implemented by an engine without requiring for this engine to support WIT and everything.

view this post on Zulip a (Jul 21 2026 at 15:26):

Chris Fallin said:

Well, the path of interface description languages (IDLs) to offer a higher abstraction level for defining APIs is well-trodden. It shouldn't be too surprising that we have this in the Wasm world too.

Sure, I'm not saying the opposite. What is surprising me is that, until now, one was able to work with Wasm and ignore the high-level details of where the module was coming from. And it seems it's not the case anymore, which seems like a big conceptual shift. I've been working on core Wasm for years, and was really not expecting this from WASI.

view this post on Zulip a (Jul 21 2026 at 15:27):

I understand why having such API is important for high level languages, compilers and linkers.

view this post on Zulip a (Jul 21 2026 at 15:27):

But I fail to see why a runtime should care.

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:44):

It is, again, not the case that the engine becomes source-language-specific. Rather the ABI has variants (options) and the engine needs to support them. As Pat said this creates flexibility and allows for better performance. You're right that it's different than the wasip1 "this is the C-level API and everyone uses it" world. But there are reasons for it. Please read the documentation if you want to understand; it is not reasonable on your part to expect us to convince you when you have not read the documentation.

view this post on Zulip a (Jul 21 2026 at 15:50):

Rather the ABI has variants (options) and the engine needs to support them.

Yes I get that, but what I don't get is how it is materialized in the final Wasm binary. Let's say there are two distinct options O1 and O2. When I compile using O1 and my source program uses a function f which is a WASI function, I get an imported function f1 in the Wasm binary, with signature t1. What will I get when I compile using O2? Will the function have distinct names? Will they have the same name but with different types? If not, how am I supposed to guess which convention I'm supposed to follow regarding invariants that need to be preserved by the runtime? Really, I'm geniunely trying to understand how I should support WASI 2.0 in my engine, knowing that I need to run Wasm programs coming from many toolchain. It's really not clear to me how I can find out what I'm supposed to implement and how to do it incrementally (implementing imported functions one by one).

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:51):

There is no guessing. There is a spec. Please read the documentation.

view this post on Zulip Chris Fallin (Jul 21 2026 at 15:52):

If you have specific questions after reading the docs, of course you can ask here. But we're asking you to do your homework first. Anything else is disrespectful of others' time.

view this post on Zulip Till Schneidereit (Jul 21 2026 at 15:53):

here's a slightly higher-level intro to the canonical ABI, including some reasoning for the setup: https://component-model.bytecodealliance.org/advanced/canonical-abi.html

view this post on Zulip a (Jul 21 2026 at 16:13):

There is nothing in this doc that explains clearly what is in a component with the actual syntax. There's only:

$ wasm-tools print add.component.wasm | head -1
(component

But then, no more component is shown. Then, in the "Running components" section, it's basically said that, Wasmtime and jco are directly executing component. And not core Wasm modules. So basically, IIUC, to write a runtime, you have to do the lowering from components (i.e. write a component interpreter) yourself and it's not possible to separately lower a component to a core Wams module in a standardized way that can be later executed ?

In this page : https://github.com/WebAssembly/component-model there is: For a more formal definition of a component, take a look at the Component Model specification.

When I go to this page, I finally find something about it here : https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#canonical-definitions

Based on this description of the AST, the Canonical ABI explainer gives a detailed walkthrough of the static and dynamic semantics of lift and lower.

And then, I finally get here, https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md ; which tell me: there's no real spec but here's a Python sketch of what you should do...

So, my understanding is that WASI 2.0 is actually not a system interface for Wasm, but another language built on top of Wasm, and to use it, one has to write a Component Model interpreter and not a Wasm interpreter.

view this post on Zulip Pat Hickey (Jul 21 2026 at 16:29):

no, your assumptions continue to be incorrect, but your response doesnt convince me you are engaging with the docs or this conversation in good faith. if you have an emotional need to just complain about how stuff must all wrong because it didn't match your initial assumptions, thats not what this forum is here to support


Last updated: Jul 29 2026 at 05:03 UTC