Skip to main content

PooledVm

Struct PooledVm 

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

RAII handle to a pooled VM. Derefs to fusevm::VM; returns the VM to the pool on drop.

Methods from Deref<Target = VM>§

Source

pub fn set_numeric_hook( &mut self, hook: Arc<dyn Fn(NumOp, &Value, &Value) -> Result<Value, String> + Sync + Send>, )

Install a NumericHook, switching this VM to strict numeric mode: arithmetic that cannot be computed exactly in i64/f64 — a non-numeric operand, or integer overflow — is handed to hook instead of being coerced or wrapped.

Strict mode also constrains the JIT, which otherwise coerces and wraps in native code exactly like the default interpreter: the block tier is skipped whenever a live slot holds a non-numeric value, and JIT-compiled integer Add/Sub/Mul are emitted with overflow checks that bail back to the interpreter (where the hook runs). Native code compiled in strict mode is cached separately from the coercing kind, so the two never mix.

Source

pub fn is_strict_numeric(&self) -> bool

Whether a NumericHook is installed (strict numeric mode).

Source

pub fn set_fixnum_range(&mut self, lo: i64, hi: i64)

Narrow the range the VM keeps as a native Value::Int (strict mode only).

A Lisp whose integers are tagged has fewer than 64 bits for a fixnum — Emacs gets 62, so most-positive-fixnum is 2^61-1 — and an arithmetic result outside that range is a bignum, even though it still fits an i64. Setting the range makes strict mode delegate those results to the NumericHook alongside true i64 overflow, so the host can widen them. JIT-compiled code carries the same bounds check (two ALU ops folded into the overflow accumulator — still no branch on the hot path).

Without this, the host would see only i64 overflow and integers in the 2^61..2^63 band would masquerade as fixnums.

Source

pub fn enable_tracing_jit(&mut self)

Enable the tracing JIT for this VM. After this call, hot loops (loops crossing the backedge threshold) will be recorded and JIT- compiled at runtime; subsequent iterations dispatch through the compiled trace.

Phase 1 limits: only int-slot loops with a single backward branch and no internal jumps are traceable. Loops outside that envelope continue to run in the interpreter.

Source

pub fn disable_tracing_jit(&mut self)

Disable the tracing JIT. Existing compiled traces remain in the thread-local cache but are no longer consulted from this VM.

Source

pub fn reset(&mut self, chunk: Chunk)

Reset the VM for re-use with a new chunk, preserving internal Vec allocations to avoid the construction cost of VM::new.

State that’s cleared:

  • Value stack (truncated, capacity preserved)
  • Frame stack (rebuilt with one entry pointing at the new chunk)
  • Globals (resized to match the new chunk’s name pool)
  • Instruction pointer, halted flag, exit status
  • Tracing JIT recorder / slot buffers / deopt info
  • Cached block-JIT eligibility (the new chunk has a different hash)

State that’s preserved:

  • Tracing JIT enabled flag
  • Extension handlers (ext_handler, ext_wide_handler)
  • Builtin table
  • Shell host

This pairs with VMPool for hot-path callers that run many chunks back-to-back and want to skip the per-call allocation cost of VM::new.

Source

pub fn set_shell_host(&mut self, host: Box<dyn ShellHost>)

Register the frontend shell host. Replaces any prior host.

Source

pub fn set_awk_host(&mut self, host: Box<dyn AwkHost>)

Register the frontend AWK host. Replaces any prior host. The VM then routes the reserved AWK op range to it (see crate::awk_host::AwkHost).

Source

pub fn awk_signal(&self) -> Option<u8>

AWK control-flow signal raised by the most recent run(), if any. An awk frontend reads this after run() returns to map Op::AwkSignal codes (awk_builtins::signal::{NEXT,NEXTFILE,EXIT}) onto its own record/file/exit control flow. None when no signal was raised (always the case for zshrs/stryke, which never emit Op::AwkSignal).

Source

pub fn set_extension_handler( &mut self, handler: Box<dyn FnMut(&mut VM, u16, u8) + Send>, )

Register a handler for Op::Extended(id, arg) opcodes.

Source

pub fn set_extension_wide_handler( &mut self, handler: Box<dyn FnMut(&mut VM, u16, usize) + Send>, )

Register a handler for Op::ExtendedWide(id, payload) opcodes.

Source

pub fn register_builtin(&mut self, id: u16, handler: fn(&mut VM, u8) -> Value)

Register a builtin function by ID. CallBuiltin(id, argc) dispatches directly through the function pointer — no name lookup at runtime.

Source

pub fn run_builtin_by_name( &mut self, name: &str, args: &[String], ) -> Option<Value>

Run a shell builtin by name at run time — the runtime analog of the compile-time Op::CallBuiltin opcode. The compiler resolves a literal command name to a builtin id and emits CallBuiltin, so builtins only dispatch for names known at compile time. A host that resolves a name only at run time — builtin NAME, $var command indirection, eval of a computed name — needs this to reach the same builtins.

Resolves name via crate::shell_builtins::builtin_id, pushes args as string values in argument order (identical to what the compiler emits ahead of CallBuiltin, which the handler’s arg-pop reverses back), then invokes the registered handler and returns its status value. Returns None when name is not a known builtin or has no registered handler, so the caller falls through to function / external lookup.

Source

pub fn request_halt(&mut self)

Externally request the VM to halt after the current op finishes. Used by host-side shell semantics like set -e post-command checks and exit from inside builtins to stop dispatch at a safe point.

Source

pub fn push(&mut self, val: Value)

Push val onto the value stack. Inlined for hot-path callers (extension handlers, builtin shims) that bypass the dispatch loop’s own push.

Source

pub fn pop(&mut self) -> Value

Pop the top of the value stack, returning Value::Undef if the stack is empty. Returning Undef rather than panicking matches Perl’s “underflow is undef” semantic and lets extension/builtin handlers stay panic-free under malformed bytecode.

Source

pub fn peek(&self) -> &Value

Borrow the top of the value stack without popping. Returns a reference to Value::Undef when the stack is empty.

Source

pub fn run(&mut self) -> VMResult

Execute the loaded chunk until completion or error.

Phase 10: tiered auto-dispatch. When tracing_jit is enabled the VM consults all three Cranelift tiers in priority order:

  1. Block JIT — if the entire chunk is block-eligible, the block-JIT cache returns Some(result) after its own warmup threshold and the whole chunk runs in native code with zero interpreter dispatch.
  2. Tracing JIT — when block JIT doesn’t apply, the dispatch loop runs with the recorder armed at backward branches; hot loops compile to traces that take over subsequent iterations.
  3. Interpreter — fallback for cold code and chunks neither tier handles.

Block JIT is tried first because, when it applies, it has zero VM-side overhead (direct fn-ptr through the slot pointer). For chunks block JIT can’t take, control falls through to the interpreter with tracing JIT integrated. The two tiers don’t compete on the same chunk: block-eligible chunks short-circuit before tracing JIT records anything.

Source

pub fn get_slot(&self, slot: u16) -> Value

Read a slot from the current (top) call frame.

Returns Value::Undef when there is no active frame or the slot index is out of range. Public so frontend extension handlers (set_extension_handler) can read slot operands without reaching into frames directly.

Source

pub fn set_slot(&mut self, slot: u16, val: Value)

Write a slot in the current (top) call frame, growing the frame’s slot vector as needed. No-op when there is no active frame.

Public so frontend extension handlers can write slot results back without reaching into frames directly.

Trait Implementations§

Source§

impl Deref for PooledVm

Source§

type Target = VM

The resulting type after dereferencing.
Source§

fn deref(&self) -> &VM

Dereferences the value.
Source§

impl DerefMut for PooledVm

Source§

fn deref_mut(&mut self) -> &mut VM

Mutably dereferences the value.
Source§

impl Drop for PooledVm

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

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> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<F, W, T, D> Deserialize<With<T, W>, D> for F
where W: DeserializeWith<F, T, D>, D: Fallible + ?Sized, F: ?Sized,

Source§

fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>

Deserializes using the given deserializer
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Gets the layout of the type.
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> Pointee for T

Source§

type Metadata = ()

The type for metadata in pointers and references to Self.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more