Struct LinkerInstance

pub struct LinkerInstance<'a, T>
where T: 'static,
{ /* 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>
where T: 'static,

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 LinkerInstance.

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.

§Blocking / Async Behavior

The host function func provided here is a blocking function from the perspective of WebAssembly, regardless of how Config::async_support is defined. This function can be used both with sync and async stores and will always define a blocking function.

To define a function which is async on the host, but blocking to the guest, see the func_wrap_async method.

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

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

This function is similar to Self::func_wrap except it takes an async host function instead of a blocking host function. The F function here is intended to be:

F: AsyncFn(StoreContextMut<'_, T>, Params) -> Result<Return>

however the returned future must be Send which is not possible to bound at this time. This will be switched to an async closure once Rust supports it.

§Blocking / Async Behavior

This function can only be called when Config::async_support is enabled. The function defined which WebAssembly calls will still appear as blocking from the perspective of WebAssembly itself. The host, however, can perform asynchronous operations without blocking the thread performing a call.

When Config::async_support is enabled then all WebAssembly is invoked on a separate stack within a Wasmtime-managed fiber. This means that if the future returned by F is not immediately ready then the fiber will be suspended to block WebAssembly but not the host. When the future becomes ready again the fiber will be resumed to continue execution within WebAssembly.

§Panics

This function panics if Config::async_support is set to false.

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

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

This function defines a host function available to call from WebAssembly. WebAssembly may additionally make multiple invocations of this function concurrently all at the same time. This function requires the Config::wasm_component_model_async feature to be enabled.

The function f provided will be invoked when called by WebAssembly. WebAssembly components may then call f multiple times while previous invocations of f are already running. Additionally while f is running other host functions may be invoked.

The F function here is intended to be:

F: AsyncFn(&mut Accessor<T>, Params) -> Result<Return>

however the returned future must be Send which is not possible to bound at this time. This will be switched to an async closure once Rust supports it.

The closure f is provided an Accessor which can be used to acquire temporary, blocking, access to a StoreContextMut (through [Access]). This models how a store is not available to f across await points but it is temporarily available while actively being polled.

§Blocking / Async Behavior

This function can only be called when Config::async_support is enabled. Unlike Self::func_wrap and Self::func_wrap_async this function is asynchronous even from the perspective of guest WebAssembly. This means that if f is not immediately resolved then the call from WebAssembly will still return immediately (assuming it was lowered with async). The closure f should not block the current thread and should only perform blocking via async meaning that f won’t block either WebAssembly nor the host.

Note that WebAssembly components can lower host functions both with and without async. That means that even if a host function is defined in the “concurrent” mode here a guest may still lower it synchronously. In this situation Wasmtime will manage blocking the guest while the closure f provided here completes. If a guest lowers this function with async, though, then no blocking will happen.

§Panics

This function panics if Config::async_support is set to false.

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.

As Self::func_wrap_async is a dual of Self::func_wrap, this function is the dual of Self::func_new.

For documentation on blocking behavior see Self::func_wrap_async.

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

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

As Self::func_wrap_concurrent is a dual of Self::func_wrap, this function is the dual of Self::func_new.

For documentation on async/blocking behavior see Self::func_wrap_concurrent.

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: Fn(StoreContextMut<'_, T>, u32) -> Box<dyn Future<Output = Result<(), Error>> + Send + '_> + 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