#[repr(C, align(4096))]pub struct Instance { /* private fields */ }
Expand description
A Lucet program, together with its dedicated memory and signal handlers.
This is the primary interface for running programs, examining return values, and accessing the WebAssembly heap.
Instance
s are never created by runtime users directly, but rather are acquired from
Region
s and often accessed through
InstanceHandle
smart pointers. This guarantees that instances
and their fields are never moved in memory, otherwise raw pointers in the metadata could be
unsafely invalidated.
An instance occupies one 4096-byte page in memory, with a layout like:
0xXXXXX000:
Instance {
.magic
.embed_ctx
... etc ...
}
// unused space
InstanceInternals {
.globals
.instruction_counter
} // last address *inside* `InstanceInternals` is 0xXXXXXFFF
0xXXXXY000: // start of next page, VMContext points here
Heap {
..
}
This layout allows modules to tightly couple to a handful of fields related to the instance,
rather than possibly requiring compiler-side changes (and recompiles) whenever Instance
changes.
It also obligates Instance
to be immediately followed by the heap, but otherwise leaves the
locations of the stack, globals, and any other data, to be implementation-defined by the
Region
that actually creates Slot
s onto which Instance
are mapped.
For information about the layout of all instance-related memory, see the documentation of
MmapRegion.
Implementations§
Source§impl Instance
impl Instance
Sourcepub fn run(
&mut self,
entrypoint: &str,
args: &[Val],
) -> Result<RunResult, Error>
pub fn run( &mut self, entrypoint: &str, args: &[Val], ) -> Result<RunResult, Error>
Run a function with arguments in the guest context at the given entrypoint.
// regular execution yields `Ok(UntypedRetVal)`
let retval = instance.run("factorial", &[5u64.into()]).unwrap().unwrap_returned();
assert_eq!(u64::from(retval), 120u64);
// runtime faults yield `Err(Error)`
let result = instance.run("faulting_function", &[]);
assert!(result.is_err());
§Safety
This is unsafe in two ways:
-
The type of the entrypoint might not be correct. It might take a different number or different types of arguments than are provided to
args
. It might not even point to a function! We will likely add type information tolucetc
output so we can dynamically check the type in the future. -
The entrypoint is foreign code. While we may be convinced that WebAssembly compiled to native code by
lucetc
is safe, we do not have the same guarantee for the hostcalls that a guest may invoke. They might be implemented in an unsafe language, so we must treat this call as unsafe, just like any other FFI call.
For the moment, we do not mark this as unsafe
in the Rust type system, but that may change
in the future.
Sourcepub fn run_func_idx(
&mut self,
table_idx: u32,
func_idx: u32,
args: &[Val],
) -> Result<RunResult, Error>
pub fn run_func_idx( &mut self, table_idx: u32, func_idx: u32, args: &[Val], ) -> Result<RunResult, Error>
Run a function with arguments in the guest context from the WebAssembly function table.
§Safety
The same safety caveats of Instance::run()
apply.
Sourcepub fn resume(&mut self) -> Result<RunResult, Error>
pub fn resume(&mut self) -> Result<RunResult, Error>
Resume execution of an instance that has yielded without providing a value to the guest.
This should only be used when the guest yielded with
Vmctx::yield_()
or
Vmctx::yield_val()
. Otherwise, this call will
fail with Error::InvalidArgument
.
§Safety
The foreign code safety caveat of Instance::run()
applies.
Sourcepub fn resume_with_val<A: Any + 'static>(
&mut self,
val: A,
) -> Result<RunResult, Error>
pub fn resume_with_val<A: Any + 'static>( &mut self, val: A, ) -> Result<RunResult, Error>
Resume execution of an instance that has yielded, providing a value to the guest.
The type of the provided value must match the type expected by
Vmctx::yield_expecting_val()
or
Vmctx::yield_val_expecting_val()
.
The provided value will be dynamically typechecked against the type the guest expects to
receive, and if that check fails, this call will fail with Error::InvalidArgument
.
§Safety
The foreign code safety caveat of Instance::run()
applies.
Sourcepub fn reset(&mut self) -> Result<(), Error>
pub fn reset(&mut self) -> Result<(), Error>
Reset the instance’s heap and global variables to their initial state.
The WebAssembly start
section will also be run, if one exists.
The embedder contexts present at instance creation or added with
Instance::insert_embed_ctx()
are not
modified by this call; it is the embedder’s responsibility to clear or reset their state if
necessary.
§Safety
This function runs the guest code for the WebAssembly start
section, and running any guest
code is potentially unsafe; see Instance::run()
.
Sourcepub fn grow_memory(&mut self, additional_pages: u32) -> Result<u32, Error>
pub fn grow_memory(&mut self, additional_pages: u32) -> Result<u32, Error>
Grow the guest memory by the given number of WebAssembly pages.
On success, returns the number of pages that existed before the call.
Sourcepub fn heap_mut(&mut self) -> &mut [u8] ⓘ
pub fn heap_mut(&mut self) -> &mut [u8] ⓘ
Return the WebAssembly heap as a mutable slice of bytes.
Sourcepub fn heap_u32_mut(&mut self) -> &mut [u32]
pub fn heap_u32_mut(&mut self) -> &mut [u32]
Return the WebAssembly heap as a mutable slice of u32
s.
Sourcepub fn globals(&self) -> &[GlobalValue]
pub fn globals(&self) -> &[GlobalValue]
Return the WebAssembly globals as a slice of i64
s.
Sourcepub fn globals_mut(&mut self) -> &mut [GlobalValue]
pub fn globals_mut(&mut self) -> &mut [GlobalValue]
Return the WebAssembly globals as a mutable slice of i64
s.
Sourcepub fn check_heap<T>(&self, ptr: *const T, len: usize) -> bool
pub fn check_heap<T>(&self, ptr: *const T, len: usize) -> bool
Check whether a given range in the host address space overlaps with the memory that backs the instance heap.
Sourcepub fn contains_embed_ctx<T: Any>(&self) -> bool
pub fn contains_embed_ctx<T: Any>(&self) -> bool
Check whether a context value of a particular type exists.
Sourcepub fn get_embed_ctx<T: Any>(&self) -> Option<Result<Ref<'_, T>, BorrowError>>
pub fn get_embed_ctx<T: Any>(&self) -> Option<Result<Ref<'_, T>, BorrowError>>
Get a reference to a context value of a particular type, if it exists.
Sourcepub fn get_embed_ctx_mut<T: Any>(
&self,
) -> Option<Result<RefMut<'_, T>, BorrowMutError>>
pub fn get_embed_ctx_mut<T: Any>( &self, ) -> Option<Result<RefMut<'_, T>, BorrowMutError>>
Get a mutable reference to a context value of a particular type, if it exists.
Sourcepub fn insert_embed_ctx<T: Any>(&mut self, x: T) -> Option<T>
pub fn insert_embed_ctx<T: Any>(&mut self, x: T) -> Option<T>
Insert a context value.
If a context value of the same type already existed, it is returned.
Note: this method is intended for embedder contexts that need to be added after an
instance is created and initialized. To add a context for an instance’s entire lifetime,
including the execution of its start
section, see
Region::new_instance_builder()
.
Sourcepub fn remove_embed_ctx<T: Any>(&mut self) -> Option<T>
pub fn remove_embed_ctx<T: Any>(&mut self) -> Option<T>
Remove a context value of a particular type, returning it if it exists.
Sourcepub fn set_signal_handler<H>(&mut self, handler: H)
pub fn set_signal_handler<H>(&mut self, handler: H)
Set the handler run when SIGBUS
, SIGFPE
, SIGILL
, or SIGSEGV
are caught by the
instance thread.
In most cases, these signals are unrecoverable for the instance that raised them, but do not affect the rest of the process.
The default signal handler returns
SignalBehavior::Default
, which yields a
runtime fault error.
The signal handler must be signal-safe.
Sourcepub fn set_fatal_handler(&mut self, handler: fn(&Instance) -> !)
pub fn set_fatal_handler(&mut self, handler: fn(&Instance) -> !)
Set the handler run for signals that do not arise from a known WebAssembly trap, or that involve memory outside of the current instance.
Fatal signals are not only unrecoverable for the instance that raised them, but may compromise the correctness of the rest of the process if unhandled.
The default fatal handler calls panic!()
.
Sourcepub fn set_c_fatal_handler(
&mut self,
handler: unsafe extern "C" fn(*mut Instance),
)
pub fn set_c_fatal_handler( &mut self, handler: unsafe extern "C" fn(*mut Instance), )
Set the fatal handler to a C-compatible function.
This is a separate interface, because C functions can’t return the !
type. Like the
regular fatal_handler
, it is not expected to return, but we cannot enforce that through
types.
When a fatal error occurs, this handler is run first, and then the regular fatal_handler
runs in case it returns.
pub fn kill_switch(&self) -> KillSwitch
pub fn is_ready(&self) -> bool
pub fn is_yielded(&self) -> bool
pub fn is_faulted(&self) -> bool
pub fn is_terminated(&self) -> bool
pub fn get_instruction_count(&self) -> Option<u64>
pub fn set_instruction_count(&mut self, instruction_count: u64)
Trait Implementations§
Source§impl Drop for Instance
Users of Instance
must be very careful about when instances are dropped!
impl Drop for Instance
Users of Instance
must be very careful about when instances are dropped!
Typically you will not have to worry about this, as InstanceHandle will robustly handle Instance drop semantics. If an instance is dropped, and the Region it’s in has already dropped, it may contain the last reference counted pointer to its Region. If so, when Instance’s destructor runs, Region will be dropped, and may free or otherwise invalidate the memory that this Instance exists in, while the Instance destructor is executing.
Source§impl InstanceInternal for Instance
impl InstanceInternal for Instance
Source§fn valid_magic(&self) -> bool
fn valid_magic(&self) -> bool
Check whether the instance magic is valid.