Skip to content

Commit 81a8916

Browse files
authored
Add support for #![no_std] to the wasmtime crate (bytecodealliance#8533)
* Always fall back to custom platform for Wasmtime This commit updates Wasmtime's platform support to no longer require an opt-in `RUSTFLAGS` `--cfg` flag to be specified. With `no_std` becoming officially supported this should provide a better onboarding experience where the fallback custom platform is used. This will cause linker errors if the symbols aren't implemented and searching/googling should lead back to our docs/repo (eventually, hopefully). * Change Wasmtime's TLS state to a single pointer This commit updates the management of TLS to rely on just a single pointer rather than a pair of a pointer and a `bool`. Additionally management of the TLS state is pushed into platform-specific modules to enable different means of managing it, namely the "custom" platform now has a C function required to implement TLS state for Wasmtime. * Delay conversion to `Instant` in atomic intrinsics The `Duration` type is available in `no_std` but the `Instant` type is not. The intention is to only support the `threads` proposal if `std` is active but to assist with this split push the `Duration` further into Wasmtime to avoid using a type that can't be mentioned in `no_std`. * Gate more parts of Wasmtime on the `profiling` feature Move `serde_json` to an optional dependency and gate the guest profiler entirely on the `profiling` feature. * Refactor conversion to `anyhow::Error` in `wasmtime-environ` Have a dedicated trait for consuming `self` in addition to a `Result`-friendly trait. * Gate `gimli` in Wasmtime on `addr2line` Cut down the dependency list if `addr2line` isn't enabled since then the dependency is not used. While here additionally lift the version requirement for `addr2line` up to the workspace level. * Update `bindgen!` to have `no_std`-compatible output Pull most types from Wasmtime's `__internal` module as the source of truth. * Use an `Option` for `gc_store` instead of `OnceCell` No need for synchronization here when mutability is already available in the necessary contexts. * Enable embedder-defined host feature detection * Add `#![no_std]` support to the `wasmtime` crate This commit enables compiling the `runtime`, `gc`, and `component-model` features of the `wasmtime` crate on targets that do not have `std`. This tags the crate as `#![no_std]` and then updates everything internally to import from `core` or `alloc` and adapt for the various idioms. This ended up requiring some relatively extensive changes, but nothing too too bad in the grand scheme of things. * Require `std` for the perfmap profiling agent prtest:full * Fix build on wasm * Fix windows build * Remove unused import * Fix Windows/Unix build without `std` feature * Fix some doc links * Remove unused import * Fix build of wasi-common in isolation * Fix no_std build on macos * Re-fix build * Fix standalone build of wasmtime-cli-flags * Resolve a merge conflict * Review comments * Remove unused import
1 parent fd50e79 commit 81a8916

File tree

147 files changed

+1765
-919
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+1765
-919
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ jobs:
323323
- run: cargo check -p wasmtime --no-default-features --features pooling-allocator
324324
- run: cargo check -p wasmtime --no-default-features --features cranelift
325325
- run: cargo check -p wasmtime --no-default-features --features component-model
326+
- run: cargo check -p wasmtime --no-default-features --features runtime,component-model
326327
- run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache
327328
- run: cargo check -p wasmtime --no-default-features --features winch
328329
- run: cargo check -p wasmtime --no-default-features --features wmemcheck
@@ -363,16 +364,7 @@ jobs:
363364
# Checks for no_std support, ensure that crates can build on a no_std
364365
# target
365366
- run: rustup target add x86_64-unknown-none
366-
- run: cargo check -p wasmtime-jit-icache-coherence
367-
env:
368-
CARGO_BUILD_TARGET: x86_64-unknown-none
369-
- run: cargo check -p wasmtime-asm-macros
370-
env:
371-
CARGO_BUILD_TARGET: x86_64-unknown-none
372-
- run: cargo check -p wasmtime-slab
373-
env:
374-
CARGO_BUILD_TARGET: x86_64-unknown-none
375-
- run: cargo check -p wasmtime-environ --features gc,component-model
367+
- run: cargo check -p wasmtime --no-default-features --features gc,component-model
376368
env:
377369
CARGO_BUILD_TARGET: x86_64-unknown-none
378370

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ path = "src/bin/wasmtime.rs"
2525
doc = false
2626

2727
[dependencies]
28-
wasmtime = { workspace = true }
28+
wasmtime = { workspace = true, features = ['std'] }
2929
wasmtime-cache = { workspace = true, optional = true }
3030
wasmtime-cli-flags = { workspace = true }
3131
wasmtime-cranelift = { workspace = true, optional = true }
@@ -246,14 +246,15 @@ wit-component = "0.206.0"
246246
cc = "1.0"
247247
object = { version = "0.33", default-features = false, features = ['read_core', 'elf'] }
248248
gimli = { version = "0.28.0", default-features = false, features = ['read'] }
249+
addr2line = { version = "0.21.0", default-features = false }
249250
anyhow = { version = "1.0.22", default-features = false }
250251
windows-sys = "0.52.0"
251252
env_logger = "0.10"
252253
log = { version = "0.4.8", default-features = false }
253254
clap = { version = "4.3.12", default-features = false, features = ["std", "derive"] }
254255
hashbrown = { version = "0.14", default-features = false }
255256
capstone = "0.12.0"
256-
once_cell = "1.12.0"
257+
once_cell = { version = "1.12.0", default-features = false }
257258
smallvec = { version = "1.6.1", features = ["union"] }
258259
tracing = "0.1.26"
259260
bitflags = "2.0"

crates/c-api/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ doctest = false
2222
env_logger = { workspace = true, optional = true }
2323
anyhow = { workspace = true }
2424
once_cell = { workspace = true }
25-
wasmtime = { workspace = true, features = ['cranelift', 'runtime', 'gc'] }
25+
wasmtime = { workspace = true, features = ['cranelift', 'runtime', 'gc', 'std'] }
2626
wasmtime-c-api-macros = { workspace = true }
2727
log = { workspace = true }
2828
tracing = { workspace = true }

crates/cli-flags/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ edition.workspace = true
1212
workspace = true
1313

1414
[dependencies]
15-
anyhow = { workspace = true }
15+
anyhow = { workspace = true, features = ['std'] }
1616
clap = { workspace = true }
1717
file-per-thread-logger = { workspace = true, optional = true }
1818
tracing-subscriber = { workspace = true, optional = true }

crates/component-macro/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ serde_json = { workspace = true }
3737

3838
[features]
3939
async = []
40+
std = ['wasmtime-wit-bindgen/std']

crates/component-macro/src/component.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ impl Expander for LowerExpander {
569569
&self,
570570
cx: &mut #internal::LowerContext<'_, T>,
571571
ty: #internal::InterfaceType,
572-
dst: &mut std::mem::MaybeUninit<Self::Lower>,
572+
dst: &mut core::mem::MaybeUninit<Self::Lower>,
573573
) -> #internal::anyhow::Result<()> {
574574
#extract_ty
575575
#lowers
@@ -677,7 +677,7 @@ impl Expander for LowerExpander {
677677
&self,
678678
cx: &mut #internal::LowerContext<'_, T>,
679679
ty: #internal::InterfaceType,
680-
dst: &mut std::mem::MaybeUninit<Self::Lower>,
680+
dst: &mut core::mem::MaybeUninit<Self::Lower>,
681681
) -> #internal::anyhow::Result<()> {
682682
#extract_ty
683683
match self {
@@ -1136,7 +1136,7 @@ pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
11361136
}
11371137

11381138
pub fn all() -> Self {
1139-
use std::ops::Not;
1139+
use core::ops::Not;
11401140
Self::default().not()
11411141
}
11421142

@@ -1149,63 +1149,63 @@ pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
11491149
}
11501150
}
11511151

1152-
impl std::cmp::PartialEq for #name {
1152+
impl core::cmp::PartialEq for #name {
11531153
fn eq(&self, rhs: &#name) -> bool {
11541154
#eq
11551155
}
11561156
}
11571157

1158-
impl std::cmp::Eq for #name { }
1158+
impl core::cmp::Eq for #name { }
11591159

1160-
impl std::fmt::Debug for #name {
1161-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1160+
impl core::fmt::Debug for #name {
1161+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
11621162
#internal::format_flags(&self.as_array(), &[#rust_names], f)
11631163
}
11641164
}
11651165

1166-
impl std::ops::BitOr for #name {
1166+
impl core::ops::BitOr for #name {
11671167
type Output = #name;
11681168

11691169
fn bitor(self, rhs: #name) -> #name {
11701170
#bitor
11711171
}
11721172
}
11731173

1174-
impl std::ops::BitOrAssign for #name {
1174+
impl core::ops::BitOrAssign for #name {
11751175
fn bitor_assign(&mut self, rhs: #name) {
11761176
#bitor_assign
11771177
}
11781178
}
11791179

1180-
impl std::ops::BitAnd for #name {
1180+
impl core::ops::BitAnd for #name {
11811181
type Output = #name;
11821182

11831183
fn bitand(self, rhs: #name) -> #name {
11841184
#bitand
11851185
}
11861186
}
11871187

1188-
impl std::ops::BitAndAssign for #name {
1188+
impl core::ops::BitAndAssign for #name {
11891189
fn bitand_assign(&mut self, rhs: #name) {
11901190
#bitand_assign
11911191
}
11921192
}
11931193

1194-
impl std::ops::BitXor for #name {
1194+
impl core::ops::BitXor for #name {
11951195
type Output = #name;
11961196

11971197
fn bitxor(self, rhs: #name) -> #name {
11981198
#bitxor
11991199
}
12001200
}
12011201

1202-
impl std::ops::BitXorAssign for #name {
1202+
impl core::ops::BitXorAssign for #name {
12031203
fn bitxor_assign(&mut self, rhs: #name) {
12041204
#bitxor_assign
12051205
}
12061206
}
12071207

1208-
impl std::ops::Not for #name {
1208+
impl core::ops::Not for #name {
12091209
type Output = #name;
12101210

12111211
fn not(self) -> #name {
@@ -1220,7 +1220,7 @@ pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
12201220
&self,
12211221
cx: &mut #internal::LowerContext<'_, T>,
12221222
_ty: #internal::InterfaceType,
1223-
dst: &mut std::mem::MaybeUninit<Self::Lower>,
1223+
dst: &mut core::mem::MaybeUninit<Self::Lower>,
12241224
) -> #internal::anyhow::Result<()> {
12251225
#(
12261226
self.#field_names.lower(
@@ -1245,7 +1245,7 @@ pub fn expand_flags(flags: &Flags) -> Result<TokenStream> {
12451245
#field_interface_type,
12461246
offset,
12471247
)?;
1248-
offset += std::mem::size_of_val(&self.#field_names);
1248+
offset += core::mem::size_of_val(&self.#field_names);
12491249
)*
12501250
Ok(())
12511251
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// The output of `bindgen!` should be compatible with `no_std` by default, so
2+
// test that here with a no_std crate.
3+
4+
#![no_std]
5+
6+
extern crate std;
7+
8+
macro_rules! gentest {
9+
($id:ident $name:tt $path:tt) => {
10+
mod $id {
11+
wasmtime::component::bindgen!(in $path);
12+
}
13+
};
14+
}
15+
16+
component_macro_test_helpers::foreach!(gentest);

crates/environ/src/lib.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern crate alloc;
3333
///
3434
/// and then `use crate::*` works as usual.
3535
pub mod prelude {
36-
pub use crate::Err2Anyhow;
36+
pub use crate::{Err2Anyhow, IntoAnyhow};
3737
pub use alloc::borrow::ToOwned;
3838
pub use alloc::boxed::Box;
3939
pub use alloc::format;
@@ -62,20 +62,42 @@ pub trait Err2Anyhow<T> {
6262
fn err2anyhow(self) -> anyhow::Result<T>;
6363
}
6464

65-
#[cfg(feature = "std")]
66-
impl<T, E: Into<anyhow::Error>> Err2Anyhow<T> for Result<T, E> {
65+
impl<T, E: IntoAnyhow> Err2Anyhow<T> for Result<T, E> {
6766
fn err2anyhow(self) -> anyhow::Result<T> {
68-
self.map_err(|e| e.into())
67+
match self {
68+
Ok(e) => Ok(e),
69+
Err(e) => Err(e.into_anyhow()),
70+
}
71+
}
72+
}
73+
74+
/// Convenience trait to convert a value into `anyhow::Error`
75+
///
76+
/// This trait is not a suitable public interface of Wasmtime so it's just an
77+
/// internal implementation detail for now. This trait is conditionally
78+
/// implemented on the `std` feature with different bounds.
79+
pub trait IntoAnyhow {
80+
/// Converts `self` into an `anyhow::Error`.
81+
fn into_anyhow(self) -> anyhow::Error;
82+
}
83+
84+
#[cfg(feature = "std")]
85+
impl<T> IntoAnyhow for T
86+
where
87+
T: Into<anyhow::Error>,
88+
{
89+
fn into_anyhow(self) -> anyhow::Error {
90+
self.into()
6991
}
7092
}
7193

7294
#[cfg(not(feature = "std"))]
73-
impl<T, E> Err2Anyhow<T> for Result<T, E>
95+
impl<T> IntoAnyhow for T
7496
where
75-
E: core::fmt::Display + core::fmt::Debug + Send + Sync + 'static,
97+
T: core::fmt::Display + core::fmt::Debug + Send + Sync + 'static,
7698
{
77-
fn err2anyhow(self) -> anyhow::Result<T> {
78-
self.map_err(anyhow::Error::msg)
99+
fn into_anyhow(self) -> anyhow::Error {
100+
anyhow::Error::msg(self)
79101
}
80102
}
81103

crates/wasi-common/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ include = ["src/**/*", "tests/**/*", "witx", "README.md", "LICENSE", "build.rs"]
1515
workspace = true
1616

1717
[dependencies]
18-
anyhow = { workspace = true }
18+
anyhow = { workspace = true, features = ['std'] }
1919
thiserror = { workspace = true }
2020
wiggle = { workspace = true }
2121
tracing = { workspace = true }

0 commit comments

Comments
 (0)