about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-11T08·55+0300
committertazjin <tazjin@tvl.su>2022-08-25T12·07+0000
commit9407af5684ca5602df51c4edddc428db7fc98417 (patch)
tree07c3a47159daf756d18faceb525595f4dfd92cca /tvix
parent75a22321ce55512d5f436168a2f913cf9f8f8ee3 (diff)
refactor(tvix/eval): encapsulate list construction in value::list r/4480
Ensuring that the implementation is not leaking out of the module lets
us keep things open for optimisations (e.g. empty list or pairs
through tuples).

Change-Id: I18fd9b7740f28c55736471e16c6b4095a05dd6d0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6145
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix')
-rw-r--r--tvix/eval/src/value/list.rs13
-rw-r--r--tvix/eval/src/vm.rs21
2 files changed, 17 insertions, 17 deletions
diff --git a/tvix/eval/src/value/list.rs b/tvix/eval/src/value/list.rs
index f9d8522941..546d2c88a5 100644
--- a/tvix/eval/src/value/list.rs
+++ b/tvix/eval/src/value/list.rs
@@ -4,7 +4,7 @@ use std::fmt::Display;
 use super::Value;
 
 #[derive(Clone, Debug, PartialEq)]
-pub struct NixList(pub Vec<Value>);
+pub struct NixList(Vec<Value>);
 
 impl Display for NixList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -26,4 +26,15 @@ impl NixList {
         lhs.0.append(&mut rhs.0);
         lhs
     }
+
+    pub fn construct(count: usize, stack_slice: Vec<Value>) -> Self {
+        debug_assert!(
+            count == stack_slice.len(),
+            "NixList::construct called with count == {}, but slice.len() == {}",
+            count,
+            stack_slice.len(),
+        );
+
+        NixList(stack_slice)
+    }
 }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 540845d2c6..a64e0b337a 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -150,7 +150,11 @@ impl VM {
                     self.push(Value::Attrs(Rc::new(lhs.update(&rhs))))
                 }
 
-                OpCode::OpList(count) => self.run_list(count)?,
+                OpCode::OpList(count) => {
+                    let list =
+                        NixList::construct(count, self.stack.split_off(self.stack.len() - count));
+                    self.push(Value::List(list));
+                }
 
                 OpCode::OpConcat => {
                     let rhs = self.pop().as_list()?;
@@ -204,21 +208,6 @@ impl VM {
         self.push(Value::String(out.into()));
         Ok(())
     }
-
-    // Construct runtime representation of a list. Because the list
-    // items are on the stack in reverse order, the vector is created
-    // initialised and elements are directly assigned to their
-    // respective indices.
-    fn run_list(&mut self, count: usize) -> EvalResult<()> {
-        let mut list = vec![Value::Null; count];
-
-        for idx in 0..count {
-            list[count - idx - 1] = self.pop();
-        }
-
-        self.push(Value::List(NixList(list)));
-        Ok(())
-    }
 }
 
 pub fn run_chunk(chunk: Chunk) -> EvalResult<Value> {