diff --git a/crates/fiber/Cargo.toml b/crates/fiber/Cargo.toml index 964d37afe497..6aef47ad2997 100644 --- a/crates/fiber/Cargo.toml +++ b/crates/fiber/Cargo.toml @@ -39,3 +39,7 @@ backtrace = "0.3.68" # Assume presence of the standard library. Allows propagating # panic-unwinds across fiber invocations. std = [] + +# Use embedder-provided stack-switching routines on unsupported architectures. +# See `src/stackswitch/custom.rs` for the C ABI the embedder must implement. +custom = [] diff --git a/crates/fiber/src/lib.rs b/crates/fiber/src/lib.rs index 5f6d630840d2..99754203dace 100644 --- a/crates/fiber/src/lib.rs +++ b/crates/fiber/src/lib.rs @@ -34,7 +34,9 @@ cfg_if::cfg_if! { use unix as imp; mod stackswitch; } else { - compile_error!("fibers are not supported on this platform"); + mod nostd; + use nostd as imp; + mod stackswitch; } } diff --git a/crates/fiber/src/stackswitch.rs b/crates/fiber/src/stackswitch.rs index a249e86c9563..2920d23a3fbb 100644 --- a/crates/fiber/src/stackswitch.rs +++ b/crates/fiber/src/stackswitch.rs @@ -33,6 +33,10 @@ cfg_if::cfg_if! { mod riscv32imac; pub(crate) use supported::*; pub(crate) use riscv32imac::*; + } else if #[cfg(feature = "custom")] { + mod custom; + pub(crate) use supported::*; + pub(crate) use custom::*; } else { // No support for this platform. Don't fail compilation though and // instead defer the error to happen at runtime when a fiber is created. diff --git a/crates/fiber/src/stackswitch/custom.rs b/crates/fiber/src/stackswitch/custom.rs new file mode 100644 index 000000000000..2916d477baab --- /dev/null +++ b/crates/fiber/src/stackswitch/custom.rs @@ -0,0 +1,18 @@ +//! Embedder-provided stack-switching routines. +//! +//! This module is used when the `custom` feature is enabled and the target +//! architecture has no built-in inline-assembly implementation. It is the +//! stack-switching analogue of Wasmtime's `custom-virtual-memory` feature: +//! rather than relying on inline assembly for a known architecture, the +//! routines below are declared as `extern "C"` imports which the embedder is +//! expected to supply. + +unsafe extern "C" { + pub(crate) fn wasmtime_fiber_init( + top_of_stack: *mut u8, + entry: extern "C" fn(*mut u8, *mut u8) -> *mut u8, + entry_arg0: *mut u8, + ); + + pub(crate) fn wasmtime_fiber_switch(top_of_stack: *mut u8); +} diff --git a/crates/wasmtime/Cargo.toml b/crates/wasmtime/Cargo.toml index 0d08121831f7..cc14bdaf63f5 100644 --- a/crates/wasmtime/Cargo.toml +++ b/crates/wasmtime/Cargo.toml @@ -385,6 +385,9 @@ custom-native-signals = [] # Same as `custom-virtual-memory` above, but for custom sync primitive APIs. custom-sync-primitives = [] +# Same as `custom-virtual-memory` above, but for custom fiber APIs. +custom-fiber = ["wasmtime-fiber?/custom"] + # 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.