diff options
author | Vincent Ambo <mail@tazj.in> | 2022-09-06T19·08+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-11T12·16+0000 |
commit | d75b207a63492cb120bcdd918fcc4178dca2bc36 (patch) | |
tree | 9f8a0c5afbc5f7ea9b0b88a8208082738077b4ba /tvix/eval/src/vm.rs | |
parent | 6c9abc1f6854c0b9b567ec31790cc052c1e037c9 (diff) |
refactor(tvix/eval): introduce Upvalues struct in closures & thunks r/4800
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>
Diffstat (limited to '')
-rw-r--r-- | tvix/eval/src/vm.rs | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index c124a653a019..31964cf90969 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -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) } |