Struct Instance

Source
pub struct Instance { /* private fields */ }
Available on crate features 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

Source

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

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.

Source

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

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

Source

pub async fn run<F>( &self, store: impl AsContextMut, fut: F, ) -> Result<F::Output>
where F: Future,

Available on crate feature 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 Futures which depend (directly or indirectly) on previously-started concurrent tasks: e.g. the Futures returned by TypedFunc::call_concurrent, StreamReader::read, etc., or Futures derived from those.

Such Futures 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. Futures 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 Futures 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.

Source

pub async fn run_with<U, V, F>( &self, store: impl AsContextMut<Data = U>, fun: F, ) -> Result<V>
where U: 'static, F: FnOnce(&mut Accessor<U>) -> Pin<Box<dyn Future<Output = V> + Send + '_>> + Send + 'static,

Available on crate feature 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 the Store in between, possibly moving resources, streams, etc. between the Store and the futures passed to run.
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 use Accessor::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??;
Source

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

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

Source

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();
Source

pub fn get_typed_func<Params, Results>( &self, store: impl AsContextMut, name: impl InstanceExportLookup, ) -> Result<TypedFunc<Params, Results>>
where Params: ComponentNamedList + Lower, Results: ComponentNamedList + Lift,

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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§

Source§

impl Clone for Instance

Source§

fn clone(&self) -> Instance

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Instance

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Copy for Instance

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.