Struct wasmtime::Store

source ·
pub struct Store<T> { /* private fields */ }
Expand description

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

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.

A Store is intended to be a short-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 the Store itself is dropped. This makes Store unsuitable for creating an unbounded number of instances in it because Store will never release this memory. It’s recommended to have a Store correspond roughly to the lifetime of a “main instance” that an embedding is interested in executing.

§Type parameter T

Each Store has a type parameter T associated with it. This T represents state defined by the host. This state will be accessible through the Caller type that host-defined functions get access to. This T is suitable for storing Store-specific information which imported functions may want access to.

The data T can be accessed through methods like Store::data and Store::data_mut.

§Stores, contexts, oh my

Most methods in Wasmtime take something of the form AsContext or AsContextMut as the first argument. These two traits allow ergonomically passing in the context you currently have to any method. The primary two sources of contexts are:

  • Store<T>
  • Caller<'_, T>

corresponding to what you create and what you have access to in a host function. You can also explicitly acquire a StoreContext or StoreContextMut and pass that around as well.

Note that all methods on Store are mirrored onto StoreContext, StoreContextMut, and Caller. This way no matter what form of context you have you can call various methods, create objects, etc.

§Stores and Default

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

Implementations§

source§

impl<T> Store<T>

source

pub fn new(engine: &Engine, data: T) -> Self

Creates a new Store to be associated with the given Engine and data provided.

The created Store will place no additional limits on the size of linear memories or tables at runtime. Linear memories and tables will be allowed to grow to any upper limit specified in their definitions. The store will limit the number of instances, linear memories, and tables created to 10,000. This can be overridden with the Store::limiter configuration method.

source

pub fn data(&self) -> &T

Access the underlying data owned by this Store.

source

pub fn data_mut(&mut self) -> &mut T

Access the underlying data owned by this Store.

source

pub fn into_data(self) -> T

Consumes this Store, destroying it, and returns the underlying data.

source

pub fn limiter( &mut self, limiter: impl FnMut(&mut T) -> &mut dyn ResourceLimiter + Send + Sync + 'static, )

Configures the ResourceLimiter used to limit resource creation within this Store.

Whenever resources such as linear memory, tables, or instances are allocated the limiter specified here is invoked with the store’s data T and the returned ResourceLimiter is used to limit the operation being allocated. The returned ResourceLimiter is intended to live within the T itself, for example by storing a StoreLimits.

Note that this limiter is only used to limit the creation/growth of resources in the future, this does not retroactively attempt to apply limits to the Store.

§Examples
use wasmtime::*;

struct MyApplicationState {
    my_state: u32,
    limits: StoreLimits,
}

let engine = Engine::default();
let my_state = MyApplicationState {
    my_state: 42,
    limits: StoreLimitsBuilder::new()
        .memory_size(1 << 20 /* 1 MB */)
        .instances(2)
        .build(),
};
let mut store = Store::new(&engine, my_state);
store.limiter(|state| &mut state.limits);

// Creation of smaller memories is allowed
Memory::new(&mut store, MemoryType::new(1, None)).unwrap();

// Creation of a larger memory, however, will exceed the 1MB limit we've
// configured
assert!(Memory::new(&mut store, MemoryType::new(1000, None)).is_err());

// The number of instances in this store is limited to 2, so the third
// instance here should fail.
let module = Module::new(&engine, "(module)").unwrap();
assert!(Instance::new(&mut store, &module, &[]).is_ok());
assert!(Instance::new(&mut store, &module, &[]).is_ok());
assert!(Instance::new(&mut store, &module, &[]).is_err());
source

pub fn call_hook( &mut self, hook: impl FnMut(&mut T, CallHook) -> Result<()> + Send + Sync + 'static, )

Configure a function that runs on calls and returns between WebAssembly and host code.

The function is passed a CallHook argument, which indicates which state transition the VM is making.

This function may return a Trap. If a trap is returned when an import was called, it is immediately raised as-if the host import had returned the trap. If a trap is returned after wasm returns to the host then the wasm function’s result is ignored and this trap is returned instead.

After this function returns a trap, it may be called for subsequent returns to host or wasm code as the trap propagates to the root call.

source

pub fn engine(&self) -> &Engine

Returns the Engine that this store is associated with.

source

pub fn gc(&mut self)

Perform garbage collection of ExternRefs.

Note that it is not required to actively call this function. GC will automatically happen when internal buffers fill up. This is provided if fine-grained control over the GC is desired.

source

pub fn fuel_consumed(&self) -> Option<u64>

Returns the amount of fuel consumed by this store’s execution so far.

If fuel consumption is not enabled via Config::consume_fuel then this function will return None. Also note that fuel, if enabled, must be originally configured via Store::add_fuel.

source

pub fn add_fuel(&mut self, fuel: u64) -> Result<()>

Adds fuel to this Store for wasm to consume while executing.

For this method to work fuel consumption must be enabled via Config::consume_fuel. By default a Store starts with 0 fuel for wasm to execute with (meaning it will immediately trap). This function must be called for the store to have some fuel to allow WebAssembly to execute.

Most WebAssembly instructions consume 1 unit of fuel. Some instructions, such as nop, drop, block, and loop, consume 0 units, as any execution cost associated with them involves other instructions which do consume fuel.

Note that at this time when fuel is entirely consumed it will cause wasm to trap. More usages of fuel are planned for the future.

§Errors

This function will return an error if fuel consumption is not enabled via Config::consume_fuel.

source

pub fn consume_fuel(&mut self, fuel: u64) -> Result<u64>

Synthetically consumes fuel from this Store.

For this method to work fuel consumption must be enabled via Config::consume_fuel.

WebAssembly execution will automatically consume fuel but if so desired the embedder can also consume fuel manually to account for relative costs of host functions, for example.

This function will attempt to consume fuel units of fuel from within this store. If the remaining amount of fuel allows this then Ok(N) is returned where N is the amount of remaining fuel. Otherwise an error is returned and no fuel is consumed.

§Errors

This function will return an error either if fuel consumption is not enabled via Config::consume_fuel or if fuel exceeds the amount of remaining fuel within this store.

source

pub fn out_of_fuel_trap(&mut self)

Configures a Store to generate a Trap whenever it runs out of fuel.

When a Store is configured to consume fuel with Config::consume_fuel this method will configure what happens when fuel runs out. Specifically a WebAssembly trap will be raised and the current execution of WebAssembly will be aborted.

This is the default behavior for running out of fuel.

source

pub fn out_of_fuel_async_yield( &mut self, injection_count: u64, fuel_to_inject: u64, )

Configures a Store to yield execution of async WebAssembly code periodically.

When a Store is configured to consume fuel with Config::consume_fuel this method will configure what happens when fuel runs out. Specifically executing WebAssembly will be suspended and control will be yielded back to the caller. This is only suitable with use of a store associated with an async config because only then are futures used and yields are possible.

The purpose of this behavior is to ensure that futures which represent execution of WebAssembly do not execute too long inside their Future::poll method. This allows for some form of cooperative multitasking where WebAssembly will voluntarily yield control periodically (based on fuel consumption) back to the running thread.

Note that futures returned by this crate will automatically flag themselves to get re-polled if a yield happens. This means that WebAssembly will continue to execute, just after giving the host an opportunity to do something else.

The fuel_to_inject parameter indicates how much fuel should be automatically re-injected after fuel runs out. This is how much fuel will be consumed between yields of an async future.

The injection_count parameter indicates how many times this fuel will be injected. Multiplying the two parameters is the total amount of fuel this store is allowed before wasm traps.

§Panics

This method will panic if it is not called on a store associated with an async config.

source

pub fn set_epoch_deadline(&mut self, ticks_beyond_current: u64)

Sets the epoch deadline to a certain number of ticks in the future.

When the Wasm guest code is compiled with epoch-interruption instrumentation (Config::epoch_interruption()), and when the Engine’s epoch is incremented (Engine::increment_epoch()) past a deadline, execution can be configured to either trap or yield and then continue.

This deadline is always set relative to the current epoch: delta_beyond_current ticks in the future. The deadline can be set explicitly via this method, or refilled automatically on a yield if configured via epoch_deadline_async_yield_and_update(). After this method is invoked, the deadline is reached when Engine::increment_epoch() has been invoked at least ticks_beyond_current times.

By default a store will trap immediately with an epoch deadline of 0 (which has always “elapsed”). This method is required to be configured for stores with epochs enabled to some future epoch deadline.

See documentation on Config::epoch_interruption() for an introduction to epoch-based interruption.

source

pub fn epoch_deadline_trap(&mut self)

Configures epoch-deadline expiration to trap.

When epoch-interruption-instrumented code is executed on this store and the epoch deadline is reached before completion, with the store configured in this way, execution will terminate with a trap as soon as an epoch check in the instrumented code is reached.

This behavior is the default if the store is not otherwise configured via epoch_deadline_trap(), epoch_deadline_callback() or epoch_deadline_async_yield_and_update().

This setting is intended to allow for coarse-grained interruption, but not a deterministic deadline of a fixed, finite interval. For deterministic interruption, see the “fuel” mechanism instead.

Note that when this is used it’s required to call Store::set_epoch_deadline or otherwise wasm will always immediately trap.

See documentation on Config::epoch_interruption() for an introduction to epoch-based interruption.

source

pub fn epoch_deadline_callback( &mut self, callback: impl FnMut(StoreContextMut<'_, T>) -> Result<u64> + Send + Sync + 'static, )

Configures epoch-deadline expiration to invoke a custom callback function.

When epoch-interruption-instrumented code is executed on this store and the epoch deadline is reached before completion, the provided callback function is invoked.

This function should return a positive delta, which is used to update the new epoch, setting it to the current epoch plus delta ticks. Alternatively, the callback may return an error, which will terminate execution.

This setting is intended to allow for coarse-grained interruption, but not a deterministic deadline of a fixed, finite interval. For deterministic interruption, see the “fuel” mechanism instead.

See documentation on Config::epoch_interruption() for an introduction to epoch-based interruption.

Trait Implementations§

source§

impl<T> AsContext for Store<T>

§

type Data = T

The host information associated with the Store, aka the T in Store<T>.
source§

fn as_context(&self) -> StoreContext<'_, T>

Returns the store context that this type provides access to.
source§

impl<T> AsContextMut for Store<T>

source§

fn as_context_mut(&mut self) -> StoreContextMut<'_, T>

Returns the store context that this type provides access to.
source§

impl<T: Debug> Debug for Store<T>

source§

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

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

impl<T: Default> Default for Store<T>

source§

fn default() -> Store<T>

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

impl<T> Drop for Store<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T> StoreExt for Store<T>

source§

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

The signal handler must be async-signal-safe.

Auto Trait Implementations§

§

impl<T> Freeze for Store<T>

§

impl<T> !RefUnwindSafe for Store<T>

§

impl<T> Send for Store<T>
where T: Send,

§

impl<T> Sync for Store<T>
where T: Sync,

§

impl<T> Unpin for Store<T>

§

impl<T> !UnwindSafe for Store<T>

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

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

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.