From e56daf6570e152b9f0a1ea442c0beda7fb7fc5e0 Mon Sep 17 00:00:00 2001 From: Marco Allegretti Date: Wed, 11 Mar 2026 15:03:16 +0100 Subject: [PATCH] feat(runtime): upgrade to WASI Preview 2 + Component Model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the wasmtime-runtime run_module implementation: - wasmtime::Module → wasmtime::component::Component - wasmtime::Linker → wasmtime::component::Linker - wasmtime_wasi::add_to_linker → wasmtime_wasi::add_to_linker_sync - _start typed func call → wasmtime_wasi::bindings::sync::Command::instantiate + call_run Config now sets wasm_component_model(true). State struct implements WasiView (ctx + table). app.wasm must be a WASI 0.2 component; core modules are no longer supported. --- crates/weft-runtime/src/main.rs | 61 ++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/crates/weft-runtime/src/main.rs b/crates/weft-runtime/src/main.rs index a2cd9ac..5cd9a92 100644 --- a/crates/weft-runtime/src/main.rs +++ b/crates/weft-runtime/src/main.rs @@ -55,32 +55,61 @@ fn run_module(_wasm_path: &std::path::Path) -> anyhow::Result<()> { #[cfg(feature = "wasmtime-runtime")] fn run_module(wasm_path: &std::path::Path) -> anyhow::Result<()> { - use anyhow::Context as _; - use wasmtime::{Config, Engine, Module, Store}; + use wasmtime::{ + Config, Engine, Store, + component::{Component, Linker}, + }; + use wasmtime_wasi::{ + ResourceTable, WasiCtx, WasiCtxBuilder, WasiView, add_to_linker_sync, + bindings::sync::Command, + }; - let engine = Engine::new(&Config::default()).context("create Wasmtime engine")?; - let module = Module::from_file(&engine, wasm_path).context("load Wasm module")?; + struct State { + ctx: WasiCtx, + table: ResourceTable, + } - let mut linker: wasmtime::Linker = wasmtime::Linker::new(&engine); - wasmtime_wasi::add_to_linker(&mut linker, |cx| cx).context("add WASI to linker")?; + impl WasiView for State { + fn ctx(&mut self) -> &mut WasiCtx { + &mut self.ctx + } + fn table(&mut self) -> &mut ResourceTable { + &mut self.table + } + } - let wasi = wasmtime_wasi::WasiCtxBuilder::new() + let mut config = Config::new(); + config.wasm_component_model(true); + let engine = Engine::new(&config).context("create engine")?; + + let component = Component::from_file(&engine, wasm_path) + .with_context(|| format!("load component {}", wasm_path.display()))?; + + let mut linker: Linker = Linker::new(&engine); + add_to_linker_sync(&mut linker).context("add WASI to linker")?; + + let ctx = WasiCtxBuilder::new() .inherit_stdout() .inherit_stderr() .build(); - let mut store = Store::new(&engine, wasi); + let mut store = Store::new( + &engine, + State { + ctx, + table: ResourceTable::new(), + }, + ); println!("READY"); - let instance = linker - .instantiate(&mut store, &module) - .context("instantiate module")?; - let start = instance - .get_typed_func::<(), ()>(&mut store, "_start") - .context("get _start export")?; - start.call(&mut store, ()).context("call _start")?; + let command = + Command::instantiate(&mut store, &component, &linker).context("instantiate component")?; - Ok(()) + command + .wasi_cli_run() + .call_run(&mut store) + .context("call run")? + .map_err(|()| anyhow::anyhow!("wasm component run exited with error")) } fn package_store_roots() -> Vec {