# 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: 1. `plugin_runtime` loads and runs compiled `Wasm` plugins, and handles setting up system bindings. 2. `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 that `plugin_runtime` can hook into. 3. `plugin_macros` implements the proc macros required by `plugin`, 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 a `Buffer`, and the arguments are the component parts of a `Buffer`. - The input `Buffer` will contain the input arguments serialized to `bincode`. - The output `Buffer` will contain the output arguments serialized to `bincode`. - Have a name starting with two underscores. Additionally, Plugin must export an: - `__alloc_buffer` function that, given a `u32` length, returns a `u32` 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` passed into it: ```rust use plugin::prelude::*; #[bind] pub fn double(mut x: Vec) -> Vec { x.into_iter().map(|x| x * 2.0).collect() } ``` All the serialization code is automatically generated by `#[bind]`.