wiggle::wasmtime_crate::component

Struct LinkerInstance

pub struct LinkerInstance<'a, T> { /* private fields */ }
Expand description

Structure representing an “instance” being defined within a linker.

Instances do not need to be actual Instances and instead are defined by a “bag of named items”, so each LinkerInstance can further define items internally.

Implementations§

§

impl<T> LinkerInstance<'_, T>

pub fn func_wrap<F, Params, Return>( &mut self, name: &str, func: F, ) -> Result<(), Error>
where F: Fn(StoreContextMut<'_, T>, Params) -> Result<Return, Error> + Send + Sync + 'static, Params: ComponentNamedList + Lift + 'static, Return: ComponentNamedList + Lower + 'static,

Defines a new host-provided function into this Linker.

This method is used to give host functions to wasm components. The func provided will be callable from linked components with the type signature dictated by Params and Return. The Params is a tuple of types that will come from wasm and Return is a value coming from the host going back to wasm.

Additionally the func takes a StoreContextMut as its first parameter.

Note that func must be an Fn and must also be Send + Sync + 'static. Shared state within a func is typically accessed with the T type parameter from Store<T> which is accessible through the leading StoreContextMut<'_, T> argument which can be provided to the func given here.

pub fn func_wrap_async<Params, Return, F>( &mut self, name: &str, f: F, ) -> Result<(), Error>
where F: for<'a> Fn(StoreContextMut<'a, T>, Params) -> Box<dyn Future<Output = Result<Return, Error>> + Send + 'a> + Send + Sync + 'static, Params: ComponentNamedList + Lift + 'static, Return: ComponentNamedList + Lower + 'static,

Defines a new host-provided async function into this Linker.

This is exactly like Self::func_wrap except it takes an async host function.

pub fn func_new( &mut self, name: &str, func: impl Fn(StoreContextMut<'_, T>, &[Val], &mut [Val]) -> Result<(), Error> + Send + Sync + 'static, ) -> Result<(), Error>

Define a new host-provided function using dynamically typed values.

The name provided is the name of the function to define and the func provided is the host-defined closure to invoke when this function is called.

This function is the “dynamic” version of defining a host function as compared to LinkerInstance::func_wrap. With LinkerInstance::func_wrap a function’s type is statically known but with this method the func argument’s type isn’t known ahead of time. That means that func can be by imported component so long as it’s imported as a matching name.

Type information will be available at execution time, however. For example when func is invoked the second argument, a &[Val] list, contains Val entries that say what type they are. Additionally the third argument, &mut [Val], is the expected number of results. Note that the expected types of the results cannot be learned during the execution of func. Learning that would require runtime introspection of a component.

Return values, stored in the third argument of &mut [Val], are type-checked at runtime to ensure that they have the appropriate type. A trap will be raised if they do not have the right type.

§Examples
use wasmtime::{Store, Engine};
use wasmtime::component::{Component, Linker, Val};

let engine = Engine::default();
let component = Component::new(
    &engine,
    r#"
        (component
            (import "thunk" (func $thunk))
            (import "is-even" (func $is-even (param "x" u32) (result bool)))

            (core module $m
                (import "" "thunk" (func $thunk))
                (import "" "is-even" (func $is-even (param i32) (result i32)))

                (func (export "run")
                    call $thunk

                    (call $is-even (i32.const 1))
                    if unreachable end

                    (call $is-even (i32.const 2))
                    i32.eqz
                    if unreachable end
                )
            )
            (core func $thunk (canon lower (func $thunk)))
            (core func $is-even (canon lower (func $is-even)))
            (core instance $i (instantiate $m
                (with "" (instance
                    (export "thunk" (func $thunk))
                    (export "is-even" (func $is-even))
                ))
            ))

            (func (export "run") (canon lift (core func $i "run")))
        )
    "#,
)?;

let mut linker = Linker::<()>::new(&engine);

// Sample function that takes no arguments.
linker.root().func_new("thunk", |_store, params, results| {
    assert!(params.is_empty());
    assert!(results.is_empty());
    println!("Look ma, host hands!");
    Ok(())
})?;

// This function takes one argument and returns one result.
linker.root().func_new("is-even", |_store, params, results| {
    assert_eq!(params.len(), 1);
    let param = match params[0] {
        Val::U32(n) => n,
        _ => panic!("unexpected type"),
    };

    assert_eq!(results.len(), 1);
    results[0] = Val::Bool(param % 2 == 0);
    Ok(())
})?;

let mut store = Store::new(&engine, ());
let instance = linker.instantiate(&mut store, &component)?;
let run = instance.get_typed_func::<(), ()>(&mut store, "run")?;
run.call(&mut store, ())?;

pub fn func_new_async<F>(&mut self, name: &str, f: F) -> Result<(), Error>
where F: for<'a> Fn(StoreContextMut<'a, T>, &'a [Val], &'a mut [Val]) -> Box<dyn Future<Output = Result<(), Error>> + Send + 'a> + Send + Sync + 'static,

Define a new host-provided async function using dynamic types.

This is exactly like Self::func_new except it takes an async host function.

pub fn module(&mut self, name: &str, module: &Module) -> Result<(), Error>

Defines a Module within this instance.

This can be used to provide a core wasm Module as an import to a component. The Module provided is saved within the linker for the specified name in this instance.

pub fn resource( &mut self, name: &str, ty: ResourceType, dtor: impl Fn(StoreContextMut<'_, T>, u32) -> Result<(), Error> + Send + Sync + 'static, ) -> Result<(), Error>

Defines a new resource of a given ResourceType in this linker.

This function is used to specify resources defined in the host.

The name argument is the name to define the resource within this linker.

The dtor provided is a destructor that will get invoked when an owned version of this resource is destroyed from the guest. Note that this destructor is not called when a host-owned resource is destroyed as it’s assumed the host knows how to handle destroying its own resources.

The dtor closure is provided the store state as the first argument along with the representation of the resource that was just destroyed.

§Errors

The provided dtor closure returns an error if something goes wrong when a guest calls the dtor to drop a Resource<T> such as a runtime trap or a runtime limit being exceeded.

pub fn resource_async<F>( &mut self, name: &str, ty: ResourceType, dtor: F, ) -> Result<(), Error>
where F: for<'a> Fn(StoreContextMut<'a, T>, u32) -> Box<dyn Future<Output = Result<(), Error>> + Send + 'a> + Send + Sync + 'static,

Identical to Self::resource, except that it takes an async destructor.

pub fn instance(&mut self, name: &str) -> Result<LinkerInstance<'_, T>, Error>

Defines a nested instance within this instance.

This can be used to describe arbitrarily nested levels of instances within a linker to satisfy nested instance exports of components.

pub fn into_instance(self, name: &str) -> Result<LinkerInstance<'_, T>, Error>

Same as LinkerInstance::instance except with different lifetime parameters.

Auto Trait Implementations§

§

impl<'a, T> Freeze for LinkerInstance<'a, T>

§

impl<'a, T> !RefUnwindSafe for LinkerInstance<'a, T>

§

impl<'a, T> Send for LinkerInstance<'a, T>

§

impl<'a, T> Sync for LinkerInstance<'a, T>

§

impl<'a, T> Unpin for LinkerInstance<'a, T>

§

impl<'a, T> !UnwindSafe for LinkerInstance<'a, T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Pointee for T

source§

type Pointer = u32

source§

fn debug( pointer: <T as Pointee>::Pointer, f: &mut Formatter<'_>, ) -> Result<(), Error>

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more