about summary refs log tree commit diff
path: root/tvix/eval/src/value/thunk.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-29T15·07+0300
committertazjin <tazjin@tvl.su>2022-09-06T14·58+0000
commit25c62dd0ef70a37915957bb1eb8ba3f4885c7aad (patch)
treeadfd834383a0238bafc1cd64418b7114e4c4521e /tvix/eval/src/value/thunk.rs
parent8033a7abaea3c44a16eb6d3db477a89c2fa88a82 (diff)
refactor(tvix/eval): introduce UpvalueCarrier trait r/4677
This trait abstracts over the commonalities of upvalue handling
between closures and thunks.

It allows the VM to simplify the code used for setting up upvalues,
without duplicating between the two different types.

Note that this does not yet refactor the VM code to optimally make use
of this.

Change-Id: If8de5181f26ae1fa00d554f1ae6ea473ee4b6070
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6347
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src/value/thunk.rs')
-rw-r--r--tvix/eval/src/value/thunk.rs31
1 files changed, 29 insertions, 2 deletions
diff --git a/tvix/eval/src/value/thunk.rs b/tvix/eval/src/value/thunk.rs
index 57c38e0894..3b7cb7f5f7 100644
--- a/tvix/eval/src/value/thunk.rs
+++ b/tvix/eval/src/value/thunk.rs
@@ -18,9 +18,12 @@
 //! object, but when forcing a thunk, the runtime *must* mutate the
 //! memoisable slot.
 
-use std::{cell::RefCell, rc::Rc};
+use std::{
+    cell::{Ref, RefCell, RefMut},
+    rc::Rc,
+};
 
-use crate::Value;
+use crate::{upvalues::UpvalueCarrier, Value};
 
 use super::Lambda;
 
@@ -53,3 +56,27 @@ impl Thunk {
         })))
     }
 }
+
+impl UpvalueCarrier for Thunk {
+    fn upvalue_count(&self) -> usize {
+        if let ThunkRepr::Suspended { lambda, .. } = &*self.0.borrow() {
+            return lambda.upvalue_count;
+        }
+
+        panic!("upvalues() on non-suspended thunk");
+    }
+
+    fn upvalues(&self) -> Ref<'_, [Value]> {
+        Ref::map(self.0.borrow(), |thunk| match thunk {
+            ThunkRepr::Suspended { upvalues, .. } => upvalues.as_slice(),
+            _ => panic!("upvalues() on non-suspended thunk"),
+        })
+    }
+
+    fn upvalues_mut(&self) -> RefMut<'_, Vec<Value>> {
+        RefMut::map(self.0.borrow_mut(), |thunk| match thunk {
+            ThunkRepr::Suspended { upvalues, .. } => upvalues,
+            _ => panic!("upvalues() on non-suspended thunk"),
+        })
+    }
+}