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 Instance
s and instead are defined by
a “bag of named items”, so each LinkerInstance
can further define items
internally.
Implementations§
§impl<T> LinkerInstance<'_, T>
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,
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,
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>
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>
pub fn func_new_async<F>(&mut self, name: &str, f: F) -> Result<(), Error>
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 resource(
&mut self,
name: &str,
ty: ResourceType,
dtor: impl Fn(StoreContextMut<'_, T>, u32) -> Result<(), Error> + Send + Sync + 'static,
) -> Result<(), Error>
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>
pub fn resource_async<F>( &mut self, name: &str, ty: ResourceType, dtor: F, ) -> Result<(), Error>
Identical to Self::resource
, except that it takes an async destructor.
pub fn instance(&mut self, name: &str) -> Result<LinkerInstance<'_, T>, Error>
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>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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