Perf: Restore core optimizations and stabilize VM execution
This commit restores and enhances several high-performance features that were previously lost, while fixing critical bugs in scope management. Performance Optimizations: - Zero-Copy TCO: Refactored TailCallRequest to use (Rc, usize), moving arguments directly on the VM stack via drain/resize instead of heap-allocating Vecs. - Slice-based Calls: Native functions and field accessors now operate directly on stack slices, significantly reducing memory churn. - SoA Push Fast-Path: Restored specialized 'push' intrinsic for RecordSeries. Matches layouts via Arc::ptr_eq to distribute values directly into columns without keyword lookups. Architectural Improvements: - Static Stack Frames (max_slots): The Binder now calculates the maximum required slots per lambda. The VM pre-resizes the stack frame, preventing collisions between local variables and temporary call arguments. - Macro Hygiene: Fixed a bug where macro-internal variables could overwrite outer call arguments due to stack overlap. - Trait Refactoring: Unified series operations via a polymorphic 'push_value' on the Series trait, with a generic implementation for ScalarSeries<T>. Code Quality: - Resolved all 'cargo clippy' warnings (collapsible ifs, redundant borrows, etc). - Restored 100% test pass rate (64/64 tests). - Verified stability of all examples and benchmarks.
This commit is contained in:
+21
-9
@@ -202,6 +202,9 @@ pub trait Series {
|
||||
/// Gets the value at the specified lookback index (0 = newest).
|
||||
fn get_item(&self, index: usize) -> Option<Value>;
|
||||
|
||||
/// Pushes a new value into the series.
|
||||
fn push_value(&self, value: Value);
|
||||
|
||||
/// Returns the current number of elements in the buffer.
|
||||
fn len(&self) -> usize;
|
||||
|
||||
@@ -259,7 +262,7 @@ pub enum Value {
|
||||
Function(Rc<NativeFunction>),
|
||||
Object(Rc<dyn Object>), // For compiled Closures and other opaque types
|
||||
Cell(Rc<RefCell<Value>>), // Boxed value for captures
|
||||
TailCallRequest(Box<(Rc<dyn Object>, Vec<Value>)>), // Internal: For TCO (Boxed to keep Value small)
|
||||
TailCallRequest(Rc<dyn Object>, usize), // Internal: For TCO (target object + argc on stack)
|
||||
}
|
||||
|
||||
impl PartialEq for Value {
|
||||
@@ -280,8 +283,8 @@ impl PartialEq for Value {
|
||||
(Value::Function(a), Value::Function(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Object(a), Value::Object(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::Cell(a), Value::Cell(b)) => Rc::ptr_eq(a, b),
|
||||
(Value::TailCallRequest(a), Value::TailCallRequest(b)) => {
|
||||
Rc::ptr_eq(&a.0, &b.0) && a.1 == b.1
|
||||
(Value::TailCallRequest(oa, ca), Value::TailCallRequest(ob, cb)) => {
|
||||
Rc::ptr_eq(oa, ob) && ca == cb
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
@@ -527,11 +530,12 @@ impl StaticType {
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn as_float(&self) -> Option<f64> {
|
||||
pub fn get_field(&self, key: Keyword) -> Option<Value> {
|
||||
match self {
|
||||
Value::Float(f) => Some(*f),
|
||||
Value::Int(i) => Some(*i as f64),
|
||||
_ => None,
|
||||
Value::Record(layout, values) => {
|
||||
layout.index_of(key).map(|idx| values[idx].clone())
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,6 +548,14 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_float(&self) -> Option<f64> {
|
||||
match self {
|
||||
Value::Float(f) => Some(*f),
|
||||
Value::Int(i) => Some(*i as f64),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_truthy(&self) -> bool {
|
||||
match self {
|
||||
Value::Void => false,
|
||||
@@ -623,7 +635,7 @@ impl Value {
|
||||
Value::Function(_) => StaticType::Any, // Dynamic function
|
||||
Value::Object(o) => StaticType::Object(o.type_name()),
|
||||
Value::Cell(c) => c.borrow().static_type(),
|
||||
Value::TailCallRequest(_) => StaticType::Any, // Internal state, but typable as Any
|
||||
Value::TailCallRequest(_, _) => StaticType::Any, // Internal state, but typable as Any
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -680,7 +692,7 @@ impl fmt::Display for Value {
|
||||
}
|
||||
}
|
||||
Value::Cell(c) => write!(f, "{}", c.borrow()),
|
||||
Value::TailCallRequest(_) => write!(f, "<tail call request>"),
|
||||
Value::TailCallRequest(_, _) => write!(f, "<tail call request>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user