Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for #![no_std] to the wasmtime crate #8533

Merged
merged 25 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7785b91
Always fall back to custom platform for Wasmtime
alexcrichton May 2, 2024
22f269d
Change Wasmtime's TLS state to a single pointer
alexcrichton May 2, 2024
3e87607
Delay conversion to `Instant` in atomic intrinsics
alexcrichton May 3, 2024
57d13e1
Gate more parts of Wasmtime on the `profiling` feature
alexcrichton May 3, 2024
8982b0c
Refactor conversion to `anyhow::Error` in `wasmtime-environ`
alexcrichton May 3, 2024
173fbdd
Gate `gimli` in Wasmtime on `addr2line`
alexcrichton May 3, 2024
4d90a7d
Update `bindgen!` to have `no_std`-compatible output
alexcrichton May 3, 2024
e6be5ff
Use an `Option` for `gc_store` instead of `OnceCell`
alexcrichton May 3, 2024
4198291
Enable embedder-defined host feature detection
alexcrichton May 3, 2024
537c9e3
Add `#![no_std]` support to the `wasmtime` crate
alexcrichton May 3, 2024
40ca806
Require `std` for the perfmap profiling agent
alexcrichton May 3, 2024
f551514
Fix build on wasm
alexcrichton May 3, 2024
e0f2179
Fix windows build
alexcrichton May 3, 2024
7f35cfa
Remove unused import
alexcrichton May 3, 2024
4131eeb
Fix Windows/Unix build without `std` feature
alexcrichton May 3, 2024
863a18e
Fix some doc links
alexcrichton May 3, 2024
d275aa5
Remove unused import
alexcrichton May 3, 2024
20c6785
Fix build of wasi-common in isolation
alexcrichton May 3, 2024
ac4cbaf
Fix no_std build on macos
alexcrichton May 3, 2024
664b2b6
Re-fix build
alexcrichton May 3, 2024
6a1a111
Fix standalone build of wasmtime-cli-flags
alexcrichton May 3, 2024
531a1a0
Resolve a merge conflict
alexcrichton May 3, 2024
8d67bf4
Review comments
alexcrichton May 4, 2024
34f6bc4
Merge remote-tracking branch 'origin/main' into no-std-rebase
alexcrichton May 4, 2024
1143fe5
Remove unused import
alexcrichton May 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ jobs:
- run: cargo check -p wasmtime --no-default-features --features pooling-allocator
- run: cargo check -p wasmtime --no-default-features --features cranelift
- run: cargo check -p wasmtime --no-default-features --features component-model
- run: cargo check -p wasmtime --no-default-features --features runtime,component-model
- run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache
- run: cargo check -p wasmtime --no-default-features --features winch
- run: cargo check -p wasmtime --no-default-features --features wmemcheck
Expand Down Expand Up @@ -363,16 +364,7 @@ jobs:
# Checks for no_std support, ensure that crates can build on a no_std
# target
- run: rustup target add x86_64-unknown-none
- run: cargo check -p wasmtime-jit-icache-coherence
env:
CARGO_BUILD_TARGET: x86_64-unknown-none
- run: cargo check -p wasmtime-asm-macros
env:
CARGO_BUILD_TARGET: x86_64-unknown-none
- run: cargo check -p wasmtime-slab
env:
CARGO_BUILD_TARGET: x86_64-unknown-none
- run: cargo check -p wasmtime-environ --features gc,component-model
- run: cargo check -p wasmtime --no-default-features --features gc,component-model
env:
CARGO_BUILD_TARGET: x86_64-unknown-none

Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ path = "src/bin/wasmtime.rs"
doc = false

[dependencies]
wasmtime = { workspace = true }
wasmtime = { workspace = true, features = ['std'] }
wasmtime-cache = { workspace = true, optional = true }
wasmtime-cli-flags = { workspace = true }
wasmtime-cranelift = { workspace = true, optional = true }
Expand Down Expand Up @@ -254,7 +254,7 @@ log = { version = "0.4.8", default-features = false }
clap = { version = "4.3.12", default-features = false, features = ["std", "derive"] }
hashbrown = { version = "0.14", default-features = false }
capstone = "0.12.0"
once_cell = "1.12.0"
once_cell = { version = "1.12.0", default-features = false }
smallvec = { version = "1.6.1", features = ["union"] }
tracing = "0.1.26"
bitflags = "2.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ doctest = false
env_logger = { workspace = true, optional = true }
anyhow = { workspace = true }
once_cell = { workspace = true }
wasmtime = { workspace = true, features = ['cranelift', 'runtime', 'gc'] }
wasmtime = { workspace = true, features = ['cranelift', 'runtime', 'gc', 'std'] }
wasmtime-c-api-macros = { workspace = true }
log = { workspace = true }
tracing = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ include = ["src/**/*", "README.md", "LICENSE", "witx/*", "wit/**/*", "tests/*"]
workspace = true

[dependencies]
wasmtime = { workspace = true, features = ["component-model", "async", "runtime"] }
wasmtime = { workspace = true, features = ["component-model", "async", "runtime", "std"] }
anyhow = { workspace = true }
wiggle = { workspace = true, optional = true, features = ["wasmtime"] }
tokio = { workspace = true, features = ["time", "sync", "io-std", "io-util", "rt", "rt-multi-thread", "net"] }
Expand Down
47 changes: 33 additions & 14 deletions crates/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ features = ["component-model"]

[dependencies]
wasmtime-asm-macros = { workspace = true, optional = true }
wasmtime-environ = { workspace = true, features = ['std'] }
wasmtime-environ = { workspace = true }
wasmtime-jit-debug = { workspace = true, features = ["gdb_jit_int", "perf_jitdump"], optional = true }
wasmtime-jit-icache-coherence = { workspace = true, optional = true }
wasmtime-cache = { workspace = true, optional = true }
Expand Down Expand Up @@ -50,16 +50,18 @@ indexmap = { workspace = true }
paste = "1.0.3"
once_cell = { workspace = true }
rayon = { version = "1.0", optional = true }
object = { workspace = true, features = ['std'] }
object = { workspace = true }
async-trait = { workspace = true, optional = true }
encoding_rs = { version = "0.8.31", optional = true }
bumpalo = "3.11.0"
fxprof-processed-profile = { version = "0.6.0", optional = true }
gimli = { workspace = true, optional = true }
addr2line = { workspace = true, optional = true }
semver = { version = "1.0.17", optional = true }
semver = { version = "1.0.17", optional = true, default-features = false }
smallvec = { workspace = true, optional = true }
memoffset = { workspace = true, optional = true }
hashbrown = { workspace = true }
libm = "0.2.7"

[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
workspace = true
Expand Down Expand Up @@ -125,21 +127,22 @@ default = [
'runtime',
'component-model',
'threads',
'std',
]

# 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
# precompiled WebAssembly modules.
cranelift = ["dep:wasmtime-cranelift"]
cranelift = ["dep:wasmtime-cranelift", "std"]

# Enables support for winch, the WebAssembly baseline compiler. The Winch compiler
# strategy in `Config` will be available. It is currently in active development
# and shouldn't be used in production applications.
winch = ["dep:wasmtime-winch"]
winch = ["dep:wasmtime-winch", "std"]

# Enables support for incremental compilation cache to be enabled in `Config`.
incremental-cache = ["wasmtime-cranelift?/incremental-cache"]
incremental-cache = ["wasmtime-cranelift?/incremental-cache", "std"]

# Enables support for profiling guest modules.
profiling = [
Expand All @@ -149,13 +152,14 @@ profiling = [
"dep:rustix",
"rustix/thread",
"dep:serde_json",
"std",
]

# Enables parallel compilation of WebAssembly code.
parallel-compilation = ["dep:rayon"]
parallel-compilation = ["dep:rayon", "std"]

# Enables support for automatic cache configuration to be enabled in `Config`.
cache = ["dep:wasmtime-cache"]
cache = ["dep:wasmtime-cache", "std"]

# Enables support for "async stores" as well as defining host functions as
# `async fn` and calling functions asynchronously.
Expand All @@ -164,10 +168,11 @@ async = [
"dep:async-trait",
"wasmtime-component-macro?/async",
"runtime",
"std",
]

# Enables support for the pooling instance allocation strategy
pooling-allocator = ["runtime"]
pooling-allocator = ["runtime", "std"]

# Enables support for all architectures in Cranelift, allowing
# cross-compilation using the `wasmtime` crate's API, notably the
Expand All @@ -191,18 +196,19 @@ wmemcheck = [
"dep:wasmtime-wmemcheck",
"wasmtime-cranelift?/wmemcheck",
"wasmtime-environ/wmemcheck",
"std",
]

# Enables support for demangling WebAssembly function names at runtime in
# errors such as backtraces.
demangle = ["wasmtime-environ/demangle"]
demangle = ["wasmtime-environ/demangle", "std"]

# Enable support for generating core dumps on traps.
coredump = ["dep:wasm-encoder", "runtime"]
coredump = ["dep:wasm-encoder", "runtime", "std"]

# Export some symbols from the final binary to assist in debugging
# Cranelift-generated code with native debuggers like GDB and LLDB.
debug-builtins = ["dep:wasmtime-jit-debug"]
debug-builtins = ["dep:wasmtime-jit-debug", "std"]

# Enable support for executing compiled Wasm modules.
runtime = [
Expand Down Expand Up @@ -238,9 +244,22 @@ runtime = [
gc = ["wasmtime-environ/gc", "wasmtime-cranelift?/gc"]

# Enable runtime support for the WebAssembly threads proposal.
threads = ["wasmtime-cranelift?/threads"]
threads = ["wasmtime-cranelift?/threads", "std"]

# Controls whether backtraces will attempt to parse DWARF information in
# WebAssembly modules and components to provide filenames and line numbers in
# stack traces.
addr2line = ["dep:addr2line", "dep:gimli"]
addr2line = ["dep:addr2line", "dep:gimli", "std"]

# Enables support for the Rust standard library, enabling APIs that require
# types and traits from Rust's `std` such as `Path` and `Error`.
#
# Many features of the Wasmtime crate implicitly require this `std` feature.
# This will be automatically enabled if necessary.
std = [
'postcard/use-std',
'wasmtime-component-macro?/std',
'wasmtime-environ/std',
'object/std',
'once_cell/std',
]
1 change: 1 addition & 0 deletions crates/wasmtime/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//! functions. It is up to the caller to serialize the relevant parts of the
//! `Artifacts` into the ELF file.

use crate::prelude::*;
use crate::Engine;
use anyhow::{Context, Result};
use std::{
Expand Down
1 change: 1 addition & 0 deletions crates/wasmtime/src/compile/code_builder.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::prelude::*;
use crate::Engine;
use anyhow::{anyhow, bail, Context, Result};
use std::borrow::Cow;
Expand Down
32 changes: 21 additions & 11 deletions crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::prelude::*;
use alloc::sync::Arc;
use anyhow::{bail, ensure, Result};
use core::fmt;
use core::str::FromStr;
use hashbrown::{HashMap, HashSet};
use serde_derive::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fmt;
#[cfg(any(feature = "cache", feature = "cranelift", feature = "winch"))]
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
use target_lexicon::Architecture;
use wasmparser::WasmFeatures;
#[cfg(feature = "cache")]
Expand Down Expand Up @@ -85,8 +86,8 @@ impl Default for ModuleVersionStrategy {
}
}

impl std::hash::Hash for ModuleVersionStrategy {
fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
impl core::hash::Hash for ModuleVersionStrategy {
fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {
match self {
Self::WasmtimeVersion => env!("CARGO_PKG_VERSION").hash(hasher),
Self::Custom(s) => s.hash(hasher),
Expand Down Expand Up @@ -474,18 +475,27 @@ impl Config {
/// filename/line number for each wasm frame in the stack trace.
///
/// By default this option is `WasmBacktraceDetails::Environment`, meaning
/// that wasm will read `WASMTIME_BACKTRACE_DETAILS` to indicate whether details
/// should be parsed.
/// that wasm will read `WASMTIME_BACKTRACE_DETAILS` to indicate whether
/// details should be parsed. Note that the `std` feature of this crate must
/// be active to read environment variables, otherwise this is disabled by
/// default.
pub fn wasm_backtrace_details(&mut self, enable: WasmBacktraceDetails) -> &mut Self {
self.wasm_backtrace_details_env_used = false;
self.tunables.parse_wasm_debuginfo = match enable {
WasmBacktraceDetails::Enable => Some(true),
WasmBacktraceDetails::Disable => Some(false),
WasmBacktraceDetails::Environment => {
self.wasm_backtrace_details_env_used = true;
std::env::var("WASMTIME_BACKTRACE_DETAILS")
.map(|s| Some(s == "1"))
.unwrap_or(Some(false))
#[cfg(feature = "std")]
{
std::env::var("WASMTIME_BACKTRACE_DETAILS")
.map(|s| Some(s == "1"))
.unwrap_or(Some(false))
}
#[cfg(not(feature = "std"))]
{
Some(false)
}
}
};
self
Expand Down
38 changes: 26 additions & 12 deletions crates/wasmtime/src/engine.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use crate::prelude::*;
#[cfg(feature = "runtime")]
use crate::runtime::type_registry::TypeRegistry;
#[cfg(feature = "runtime")]
use crate::runtime::vm::GcRuntime;
use crate::sync::OnceLock;
use crate::Config;
use alloc::sync::Arc;
use anyhow::{Context, Result};
use core::sync::atomic::{AtomicU64, Ordering};
#[cfg(any(feature = "cranelift", feature = "winch"))]
use object::write::{Object, StandardSegment};
use object::SectionKind;
use once_cell::sync::OnceCell;
#[cfg(feature = "std")]
use std::path::Path;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use wasmparser::WasmFeatures;
use wasmtime_environ::obj;
use wasmtime_environ::{FlagValue, ObjectKind, Tunables};
Expand Down Expand Up @@ -64,7 +66,8 @@ struct EngineInner {

/// One-time check of whether the compiler's settings, if present, are
/// compatible with the native host.
compatible_with_native_host: OnceCell<Result<(), String>>,
#[cfg(any(feature = "cranelift", feature = "winch"))]
compatible_with_native_host: OnceLock<Result<(), String>>,
}

impl Default for Engine {
Expand Down Expand Up @@ -123,7 +126,8 @@ impl Engine {
epoch: AtomicU64::new(0),
#[cfg(feature = "runtime")]
unique_id_allocator: crate::runtime::vm::CompiledModuleIdAllocator::new(),
compatible_with_native_host: OnceCell::new(),
#[cfg(any(feature = "cranelift", feature = "winch"))]
compatible_with_native_host: OnceLock::new(),
config,
tunables,
}),
Expand Down Expand Up @@ -203,6 +207,7 @@ impl Engine {
}

/// Like [`Engine::detect_precompiled`], but performs the detection on a file.
#[cfg(feature = "std")]
pub fn detect_precompiled_file(&self, path: impl AsRef<Path>) -> Result<Option<Precompiled>> {
serialization::detect_precompiled_file(path)
}
Expand All @@ -227,11 +232,18 @@ impl Engine {
/// Note that if cranelift is disabled this trivially returns `Ok` because
/// loaded serialized modules are checked separately.
pub(crate) fn check_compatible_with_native_host(&self) -> Result<()> {
self.inner
.compatible_with_native_host
.get_or_init(|| self._check_compatible_with_native_host())
.clone()
.map_err(anyhow::Error::msg)
#[cfg(any(feature = "cranelift", feature = "winch"))]
{
self.inner
.compatible_with_native_host
.get_or_init(|| self._check_compatible_with_native_host())
.clone()
.map_err(anyhow::Error::msg)
}
#[cfg(not(any(feature = "cranelift", feature = "winch")))]
{
Ok(())
}
}

fn _check_compatible_with_native_host(&self) -> Result<(), String> {
Expand Down Expand Up @@ -516,6 +528,7 @@ impl Engine {
serialization::append_compiler_info(self, obj, &serialization::Metadata::new(&self))
}

#[cfg(any(feature = "cranelift", feature = "winch"))]
pub(crate) fn append_bti(&self, obj: &mut Object<'_>) {
let section = obj.add_section(
obj.segment_name(StandardSegment::Data).to_vec(),
Expand Down Expand Up @@ -669,6 +682,7 @@ impl Engine {
}

/// Like `load_code_bytes`, but creates a mmap from a file on disk.
#[cfg(feature = "std")]
pub(crate) fn load_code_file(
&self,
path: &Path,
Expand Down Expand Up @@ -697,13 +711,13 @@ impl Engine {
/// A weak reference to an [`Engine`].
#[derive(Clone)]
pub struct EngineWeak {
inner: std::sync::Weak<EngineInner>,
inner: alloc::sync::Weak<EngineInner>,
}

impl EngineWeak {
/// Upgrade this weak reference into an [`Engine`]. Returns `None` if
/// strong references (the [`Engine`] type itself) no longer exist.
pub fn upgrade(&self) -> Option<Engine> {
std::sync::Weak::upgrade(&self.inner).map(|inner| Engine { inner })
alloc::sync::Weak::upgrade(&self.inner).map(|inner| Engine { inner })
}
}
Loading