Struct Store

Source
pub struct Store { /* private fields */ }
Expand description

A Store is a collection of WebAssembly instances and host-defined items.

All WebAssembly instances and items will be attached to and refer to a Store. For example instances, functions, globals, and tables are all attached to a Store. Instances are created by instantiating a Module within a Store.

Store is not thread-safe and cannot be sent to other threads. All items which refer to a Store additionally are not threadsafe and can only be used on the original thread that they were created on.

A Store is not intended to be a long-lived object in a program. No form of GC is implemented at this time so once an instance is created within a Store it will not be deallocated until all references to the Store have gone away (this includes all references to items in the store). This makes Store unsuitable for creating an unbounded number of instances in it because Store will never release this memory. It’s instead recommended to have a long-lived Engine and instead create a Store for a more scoped portion of your application.

§Stores and Clone

Using clone on a Store is a cheap operation. It will not create an entirely new store, but rather just a new reference to the existing object. In other words it’s a shallow copy, not a deep copy.

§Stores and Default

You can create a store with default configuration settings using Store::default(). This will create a brand new Engine with default ocnfiguration (see Config for more information).

Implementations§

Source§

impl Store

Source

pub fn new(engine: &Engine) -> Store

Creates a new store to be associated with the given Engine.

Source

pub fn engine(&self) -> &Engine

Returns the Engine that this store is associated with.

Source

pub fn same(a: &Store, b: &Store) -> bool

Returns whether the stores a and b refer to the same underlying Store.

Because the Store type is reference counted multiple clones may point to the same underlying storage, and this method can be used to determine whether two stores are indeed the same.

Source

pub fn interrupt_handle(&self) -> Result<InterruptHandle>

Creates an InterruptHandle which can be used to interrupt the execution of instances within this Store.

An InterruptHandle handle is a mechanism of ensuring that guest code doesn’t execute for too long. For example it’s used to prevent wasm programs for executing infinitely in infinite loops or recursive call chains.

The InterruptHandle type is sendable to other threads so you can interact with it even while the thread with this Store is executing wasm code.

There’s one method on an interrupt handle: InterruptHandle::interrupt. This method is used to generate an interrupt and cause wasm code to exit “soon”.

§When are interrupts delivered?

The term “interrupt” here refers to one of two different behaviors that are interrupted in wasm:

  • The head of every loop in wasm has a check to see if it’s interrupted.
  • The prologue of every function has a check to see if it’s interrupted.

This interrupt mechanism makes no attempt to signal interrupts to native code. For example if a host function is blocked, then sending an interrupt will not interrupt that operation.

Interrupts are consumed as soon as possible when wasm itself starts executing. This means that if you interrupt wasm code then it basically guarantees that the next time wasm is executing on the target thread it will return quickly (either normally if it were already in the process of returning or with a trap from the interrupt). Once an interrupt trap is generated then an interrupt is consumed, and further execution will not be interrupted (unless another interrupt is set).

When implementing interrupts you’ll want to ensure that the delivery of interrupts into wasm code is also handled in your host imports and functionality. Host functions need to either execute for bounded amounts of time or you’ll need to arrange for them to be interrupted as well.

§Return Value

This function returns a Result since interrupts are not always enabled. Interrupts are enabled via the Config::interruptable method, and if this store’s Config hasn’t been configured to enable interrupts then an error is returned.

§Examples
// Enable interruptable code via `Config` and then create an interrupt
// handle which we'll use later to interrupt running code.
let engine = Engine::new(Config::new().interruptable(true));
let store = Store::new(&engine);
let interrupt_handle = store.interrupt_handle()?;

// Compile and instantiate a small example with an infinite loop.
let module = Module::new(&engine, r#"
    (func (export "run") (loop br 0))
"#)?;
let instance = Instance::new(&store, &module, &[])?;
let run = instance
    .get_func("run")
    .ok_or(anyhow::format_err!("failed to find `run` function export"))?
    .get0::<()>()?;

// Spin up a thread to send us an interrupt in a second
std::thread::spawn(move || {
    std::thread::sleep(std::time::Duration::from_secs(1));
    interrupt_handle.interrupt();
});

let trap = run().unwrap_err();
assert!(trap.to_string().contains("wasm trap: interrupt"));
Source

pub fn gc(&self)

Perform garbage collection of ExternRefs.

Trait Implementations§

Source§

impl Clone for Store

Source§

fn clone(&self) -> Store

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 Store

Source§

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

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

impl Default for Store

Source§

fn default() -> Store

Returns the “default value” for a type. Read more
Source§

impl StoreExt for Store

Source§

unsafe fn set_signal_handler<H>(&self, handler: H)
where H: 'static + Fn(c_int, *const siginfo_t, *const c_void) -> bool,

The signal handler must be async-signal-safe.

Auto Trait Implementations§

§

impl Freeze for Store

§

impl !RefUnwindSafe for Store

§

impl !Send for Store

§

impl !Sync for Store

§

impl Unpin for Store

§

impl !UnwindSafe for Store

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

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.