Skip to main content

add_named_to_linker

Function add_named_to_linker 

Source
pub fn add_named_to_linker<T>(
    linker: &mut Linker<T>,
    component: &Component,
    lookup: impl FnMut(Interface, &str) -> Result<NamedId>,
) -> Result<()>
where T: WasiSocketsNamedView + 'static,
Available on crate feature p3 only.
Expand description

Convenience function to add wasi:sockets interfaces into linker for any named imports of wasi:sockets interfaces.

This function is similar to add_to_linker except that it’s specifically designed to work with named imports of wasi:sockets 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.

Like add_to_linker this is a bit low level and you may want to possibly invoke wasmtime_wasi::p3::add_named_to_linker instead. Alternatively if this isn’t low level enough you can additionally invoke bindgen-generated add_to_linker functions directly from within the named_imports::wasi::sockets module.

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 WasiSocketsNamedView 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;
use wasmtime_wasi::sockets::{WasiSocketsCtx, WasiSocketsCtxView, WasiSocketsNamedView};

fn main() -> Result<()> {
    let engine = Engine::default();
    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:sockets` interfaces.
    let mut name_map = HashMap::new();
    wasmtime_wasi::p3::sockets::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 `WasiSocketsCtx` 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(WasiSocketsCtx::default());
    }
    let mut store = Store::new(&engine, my_state);
    let instance = linker.instantiate(&mut store, &component)?;

    // ... work with `instance` ...

    Ok(())
}

#[derive(Default)]
struct MyState {
    table: ResourceTable,
    contexts: Vec<WasiSocketsCtx>,
}

impl WasiSocketsNamedView for MyState {
    fn sockets(&mut self, id: NamedId) -> WasiSocketsCtxView<'_> {
        WasiSocketsCtxView {
            ctx: &mut self.contexts[id.0],
            table: &mut self.table,
        }
    }
}