Implement RFC 11: Redesigning Wasmtime's APIs (#2897)

Implement Wasmtime's new API as designed by RFC 11. This is quite a large commit which has had lots of discussion externally, so for more information it's best to read the RFC thread and the PR thread.
This commit is contained in:
Alex Crichton
2021-06-03 09:10:53 -05:00
committed by GitHub
parent a5a28b1c5b
commit 7a1b7cdf92
233 changed files with 13349 additions and 11997 deletions

View File

@@ -16,12 +16,11 @@ build = "build.rs"
wasi-common = { path = "../wasi-common", version = "0.27.0" }
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", version = "0.27.0", optional = true }
wasi-tokio = { path = "../wasi-common/tokio", version = "0.27.0", optional = true }
wiggle = { path = "../wiggle", default-features = false, version = "0.27.0" }
wasmtime-wiggle = { path = "../wiggle/wasmtime", default-features = false, version = "0.27.0" }
wiggle = { path = "../wiggle", default-features = false, version = "0.27.0", features = ["wasmtime_integration"] }
wasmtime = { path = "../wasmtime", default-features = false, version = "0.27.0" }
anyhow = "1.0"
[features]
default = ["sync"]
sync = ["wasi-cap-std-sync"]
tokio = ["wasi-tokio", "wasmtime/async", "wasmtime-wiggle/async"]
tokio = ["wasi-tokio", "wasmtime/async", "wiggle/wasmtime_async"]

View File

@@ -28,7 +28,7 @@ pub use sync::*;
#[cfg(feature = "tokio")]
pub mod tokio {
pub use wasi_tokio::*;
super::define_wasi!(async);
super::define_wasi!(async T: Send);
}
// The only difference between these definitions for sync vs async is whether
@@ -38,100 +38,41 @@ pub mod tokio {
#[doc(hidden)]
#[macro_export]
macro_rules! define_wasi {
($async_mode: tt) => {
($async_mode:tt $($bounds:tt)*) => {
use std::cell::RefCell;
use std::rc::Rc;
use wasmtime::{Config, Linker, Store};
use wasi_common::WasiCtx;
use wasmtime::Linker;
/// An instantiated instance of all available wasi exports. Presently includes
/// both the "preview1" snapshot and the "unstable" (preview0) snapshot.
pub struct Wasi {
preview_1: snapshots::preview_1::Wasi,
preview_0: snapshots::preview_0::Wasi,
}
impl Wasi {
pub fn new(store: &Store, context: WasiCtx) -> Self {
let context = Rc::new(RefCell::new(context));
let preview_1 = snapshots::preview_1::Wasi::new(store, context.clone());
let preview_0 = snapshots::preview_0::Wasi::new(store, context);
Self {
preview_1,
preview_0,
}
}
pub fn add_to_linker(&self, linker: &mut Linker) -> Result<(), anyhow::Error> {
self.preview_1.add_to_linker(linker)?;
self.preview_0.add_to_linker(linker)?;
Ok(())
}
pub fn add_to_config(config: &mut Config) {
snapshots::preview_1::Wasi::add_to_config(config);
snapshots::preview_0::Wasi::add_to_config(config);
}
pub fn set_context(store: &Store, context: WasiCtx) -> Result<(), WasiCtx> {
// It doesn't matter which underlying `Wasi` type this gets called on as the
// implementations are identical
snapshots::preview_1::Wasi::set_context(store, context)
}
pub fn add_to_linker<T>(
linker: &mut Linker<T>,
get_cx: impl Fn(&mut T) -> &mut crate::WasiCtx + Send + Sync + Copy + 'static,
) -> anyhow::Result<()>
where $($bounds)*
{
snapshots::preview_1::add_wasi_snapshot_preview1_to_linker(linker, get_cx)?;
snapshots::preview_0::add_wasi_unstable_to_linker(linker, get_cx)?;
Ok(())
}
pub mod snapshots {
pub mod preview_1 {
use wasi_common::WasiCtx;
// Defines a `struct Wasi` with member fields and appropriate APIs for dealing
// with all the various WASI exports.
wasmtime_wiggle::wasmtime_integration!({
wiggle::wasmtime_integration!({
// The wiggle code to integrate with lives here:
target: wasi_common::snapshots::preview_1,
// This must be the same witx document as used above. This should be ensured by
// the `WASI_ROOT` env variable, which is set in wasi-common's `build.rs`.
witx: ["$WASI_ROOT/phases/snapshot/witx/wasi_snapshot_preview1.witx"],
// This must be the same ctx type as used for the target:
ctx: WasiCtx,
// This macro will emit a struct to represent the instance,
// with this name and docs:
modules: { wasi_snapshot_preview1 =>
{ name: Wasi,
docs: "An instantiated instance of the wasi exports.
This represents a wasi module which can be used to instantiate other wasm
modules. This structure exports all that various fields of the wasi instance
as fields which can be used to implement your own instantiation logic, if
necessary. Additionally [`Wasi::get_export`] can be used to do name-based
resolution.",
},
},
errors: { errno => Error },
$async_mode: *
});
}
pub mod preview_0 {
use wasi_common::WasiCtx;
// Defines a `struct Wasi` with member fields and appropriate APIs for dealing
// with all the various WASI exports.
wasmtime_wiggle::wasmtime_integration!({
wiggle::wasmtime_integration!({
// The wiggle code to integrate with lives here:
target: wasi_common::snapshots::preview_0,
// This must be the same witx document as used above. This should be ensured by
// the `WASI_ROOT` env variable, which is set in wasi-common's `build.rs`.
witx: ["$WASI_ROOT/phases/old/snapshot_0/witx/wasi_unstable.witx"],
// This must be the same ctx type as used for the target:
ctx: WasiCtx,
// This macro will emit a struct to represent the instance,
// with this name and docs:
modules: { wasi_unstable =>
{ name: Wasi,
docs: "An instantiated instance of the wasi exports.
This represents a wasi module which can be used to instantiate other wasm
modules. This structure exports all that various fields of the wasi instance
as fields which can be used to implement your own instantiation logic, if
necessary. Additionally [`Wasi::get_export`] can be used to do name-based
resolution.",
},
},
errors: { errno => Error },
$async_mode: *
});
}