Stream: general

Topic: ✔ https://github.com/bytecodealliance/wasmtime/issues/7716


view this post on Zulip Zeeshan Lakhani (Jan 05 2024 at 21:39):

@Pat Hickey, others. I'm also running into this issue when compiling my wasm wit-bindgen (version 0.16) code with wasi (it works fine with wasm32-unknown-known). I'm using the reactor version of wasi_snapshot_preview1.wasm from wasmtime 16 when running --adapt. Our runtime, which embeds wasmtime, has

wasmparser = "0.118"
wasmtime = { version = "16.0", default-features = false, features = [
  "async",
  "component-model",
  "cranelift",
  "parallel-compilation",
  "pooling-allocator",
  "wat",
] }
wasmtime-component-util = "16.0"
wasmtime-wasi = { version = "16.0", default-features = false, features = [
  "tokio",
] }
wat = "1.0"
wit-component = "0.19"

It fails on instantiation:

let instance = linker.instantiate_async(&mut store, &component).await?;

I even removed any WASI bits from the component code, but just focused on targetting wasm32-wasi.

view this post on Zulip Zeeshan Lakhani (Jan 05 2024 at 21:41):

Should I attempt to go backwards in time with different versions?

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:47):

@Zeeshan Lakhani can you share a bit more of the embedding code? e.g. what calls to add_to_linker do you have?

view this post on Zulip Zeeshan Lakhani (Jan 05 2024 at 21:51):

@Alex Crichton, thanks for reaching out. so we instantiate this way (i'll share the component_bytes_fn, as it's all oss):

    /// Instantiates the provided `module` using the specified
    /// parameters, wrapping up the result in a [Env] structure
    /// that translates between wasm and the host, and gives access
    /// for future invocations to use the already-initialized linker, store.
    ///
    /// Used when first initiating a module of a workflow.
    pub async fn instantiate(
        bytes: Vec<u8>,
        fun_name: &str,
        data: State,
    ) -> Result<Env<State>, Error> {
        let config = Self::configure();
        let engine = Engine::new(&config)?;
        let linker = Self::define_linker(&engine);

        let mut store = Store::new(&engine, data);
        store.limiter_async(|s| &mut s.limits);
        store.set_fuel(store.data().fuel)?;

        // Configures a `Store` to yield execution of async WebAssembly code
        // periodically and not cause extended polling.
        store.fuel_async_yield_interval(Some(UNIT_OF_COMPUTE_INSTRUCTIONS))?;

        // engine clones are shallow (not deep).
        let component = component_from_bytes(&bytes, engine.clone())?;

        let instance = linker.instantiate_async(&mut store, &component).await?;

        let bindings = Self::new(&mut store, &instance, fun_name)?;
        let mut env = Env::new(engine, linker, store);
        env.set_bindings(bindings);
        env.set_instance(instance);

        Ok(env)
    }

I haven't pushed this code upstream yet (which is outdated versions), but component_from_bytes remains the same, but with the newest versions in my local code: https://github.com/ipvm-wg/homestar/blob/main/homestar-wasm/src/wasmtime/world.rs#L326

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:52):

It looks like nothing is being added to Linker in that file?

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:52):

You'll need to specify in the embedding what to add to Linker which adds host functions like WASI functions

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:53):

that comes from the wasmtime-wasi crate, e.g. wasmtime_wasi::preview2::command::add_to_linker

view this post on Zulip Zeeshan Lakhani (Jan 05 2024 at 21:57):

ah gotcha. is there a way to know if the component was wasi compiled or not?

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:58):

yes you can look at the imports of the component to see if it includes wasi

view this post on Zulip Alex Crichton (Jan 05 2024 at 21:58):

e.g. wasm-tools print and you can take a look at that

view this post on Zulip Zeeshan Lakhani (Jan 05 2024 at 22:04):

@Alex Crichton perfect. thank you. derp for missing that!, will update the thread once I update these.

view this post on Zulip Zeeshan Lakhani (Jan 06 2024 at 02:28):

@Alex Crichton (or others). Zeeshan being dumb alert :). So, I was trying to use an import of print on the example and using it: print("blah").

I've defaulted the wasictx in state to:

        let wasi_ctx = wasmtime_wasi::preview2::WasiCtxBuilder::new()
            .inherit_stdio()
            .build();

So, I must be missing something to make this work in the embedded context? Error is

called `Result::unwrap()` on an `Err` value: WasmRuntime(import `print` has the wrong type

Caused by:
    expected func found nothing

print compiled to wasi target is

...
impl Guest for Component {
    fn crop_base64(data: String, x: u32, y: u32, target_width: u32, target_height: u32) -> Vec<u8> {
        print("running crop_base64");
        let base64_encoded_png = data.replace("data:image/png;base64,", "");
        let decoded = general_purpose::STANDARD
            .decode(base64_encoded_png)
            .unwrap();
        Self::crop(decoded, x, y, target_width, target_height)
    }

Everything compiles and works without the print.

view this post on Zulip Zeeshan Lakhani (Jan 07 2024 at 08:31):

@Alex Crichton I'm all good btw! Just need to go through the tests and docs in detail around how to impl Host for the State context. Thanks again.

view this post on Zulip Notification Bot (Jan 07 2024 at 08:32):

Zeeshan Lakhani has marked this topic as resolved.


Last updated: Nov 22 2024 at 16:03 UTC