pub struct Instance { /* private fields */ }
runtime
and component-model
only.Expand description
An instantiated component.
This type represents an instantiated Component
.
Instances have exports which can be accessed through functions such as
Instance::get_func
or Instance::get_export
. Instances are owned by a
Store
and all methods require a handle to the store.
Component instances are created through
Linker::instantiate
and its family of
methods.
This type is similar to the core wasm version
wasmtime::Instance
except that it represents an
instantiated component instead of an instantiated module.
Implementations§
Source§impl Instance
impl Instance
Sourcepub fn future<T: Lower + Lift + Send + Sync + 'static>(
self,
default: fn() -> T,
store: impl AsContextMut,
) -> Result<(FutureWriter<T>, FutureReader<T>)>
Available on crate feature component-model-async
only.
pub fn future<T: Lower + Lift + Send + Sync + 'static>( self, default: fn() -> T, store: impl AsContextMut, ) -> Result<(FutureWriter<T>, FutureReader<T>)>
component-model-async
only.Create a new Component Model future
as pair of writable and readable ends,
the latter of which may be passed to guest code.
The default
parameter will be used if the returned FutureWriter
is
dropped before FutureWriter::write
is called. Since the write end of
a Component Model future
must be written to before it is dropped, and
since Rust does not currently provide a way to statically enforce that
(e.g. linear typing), we use this mechanism to ensure a value is always
written prior to closing.
If there’s no plausible default value, and you’re sure
FutureWriter::write
will be called, you can consider passing || unreachable!()
as the default
parameter.
Sourcepub fn stream<T: Lower + Lift + Send + 'static, W: WriteBuffer<T>, R: ReadBuffer<T>>(
self,
store: impl AsContextMut,
) -> Result<(StreamWriter<W>, StreamReader<R>)>
Available on crate feature component-model-async
only.
pub fn stream<T: Lower + Lift + Send + 'static, W: WriteBuffer<T>, R: ReadBuffer<T>>( self, store: impl AsContextMut, ) -> Result<(StreamWriter<W>, StreamReader<R>)>
component-model-async
only.Create a new Component Model stream
as pair of writable and readable ends,
the latter of which may be passed to guest code.
Source§impl Instance
impl Instance
Sourcepub async fn run<F>(
&self,
store: impl AsContextMut,
fut: F,
) -> Result<F::Output>where
F: Future,
Available on crate feature component-model-async
only.
pub async fn run<F>(
&self,
store: impl AsContextMut,
fut: F,
) -> Result<F::Output>where
F: Future,
component-model-async
only.Poll the specified future as part of this instance’s event loop until it yields a result or no further progress can be made.
This is intended for use in the top-level code of a host embedding with
Future
s which depend (directly or indirectly) on previously-started
concurrent tasks: e.g. the Future
s returned by
TypedFunc::call_concurrent
, StreamReader::read
, etc., or Future
s
derived from those.
Such Future
s can only usefully be polled in the context of the event
loop of the instance from which they originated; they will panic if
polled elsewhere. Future
s returned by host functions registered using
LinkerInstance::func_wrap_concurrent
are always polled as part of the
event loop, so this function is not needed in that case. However,
top-level code which needs to poll Future
s involving concurrent tasks
must use either this function, Instance::run_with
, or
Instance::spawn
to ensure they are polled as part of the correct event
loop.
Consider the following examples:
linker.root().func_wrap_concurrent("foo", |accessor, (future,): (HostFuture<bool>,)| Box::pin(async move {
let future = accessor.with(|view| future.into_reader(view));
// We can `.await` this directly (i.e. without using
// `Instance::{run,run_with,spawn}`) since we're running in a host
// function:
Ok((future.read().await.ok_or_else(|| anyhow!("read failed"))?,))
}))?;
let instance = linker.instantiate_async(&mut store, &component).await?;
let bar = instance.get_typed_func::<(), (HostFuture<bool>,)>(&mut store, "bar")?;
let call = bar.call_concurrent(&mut store, ());
// // NOT OK; this will panic if polled outside the event loop:
// let (future,) = call.await?;
// OK, since we use `Instance::run` to poll `call` inside the event loop:
let (future,) = instance.run(&mut store, call).await??;
let future = future.into_reader(&mut store);
// // NOT OK; this will panic if polled outside the event loop:
// let _result = future.read().await;
// OK, since we use `Instance::run` to poll the `Future` returned by
// `FutureReader::read`. Here we wrap that future in an async block for
// illustration, although it's redundant for a simple case like this. In
// a more complex scenario, we could use composition, loops, conditionals,
// etc.
let _result = instance.run(&mut store, Box::pin(async move {
future.read().await
})).await?;
Note that this function will return a “deadlock” error in either of the following scenarios:
-
One or more guest tasks are still pending (i.e. have not yet returned, or, in the case of async-lifted exports with callbacks, have not yet returned
CALLBACK_CODE_EXIT
) even though all host tasks have completed all host-owned stream and future handles have been dropped, etc. -
Any and all guest tasks complete normally, but the future passed to this function continues to return
Pending
when polled. In that case, the future presumably does not depend on any guest task making further progress (since no futher progress can be made) and thus is not an appropriate future to poll using this function.
Sourcepub async fn run_with<U, V, F>(
&self,
store: impl AsContextMut<Data = U>,
fun: F,
) -> Result<V>
Available on crate feature component-model-async
only.
pub async fn run_with<U, V, F>( &self, store: impl AsContextMut<Data = U>, fun: F, ) -> Result<V>
component-model-async
only.Run the specified task as part of this instance’s event loop.
Like Self::run
, this will poll a specified future as part of this
instance’s event loop until it yields a result or there are no more
tasks to run. Unlike Self::run
, the future may close over an
Accessor
, which provides controlled access to the Store
and its
data.
This enables a different control flow model than Self::run
in that the
future has arbitrary access to the Store
between await
operations,
whereas with run
the future has no access to the Store
. Either one
can be used to interleave await
operations and Store
access;
i.e. you can either:
- Call
run
multiple times with access to theStore
in between, possibly moving resources, streams, etc. between theStore
and the futures passed torun
.
let resource = store.data_mut().table.push(MyResource(42))?;
let call = foo.call_concurrent(&mut store, (resource,));
let (another_resource,) = instance.run(&mut store, call).await??;
let value = store.data_mut().table.delete(another_resource)?;
let call = bar.call_concurrent(&mut store, (value.0,));
instance.run(&mut store, call).await??;
- Call
run_with
once and useAccessor::with
to access the store from within the future.
instance.run_with(&mut store, move |accessor: &mut Accessor<_>| Box::pin(async move {
let (another_resource,) = accessor.with(|mut access| {
let resource = access.get().table.push(MyResource(42))?;
Ok::<_, Error>(foo.call_concurrent(access, (resource,)))
})?.await?;
accessor.with(|mut access| {
let value = access.get().table.delete(another_resource)?;
Ok::<_, Error>(bar.call_concurrent(access, (value.0,)))
})?.await
})).await??;
Sourcepub fn spawn<U: 'static>(
self,
store: impl AsContextMut<Data = U>,
task: impl AccessorTask<U, HasSelf<U>, Result<()>>,
) -> AbortHandle
Available on crate feature component-model-async
only.
pub fn spawn<U: 'static>( self, store: impl AsContextMut<Data = U>, task: impl AccessorTask<U, HasSelf<U>, Result<()>>, ) -> AbortHandle
component-model-async
only.Spawn a background task to run as part of this instance’s event loop.
The task will receive an &mut Accessor<U>
and run concurrently with
any other tasks in progress for the instance.
Note that the task will only make progress if and when the event loop for this instance is run.
The returned [SpawnHandle
] may be used to cancel the task.
Source§impl Instance
impl Instance
Sourcepub fn get_func(
&self,
store: impl AsContextMut,
name: impl InstanceExportLookup,
) -> Option<Func>
pub fn get_func( &self, store: impl AsContextMut, name: impl InstanceExportLookup, ) -> Option<Func>
Looks up an exported function by name within this Instance
.
The store
argument provided must be the store that this instance
lives within and the name
argument is the lookup key by which to find
the exported function. If the function is found then Some
is returned
and otherwise None
is returned.
The name
here can be a string such as &str
or it can be a
ComponentExportIndex
which is loaded prior from a Component
.
§Panics
Panics if store
does not own this instance.
§Examples
Looking up a function which is exported from the root of a component:
use wasmtime::{Engine, Store};
use wasmtime::component::{Component, Linker};
let engine = Engine::default();
let component = Component::new(
&engine,
r#"
(component
(core module $m
(func (export "f"))
)
(core instance $i (instantiate $m))
(func (export "f")
(canon lift (core func $i "f")))
)
"#,
)?;
// Look up the function by name
let mut store = Store::new(&engine, ());
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
let func = instance.get_func(&mut store, "f").unwrap();
// The function can also be looked up by an index via a precomputed index.
let export = component.get_export_index(None, "f").unwrap();
let func = instance.get_func(&mut store, &export).unwrap();
Looking up a function which is exported from a nested instance:
use wasmtime::{Engine, Store};
use wasmtime::component::{Component, Linker};
let engine = Engine::default();
let component = Component::new(
&engine,
r#"
(component
(core module $m
(func (export "f"))
)
(core instance $i (instantiate $m))
(func $f
(canon lift (core func $i "f")))
(instance $i
(export "f" (func $f)))
(export "i" (instance $i))
)
"#,
)?;
// First look up the exported instance, then use that to lookup the
// exported function.
let instance_index = component.get_export_index(None, "i").unwrap();
let func_index = component.get_export_index(Some(&instance_index), "f").unwrap();
// Then use `func_index` at runtime.
let mut store = Store::new(&engine, ());
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
let func = instance.get_func(&mut store, &func_index).unwrap();
// Alternatively the `instance` can be used directly in conjunction with
// the `get_export_index` method.
let instance_index = instance.get_export_index(&mut store, None, "i").unwrap();
let func_index = instance.get_export_index(&mut store, Some(&instance_index), "f").unwrap();
let func = instance.get_func(&mut store, &func_index).unwrap();
Sourcepub fn get_typed_func<Params, Results>(
&self,
store: impl AsContextMut,
name: impl InstanceExportLookup,
) -> Result<TypedFunc<Params, Results>>
pub fn get_typed_func<Params, Results>( &self, store: impl AsContextMut, name: impl InstanceExportLookup, ) -> Result<TypedFunc<Params, Results>>
Looks up an exported Func
value by name and with its type.
This function is a convenience wrapper over Instance::get_func
and
Func::typed
. For more information see the linked documentation.
Returns an error if name
isn’t a function export or if the export’s
type did not match Params
or Results
§Panics
Panics if store
does not own this instance.
Sourcepub fn get_module(
&self,
store: impl AsContextMut,
name: impl InstanceExportLookup,
) -> Option<Module>
pub fn get_module( &self, store: impl AsContextMut, name: impl InstanceExportLookup, ) -> Option<Module>
Looks up an exported module by name within this Instance
.
The store
argument provided must be the store that this instance
lives within and the name
argument is the lookup key by which to find
the exported module. If the module is found then Some
is returned
and otherwise None
is returned.
The name
here can be a string such as &str
or it can be a
ComponentExportIndex
which is loaded prior from a Component
.
For some examples see Instance::get_func
for loading values from a
component.
§Panics
Panics if store
does not own this instance.
Sourcepub fn get_resource(
&self,
store: impl AsContextMut,
name: impl InstanceExportLookup,
) -> Option<ResourceType>
pub fn get_resource( &self, store: impl AsContextMut, name: impl InstanceExportLookup, ) -> Option<ResourceType>
Looks up an exported resource type by name within this Instance
.
The store
argument provided must be the store that this instance
lives within and the name
argument is the lookup key by which to find
the exported resource. If the resource is found then Some
is returned
and otherwise None
is returned.
The name
here can be a string such as &str
or it can be a
ComponentExportIndex
which is loaded prior from a Component
.
For some examples see Instance::get_func
for loading values from a
component.
§Panics
Panics if store
does not own this instance.
Sourcepub fn get_export(
&self,
store: impl AsContextMut,
instance: Option<&ComponentExportIndex>,
name: &str,
) -> Option<(ComponentItem, ComponentExportIndex)>
pub fn get_export( &self, store: impl AsContextMut, instance: Option<&ComponentExportIndex>, name: &str, ) -> Option<(ComponentItem, ComponentExportIndex)>
A methods similar to Component::get_export
except for this
instance.
This method will lookup the name
provided within the instance
provided and return a ComponentItem
describing the export,
and ComponentExportIndex
which can be passed other get_*
functions like Instance::get_func
.
The ComponentItem
is more expensive to compute than the
ComponentExportIndex
. If you are not consuming the
ComponentItem
, use Instance::get_export_index
instead.
§Panics
Panics if store
does not own this instance.
Sourcepub fn get_export_index(
&self,
store: impl AsContextMut,
instance: Option<&ComponentExportIndex>,
name: &str,
) -> Option<ComponentExportIndex>
pub fn get_export_index( &self, store: impl AsContextMut, instance: Option<&ComponentExportIndex>, name: &str, ) -> Option<ComponentExportIndex>
A methods similar to Component::get_export_index
except for this
instance.
This method will lookup the name
provided within the instance
provided and return a ComponentExportIndex
which can be passed
other get_*
functions like Instance::get_func
.
If you need the ComponentItem
corresponding to this export, use
the Instance::get_export
instead.
§Panics
Panics if store
does not own this instance.
Sourcepub fn instance_pre<T>(&self, store: impl AsContext<Data = T>) -> InstancePre<T>
pub fn instance_pre<T>(&self, store: impl AsContext<Data = T>) -> InstancePre<T>
Returns the InstancePre
that was used to create this instance.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Instance
impl RefUnwindSafe for Instance
impl Send for Instance
impl Sync for Instance
impl Unpin for Instance
impl UnwindSafe for Instance
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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