Stream: wasmtime

Topic: Having trouble composing worlds


view this post on Zulip mainrs (Jun 05 2024 at 16:50):

Hello!
I want to define a custom world that I use as a service interface between different WASM apps. But I also want to give those apps access to WASI. I thought this should be enough to make it work:

world imports {
    // Our custom WIT world.
    import game;

    // Some of the base WASI worlds for file access and more. Makes it possible to rely on `stdlib` in
    // various languages.
    include wasi:filesystem@0.2.0;
    include wasi:io@0.2.0;
}

(where game is an interface). But when using wasmtime to generate the binding code for the host, I get an error saying that / was expected instead of @. I assume my syntax for the include statement is wrong. But I could not find any code that showcases how to import existing worlds.

This is the code I use in Rust to create the wasmtime bindgen:

wasmtime::component::bindgen!({
    path: "./wit/world.wit",
    world: "world",
});

Thank yoU!

view this post on Zulip mainrs (Jun 05 2024 at 17:02):

Ah, sorry! The error I got was

error: failed to resolve directory while parsing WIT for path [/home/me/code/plugin-host/wit]

       Caused by:
           package not found
                --> /home/me/code/plugin-host/wit/world.wit:9:13
                 |
               9 |     include wasi:filesystem/filesystem@0.2.0;
                 |                        ^--------------

I fixed the other one above earlier. Do I have to clone the WASI Wit files and put them next to my world?

view this post on Zulip Alex Crichton (Jun 05 2024 at 17:07):

Yeah for now you'll need to copy the *.wit files for WASI into your project

view this post on Zulip Alex Crichton (Jun 05 2024 at 17:07):

(it's something we hope to improve in the future though)

view this post on Zulip mainrs (Jun 05 2024 at 19:54):

At the end, my world looks like this:

package ugl:plugin;

world ugl {
    // Our custom WIT world.
    import game;

    include wasi:filesystem/imports@0.2.0;
    include wasi:io/imports@0.2.0;

Do I need to exclude the WASI worlds from bindgen? It looks like a bunch of types are generated for these worlds. At the end, I plan to use the existing wasmtime_wasi library that already implement the host part.

view this post on Zulip Alex Crichton (Jun 05 2024 at 19:57):

You can use the with keyword to point the wasi bits over to the wasmtime_wasi crate, but you can also omit it entirely with a separate world passed to wasmtime's bindgen

view this post on Zulip mainrs (Jun 05 2024 at 20:20):

I really appreciate your help! Getting started with WASI and the component model is quite hard for me tbh.
I added the with statement:

wasmtime::component::bindgen!({
    world: "ugl",
    with: {
        "wasi:filesystem": wasmtime_wasi::bindings::filesystem,
        "wasi:io": wasmtime_wasi::bindings::io,
    },
});

And it seems to work. I only get add_to_linker function references are missing. It sounds like the codegen relies on the function being imported inside the scope. But every module exports their own add_to_linker_get_host function. So I am not sure how I can satisfy this condition for the io and filesystem. It looks to me like they both expect that their respective add_to_linker functions are in scope.

 cargo check
    Checking ugl-plugin-api v0.1.0 (/home/me/code/plugin-host)
error[E0425]: cannot find function `add_to_linker` in module `__with_name1::error`
 --> src/lib.rs:1:1
  |
1 | / wasmtime::component::bindgen!({
2 | |     world: "ugl",
3 | |     with: {
4 | |         "wasi:filesystem": wasmtime_wasi::bindings::filesystem,
5 | |         "wasi:io": wasmtime_wasi::bindings::io,
6 | |     },
7 | | });
  | |__^ not found in `__with_name1::error`
  |
  = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
  |
1 + use crate::ugl::plugin::game::add_to_linker;
  |
1 + use crate::wasi::clocks::wall_clock::add_to_linker;
  |
1 + use wasmtime_wasi::preview0::wasi_unstable::add_to_linker;
  |
1 + use wasmtime_wasi::preview1::wasi_snapshot_preview1::add_to_linker;
  |

error[E0425]: cannot find function `add_to_linker` in module `__with_name1::poll`
 --> src/lib.rs:1:1
  |
1 | / wasmtime::component::bindgen!({
2 | |     world: "ugl",
3 | |     with: {
4 | |         "wasi:filesystem": wasmtime_wasi::bindings::filesystem,
5 | |         "wasi:io": wasmtime_wasi::bindings::io,
6 | |     },
7 | | });
  | |__^ not found in `__with_name1::poll`
  |
  = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
  |
1 + use crate::ugl::plugin::game::add_to_linker;
  |
1 + use crate::wasi::clocks::wall_clock::add_to_linker;
  |
1 + use wasmtime_wasi::preview0::wasi_unstable::add_to_linker;
  |
1 + use wasmtime_wasi::preview1::wasi_snapshot_preview1::add_to_linker;

but you can also omit it entirely with a separate world passed to wasmtime's bindgen

I do not understand this part.

view this post on Zulip Alex Crichton (Jun 05 2024 at 20:22):

Ah yes that compile error is fixed in Wasmtime 22, that was a bug in Wasmtime 21

view this post on Zulip Alex Crichton (Jun 05 2024 at 20:23):

For separating the world that would involve having a second world in WIT which doesn't have WASI, and that's what you use for bindgen. You'd then have a "real" world which would import wasi and include this world

view this post on Zulip mainrs (Jun 06 2024 at 14:04):

Alex Crichton said:

Ah yes that compile error is fixed in Wasmtime 22, that was a bug in Wasmtime 21

My wasmtime dependency is using the git repository's main branch directly. Using that I got the above error.

wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", features = ["component-model"] }
wasmtime-wasi ="21.0.1" #  {git = "https://github.com/bytecodealliance/wasmtime" }

Using the git repository wasmtime-wasi dependency complains about non-matching types for the T in Linker<T>.

view this post on Zulip Lann Martin (Jun 06 2024 at 14:06):

You probably need to pin all wasmtime* deps to the same revision, e.g.

wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "23409ca7e184ef3b7d42fe17938caed470643d5d" }
wasmtime-wasi = { git = "https://github.com/bytecodealliance/wasmtime", rev = "23409ca7e184ef3b7d42fe17938caed470643d5d" }

Last updated: Dec 23 2024 at 13:07 UTC