refactor(tvix/eval): introduce Upvalues struct in closures & thunks
This struct will be responsible for tracking upvalues (and is a convenient place to introduce optimisations for reducing value clones) instead of a plain value vector. The main motivation for this is that the upvalues will have to capture the `with`-stack fully and I want to avoid duplicating the logic for this between the two capturing types. Change-Id: I6654f8739fc2e04ca046e6667d4a015f51724e99 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6485 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
6c9abc1f68
commit
d75b207a63
4 changed files with 65 additions and 30 deletions
|
@ -8,13 +8,13 @@ use crate::{
|
|||
errors::{Error, ErrorKind, EvalResult},
|
||||
observer::Observer,
|
||||
opcode::{CodeIdx, ConstantIdx, Count, JumpOffset, OpCode, StackIdx, UpvalueIdx},
|
||||
upvalues::UpvalueCarrier,
|
||||
upvalues::{UpvalueCarrier, Upvalues},
|
||||
value::{Builtin, Closure, Lambda, NixAttrs, NixList, Thunk, Value},
|
||||
};
|
||||
|
||||
struct CallFrame {
|
||||
lambda: Rc<Lambda>,
|
||||
upvalues: Vec<Value>,
|
||||
upvalues: Upvalues,
|
||||
ip: usize,
|
||||
stack_offset: usize,
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ struct CallFrame {
|
|||
impl CallFrame {
|
||||
/// Retrieve an upvalue from this frame at the given index.
|
||||
fn upvalue(&self, idx: UpvalueIdx) -> &Value {
|
||||
&self.upvalues[idx.0]
|
||||
&self.upvalues[idx]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ impl<'o> VM<'o> {
|
|||
pub fn call(
|
||||
&mut self,
|
||||
lambda: Rc<Lambda>,
|
||||
upvalues: Vec<Value>,
|
||||
upvalues: Upvalues,
|
||||
arg_count: usize,
|
||||
) -> EvalResult<Value> {
|
||||
self.observer
|
||||
|
@ -443,7 +443,7 @@ impl<'o> VM<'o> {
|
|||
match callable {
|
||||
Value::Closure(closure) => {
|
||||
let result =
|
||||
self.call(closure.lambda(), closure.upvalues().to_vec(), 1)?;
|
||||
self.call(closure.lambda(), closure.upvalues().clone(), 1)?;
|
||||
self.push(result)
|
||||
}
|
||||
|
||||
|
@ -468,7 +468,7 @@ impl<'o> VM<'o> {
|
|||
// closure.
|
||||
let mut frame = self.frame_mut();
|
||||
frame.lambda = lambda;
|
||||
frame.upvalues = closure.upvalues().to_vec();
|
||||
frame.upvalues = closure.upvalues().clone();
|
||||
frame.ip = 0; // reset instruction pointer to beginning
|
||||
}
|
||||
|
||||
|
@ -658,7 +658,7 @@ impl<'o> VM<'o> {
|
|||
fn populate_upvalues(
|
||||
&mut self,
|
||||
count: usize,
|
||||
mut upvalues: RefMut<'_, Vec<Value>>,
|
||||
mut upvalues: RefMut<'_, Upvalues>,
|
||||
) -> EvalResult<()> {
|
||||
for _ in 0..count {
|
||||
match self.inc_ip() {
|
||||
|
@ -744,7 +744,7 @@ fn unwrap_or_clone_rc<T: Clone>(rc: Rc<T>) -> T {
|
|||
|
||||
pub fn run_lambda(observer: &mut dyn Observer, lambda: Rc<Lambda>) -> EvalResult<Value> {
|
||||
let mut vm = VM::new(observer);
|
||||
let value = vm.call(lambda, vec![], 0)?;
|
||||
let value = vm.call(lambda, Upvalues::with_capacity(0), 0)?;
|
||||
vm.force_for_output(&value)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue