Stream: git-wasmtime

Topic: wasmtime / issue #8985 Error when calling a function defi...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 14:26):

cryarchy added the bug label to Issue #8985.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 14:26):

cryarchy opened issue #8985:

I have provided an example to reproduce the bug.

To run the example:

Steps to Reproduce

To reproduce the bug, uncomment the commented-out code and run:

cargo run --bin runner

Expected Results

5 + 3 = 8
10 + 20 = 30

Actual Results

5 + 3 = 8
Error: error while executing at wasm backtrace:
    0: 0x12b2 - calculator.wasm!component:calculator/calculate#eval-expression

Caused by:
    wasm trap: cannot enter component instance

Versions and Environment

rustc version: rustc 1.79.0 (129f3b996 2024-06-10)
wasmtime = {version = "22.0", features = ["runtime", "component-model"]}
wasmtime-wasi = "22.0.0"
operating system: Linux Mint 21.3 Cinnamon
linux kernel version: 6.5.0-44-generic
x86_64 bits: 64

Extra Info

The runner code causing the error:

use anyhow::Context;
use std::path::PathBuf;
use wasmtime::component::{Component, Linker, ResourceTable, Val};
use wasmtime::{Config, Engine, Store};
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};

pub async fn add(add_path: PathBuf, calc_path: PathBuf, x: i32, y: i32) -> wasmtime::Result<i32> {
    let mut config = Config::default();
    config.wasm_component_model(true);
    config.async_support(true);
    let engine = Engine::new(&config)?;

    let wasi = WasiCtxBuilder::new().inherit_stdio().build();
    let mut linker = Linker::<ServerWasiView>::new(&engine);

    wasmtime_wasi::add_to_linker_async(&mut linker)?;

    let wasi_view = ServerWasiView::new(wasi);
    let mut store = Store::new(&engine, wasi_view);

    let add_component =
        Component::from_file(&engine, add_path).context("Add component file not found")?;
    let calc_component =
        Component::from_file(&engine, calc_path).context("Calculator component file not found")?;

    let add_instance = linker.instantiate_async(&mut store, &add_component).await?;

    let add = add_instance
        .exports(&mut store)
        .instance("docs:adder/add")
        .expect("instance 'docs:adder/add' not found")
        .func("add")
        .expect("add function not found");

    let mut results = [Val::S32(0)];

    add.call_async(&mut store, &[Val::S32(5), Val::S32(3)], &mut results)
        .await?;

    let Val::S32(result) = results[0] else {
        panic!("Unexpected result type");
    };

    println!("5 + 3 = {}", result);

    linker.instance("docs:adder/add")?.func_wrap_async(
        "add",
        move |store, params: (i32, i32)| {
            Box::new(async move {
                let mut results = [Val::S32(0)];
                add.call_async(
                    store,
                    &[Val::S32(params.0), Val::S32(params.1)],
                    &mut results,
                )
                .await?;

                if let Val::S32(result) = results[0] {
                    Ok((result,))
                } else {
                    Err(anyhow::anyhow!("Unexpected result type"))
                }
            })
        },
    )?;

    let calc_instance = linker
        .instantiate_async(&mut store, &calc_component)
        .await?;
    let calc_fn = calc_instance
        .exports(&mut store)
        .instance("component:calculator/calculate")
        .expect("instance 'component:calculator/calculate' not found")
        .func("eval-expression")
        .expect("eval-expression function not found");
    let mut result = [Val::S32(0)];
    calc_fn
        .call_async(
            &mut store,
            &[Val::String(format!("{} + {}", x, y))],
            &mut result,
        )
        .await?;
    let Val::S32(result) = result[0] else {
        panic!("Unexpected result type");
    };
    Ok(result)
}

struct ServerWasiView {
    table: ResourceTable,
    ctx: WasiCtx,
}

impl ServerWasiView {
    fn new(ctx: WasiCtx) -> Self {
        let table = ResourceTable::new();
        Self { table, ctx }
    }
}

impl WasiView for ServerWasiView {
    fn table(&mut self) -> &mut ResourceTable {
        &mut self.table
    }

    fn ctx(&mut self) -> &mut WasiCtx {
        &mut self.ctx
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let add_path = PathBuf::from("target/wasm32-wasip1/release/add.wasm");
    let calc_path = PathBuf::from("target/wasm32-wasip1/release/calculator.wasm");
    let lhs = 10;
    let rhs = 20;
    let sum = add(add_path, calc_path, lhs, rhs).await?;
    println!("{} + {} = {sum}", lhs, rhs);
    Ok(())
}

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 17:31):

alexcrichton commented on issue #8985:

You'll want to take a look at the documentation of Func::call and to fix this you'll need to call Func::post_return after you call_async (or post_return_async)

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 19:03):

cryarchy commented on issue #8985:

Thank you, @alexcrichton.

I added the code add.post_return_async(&mut store).await?; after the invocation of the add function and that solved the problem.

Do you know if it is possible to call the add function from the calculator wasm component without wrapping it in a host function? What is required to do so?

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 19:08):

alexcrichton commented on issue #8985:

You can use a tool such as wac to compose the component together and hook things up, although that's a bit advanced I believe at this time. Otherwise purely with the Wasmtime API at this time there's no way to do this without the wrapper host function.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 19:10):

cryarchy closed issue #8985:

I have provided an example to reproduce the bug.

To run the example:

Steps to Reproduce

To reproduce the bug, uncomment the commented-out code and run:

cargo run --bin runner

Expected Results

5 + 3 = 8
10 + 20 = 30

Actual Results

5 + 3 = 8
Error: error while executing at wasm backtrace:
    0: 0x12b2 - calculator.wasm!component:calculator/calculate#eval-expression

Caused by:
    wasm trap: cannot enter component instance

Versions and Environment

rustc version: rustc 1.79.0 (129f3b996 2024-06-10)
wasmtime = {version = "22.0", features = ["runtime", "component-model"]}
wasmtime-wasi = "22.0.0"
operating system: Linux Mint 21.3 Cinnamon
linux kernel version: 6.5.0-44-generic
x86_64 bits: 64

Extra Info

The runner code causing the error:

use anyhow::Context;
use std::path::PathBuf;
use wasmtime::component::{Component, Linker, ResourceTable, Val};
use wasmtime::{Config, Engine, Store};
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};

pub async fn add(add_path: PathBuf, calc_path: PathBuf, x: i32, y: i32) -> wasmtime::Result<i32> {
    let mut config = Config::default();
    config.wasm_component_model(true);
    config.async_support(true);
    let engine = Engine::new(&config)?;

    let wasi = WasiCtxBuilder::new().inherit_stdio().build();
    let mut linker = Linker::<ServerWasiView>::new(&engine);

    wasmtime_wasi::add_to_linker_async(&mut linker)?;

    let wasi_view = ServerWasiView::new(wasi);
    let mut store = Store::new(&engine, wasi_view);

    let add_component =
        Component::from_file(&engine, add_path).context("Add component file not found")?;
    let calc_component =
        Component::from_file(&engine, calc_path).context("Calculator component file not found")?;

    let add_instance = linker.instantiate_async(&mut store, &add_component).await?;

    let add = add_instance
        .exports(&mut store)
        .instance("docs:adder/add")
        .expect("instance 'docs:adder/add' not found")
        .func("add")
        .expect("add function not found");

    let mut results = [Val::S32(0)];

    add.call_async(&mut store, &[Val::S32(5), Val::S32(3)], &mut results)
        .await?;

    let Val::S32(result) = results[0] else {
        panic!("Unexpected result type");
    };

    println!("5 + 3 = {}", result);

    linker.instance("docs:adder/add")?.func_wrap_async(
        "add",
        move |store, params: (i32, i32)| {
            Box::new(async move {
                let mut results = [Val::S32(0)];
                add.call_async(
                    store,
                    &[Val::S32(params.0), Val::S32(params.1)],
                    &mut results,
                )
                .await?;

                if let Val::S32(result) = results[0] {
                    Ok((result,))
                } else {
                    Err(anyhow::anyhow!("Unexpected result type"))
                }
            })
        },
    )?;

    let calc_instance = linker
        .instantiate_async(&mut store, &calc_component)
        .await?;
    let calc_fn = calc_instance
        .exports(&mut store)
        .instance("component:calculator/calculate")
        .expect("instance 'component:calculator/calculate' not found")
        .func("eval-expression")
        .expect("eval-expression function not found");
    let mut result = [Val::S32(0)];
    calc_fn
        .call_async(
            &mut store,
            &[Val::String(format!("{} + {}", x, y))],
            &mut result,
        )
        .await?;
    let Val::S32(result) = result[0] else {
        panic!("Unexpected result type");
    };
    Ok(result)
}

struct ServerWasiView {
    table: ResourceTable,
    ctx: WasiCtx,
}

impl ServerWasiView {
    fn new(ctx: WasiCtx) -> Self {
        let table = ResourceTable::new();
        Self { table, ctx }
    }
}

impl WasiView for ServerWasiView {
    fn table(&mut self) -> &mut ResourceTable {
        &mut self.table
    }

    fn ctx(&mut self) -> &mut WasiCtx {
        &mut self.ctx
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let add_path = PathBuf::from("target/wasm32-wasip1/release/add.wasm");
    let calc_path = PathBuf::from("target/wasm32-wasip1/release/calculator.wasm");
    let lhs = 10;
    let rhs = 20;
    let sum = add(add_path, calc_path, lhs, rhs).await?;
    println!("{} + {} = {sum}", lhs, rhs);
    Ok(())
}

view this post on Zulip Wasmtime GitHub notifications bot (Jul 22 2024 at 19:10):

cryarchy commented on issue #8985:

Thank you, @alexcrichton.


Last updated: Nov 22 2024 at 17:03 UTC