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).
§Cross-store usage of items
In wasmtime wasm items such as Global and Memory “belong” to a
Store. The store they belong to is the one they were created with
(passed in as a parameter) or instantiated with. This store is the only
store that can be used to interact with wasm items after they’re created.
The wasmtime crate will panic if the Store argument passed in to these
operations is incorrect. In other words it’s considered a programmer error
rather than a recoverable error for the wrong Store to be used when
calling APIs.
Implementations§
Source§impl<T> Store<T>
impl<T> Store<T>
Sourcepub fn new(engine: &Engine, data: T) -> Self
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.
Sourcepub fn into_data(self) -> T
pub fn into_data(self) -> T
Consumes this Store, destroying it, and returns the underlying data.
Sourcepub fn limiter(
&mut self,
limiter: impl FnMut(&mut T) -> &mut dyn ResourceLimiter + Send + Sync + 'static,
)
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());Sourcepub fn get_fuel(&self) -> Result<u64>
pub fn get_fuel(&self) -> Result<u64>
Returns the amount fuel in this Store. When fuel is enabled, it must
be configured via Store::set_fuel.
§Errors
This function will return an error if fuel consumption is not enabled
via Config::consume_fuel.
Sourcepub fn set_fuel(&mut self, fuel: u64) -> Result<()>
pub fn set_fuel(&mut self, fuel: u64) -> Result<()>
Set the 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 when fuel is entirely consumed it will cause wasm to trap.
§Errors
This function will return an error if fuel consumption is not enabled via
Config::consume_fuel.
Sourcepub fn fuel_async_yield_interval(&mut self, interval: Option<u64>) -> Result<()>
pub fn fuel_async_yield_interval(&mut self, interval: Option<u64>) -> Result<()>
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 WebAssembly to be suspended and control will be yielded back to the
caller every interval units of fuel consumed. 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 interval parameter indicates how much fuel should be
consumed between yields of an async future. When fuel runs out wasm will trap.
§Error
This method will error if it is not called on a store associated with an async config.
Sourcepub fn set_epoch_deadline(&mut self, ticks_beyond_current: u64)
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:
ticks_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.
Sourcepub fn epoch_deadline_trap(&mut self)
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.
Sourcepub fn epoch_deadline_callback(
&mut self,
callback: impl FnMut(StoreContextMut<'_, T>) -> Result<UpdateDeadline> + Send + Sync + 'static,
)
pub fn epoch_deadline_callback( &mut self, callback: impl FnMut(StoreContextMut<'_, T>) -> Result<UpdateDeadline> + 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 callback should either return an UpdateDeadline, or
return an error, which will terminate execution with a trap.
The UpdateDeadline is a positive number of ticks to
add to the epoch deadline, as well as indicating what
to do after the callback returns. If the Store is
configured with async support, then the callback may return
[UpdateDeadline::Yield] to yield to the async executor before
updating the epoch deadline. Alternatively, the callback may
return UpdateDeadline::Continue to update the epoch deadline
immediately.
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>
impl<T> AsContext for Store<T>
Source§fn as_context(&self) -> StoreContext<'_, T>
fn as_context(&self) -> StoreContext<'_, T>
Source§impl<T> AsContextMut for Store<T>
impl<T> AsContextMut for Store<T>
Source§fn as_context_mut(&mut self) -> StoreContextMut<'_, T>
fn as_context_mut(&mut self) -> StoreContextMut<'_, T>
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> 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> 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