pub fn add_named_to_linker<T>(
linker: &mut Linker<T>,
component: &Component,
lookup: impl FnMut(Interface, &str) -> Result<NamedId>,
) -> Result<()>where
T: WasiNamedView + 'static,p3 only.Expand description
Add all WASI interfaces from this module into the linker provided for any
named imports that a component has.
This function is similar to add_to_linker except that it’s specifically
designed to work with named imports of WASI interfaces that components may
have. This requires a Component parameter to be passed in when
populating the Linker provided to see what the Component actually
imports.
All interfaces implemented by this module are added here, so the
per-package functions such as cli::add_named_to_linker do not
additionally need to be invoked. If this isn’t low level enough you can
invoke those functions, or the bindgen-generated add_to_linker functions
within the named_imports module, directly instead.
The lookup function provided here is invoked for every named import found
for a particular interface. The Interface given is what’s being bound,
and the &str argument is the name that the component imports it as. The
embedder can then decide how it would like to allocate a NamedId for
this import. If Ok is returned then the linker is populated with this
name, and imported functions will pass the NamedId later to the
implementation of WasiNamedView on T when invoked. If Err is
returned then the error will cause this entire function to fail and this
function call will return the same error.
§Example
use std::collections::HashMap;
use wasmtime::component::{Component, Linker, ResourceTable};
use wasmtime::{Engine, Result, Store, Config};
use wasmtime_wasi::{NamedId, WasiCtx, WasiCtxView, WasiNamedView};
fn main() -> Result<()> {
let mut config = Config::new();
config.wasm_component_model_async(true);
let engine = Engine::new(&config)?;
let component = Component::new(&engine, "(component)")?;
let mut linker = Linker::<MyState>::new(&engine);
// ... add default functionality to `linker` as needed ...
// and then additionally fill in any specific named imports `component`
// might have for WASI interfaces.
let mut name_map = HashMap::new();
wasmtime_wasi::p3::add_named_to_linker(&mut linker, &component, |_i, name| {
let len = name_map.len();
Ok(NamedId(*name_map.entry(name.to_string()).or_insert(len)))
})?;
// Here a `WasiCtx` is allocated per-named-import and will then be
// referred to internally by the [`NamedId`] allocated above. You could
// also use `name_map` to configure each context differently.
let mut my_state = MyState::default();
for _ in 0..name_map.len() {
my_state.contexts.push(WasiCtx::default());
}
let mut store = Store::new(&engine, my_state);
// ... use `linker` to instantiate within `store` ...
Ok(())
}
#[derive(Default)]
struct MyState {
table: ResourceTable,
contexts: Vec<WasiCtx>,
}
impl WasiNamedView for MyState {
fn ctx(&mut self, id: NamedId) -> WasiCtxView<'_> {
WasiCtxView {
ctx: &mut self.contexts[id.0],
table: &mut self.table,
}
}
}