Skip to main content

Vm

Struct Vm 

Source
pub struct Vm<'a> {
    pub step_limit: u64,
    pub steps: u64,
    pub pure_memo_hits: u64,
    pub pure_memo_misses: u64,
    pub pure_memo_skips: u64,
    pub stack_record_allocs: u64,
    pub stack_record_heap_fallbacks: u64,
    pub heap_record_allocs: u64,
    /* private fields */
}

Fields§

§step_limit: u64

Soft cap to avoid runaway computations in tests.

§steps: u64§pure_memo_hits: u64

Diagnostic counters for --trace observability (#229).

§pure_memo_misses: u64§pure_memo_skips: u64

Number of effect-free calls that skipped the cache entirely because adaptive memoization disabled their function (#229 adaptive). Observability only.

§stack_record_allocs: u64

Per-Vm counters for #464 acceptance measurement. Incremented on every Op::MakeRecord / Op::AllocStackRecord dispatch. The bench reads these to compute the stack-allocation rate (≥ 60% of records on the stack is the acceptance bar). Cheap in the hot path — two unconditional u64 increments per record.

§stack_record_heap_fallbacks: u64§heap_record_allocs: u64

Implementations§

Source§

impl<'a> Vm<'a>

Source

pub fn new(program: &'a Program) -> Self

Source

pub fn with_handler( program: &'a Program, handler: Box<dyn EffectHandler + 'a>, ) -> Self

Source

pub fn set_tracer(&mut self, tracer: Box<dyn Tracer + 'a>)

Source

pub fn set_step_limit(&mut self, limit: u64)

Cap the number of opcode dispatches before the VM aborts with step limit exceeded. Useful as a runtime DoS guard against untrusted code (e.g. the agent-tool sandbox, where an LLM could emit list.fold(list.range(0, 1_000_000_000), …) to hang the host). Default is 10_000_000.

Source

pub fn call(&mut self, name: &str, args: Vec<Value>) -> Result<Value, VmError>

Source

pub fn invoke_closure_value( &mut self, closure: Value, args: Vec<Value>, ) -> Result<Value, VmError>

Invoke a Value::Closure by combining its captures with the supplied call args and dispatching to the underlying function. Used by the parser interpreter (#221) to call user-supplied f arguments inside parser.map / parser.and_then nodes.

Source

pub fn invoke_closure_1( &mut self, closure: Value, arg: Value, ) -> Result<Value, VmError>

Invoke a 1-arg closure without allocating a separate args Vec (#464 call-overhead). The closure’s own captures Vec is reused as the combined captures ++ [arg] argument buffer, so the per-element call in ListMap/ListFilter/SortByKey allocates at most once (the push) instead of twice (a fresh vec![arg] plus the extend). Semantically identical to invoke_closure_value(closure, vec![arg]).

Source

pub fn invoke_closure_2( &mut self, closure: Value, a: Value, b: Value, ) -> Result<Value, VmError>

Invoke a 2-arg closure without a separate args Vec — the ListFold combiner path. See invoke_closure_1.

Source

pub fn enter_request_scope(&mut self) -> u64

Open a request-scoped arena via the underlying EffectHandler::enter_request_scope (#463 scaffolding). Runtime layers — net.serve_fn, net.serve_ws, net.serve_quic — call this immediately before invoking the user handler closure for a single request. Pair with exit_request_scope once the response has been built and any lazy iterators in it have been drained (#477).

Returns the scope id the runtime should pass back to exit_request_scope. The handler’s default impl returns 0 and the matching exit is a no-op; DefaultHandler’s implementation actually allocates an arena.

Source

pub fn exit_request_scope(&mut self, scope_id: u64)

Close the request scope opened by enter_request_scope. Drops the associated arena.

Source

pub fn invoke(&mut self, fn_id: u32, args: Vec<Value>) -> Result<Value, VmError>

Trait Implementations§

Source§

impl<'a> ClosureCaller for Vm<'a>

Vm exposes itself as a ClosureCaller so the parser interpreter can invoke user-supplied closures during a parser.run walk (#221). The Vm is reentrant for closure invocation: pushing a new frame onto an active call stack is supported, and the handler stays in place so any effects the closure body fires dispatch normally.

Source§

fn call_closure( &mut self, closure: Value, args: Vec<Value>, ) -> Result<Value, String>

Source§

impl Drop for Vm<'_>

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§

§

impl<'a> Freeze for Vm<'a>

§

impl<'a> !RefUnwindSafe for Vm<'a>

§

impl<'a> !Send for Vm<'a>

§

impl<'a> !Sync for Vm<'a>

§

impl<'a> Unpin for Vm<'a>

§

impl<'a> UnsafeUnpin for Vm<'a>

§

impl<'a> !UnwindSafe for Vm<'a>

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> 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<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<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,