cryarchy added the bug label to Issue #8985.
cryarchy opened issue #8985:
I have provided an example to reproduce the bug.
To run the example:
Run the following command from the add folder:
cargo component build --release
Run the following command from the calculator folder:
cargo component build --release
From the workspace root folder run:
cargo run --bin runner
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: 64Extra 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(()) }
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 callFunc::post_return
after youcall_async
(orpost_return_async
)
cryarchy commented on issue #8985:
Thank you, @alexcrichton.
I added the code
add.post_return_async(&mut store).await?;
after the invocation of theadd
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?
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.
cryarchy closed issue #8985:
I have provided an example to reproduce the bug.
To run the example:
Run the following command from the add folder:
cargo component build --release
Run the following command from the calculator folder:
cargo component build --release
From the workspace root folder run:
cargo run --bin runner
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: 64Extra 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(()) }
cryarchy commented on issue #8985:
Thank you, @alexcrichton.
Last updated: Dec 23 2024 at 13:07 UTC