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 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>where
T: 'static,
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,
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,
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>
pub fn func_wrap_concurrent<Params, Return, F>( &mut self, name: &str, f: F, ) -> Result<(), Error>
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>
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.
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>
pub fn func_new_concurrent<F>(&mut self, name: &str, f: F) -> Result<(), Error>
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 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