diff --git a/Cargo.lock b/Cargo.lock index d57cf1d0e371..9c30147723d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4756,6 +4756,7 @@ dependencies = [ name = "wasmtime-fuzz" version = "0.0.0" dependencies = [ + "anyhow", "arbitrary", "cranelift-assembler-x64", "cranelift-codegen", diff --git a/Cargo.toml b/Cargo.toml index 956c8fcd67e3..810e92beadf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,7 @@ rustix = { workspace = true, features = ["mm", "process"] } [dev-dependencies] # depend again on wasmtime to activate its default features for tests -wasmtime = { workspace = true, features = ['default', 'winch', 'pulley', 'all-arch', 'call-hook', 'memory-protection-keys', 'component-model-async'] } +wasmtime = { workspace = true, features = ['default', 'anyhow', 'winch', 'pulley', 'all-arch', 'call-hook', 'memory-protection-keys', 'component-model-async'] } env_logger = { workspace = true } log = { workspace = true } filecheck = { workspace = true } diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index 378096f1a6d3..ee3bc5c96308 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -55,6 +55,7 @@ name = "factc" required-features = ['component-model', 'compile'] [features] +anyhow = [] component-model = [ "dep:wasmtime-component-util", "dep:semver", diff --git a/crates/environ/examples/factc.rs b/crates/environ/examples/factc.rs index 2d682e8f743a..41724e9a095e 100644 --- a/crates/environ/examples/factc.rs +++ b/crates/environ/examples/factc.rs @@ -3,9 +3,9 @@ use std::io::{IsTerminal, Write}; use std::path::{Path, PathBuf}; use wasmparser::{Validator, WasmFeatures}; use wasmtime_environ::{ - ScopeVec, Tunables, + ScopeVec, ToWasmtimeResult as _, Tunables, component::*, - error::{Context, Result, bail}, + error::{Context as _, Result, bail}, }; /// A small helper utility to explore generated adapter modules from Wasmtime's @@ -79,6 +79,7 @@ impl Factc { for wasm in adapters.into_iter() { let output = if self.text { wasmprinter::print_bytes(&wasm) + .to_wasmtime_result() .context("failed to convert binary wasm to text")? .into_bytes() } else if self.output.is_none() && std::io::stdout().is_terminal() { diff --git a/crates/environ/src/lib.rs b/crates/environ/src/lib.rs index 8c4c9b254c7a..0306bdd1f76e 100644 --- a/crates/environ/src/lib.rs +++ b/crates/environ/src/lib.rs @@ -84,5 +84,20 @@ pub use cranelift_entity::*; // migration to the `wasmtime-internal-error` crate. pub use anyhow as error; +// Temporarily polyfill `wasmtime_internal_error::ToWasmtimeResult` to ease +// migration, before we swap out `anyhow` with the `wasmtime_internal_error` +// crate. +#[cfg(feature = "anyhow")] +#[doc(hidden)] +pub trait ToWasmtimeResult { + fn to_wasmtime_result(self) -> self::error::Result; +} +#[cfg(feature = "anyhow")] +impl ToWasmtimeResult for anyhow::Result { + fn to_wasmtime_result(self) -> self::error::Result { + self + } +} + /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/explorer/Cargo.toml b/crates/explorer/Cargo.toml index b4fbf6842d51..d199bf767941 100644 --- a/crates/explorer/Cargo.toml +++ b/crates/explorer/Cargo.toml @@ -19,5 +19,5 @@ serde_derive = { workspace = true } serde_json = { workspace = true } target-lexicon = { workspace = true, features = ['std'] } wasmprinter = { workspace = true } -wasmtime = { workspace = true, features = ["cranelift", "runtime"] } -wasmtime-environ = { workspace = true } +wasmtime = { workspace = true, features = ["anyhow", "cranelift", "runtime"] } +wasmtime-environ = { workspace = true, features = ["anyhow"] } diff --git a/crates/explorer/src/lib.rs b/crates/explorer/src/lib.rs index 91eb0602e2c0..7cf03c49b5cf 100644 --- a/crates/explorer/src/lib.rs +++ b/crates/explorer/src/lib.rs @@ -13,7 +13,7 @@ use std::{ path::Path, str::FromStr, }; -use wasmtime::Result; +use wasmtime::{Result, ToWasmtimeResult as _}; use wasmtime_environ::demangle_function_name; pub fn generate( @@ -109,7 +109,8 @@ fn annotate_wat(wasm: &[u8]) -> Result { let printer = wasmprinter::Config::new(); let mut storage = String::new(); let chunks = printer - .offsets_and_lines(wasm, &mut storage)? + .offsets_and_lines(wasm, &mut storage) + .to_wasmtime_result()? .map(|(offset, wat)| AnnotatedWatChunk { wasm_offset: offset.map(|o| WasmOffset(u32::try_from(o).unwrap())), wat: wat.to_string(), diff --git a/crates/misc/component-async-tests/Cargo.toml b/crates/misc/component-async-tests/Cargo.toml index b70d5691af60..f24013a71f69 100644 --- a/crates/misc/component-async-tests/Cargo.toml +++ b/crates/misc/component-async-tests/Cargo.toml @@ -24,6 +24,7 @@ tokio = { workspace = true, features = [ wasmparser = { workspace = true } wasmtime = { workspace = true, features = [ "default", + "anyhow", "pulley", "cranelift", "component-model-async", diff --git a/crates/misc/component-async-tests/tests/scenario/util.rs b/crates/misc/component-async-tests/tests/scenario/util.rs index f5bf8498cab0..69b69873e811 100644 --- a/crates/misc/component-async-tests/tests/scenario/util.rs +++ b/crates/misc/component-async-tests/tests/scenario/util.rs @@ -11,7 +11,7 @@ use tokio::fs; use tokio::sync::Mutex; use wasm_compose::composer::ComponentComposer; use wasmtime::component::{Component, Linker, ResourceTable}; -use wasmtime::{Config, Engine, Result, Store, bail, format_err}; +use wasmtime::{Config, Engine, Result, Store, ToWasmtimeResult as _, bail, format_err}; use wasmtime_wasi::WasiCtxBuilder; pub fn init_logger() { @@ -63,6 +63,7 @@ async fn compose(a: &[u8], b: &[u8]) -> Result> { }, ) .compose() + .to_wasmtime_result() } pub async fn make_component(engine: &Engine, components: &[&str]) -> Result { diff --git a/crates/wasi-http/tests/all/p3/mod.rs b/crates/wasi-http/tests/all/p3/mod.rs index b1d8273f180a..52b58799d306 100644 --- a/crates/wasi-http/tests/all/p3/mod.rs +++ b/crates/wasi-http/tests/all/p3/mod.rs @@ -14,7 +14,7 @@ use tokio::{fs, try_join}; use wasm_compose::composer::ComponentComposer; use wasm_compose::config::{Config, Dependency, Instantiation, InstantiationArg}; use wasmtime::component::{Component, Linker, ResourceTable}; -use wasmtime::{Result, Store, error::Context as _, format_err}; +use wasmtime::{Result, Store, ToWasmtimeResult as _, error::Context as _, format_err}; use wasmtime_wasi::p3::bindings::Command; use wasmtime_wasi::{TrappableError, WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView}; use wasmtime_wasi_http::p3::bindings::Proxy; @@ -368,6 +368,7 @@ async fn compose(a: &[u8], b: &[u8]) -> Result> { }, ) .compose() + .to_wasmtime_result() } #[test_log::test(tokio::test(flavor = "multi_thread"))] @@ -422,7 +423,8 @@ async fn test_http_middleware_with_chain(host_to_host: bool) -> Result<()> { .collect(), }, ) - .compose()?; + .compose() + .to_wasmtime_result()?; fs::write(&path, &bytes).await?; test_http_echo(&path.to_str().unwrap(), true, host_to_host).await diff --git a/crates/wasmtime/Cargo.toml b/crates/wasmtime/Cargo.toml index 7657e1c57a64..5109650679e5 100644 --- a/crates/wasmtime/Cargo.toml +++ b/crates/wasmtime/Cargo.toml @@ -156,6 +156,9 @@ default = [ 'compile-time-builtins', ] +# Enables conversion helpers between `anyhow::Error` and `wasmtime::Error`. +anyhow = ["wasmtime-environ/anyhow"] + # An on-by-default feature enabling runtime compilation of WebAssembly modules # with the Cranelift compiler. Cranelift is the default compilation backend of # Wasmtime. If disabled then WebAssembly modules can only be created from @@ -397,7 +400,7 @@ custom-sync-primitives = [] # Off-by-default support to profile the Pulley interpreter. This has a # performance hit, even when not profiling, so it's disabled by default at # compile time. -profile-pulley = ['pulley', 'profiling', 'pulley-interpreter/profile'] +profile-pulley = ['anyhow', 'pulley', 'profiling', 'pulley-interpreter/profile'] # Enables support for the Component Model Async ABI, along with `future`, # `stream`, and `error-context` types. @@ -423,4 +426,4 @@ debug = [ ] # Enables support for defining compile-time builtins. -compile-time-builtins = ['dep:wasm-compose', 'dep:tempfile'] +compile-time-builtins = ['anyhow', 'dep:wasm-compose', 'dep:tempfile'] diff --git a/crates/wasmtime/src/compile/code_builder/compile_time_builtins.rs b/crates/wasmtime/src/compile/code_builder/compile_time_builtins.rs index 5b3ae655384f..c06ccd715108 100644 --- a/crates/wasmtime/src/compile/code_builder/compile_time_builtins.rs +++ b/crates/wasmtime/src/compile/code_builder/compile_time_builtins.rs @@ -1,4 +1,5 @@ use super::*; +use crate::ToWasmtimeResult as _; impl<'a> CodeBuilder<'a> { pub(crate) fn get_compile_time_builtins(&self) -> &HashMap, Cow<'a, [u8]>> { @@ -47,7 +48,7 @@ impl<'a> CodeBuilder<'a> { } let composer = wasm_compose::composer::ComponentComposer::new(&main_wasm_path, &config); - let composed = composer.compose()?; + let composed = composer.compose().to_wasmtime_result()?; Ok(composed.into()) } diff --git a/crates/wasmtime/src/lib.rs b/crates/wasmtime/src/lib.rs index 1f6d0b206cc1..a6761be4c500 100644 --- a/crates/wasmtime/src/lib.rs +++ b/crates/wasmtime/src/lib.rs @@ -411,6 +411,9 @@ use sync_nostd as sync; #[doc(inline)] pub use wasmtime_environ::error; +#[cfg(feature = "anyhow")] +pub use wasmtime_environ::ToWasmtimeResult; + pub use self::error::{Error, Result, bail, ensure, format_err}; /// A re-exported instance of Wasmtime's `wasmparser` dependency. diff --git a/crates/wasmtime/src/profiling_agent/pulley.rs b/crates/wasmtime/src/profiling_agent/pulley.rs index 726875a045a0..ef374aeea411 100644 --- a/crates/wasmtime/src/profiling_agent/pulley.rs +++ b/crates/wasmtime/src/profiling_agent/pulley.rs @@ -32,6 +32,7 @@ //! example code in the `pulley-interpreter` crate or `pulley/examples/*.rs` in //! the Wasmtime repository. +use crate::ToWasmtimeResult as _; use crate::prelude::*; use crate::profiling_agent::ProfilingAgent; use crate::vm::Interpreter; @@ -97,7 +98,7 @@ pub fn new() -> Result> { let filename = format!("./pulley-{pid}.data"); let mut agent = PulleyAgent { state: Arc::new(State { - recorder: Mutex::new(Recorder::new(&filename)?), + recorder: Mutex::new(Recorder::new(&filename).to_wasmtime_result()?), sampling: Default::default(), sampling_done: Condvar::new(), sampling_freq: std::env::var("PULLEY_SAMPLING_FREQ") diff --git a/crates/wast/Cargo.toml b/crates/wast/Cargo.toml index aa646bcab986..1060e911a4e7 100644 --- a/crates/wast/Cargo.toml +++ b/crates/wast/Cargo.toml @@ -14,7 +14,7 @@ rust-version.workspace = true workspace = true [dependencies] -wasmtime = { workspace = true, features = ['cranelift', 'wat', 'runtime', 'gc', 'async', 'threads'] } +wasmtime = { workspace = true, features = ['anyhow', 'cranelift', 'wat', 'runtime', 'gc', 'async', 'threads'] } wast = { workspace = true, features = ['dwarf'] } log = { workspace = true } tokio = { workspace = true, features = ['rt'] } diff --git a/crates/wast/src/wast.rs b/crates/wast/src/wast.rs index b656294e239f..46cc1114c6fc 100644 --- a/crates/wast/src/wast.rs +++ b/crates/wast/src/wast.rs @@ -561,7 +561,8 @@ impl WastContext { let mut ast = json_from_wast::Opts::default() .dwarf(self.generate_dwarf) - .convert(filename, wast, ast)?; + .convert(filename, wast, ast) + .to_wasmtime_result()?; let modules_by_filename = Arc::get_mut(&mut self.modules_by_filename).unwrap(); for (name, bytes) in ast.wasms.drain(..) { let prev = modules_by_filename.insert(name, bytes); diff --git a/crates/wizer/Cargo.toml b/crates/wizer/Cargo.toml index 1caee3dd6d8b..d2ff75495303 100644 --- a/crates/wizer/Cargo.toml +++ b/crates/wizer/Cargo.toml @@ -38,14 +38,14 @@ criterion = { workspace = true } env_logger = { workspace = true } wasmprinter = { workspace = true } wat = { workspace = true } -wasmtime = { workspace = true, features = ['default'] } +wasmtime = { workspace = true, features = ['default', 'anyhow'] } wasmtime-wasi = { workspace = true, features = ["p1"] } tokio = { workspace = true, features = ['macros'] } [features] # Enable this dependency to get messages with WAT disassemblies when certain # internal panics occur. -wasmprinter = ['dep:wasmprinter'] +wasmprinter = ['dep:wasmprinter', 'wasmtime/anyhow'] # Enables default runtime implementations based on the `wasmtime` crate. wasmtime = [ diff --git a/crates/wizer/src/component/wasmtime.rs b/crates/wizer/src/component/wasmtime.rs index 1f4590320ac9..2379a95c3706 100644 --- a/crates/wizer/src/component/wasmtime.rs +++ b/crates/wizer/src/component/wasmtime.rs @@ -5,6 +5,9 @@ use wasmtime::component::{ }; use wasmtime::{Result, Store, error::Context as _, format_err}; +#[cfg(feature = "wasmprinter")] +use wasmtime::ToWasmtimeResult as _; + impl Wizer { /// Same as [`Wizer::run`], except for components. pub async fn run_component( @@ -18,7 +21,7 @@ impl Wizer { #[cfg(feature = "wasmprinter")] log::debug!( "instrumented wasm: {}", - wasmprinter::print_bytes(&instrumented_wasm)?, + wasmprinter::print_bytes(&instrumented_wasm).to_wasmtime_result()?, ); let engine = store.engine(); diff --git a/crates/wizer/tests/all/component.rs b/crates/wizer/tests/all/component.rs index 3785b1fb4039..e66573956692 100644 --- a/crates/wizer/tests/all/component.rs +++ b/crates/wizer/tests/all/component.rs @@ -1,5 +1,5 @@ use wasmtime::component::{Component, Instance, Linker, Val}; -use wasmtime::{Config, Engine, Result, Store, bail, error::Context as _}; +use wasmtime::{Config, Engine, Result, Store, ToWasmtimeResult as _, bail, error::Context as _}; use wasmtime_wizer::Wizer; fn fail_wizening(msg: &str, wasm: &[u8]) -> Result<()> { @@ -8,7 +8,7 @@ fn fail_wizening(msg: &str, wasm: &[u8]) -> Result<()> { let wasm = wat::parse_bytes(wasm)?; log::debug!( "testing wizening failure for wasm:\n{}", - wasmprinter::print_bytes(&wasm)? + wasmprinter::print_bytes(&wasm).to_wasmtime_result()? ); match Wizer::new().instrument_component(&wasm) { Ok(_) => bail!("expected wizening to fail"), diff --git a/crates/wizer/tests/all/tests.rs b/crates/wizer/tests/all/tests.rs index c3e22b6d5d46..ff8f351f4e0a 100644 --- a/crates/wizer/tests/all/tests.rs +++ b/crates/wizer/tests/all/tests.rs @@ -1,6 +1,9 @@ use std::process::Command; use wasm_encoder::ConstExpr; -use wasmtime::{Config, Engine, Instance, Linker, Module, Result, Store, error::Context as _}; +use wasmtime::{ + Config, Engine, Instance, Linker, Module, Result, Store, ToWasmtimeResult as _, + error::Context as _, +}; use wasmtime_wasi::{WasiCtxBuilder, p1}; use wasmtime_wizer::Wizer; use wat::parse_str as wat_to_wasm; @@ -575,7 +578,7 @@ async fn rename_functions() -> Result<()> { wizer.func_rename("func_a", "func_b"); wizer.func_rename("func_b", "func_c"); let wasm = wizer.run(&mut store()?, &wasm, instantiate).await?; - let wat = wasmprinter::print_bytes(&wasm)?; + let wat = wasmprinter::print_bytes(&wasm).to_wasmtime_result()?; let expected_wat = r#" (module diff --git a/examples/component/main.rs b/examples/component/main.rs index 6ffa44da1d41..037e1edc51ee 100644 --- a/examples/component/main.rs +++ b/examples/component/main.rs @@ -1,6 +1,6 @@ use std::{fs, path::Path}; use wasmtime::{ - Config, Engine, Result, Store, + Config, Engine, Result, Store, ToWasmtimeResult as _, component::{Component, HasSelf, Linker, bindgen}, error::Context as _, }; @@ -29,8 +29,10 @@ impl host::Host for MyState { fn convert_to_component(path: impl AsRef) -> Result> { let bytes = &fs::read(&path).context("failed to read input file")?; wit_component::ComponentEncoder::default() - .module(&bytes)? + .module(&bytes) + .to_wasmtime_result()? .encode() + .to_wasmtime_result() } fn main() -> Result<()> { diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index ebda99ec41aa..6b9f213b5211 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -34,6 +34,10 @@ wasmtime-fuzzing = { workspace = true } wasmtime-test-util = { workspace = true } log = { workspace = true } +# Only for use by the Cranlift fuzz targets. Wasmtime fuzz targets should +# use `wasmtime::{Error, Result}`. +anyhow = { workspace = true } + [build-dependencies] proc-macro2 = { workspace = true } arbitrary = { workspace = true, features = ["derive"] } diff --git a/fuzz/fuzz_targets/cranelift-fuzzgen.rs b/fuzz/fuzz_targets/cranelift-fuzzgen.rs index 161de17bb208..8542f280f8f0 100644 --- a/fuzz/fuzz_targets/cranelift-fuzzgen.rs +++ b/fuzz/fuzz_targets/cranelift-fuzzgen.rs @@ -183,7 +183,7 @@ impl<'a> Arbitrary<'a> for TestCase { } impl TestCase { - pub fn generate(u: &mut Unstructured) -> wasmtime::Result { + pub fn generate(u: &mut Unstructured) -> anyhow::Result { let mut generator = FuzzGen::new(u); let compare_against_host = generator.u.arbitrary()?; diff --git a/fuzz/fuzz_targets/cranelift-icache.rs b/fuzz/fuzz_targets/cranelift-icache.rs index 693665fc9c56..dfb88d037b9b 100644 --- a/fuzz/fuzz_targets/cranelift-icache.rs +++ b/fuzz/fuzz_targets/cranelift-icache.rs @@ -43,7 +43,7 @@ pub struct FunctionWithIsa { } impl FunctionWithIsa { - pub fn generate(u: &mut Unstructured) -> wasmtime::Result { + pub fn generate(u: &mut Unstructured) -> anyhow::Result { let _ = env_logger::try_init(); // We filter out targets that aren't supported in the current build @@ -77,7 +77,7 @@ impl FunctionWithIsa { let sig = generator.generate_signature(&*isa)?; Ok((name, sig)) }) - .collect::>>() + .collect::>>() .map_err(|_| arbitrary::Error::IncorrectFormat)?; let func = generator diff --git a/tests/wasi.rs b/tests/wasi.rs index fffe64b37a79..1b69ab3e0568 100644 --- a/tests/wasi.rs +++ b/tests/wasi.rs @@ -11,7 +11,7 @@ use std::fs; use std::path::Path; use std::process::Output; use tempfile::TempDir; -use wasmtime::{Result, format_err}; +use wasmtime::{Result, ToWasmtimeResult as _, format_err}; use wit_component::ComponentEncoder; const KNOWN_FAILURES: &[&str] = &[ @@ -161,13 +161,16 @@ fn run_test(path: &Path, componentize: bool) -> Result<()> { let path = if componentize { let module = fs::read(path).expect("read wasm module"); let component = ComponentEncoder::default() - .module(module.as_slice())? + .module(module.as_slice()) + .to_wasmtime_result()? .validate(true) .adapter( "wasi_snapshot_preview1", &fs::read(test_programs_artifacts::ADAPTER_COMMAND)?, - )? - .encode()?; + ) + .to_wasmtime_result()? + .encode() + .to_wasmtime_result()?; let stem = path.file_stem().unwrap().to_str().unwrap(); let component_path = td.path().join(format!("{stem}.component.wasm")); fs::write(&component_path, component)?;