pub enum ListRepr {
Boxed(Vec<RuntimeValue>),
Ints(Vec<i64>),
IntsI32(Vec<i32>),
Floats(Vec<f64>),
Bools(Vec<bool>),
Strings {
data: Vec<u8>,
ends: Vec<u32>,
cache: RefCell<Vec<Option<Rc<String>>>>,
},
Structs {
type_name: String,
field_names: Vec<String>,
columns: Vec<ListRepr>,
},
Inductives {
inductive_type: String,
ctor_dict: Vec<String>,
ctors: Vec<u32>,
ranks: Vec<u32>,
arg_cols: Vec<Vec<ListRepr>>,
},
WireStructs {
bytes: Rc<Vec<u8>>,
type_name: String,
field_names: Vec<String>,
len: usize,
},
WireColumn {
bytes: Rc<Vec<u8>>,
len: usize,
floats: bool,
},
}Expand description
The List payload behind RuntimeValue::List: homogeneous all-Int and
all-Float lists store UNBOXED vectors (cache-dense, and the JIT can pin a
raw pointer to them); anything else boxes. The repr lives INSIDE the
Rc<RefCell<…>>, so promotion re-tags the payload in place and every
alias observes it — reference semantics and Rc identity are untouched.
An EMPTY list is vacuously Ints and re-tags freely on its first push.
Hot paths take &self/&mut self borrows only — no Rc refcount traffic.
Clone snapshots a buffer’s contents for the region deopt-rollback of an
in-place-mutated array (see crate::vm::native_tier::ArrayPin::mutated).
Variants§
Boxed(Vec<RuntimeValue>)
Ints(Vec<i64>)
IntsI32(Vec<i32>)
A proven-narrowable Int buffer stored half-width: every element fits
i32 (the narrowing proof in codegen::narrow), so the buffer is
Vec<i32> — half the footprint and cache pressure. Reads SIGN-EXTEND
(x as i64, lossless); writes TRUNCATE (x as i32, lossless because
of the proof, debug-asserted in range). A write outside i32 range
PROMOTES the buffer back to a full-width Ints (the proof was wrong —
soundness over speed), so observable values never differ from Ints.
Created only behind LOGOS_NARROW_VM for narrowable declarations.
Floats(Vec<f64>)
Bools(Vec<bool>)
Strings
A flat string array (Arrow-style): all element bytes concatenated in one
data buffer, with ends[i] the exclusive end offset of element i (so
element i is data[ends[i-1]..ends[i]], ends.len() == the count). This
is the columnar layout that lets a string list pack and load as two bulk
copies instead of one heap allocation per string — the same treatment the
numeric variants already get. It is read-optimized: an element materializes
to Text only when accessed, and any mutation promotes the buffer to
Boxed. The wire decoder builds it directly; normal code paths are
unaffected (a string literal stays Boxed).
cache is a LAZY memo: empty until the first get, so ship/load/iterate
pay nothing, and repeated indexing of the same element returns a cheap Rc
clone instead of re-materializing — best of both worlds (flat to move,
boxed-cheap to re-read).
Structs
A homogeneous struct list stored COLUMNAR (struct-of-arrays): instead of N
boxed StructValues (each a heap Box + a HashMap), the schema is held
once (type_name + canonical sorted field_names) and each field becomes a
packed column — itself a ListRepr, so an int field is a Vec<i64>, a bool
field is bit-packed, a nested struct field is recursively columnar. Zero
per-row Box/HashMap; field access is a column index; the wire encoder
memcpy-streams the columns. Reads reconstruct a StructValue on demand
(get); ANY mutation de-columnarizes to Boxed first (make_boxed), so
reference semantics are exactly those of a boxed list. Built by from_values
for genuinely-homogeneous struct lists (same type, same field set); ragged
lists stay Boxed. columns are all the same length (the row count).
Inductives
A homogeneous inductive (enum/ADT) list stored COLUMNAR as a tagged union:
instead of N boxed InductiveValues, the type name is held once, the distinct
constructor names are dictionaried (ctor_dict), each row carries a small
constructor index (ctors), and the constructor ARGUMENTS are packed DENSE
per constructor — arg_cols[c][j] is the column of argument j across only
the rows whose constructor is c (so arg_cols[c].len() is constructor c’s
arity, and each inner column’s length is the count of rows with constructor
c). ranks[i] is row i’s rank within its constructor, so get is O(1).
A nullary enum collapses to just the dictionary + index column (no arg cols).
Built by from_values for same-type enum lists; ragged/mixed-type lists stay
Boxed. Any mutation de-columnarizes via make_boxed.
Fields
WireStructs
A received record-list held as RAW WIRE BYTES, decoded LAZILY — the production zero-copy
receive (Cap’n Proto’s “read in place, only what you touch”). bytes is the full received
frame whose top-level value is a T_STRUCTS_VIEW record list; the schema (type_name,
field_names, len) is read ONCE from the header, so len and shape are O(1) with ZERO
rows decoded. Field access reads a single cell in place via WireView::structs_row_field
(O(1), no allocation for the untouched rows/fields); get(i) reconstructs one StructValue
on demand. ANY mutation de-lazies to Boxed first (make_boxed), so reference semantics are
exactly those of a boxed list. Built only by the view receive path; normal code is
unaffected.
WireColumn
A received NUMERIC column (T_INTS_ALIGNED/T_FLOATS_ALIGNED) held as RAW WIRE BYTES and
read ZERO-COPY: the 8-byte-aligned blob is the array. len is O(1) from the header (no
decode); get(i) reads element i straight out of the borrowed &[i64]/&[f64] (capnp’s
List<i64> read-in-place); a partial read touches only what it reads. ANY mutation
materializes to Ints/Floats first. Built only by the view receive path for an aligned
column whose blob is 8-aligned in the received buffer (else the caller decodes eagerly).
Implementations§
Source§impl ListRepr
impl ListRepr
Sourcepub fn from_record_list_view(bytes: Rc<Vec<u8>>) -> Option<ListRepr>
pub fn from_record_list_view(bytes: Rc<Vec<u8>>) -> Option<ListRepr>
Wrap a received record-list frame (T_STRUCTS_VIEW top-level) as a lazy zero-copy backing.
None if the bytes are not a self-describing record-list view (the caller decodes eagerly).
Sourcepub fn from_aligned_column_view(bytes: Rc<Vec<u8>>) -> Option<ListRepr>
pub fn from_aligned_column_view(bytes: Rc<Vec<u8>>) -> Option<ListRepr>
Wrap a received aligned numeric column (T_INTS_ALIGNED/T_FLOATS_ALIGNED) as a lazy
zero-copy backing. None unless the blob reads as an 8-aligned &[i64]/&[f64] in this
buffer (so every later read is a sound slice cast); the caller then decodes eagerly.
Source§impl ListRepr
impl ListRepr
pub fn from_values(values: Vec<RuntimeValue>) -> ListRepr
Sourcepub fn strings(data: Vec<u8>, ends: Vec<u32>) -> ListRepr
pub fn strings(data: Vec<u8>, ends: Vec<u32>) -> ListRepr
A flat string buffer with an empty (lazy) materialization cache.
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
Sourcepub fn storage_label(&self) -> &'static str
pub fn storage_label(&self) -> &'static str
A human label for the underlying storage layout — for the debugger’s memory
view. It teaches that a list of ints is a packed Vec<i64> (not boxed
values), a struct list is columnar (struct-of-arrays), and so on: the dense
representations the VM picks automatically.
Sourcepub fn truncate(&mut self, n: usize)
pub fn truncate(&mut self, n: usize)
Drop every element past n (no-op when already <= n). The region
deopt path uses this to roll a pushed buffer back to its entry length
so discard-and-replay re-pushes cleanly instead of duplicating.
Sourcepub fn get(&self, i: usize) -> Option<RuntimeValue>
pub fn get(&self, i: usize) -> Option<RuntimeValue>
0-based read; boxes the scalar (stack-only — no heap, no Rc traffic).
Sourcepub fn get_field(&self, i: usize, name: &str) -> Option<RuntimeValue>
pub fn get_field(&self, i: usize, name: &str) -> Option<RuntimeValue>
Read field name of row i from a columnar struct list by indexing ONE
column directly — no StructValue reconstruction. None for a non-columnar
repr or a missing field/row. This is the zero-alloc read path that makes a
field scan over a columnar struct list run at array speed.
Sourcepub fn column(&self, name: &str) -> Option<&ListRepr>
pub fn column(&self, name: &str) -> Option<&ListRepr>
Direct access to a struct field’s whole packed column (the array behind a
field), for aggregating one field across the list at array speed. None for
a non-columnar repr or a missing field.
Sourcepub fn set(&mut self, i: usize, value: RuntimeValue)
pub fn set(&mut self, i: usize, value: RuntimeValue)
0-based write (bounds already validated by the caller); promotes on a kind mismatch.
pub fn push(&mut self, value: RuntimeValue)
pub fn pop(&mut self) -> Option<RuntimeValue>
pub fn insert(&mut self, i: usize, value: RuntimeValue)
pub fn remove_at(&mut self, i: usize) -> RuntimeValue
Sourcepub fn position(&self, needle: &RuntimeValue) -> Option<usize>
pub fn position(&self, needle: &RuntimeValue) -> Option<usize>
Index of the first element values_equal to needle (the kernel’s
equality: epsilon floats, cross-type never equal).
pub fn contains(&self, needle: &RuntimeValue) -> bool
Sourcepub fn to_values(&self) -> Vec<RuntimeValue>
pub fn to_values(&self) -> Vec<RuntimeValue>
Materialize boxed values (snapshots, display, deep clones).
Sourcepub fn slice(&self, start: usize, end: usize) -> ListRepr
pub fn slice(&self, start: usize, end: usize) -> ListRepr
0-based inclusive-range slice as a fresh payload of the same repr.
Sourcepub fn as_ints_mut(&mut self) -> Option<&mut Vec<i64>>
pub fn as_ints_mut(&mut self) -> Option<&mut Vec<i64>>
Direct unboxed views for the JIT’s region pinning.
pub fn as_floats_mut(&mut self) -> Option<&mut Vec<f64>>
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ListRepr
impl !RefUnwindSafe for ListRepr
impl !Send for ListRepr
impl !Sync for ListRepr
impl Unpin for ListRepr
impl UnsafeUnpin for ListRepr
impl !UnwindSafe for ListRepr
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,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.