From d911f4b10fe908bc819a1420482952e44b039db3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 1 May 2024 23:49:36 -0700 Subject: [PATCH] Migrate the wasmtime-types crate to no_std (#8485) * Migrate the wasmtime-types crate to no_std This commit is where no_std for Wasmtime starts to get a bit interesting. Specifically the `wasmtime-types` crate is the first crate that depends on some nontrivial crates that also need to be migrated to `no_std`. This PR disables the default feature of `wasmparser` by default and additionally does the same for `serde`. This enables them to compile in `no_std` contexts by default and default features will be enabled elsewhere in this repository as necessary. This also opts to drop the `thiserror` dependency entirely in favor of a manual `Display` implementation with a cfg'd implementation of `Error`. As before CI checks are added for `wasmtime-types` with a `no_std` target itself to ensure the crate and all dependencies all avoid `std`. * Fix adapter build --- .github/workflows/main.yml | 3 ++ Cargo.lock | 1 - Cargo.toml | 4 +-- crates/environ/Cargo.toml | 2 +- crates/types/Cargo.toml | 4 ++- crates/types/src/error.rs | 36 +++++++++++++++---- crates/types/src/lib.rs | 14 ++++++-- .../verify/Cargo.toml | 2 +- 8 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8280db0c5e..c9ecf71e96 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -375,6 +375,9 @@ jobs: - run: cargo check -p wasmtime-slab env: CARGO_BUILD_TARGET: x86_64-unknown-none + - run: cargo check -p wasmtime-types + env: + CARGO_BUILD_TARGET: x86_64-unknown-none # Check that wasmtime compiles with panic=abort since there's some `#[cfg]` # for specifically panic=abort there. diff --git a/Cargo.lock b/Cargo.lock index c6e7dafea8..ed49de52d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3803,7 +3803,6 @@ dependencies = [ "serde", "serde_derive", "smallvec", - "thiserror", "wasmparser 0.206.0", ] diff --git a/Cargo.toml b/Cargo.toml index 5b2be064e8..0b74728b56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -231,7 +231,7 @@ rustix = "0.38.31" wit-bindgen = { version = "0.22.0", default-features = false } # wasm-tools family: -wasmparser = "0.206.0" +wasmparser = { version = "0.206.0", default-features = false } wat = "1.206.0" wast = "206.0.0" wasmprinter = "0.206.0" @@ -270,7 +270,7 @@ proptest = "1.0.0" rand = { version = "0.8.3", features = ["small_rng"] } sptr = "0.3.2" # serde and serde_derive must have the same version -serde = "1.0.188" +serde = { version = "1.0.188", default-features = false, features = ['alloc'] } serde_derive = "1.0.188" serde_json = "1.0.80" glob = "0.3.0" diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index 7933a0399e..a9d714c37f 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -18,7 +18,7 @@ anyhow = { workspace = true, features = ['std'] } postcard = { workspace = true } cpp_demangle = { version = "0.4.3", optional = true } cranelift-entity = { workspace = true } -wasmtime-types = { workspace = true } +wasmtime-types = { workspace = true, features = ['std'] } wasmparser = { workspace = true } indexmap = { workspace = true, features = ["serde"] } thiserror = { workspace = true } diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 737a4588c2..411860d8e6 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -13,8 +13,10 @@ cranelift-entity = { workspace = true, features = ['enable-serde'] } serde = { workspace = true } serde_derive = { workspace = true } smallvec = { workspace = true, features = ["serde"] } -thiserror = { workspace = true } wasmparser = { workspace = true } [lints] workspace = true + +[features] +std = ['wasmparser/std'] diff --git a/crates/types/src/error.rs b/crates/types/src/error.rs index f88536fa5f..37e5043e0e 100644 --- a/crates/types/src/error.rs +++ b/crates/types/src/error.rs @@ -1,16 +1,16 @@ -use thiserror::Error; +use alloc::string::String; +use core::fmt; /// A WebAssembly translation error. /// /// When a WebAssembly function can't be translated, one of these error codes will be returned /// to describe the failure. -#[derive(Error, Debug)] +#[derive(Debug)] pub enum WasmError { /// The input WebAssembly code is invalid. /// /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly /// code. This should never happen for validated WebAssembly code. - #[error("Invalid input WebAssembly code at offset {offset}: {message}")] InvalidWebAssembly { /// A string describing the validation error. message: String, @@ -21,7 +21,6 @@ pub enum WasmError { /// A feature used by the WebAssembly code is not supported by the embedding environment. /// /// Embedding environments may have their own limitations and feature restrictions. - #[error("Unsupported feature: {0}")] Unsupported(String), /// An implementation limit was exceeded. @@ -30,11 +29,9 @@ pub enum WasmError { /// limits][limits] that cause compilation to fail when they are exceeded. /// /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits - #[error("Implementation limit exceeded")] ImplLimitExceeded, /// Any user-defined error. - #[error("User error: {0}")] User(String), } @@ -42,7 +39,7 @@ pub enum WasmError { /// on the arguments to this macro. #[macro_export] macro_rules! wasm_unsupported { - ($($arg:tt)*) => { $crate::WasmError::Unsupported(format!($($arg)*)) } + ($($arg:tt)*) => { $crate::WasmError::Unsupported($crate::__format!($($arg)*)) } } impl From for WasmError { @@ -57,3 +54,28 @@ impl From for WasmError { /// A convenient alias for a `Result` that uses `WasmError` as the error type. pub type WasmResult = Result; + +impl fmt::Display for WasmError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + WasmError::InvalidWebAssembly { message, offset } => { + write!( + f, + "Invalid input WebAssembly code at offset {offset}: {message}" + ) + } + WasmError::Unsupported(s) => { + write!(f, "Unsupported feature: {s}") + } + WasmError::ImplLimitExceeded => { + write!(f, "Implementation limit exceeded") + } + WasmError::User(s) => { + write!(f, "User error: {s}") + } + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for WasmError {} diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 32cf700405..045442ac24 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -1,12 +1,22 @@ //! Internal dependency of Wasmtime and Cranelift that defines types for //! WebAssembly. -use smallvec::SmallVec; +#![no_std] + +extern crate alloc; +#[cfg(feature = "std")] +extern crate std; + pub use wasmparser; +#[doc(hidden)] +pub use alloc::format as __format; + +use alloc::boxed::Box; +use core::{fmt, ops::Range}; use cranelift_entity::entity_impl; use serde_derive::{Deserialize, Serialize}; -use std::{fmt, ops::Range}; +use smallvec::SmallVec; mod error; pub use error::*; diff --git a/crates/wasi-preview1-component-adapter/verify/Cargo.toml b/crates/wasi-preview1-component-adapter/verify/Cargo.toml index 27234761ab..093ce06788 100644 --- a/crates/wasi-preview1-component-adapter/verify/Cargo.toml +++ b/crates/wasi-preview1-component-adapter/verify/Cargo.toml @@ -9,6 +9,6 @@ publish = false workspace = true [dependencies] -wasmparser = { workspace = true } +wasmparser = { workspace = true, features = ['std'] } wat = { workspace = true } anyhow = { workspace = true, features = ['std'] }