Stream: git-wasmtime

Topic: wasmtime / issue #6523 import `wasi:clocks/wall-clock` ha...


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

truls opened issue #6523:

Hi,

I'm trying to instantiate a component compiled using tinygo from wasmtime in rust

The components implements the following WIT interface

package producer:host

world producer-interface {

export hello-world: interface {

record hello-request {
    name: string
  }

record hello-reply {
   message: string
}

  say-hello: func(reqyest: hello-request) -> result<hello-reply, s32>
  init-component: func()
}

}

I generate the component using the commands

    go generate
    tinygo build -target=wasi -o main.wasm component.go
    wasm-tools component embed --world producer-interface ./wit main.wasm -o main.embed.wasm
    wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.wasm -o main.component.wasm
    wasm-tools validate main.component.wasm --features component-model

where the `wasi_snapshot_preview1.wasm build comes from https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasi_snapshot_preview1.command.wasm

I am instantiating the component using the following rust code

use wasmtime::component::{*, self};
use wasmtime::{Config, Engine, Store};

use crate::exports::hello_world::{HelloRequest};

bindgen!(in "../producer/component/wit");

struct MyState {}

fn main() -> wasmtime::Result<()> {
    let mut config = Config::new();
    config.wasm_component_model(true);
    let engine = Engine::new(&config)?;
    let component = Component::from_file(&engine, "../producer/component/main.component.wasm")?;

    let linker = Linker::new(&engine);

    let mut store = Store::new(
        &engine,
        MyState { /* ... */ },
    );
    let (bindings, _) = ProducerInterface::instantiate(&mut store, &component, &linker)?;

    let interf = bindings.hello_world();
    interf.call_init_component(&mut store)?;

    let arg = HelloRequest{name: &"foo"};
    let res = interf.call_say_hello(&mut store, arg)?;

    println!("{:?}", res);

    Ok(())
}

However, when running the above program I get the following message

$ target/debug/wrapper
Error: import `wasi:clocks/wall-clock` has the wrong type

Caused by:
    0: instance export `now` has the wrong type
    1: expected func found nothing

Can anyone give me some hints about what the problem is?

Package versions::
wit-bindgen: 0.7.0
wasmtime crate: 10,0,0
tinygo: 0.27.0
wasm-tools: 1.0.35

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 17:55):

pchickey commented on issue #6523:

I'm not sure where the type mismatch is. I believe, since my understanding is that tinygo is not using component model imports directly, that the wall-clock import is coming from the wasi_snapshot_preview1.component.wasm adapter, and not from any of your go source code.

In that case, I'd check whether the adapter from the wasmtime 10.0.0 release assets, or using a git dep on wasmtime (and wasmtime-wasi) crate matching the git commit where you downloaded the adapter, resolves the problem - both construction and our test suite should verify that the component adapter and host have matching interfaces at any given release (or commit in wasmtime main), but the interfaces are changing somewhat frequently so we can't expect any stability between different versions yet.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 17:56):

pchickey edited a comment on issue #6523:

I'm not sure where the type mismatch is. I believe, since my understanding is that tinygo is not using component model imports directly, that the wall-clock import is coming from the wasi_snapshot_preview1.component.wasm adapter, and not from any of your go source code.

In that case, I'd check whether the adapter from the wasmtime 10.0.0 release assets, or using a git dep on wasmtime (and wasmtime-wasi) crate matching the git commit where you downloaded the adapter, resolves the problem - both construction and our test suite should ensure that the component adapter and host have matching interfaces at any given release (or commit in wasmtime main), but the interfaces are changing somewhat frequently so we can't expect any stability between different versions yet.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 20:48):

truls commented on issue #6523:

Thank you for your reply. Yes the wall-clock import was coming for wasi_snapshot_preview1 and not my code. I tried changing my toolchain to use the versions that are supposed to be supported according to the component model compatibility matrix (https://bytecodealliance.org/articles/component-model-tooling-compatibility) but it didn't change anything.

I just got it working using the following code and the toolchain versions from my original issue.

use wasmtime::component::*;
use wasmtime::{Config, Engine, Store};
use wasmtime_wasi::preview2::{WasiCtx, WasiCtxBuilder, Table, WasiView};
use wasmtime_wasi::preview2;

use crate::exports::hello_world::HelloRequest;

bindgen!({
    path:"../producer/component/wit",
    async: true
});

struct MyState {
    table: Table,
    wasi: WasiCtx,
}

impl WasiView for MyState {
    fn table(&self) -> &Table {
        &self.table
    }
    fn table_mut(&mut self) -> &mut Table {
        &mut self.table
    }
    fn ctx(&self) -> &WasiCtx {
        &self.wasi
    }
    fn ctx_mut(&mut self) -> &mut WasiCtx {
        &mut self.wasi
    }
}

#[tokio::main]
async fn main() -> wasmtime::Result<()> {
    let mut config = Config::new();
    config.wasm_component_model(true);
    config.async_support(true);
    let engine = Engine::new(&config)?;
    let component = Component::from_file(&engine, "../producer/component/main-component.wasm")?;

    let mut linker = Linker::new(&engine);

    let mut table = Table::new();
    let wasi = WasiCtxBuilder::new().inherit_stdio().set_args(&[""]).build(&mut table)?;

    preview2::wasi::filesystem::filesystem::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::io::streams::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::environment::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::preopens::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::exit::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::stdin::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::stdout::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::cli_base::stderr::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::clocks::wall_clock::add_to_linker(&mut linker, |x| x)?;
    preview2::wasi::clocks::monotonic_clock::add_to_linker(&mut linker, |x| x)?;

    let mut store = Store::new(
        &engine,
        MyState {  table, wasi },
    );
    let (bindings, _) = ProducerInterface::instantiate_async(&mut store, &component, &linker).await?;

    let interf = bindings.hello_world();
    interf.call_test(&mut store).await?;
    interf.call_init_component(&mut store).await?;

    let arg = HelloRequest{name: &"foo"};
    let res = interf.call_say_hello(&mut store, arg).await?;

    println!("{:?}", res);

    Ok(())
}

If the preview2 WASI ABI implementation is supposed to be provided by the host without explicitly adding it to the linker, then I'm still doing something wrong.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 21:54):

pchickey commented on issue #6523:

Oh, I missed that, yes you are expected to explicitly add all of the wasi modules that you are using to the component Linker.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 21:54):

pchickey closed issue #6523:

Hi,

I'm trying to instantiate a component compiled using tinygo from wasmtime in rust

The components implements the following WIT interface

package producer:host

world producer-interface {

export hello-world: interface {

record hello-request {
    name: string
  }

record hello-reply {
   message: string
}

  say-hello: func(reqyest: hello-request) -> result<hello-reply, s32>
  init-component: func()
}

}

I generate the component using the commands

    go generate
    tinygo build -target=wasi -o main.wasm component.go
    wasm-tools component embed --world producer-interface ./wit main.wasm -o main.embed.wasm
    wasm-tools component new main.embed.wasm --adapt wasi_snapshot_preview1.wasm -o main.component.wasm
    wasm-tools validate main.component.wasm --features component-model

where the `wasi_snapshot_preview1.wasm build comes from https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasi_snapshot_preview1.command.wasm

I am instantiating the component using the following rust code

use wasmtime::component::{*, self};
use wasmtime::{Config, Engine, Store};

use crate::exports::hello_world::{HelloRequest};

bindgen!(in "../producer/component/wit");

struct MyState {}

fn main() -> wasmtime::Result<()> {
    let mut config = Config::new();
    config.wasm_component_model(true);
    let engine = Engine::new(&config)?;
    let component = Component::from_file(&engine, "../producer/component/main.component.wasm")?;

    let linker = Linker::new(&engine);

    let mut store = Store::new(
        &engine,
        MyState { /* ... */ },
    );
    let (bindings, _) = ProducerInterface::instantiate(&mut store, &component, &linker)?;

    let interf = bindings.hello_world();
    interf.call_init_component(&mut store)?;

    let arg = HelloRequest{name: &"foo"};
    let res = interf.call_say_hello(&mut store, arg)?;

    println!("{:?}", res);

    Ok(())
}

However, when running the above program I get the following message

$ target/debug/wrapper
Error: import `wasi:clocks/wall-clock` has the wrong type

Caused by:
    0: instance export `now` has the wrong type
    1: expected func found nothing

Can anyone give me some hints about what the problem is?

Package versions::
wit-bindgen: 0.7.0
wasmtime crate: 10,0,0
tinygo: 0.27.0
wasm-tools: 1.0.35

view this post on Zulip Wasmtime GitHub notifications bot (Jun 07 2023 at 21:56):

pchickey edited a comment on issue #6523:

Oh, I missed that, yes you are expected to explicitly add all of the wasi modules that you are using to the component Linker.

As a shortcut for listing them all, you can use wasmtime_wasi::preview2::wasi::command::add_to_linker, if the set in there is sufficient. (It provides all the ones you did, plus timezone, which has a bogus implementation so isnt very useful right now)


Last updated: Dec 23 2024 at 13:07 UTC