1.9 KiB
Zed's Plugin Runner
Wasm plugins can be run through wasmtime
, with supported for sandboxed system integration through WASI. There are three plugin
crates that implement different things:
-
plugin_runtime
loads and runs compiledWasm
plugins, and handles setting up system bindings. -
plugin
is the crate that Rust Wasm plugins should depend on. It re-exports some required crates (e.g.serde
,bincode
) and provides some necessary macros for generating bindings thatplugin_runtime
can hook into. -
plugin_macros
implements the proc macros required byplugin
, like the#[bind]
attribute macro.
ABI
The interface between the host Rust runtime ('Runtime') and plugins implemented in Wasm ('Plugin') is pretty simple.
Buffer
is a pair of two 4-byte (u32
) fields:
struct Buffer {
ptr: u32,
len: u32,
}
All functions that Plugin exports must have the following properties:
-
Have the signature
fn(ptr: u32, len: u32) -> u32
, where the return type is a pointer to aBuffer
, and the arguments are the component parts of aBuffer
.- The input
Buffer
will contain the input arguments serialized tobincode
. - The output
Buffer
will contain the output arguments serialized tobincode
.
- The input
-
Have a name starting with two underscores.
Additionally, Plugin must export an:
__alloc_buffer
function that, given au32
length, returns au32
pointer to a buffer of that length.
Note that all of these requirements are automatically fullfilled for any Rust Wasm plugin that uses the plugin
crate, and imports the prelude
.
Here's an example Rust Wasm plugin that doubles the value of every float in a Vec<f64>
passed into it:
use plugin::prelude::*;
#[bind]
pub fn double(mut x: Vec<f64>) -> Vec<f64> {
x.into_iter().map(|x| x * 2.0).collect()
}
All the serialization code is automatically generated by #[bind]
.