Expand description
WASM plugin loader for dynamic-cli (Option C — DD-021)
Provides WasmPlugin, a Plugin implementation backed by a sandboxed
WebAssembly module loaded and executed via wasmtime. Only available
when the wasm-plugins feature is enabled.
§Why WASM plugins
Static plugins (SystemPlugin and Option A
in general) must be compiled into the host binary. WASM plugins trade
that compile-time coupling for a safe, cross-platform sandbox: a .wasm
module can be distributed independently of the host application and
loaded at runtime, with no unsafe code on the host side.
§ABI contract — mandatory exports
Every WASM module loaded as a WasmPlugin must export:
| Export | Signature | Purpose |
|---|---|---|
memory | (standard linear memory) | Shared buffer for argument/result transfer |
dcli_alloc | (size: i32) -> i32 | Host asks the guest to reserve size bytes; returns the pointer |
dcli_dealloc | (ptr: i32, size: i32) | Host asks the guest to free a buffer it previously allocated |
| (business function) | (ptr: i32, len: i32) -> i32 | Reads serialized args at ptr/len; returns 0 on success, non-zero on error |
The business function’s exported name is chosen freely by the plugin
author and mapped to an implementation name via
WasmPlugin::with_function_map.
§ABI contract — optional exports
| Export | Signature | Purpose |
|---|---|---|
dcli_last_error_message | () -> (ptr: i32, len: i32) | Detailed error message when the business function returns non-zero |
When absent, errors surface with the raw code only
(WasmError::guest_error_without_message).
§Serialization
Handler arguments (HashMap<String, String>) are serialized to a byte
buffer before crossing the host/guest boundary. YAML is the default,
consistent with the framework’s config-first principle (DD-002); JSON is
available via WasmPlugin::with_format.
§Known limitation — no ExecutionContext access
WASM handlers do not receive the host’s ExecutionContext. Trait
objects cannot cross the WASM FFI boundary, and exposing arbitrary host
state to a sandboxed guest would defeat the purpose of the sandbox. WASM
plugins in this version only exchange serialized arguments and a result
code/message.
Future work may introduce a restricted set of host functions (e.g.
host_log, host_get_state) or WASI integration for guests that need
controlled access to host capabilities — see DD-021 for the open
discussion. This version intentionally ships without them.
Full reference: WASM_PLUGIN_INTERFACE.md.
§Example
use dynamic_cli::plugin::wasm::{WasmPlugin, WasmSerializationFormat};
use std::path::Path;
let plugin = WasmPlugin::load(Path::new("plugins/greet.wasm"))?
.with_function_map("greet_hello", "say_hello")
.with_format(WasmSerializationFormat::Yaml)
.with_metadata("greet", "1.0.0", "Greeting commands");Structs§
- Wasm
Plugin - A
Pluginbacked by a sandboxed WASM module.
Enums§
- Wasm
Serialization Format - Serialization format used to exchange handler arguments across the host/guest boundary.