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/value | |
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 'tvix/eval/src/value')
-rw-r--r-- | tvix/eval/src/value/function.rs | 15 | ||||
-rw-r--r-- | tvix/eval/src/value/thunk.rs | 17 |
2 files changed, 20 insertions, 12 deletions
diff --git a/tvix/eval/src/value/function.rs b/tvix/eval/src/value/function.rs index 4f5cc1154bd7..758994504e45 100644 --- a/tvix/eval/src/value/function.rs +++ b/tvix/eval/src/value/function.rs @@ -4,7 +4,10 @@ use std::{ rc::Rc, }; -use crate::{chunk::Chunk, upvalues::UpvalueCarrier, Value}; +use crate::{ + chunk::Chunk, + upvalues::{UpvalueCarrier, Upvalues}, +}; #[derive(Clone, Debug)] pub struct Lambda { @@ -30,7 +33,7 @@ impl Lambda { #[derive(Clone, Debug)] pub struct InnerClosure { pub lambda: Rc<Lambda>, - pub upvalues: Vec<Value>, + upvalues: Upvalues, } #[repr(transparent)] @@ -40,7 +43,7 @@ pub struct Closure(Rc<RefCell<InnerClosure>>); impl Closure { pub fn new(lambda: Rc<Lambda>) -> Self { Closure(Rc::new(RefCell::new(InnerClosure { - upvalues: Vec::with_capacity(lambda.upvalue_count), + upvalues: Upvalues::with_capacity(lambda.upvalue_count), lambda, }))) } @@ -59,11 +62,11 @@ impl UpvalueCarrier for Closure { self.0.borrow().lambda.upvalue_count } - fn upvalues(&self) -> Ref<'_, [Value]> { - Ref::map(self.0.borrow(), |c| c.upvalues.as_slice()) + fn upvalues(&self) -> Ref<'_, Upvalues> { + Ref::map(self.0.borrow(), |c| &c.upvalues) } - fn upvalues_mut(&self) -> RefMut<'_, Vec<Value>> { + fn upvalues_mut(&self) -> RefMut<'_, Upvalues> { RefMut::map(self.0.borrow_mut(), |c| &mut c.upvalues) } } diff --git a/tvix/eval/src/value/thunk.rs b/tvix/eval/src/value/thunk.rs index ad56b5eaf646..5098be186fa8 100644 --- a/tvix/eval/src/value/thunk.rs +++ b/tvix/eval/src/value/thunk.rs @@ -24,7 +24,12 @@ use std::{ rc::Rc, }; -use crate::{errors::ErrorKind, upvalues::UpvalueCarrier, vm::VM, Value}; +use crate::{ + errors::ErrorKind, + upvalues::{UpvalueCarrier, Upvalues}, + vm::VM, + Value, +}; use super::Lambda; @@ -35,7 +40,7 @@ enum ThunkRepr { /// execution. Suspended { lambda: Rc<Lambda>, - upvalues: Vec<Value>, + upvalues: Upvalues, }, /// Thunk currently under-evaluation; encountering a blackhole @@ -52,7 +57,7 @@ pub struct Thunk(Rc<RefCell<ThunkRepr>>); impl Thunk { pub fn new(lambda: Rc<Lambda>) -> Self { Thunk(Rc::new(RefCell::new(ThunkRepr::Suspended { - upvalues: Vec::with_capacity(lambda.upvalue_count), + upvalues: Upvalues::with_capacity(lambda.upvalue_count), lambda: lambda.clone(), }))) } @@ -119,14 +124,14 @@ impl UpvalueCarrier for Thunk { panic!("upvalues() on non-suspended thunk"); } - fn upvalues(&self) -> Ref<'_, [Value]> { + fn upvalues(&self) -> Ref<'_, Upvalues> { Ref::map(self.0.borrow(), |thunk| match thunk { - ThunkRepr::Suspended { upvalues, .. } => upvalues.as_slice(), + ThunkRepr::Suspended { upvalues, .. } => upvalues, _ => panic!("upvalues() on non-suspended thunk"), }) } - fn upvalues_mut(&self) -> RefMut<'_, Vec<Value>> { + fn upvalues_mut(&self) -> RefMut<'_, Upvalues> { RefMut::map(self.0.borrow_mut(), |thunk| match thunk { ThunkRepr::Suspended { upvalues, .. } => upvalues, _ => panic!("upvalues() on non-suspended thunk"), |