diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-11T08·55+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-08-25T12·07+0000 |
commit | 9407af5684ca5602df51c4edddc428db7fc98417 (patch) | |
tree | 07c3a47159daf756d18faceb525595f4dfd92cca | |
parent | 75a22321ce55512d5f436168a2f913cf9f8f8ee3 (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>
-rw-r--r-- | tvix/eval/src/value/list.rs | 13 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 21 |
2 files changed, 17 insertions, 17 deletions
diff --git a/tvix/eval/src/value/list.rs b/tvix/eval/src/value/list.rs index f9d85229410a..546d2c88a55a 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 540845d2c668..a64e0b337aea 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> { |