pub struct MultiUseSandbox { /* private fields */ }Expand description
A fully initialized sandbox that can execute guest functions multiple times.
Guest functions can be called repeatedly while maintaining state between calls.
Post-Stage-F: the upstream snapshot() / restore() / map_file_cow()
rollback machinery is gone along with the CoW PT marking that backed it.
If a guest call fails for any reason, drop the sandbox and build a new
one — that’s the only recovery path now (and the one nub already used).
Implementations§
Source§impl MultiUseSandbox
impl MultiUseSandbox
Sourcepub fn call_raw(&mut self, fn_id: u32, payload: &[u8]) -> Result<Vec<u8>>
pub fn call_raw(&mut self, fn_id: u32, payload: &[u8]) -> Result<Vec<u8>>
Call a guest function by fn_id with a raw byte payload.
Returns the response payload bytes on success.
Wire format: the host serialises a
[nub_host_common::rpc::Request] (rkyv) carrying fn_id and
payload, ships it via the input data ring, the guest decodes
- dispatches + writes a
Responseto the output ring, and we read + checkstatusbefore returning the inner payload.
Changes made to the sandbox during execution are persisted. On failure the sandbox should be dropped and rebuilt.
Sourcepub fn put_cap(&mut self, cap: &Cap) -> Result<AbiCapHash>
pub fn put_cap(&mut self, cap: &Cap) -> Result<AbiCapHash>
Publish a Cap into the guest’s heap-resident cap
directory via the [FN_ID_NUB_PUT_CAP] RPC.
Encodes cap as a WireCap (see javm-cap’s wire
module), ships it via Self::call_raw, and reads back the
guest-computed CapHash. On the guest side, the cap is
inserted into the
nub_arch_x86::state_cache::DIRECTORY map, keyed by hash.
Caps that can’t be represented on the wire (e.g.
DataContent::Paged, CNode with Ref-typed slots, etc.)
fail at the wire conversion step with a typed error.
Encode/decode failures are surfaced as
HyperlightError::Error. A sentinel response (all-0xFF
hash) from the guest is also turned into an error.
Sourcepub fn put_cap_with_hash(&mut self, hash: AbiCapHash, cap: &Cap) -> Result<()>
pub fn put_cap_with_hash(&mut self, hash: AbiCapHash, cap: &Cap) -> Result<()>
Pre-hashed put: idempotent fast path that short-circuits the
full Self::put_cap RPC when the guest’s directory already
holds hash.
Behaviour:
- If
GuestCacheReader::contains(hash)returnstrue, return immediately — the guest already has the cap and we skip rkyv encode + VMEXIT + guest decode + merkle walk + directory insert. This is the hot path for bench loops that re-publish the same cap graph every iteration. - Otherwise, ship
put_cap(cap), then debug-assert the returned hash matcheshash.
The reader is built lazily on first call (one nub_get_boot_info
RPC to read BootInfo.directory_va, then a single struct
construction); subsequent calls hit the cached reader.
Sourcepub fn interrupt_handle(&self) -> Arc<dyn InterruptHandle>
pub fn interrupt_handle(&self) -> Arc<dyn InterruptHandle>
Returns a handle for interrupting guest execution.
Trait Implementations§
Source§impl Debug for MultiUseSandbox
impl Debug for MultiUseSandbox
Source§impl Registerable for MultiUseSandbox
Allow registering host functions on an already-evolved
crate::MultiUseSandbox.
impl Registerable for MultiUseSandbox
Allow registering host functions on an already-evolved
crate::MultiUseSandbox.
The primary entry point for host-function registration is the
UninitializedSandbox impl above — that’s the lifecycle phase
where the guest hasn’t yet been allowed to issue host calls.
There are, however, cases where a MultiUseSandbox is obtained
without traversing the Uninitialized → evolve() path:
- Sandboxes loaded from a persisted snapshot.
- Any future API that yields a
MultiUseSandboxdirectly.
In those cases the caller never had a chance to call
register_host_function on an UninitializedSandbox, so we
expose the same trait implementation here for late registration.
The guest’s dispatcher resolves by fn_id at call time, so
inserting into the registry after evolve() is semantically safe
as long as the first host-function invocation happens after
registration completes.