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 --releaseRun the following command from the calculator folder:
cargo component build --releaseFrom the workspace root folder run:
cargo run --bin runnerSteps to Reproduce
To reproduce the bug, uncomment the commented-out code and run:
cargo run --bin runnerExpected Results
5 + 3 = 8 10 + 20 = 30Actual 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 instanceVersions 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::calland to fix this you'll need to callFunc::post_returnafter 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 theaddfunction and that solved the problem.Do you know if it is possible to call the
addfunction 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
wacto 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 --releaseRun the following command from the calculator folder:
cargo component build --releaseFrom the workspace root folder run:
cargo run --bin runnerSteps to Reproduce
To reproduce the bug, uncomment the commented-out code and run:
cargo run --bin runnerExpected Results
5 + 3 = 8 10 + 20 = 30Actual 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 instanceVersions 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 13 2025 at 19:03 UTC