about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-09-06T19·08+0300
committertazjin <tazjin@tvl.su>2022-09-11T12·16+0000
commitd75b207a63492cb120bcdd918fcc4178dca2bc36 (patch)
tree9f8a0c5afbc5f7ea9b0b88a8208082738077b4ba /tvix/eval/src/vm.rs
parent6c9abc1f6854c0b9b567ec31790cc052c1e037c9 (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 'tvix/eval/src/vm.rs')
-rw-r--r--tvix/eval/src/vm.rs16
1 files changed, 8 insertions, 8 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index c124a653a0..31964cf909 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)
 }