pub struct Scope { /* private fields */ }Expand description
Manages lexical scoping with a stack of frames. Innermost frame is last in the vector.
Implementations§
Source§impl Scope
impl Scope
pub fn new() -> Self
Sourcepub fn set_parallel_guard(&mut self, enabled: bool)
pub fn set_parallel_guard(&mut self, enabled: bool)
Enable Self::parallel_guard for parallel worker interpreters (pmap, fan, …).
pub fn parallel_guard(&self) -> bool
pub fn depth(&self) -> usize
Sourcepub fn pop_to_depth(&mut self, target_depth: usize)
pub fn pop_to_depth(&mut self, target_depth: usize)
Pop frames until we’re at target_depth. Used by VM ReturnValue
to cleanly unwind through if/while/for blocks on return.
pub fn push_frame(&mut self)
Sourcepub fn get_scalar_slot(&self, slot: u8) -> PerlValue
pub fn get_scalar_slot(&self, slot: u8) -> PerlValue
Read scalar from slot — innermost binding for slot wins (same index can exist on nested
frames; padding entries without [Frame::owns_scalar_slot_index] do not shadow outers).
Sourcepub fn set_scalar_slot(&mut self, slot: u8, val: PerlValue)
pub fn set_scalar_slot(&mut self, slot: u8, val: PerlValue)
Write scalar to slot — innermost binding for slot wins (see Self::get_scalar_slot).
Sourcepub fn set_scalar_slot_checked(
&mut self,
slot: u8,
val: PerlValue,
slot_name: Option<&str>,
) -> Result<(), PerlError>
pub fn set_scalar_slot_checked( &mut self, slot: u8, val: PerlValue, slot_name: Option<&str>, ) -> Result<(), PerlError>
Like [set_scalar_slot] but respects the parallel guard — returns Err when assigning
to a slot that belongs to an outer frame inside a parallel block. slot_name is resolved
from the bytecode’s name table by the caller when available.
Sourcepub fn declare_scalar_slot(
&mut self,
slot: u8,
val: PerlValue,
name: Option<&str>,
)
pub fn declare_scalar_slot( &mut self, slot: u8, val: PerlValue, name: Option<&str>, )
Declare + initialize scalar in the current frame’s slot array.
name (bare identifier, e.g. x for $x) is stored for Scope::capture when the
binding is slot-only (no duplicate frame.scalars row).
Sourcepub fn scalar_slot_concat_repeat_inplace(
&mut self,
slot: u8,
rhs: &str,
n: usize,
) -> bool
pub fn scalar_slot_concat_repeat_inplace( &mut self, slot: u8, rhs: &str, n: usize, ) -> bool
Slot-indexed .= — avoids frame walking and string comparison on every iteration.
Returns a PerlValue::shallow_clone (Arc::clone) of the stored value
rather than a full Clone, which would deep-copy the entire String
payload and turn a $s .= "x" loop into O(N²) memcpy.
Repeated $slot .= rhs fused-loop fast path: locates the slot’s frame once,
tries try_concat_repeat_inplace (unique heap-String → single reserve+push_str
burst), and returns true on success. Returns false when the slot is not a
uniquely-held String so the caller can fall back to the per-iteration slow
path. Called from Op::ConcatConstSlotLoop.
Sourcepub fn scalar_slot_concat_repeat_slow(&mut self, slot: u8, rhs: &str, n: usize)
pub fn scalar_slot_concat_repeat_slow(&mut self, slot: u8, rhs: &str, n: usize)
Slow fallback for the fused string-append loop: clones the RHS into a new
PerlValue::string once and runs the existing scalar_slot_concat_inplace
path n times. Used by Op::ConcatConstSlotLoop when the slot is aliased
and the in-place fast path rejected the mutation.
pub fn scalar_slot_concat_inplace( &mut self, slot: u8, rhs: &PerlValue, ) -> PerlValue
pub fn pop_frame(&mut self)
Sourcepub fn local_set_scalar(
&mut self,
name: &str,
val: PerlValue,
) -> Result<(), PerlError>
pub fn local_set_scalar( &mut self, name: &str, val: PerlValue, ) -> Result<(), PerlError>
local $name — save current value, assign val; restore on pop_frame.
Sourcepub fn local_set_array(
&mut self,
name: &str,
val: Vec<PerlValue>,
) -> Result<(), PerlError>
pub fn local_set_array( &mut self, name: &str, val: Vec<PerlValue>, ) -> Result<(), PerlError>
local @name — not valid for mysync arrays.
Sourcepub fn local_set_hash(
&mut self,
name: &str,
val: IndexMap<String, PerlValue>,
) -> Result<(), PerlError>
pub fn local_set_hash( &mut self, name: &str, val: IndexMap<String, PerlValue>, ) -> Result<(), PerlError>
local %name
Sourcepub fn local_set_hash_element(
&mut self,
name: &str,
key: &str,
val: PerlValue,
) -> Result<(), PerlError>
pub fn local_set_hash_element( &mut self, name: &str, key: &str, val: PerlValue, ) -> Result<(), PerlError>
local $h{key} = val — save key state; restore one slot on pop_frame.
Sourcepub fn local_set_array_element(
&mut self,
name: &str,
index: i64,
val: PerlValue,
) -> Result<(), PerlError>
pub fn local_set_array_element( &mut self, name: &str, index: i64, val: PerlValue, ) -> Result<(), PerlError>
local $a[i] = val — save element (as returned by Self::get_array_element), assign;
restore on Self::pop_frame.
pub fn declare_scalar(&mut self, name: &str, val: PerlValue)
Sourcepub fn declare_scalar_frozen(
&mut self,
name: &str,
val: PerlValue,
frozen: bool,
ty: Option<PerlTypeName>,
) -> Result<(), PerlError>
pub fn declare_scalar_frozen( &mut self, name: &str, val: PerlValue, frozen: bool, ty: Option<PerlTypeName>, ) -> Result<(), PerlError>
Declare a lexical scalar; frozen means no further assignment to this binding.
ty is from typed my $x : Int — enforced on every assignment.
Sourcepub fn is_scalar_frozen(&self, name: &str) -> bool
pub fn is_scalar_frozen(&self, name: &str) -> bool
True if the innermost lexical scalar binding for name is frozen.
Sourcepub fn is_array_frozen(&self, name: &str) -> bool
pub fn is_array_frozen(&self, name: &str) -> bool
True if the innermost lexical array binding for name is frozen.
Sourcepub fn is_hash_frozen(&self, name: &str) -> bool
pub fn is_hash_frozen(&self, name: &str) -> bool
True if the innermost lexical hash binding for name is frozen.
Sourcepub fn check_frozen(&self, sigil: &str, name: &str) -> Option<&'static str>
pub fn check_frozen(&self, sigil: &str, name: &str) -> Option<&'static str>
Returns Some(sigil) if the named variable is frozen, None if mutable.
pub fn get_scalar(&self, name: &str) -> PerlValue
Sourcepub fn scalar_binding_exists(&self, name: &str) -> bool
pub fn scalar_binding_exists(&self, name: &str) -> bool
True if any frame has a lexical scalar binding for name (my / our / assignment).
Sourcepub fn all_scalar_names(&self) -> Vec<String>
pub fn all_scalar_names(&self) -> Vec<String>
Collect all scalar variable names across all frames (for debugger).
Sourcepub fn array_binding_exists(&self, name: &str) -> bool
pub fn array_binding_exists(&self, name: &str) -> bool
True if any frame or atomic slot holds an array named name.
Sourcepub fn hash_binding_exists(&self, name: &str) -> bool
pub fn hash_binding_exists(&self, name: &str) -> bool
True if any frame or atomic slot holds a hash named name.
Sourcepub fn get_scalar_raw(&self, name: &str) -> PerlValue
pub fn get_scalar_raw(&self, name: &str) -> PerlValue
Get the raw scalar value WITHOUT unwrapping Atomic. Used by scope.capture() to preserve the Arc for sharing across threads.
Sourcepub fn atomic_mutate(
&mut self,
name: &str,
f: impl FnOnce(&PerlValue) -> PerlValue,
) -> PerlValue
pub fn atomic_mutate( &mut self, name: &str, f: impl FnOnce(&PerlValue) -> PerlValue, ) -> PerlValue
Atomically read-modify-write a scalar. Holds the Mutex lock for
the entire cycle so mysync variables are race-free under fan/pfor.
Returns the NEW value.
Sourcepub fn atomic_mutate_post(
&mut self,
name: &str,
f: impl FnOnce(&PerlValue) -> PerlValue,
) -> PerlValue
pub fn atomic_mutate_post( &mut self, name: &str, f: impl FnOnce(&PerlValue) -> PerlValue, ) -> PerlValue
Like atomic_mutate but returns the OLD value (for postfix $x++).
Sourcepub fn scalar_concat_inplace(
&mut self,
name: &str,
rhs: &PerlValue,
) -> Result<PerlValue, PerlError>
pub fn scalar_concat_inplace( &mut self, name: &str, rhs: &PerlValue, ) -> Result<PerlValue, PerlError>
Append rhs to a scalar string in-place (no clone of the existing string).
If the scalar is not yet a String, it is converted first.
The binding and the returned PerlValue share the same heap Arc via
PerlValue::shallow_clone on the store — a full Clone would deep-copy the
entire String each time and make repeated .= O(N²) in the total length.
pub fn set_scalar( &mut self, name: &str, val: PerlValue, ) -> Result<(), PerlError>
Sourcepub fn set_topic(&mut self, val: PerlValue)
pub fn set_topic(&mut self, val: PerlValue)
Set the topic variable $_ and its numeric alias $_0 together.
Use this for single-arg closures (map, grep, etc.) so both $_ and $_0 work.
This declares them in the current scope (not global), suitable for sub calls.
Also sets outer topic aliases: $_< = previous $_, $_<< = previous $_<, etc.
This allows nested blocks (e.g. fan inside >{}) to access enclosing topic values.
Sourcepub fn set_closure_args(&mut self, args: &[PerlValue])
pub fn set_closure_args(&mut self, args: &[PerlValue])
Set numeric closure argument aliases $_0, $_1, $_2, … for all args.
Also sets $_ to the first argument (if any), shifting outer topics like [set_topic].
Sourcepub fn push_defer(&mut self, coderef: PerlValue)
pub fn push_defer(&mut self, coderef: PerlValue)
Register a defer { BLOCK } closure to run when this scope exits.
Sourcepub fn take_defers(&mut self) -> Vec<PerlValue>
pub fn take_defers(&mut self) -> Vec<PerlValue>
Take all deferred blocks from the current frame (for execution on scope exit). Returns them in reverse order (LIFO - last defer runs first).
pub fn declare_atomic_array(&mut self, name: &str, val: Vec<PerlValue>)
pub fn declare_atomic_hash( &mut self, name: &str, val: IndexMap<String, PerlValue>, )
Sourcepub fn take_sub_underscore(&mut self) -> Option<Vec<PerlValue>>
pub fn take_sub_underscore(&mut self) -> Option<Vec<PerlValue>>
Remove @_ from the innermost frame without cloning (move out of the frame sub_underscore field).
Call sites restore with Self::declare_array before running a body that uses shift / @_.
pub fn declare_array(&mut self, name: &str, val: Vec<PerlValue>)
pub fn declare_array_frozen( &mut self, name: &str, val: Vec<PerlValue>, frozen: bool, )
pub fn get_array(&self, name: &str) -> Vec<PerlValue>
Sourcepub fn get_array_borrow(&self, name: &str) -> Option<&[PerlValue]>
pub fn get_array_borrow(&self, name: &str) -> Option<&[PerlValue]>
Borrow the innermost binding for name when it is a plain Vec (not mysync).
Used to pass @_ to [crate::list_util::native_dispatch] without cloning the vector.
pub fn get_array_mut( &mut self, name: &str, ) -> Result<&mut Vec<PerlValue>, PerlError>
Sourcepub fn push_to_array(
&mut self,
name: &str,
val: PerlValue,
) -> Result<(), PerlError>
pub fn push_to_array( &mut self, name: &str, val: PerlValue, ) -> Result<(), PerlError>
Push to array — works for both regular and atomic arrays.
Sourcepub fn push_int_range_to_array(
&mut self,
name: &str,
start: i64,
end: i64,
) -> Result<(), PerlError>
pub fn push_int_range_to_array( &mut self, name: &str, start: i64, end: i64, ) -> Result<(), PerlError>
Bulk push @name, start..end-1 for the fused counted-loop superinstruction:
reserves the Vec once, then pushes PerlValue::integer(i) for i in start..end
in a tight Rust loop. Atomic arrays take a single lock().push() burst.
Sourcepub fn pop_from_array(&mut self, name: &str) -> Result<PerlValue, PerlError>
pub fn pop_from_array(&mut self, name: &str) -> Result<PerlValue, PerlError>
Pop from array — works for both regular and atomic arrays.
Sourcepub fn shift_from_array(&mut self, name: &str) -> Result<PerlValue, PerlError>
pub fn shift_from_array(&mut self, name: &str) -> Result<PerlValue, PerlError>
Shift from array — works for both regular and atomic arrays.
Sourcepub fn array_len(&self, name: &str) -> usize
pub fn array_len(&self, name: &str) -> usize
Get array length — works for both regular and atomic arrays.
pub fn set_array( &mut self, name: &str, val: Vec<PerlValue>, ) -> Result<(), PerlError>
Sourcepub fn get_array_element(&self, name: &str, index: i64) -> PerlValue
pub fn get_array_element(&self, name: &str, index: i64) -> PerlValue
Direct element access — works for both regular and atomic arrays.
pub fn set_array_element( &mut self, name: &str, index: i64, val: PerlValue, ) -> Result<(), PerlError>
Sourcepub fn exists_array_element(&self, name: &str, index: i64) -> bool
pub fn exists_array_element(&self, name: &str, index: i64) -> bool
Perl exists $a[$i] — true when the slot index is within the current array length.
Sourcepub fn delete_array_element(
&mut self,
name: &str,
index: i64,
) -> Result<PerlValue, PerlError>
pub fn delete_array_element( &mut self, name: &str, index: i64, ) -> Result<PerlValue, PerlError>
Perl delete $a[$i] — sets the element to undef, returns the previous value.
pub fn declare_hash(&mut self, name: &str, val: IndexMap<String, PerlValue>)
pub fn declare_hash_frozen( &mut self, name: &str, val: IndexMap<String, PerlValue>, frozen: bool, )
pub fn get_hash(&self, name: &str) -> IndexMap<String, PerlValue>
pub fn get_hash_mut( &mut self, name: &str, ) -> Result<&mut IndexMap<String, PerlValue>, PerlError>
pub fn set_hash( &mut self, name: &str, val: IndexMap<String, PerlValue>, ) -> Result<(), PerlError>
pub fn get_hash_element(&self, name: &str, key: &str) -> PerlValue
Sourcepub fn atomic_hash_mutate(
&mut self,
name: &str,
key: &str,
f: impl FnOnce(&PerlValue) -> PerlValue,
) -> Result<PerlValue, PerlError>
pub fn atomic_hash_mutate( &mut self, name: &str, key: &str, f: impl FnOnce(&PerlValue) -> PerlValue, ) -> Result<PerlValue, PerlError>
Atomically read-modify-write a hash element. For atomic hashes, holds the Mutex for the full cycle. Returns the new value.
Sourcepub fn atomic_array_mutate(
&mut self,
name: &str,
index: i64,
f: impl FnOnce(&PerlValue) -> PerlValue,
) -> Result<PerlValue, PerlError>
pub fn atomic_array_mutate( &mut self, name: &str, index: i64, f: impl FnOnce(&PerlValue) -> PerlValue, ) -> Result<PerlValue, PerlError>
Atomically read-modify-write an array element. Returns the new value.
pub fn set_hash_element( &mut self, name: &str, key: &str, val: PerlValue, ) -> Result<(), PerlError>
Sourcepub fn set_hash_int_times_range(
&mut self,
name: &str,
start: i64,
end: i64,
k: i64,
) -> Result<(), PerlError>
pub fn set_hash_int_times_range( &mut self, name: &str, start: i64, end: i64, k: i64, ) -> Result<(), PerlError>
Bulk for i in start..end { $h{i} = i * k } for the fused hash-insert loop.
Reserves capacity once and runs the whole range in a tight Rust loop.
itoa is used to stringify each key without a transient format! allocation.
pub fn delete_hash_element( &mut self, name: &str, key: &str, ) -> Result<PerlValue, PerlError>
pub fn exists_hash_element(&self, name: &str, key: &str) -> bool
Sourcepub fn for_each_hash_value(&self, name: &str, visit: impl FnMut(&PerlValue))
pub fn for_each_hash_value(&self, name: &str, visit: impl FnMut(&PerlValue))
Walk all values of the named hash with a visitor. Used by the fused
for my $k (keys %h) { $sum += $h{$k} } op so the hot loop runs without
cloning the entire map into a keys array (vs the un-fused shape, which
allocates one PerlValue::string per key).
Sourcepub fn repl_binding_names(&self) -> Vec<String>
pub fn repl_binding_names(&self) -> Vec<String>
Sigil-prefixed names ($x, @a, %h) from all frames, for REPL tab-completion.
pub fn capture(&mut self) -> Vec<(String, PerlValue)>
Sourcepub fn capture_with_atomics(
&self,
) -> (Vec<(String, PerlValue)>, Vec<(String, AtomicArray)>, Vec<(String, AtomicHash)>)
pub fn capture_with_atomics( &self, ) -> (Vec<(String, PerlValue)>, Vec<(String, AtomicArray)>, Vec<(String, AtomicHash)>)
Extended capture that returns atomic arrays/hashes separately.
pub fn restore_capture(&mut self, captured: &[(String, PerlValue)])
Sourcepub fn restore_atomics(
&mut self,
arrays: &[(String, AtomicArray)],
hashes: &[(String, AtomicHash)],
)
pub fn restore_atomics( &mut self, arrays: &[(String, AtomicArray)], hashes: &[(String, AtomicHash)], )
Restore atomic arrays/hashes from capture_with_atomics.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Scope
impl !RefUnwindSafe for Scope
impl Send for Scope
impl Sync for Scope
impl Unpin for Scope
impl UnsafeUnpin for Scope
impl !UnwindSafe for Scope
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.