about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-28T13·59+0300
committertazjin <tazjin@tvl.su>2022-09-06T14·58+0000
commit1bfe32f4129a1c8627a254fe0fefe18d15339d83 (patch)
tree847948e26fb0a87bb0fe65fea810b0c8a69744ca /tvix/eval
parent6c1948a71a7a52978a3ded23e242d664a5f097de (diff)
feat(tvix/eval): set up deferred upvalues at runtime r/4666
This will leave a sentinel value in the upvalue slot in which the
actual value is to be captured after resolution once a scope is fully
set up.

Change-Id: I12b37b0dc8d32603b03e675c3bd039468e70b354
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6336
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/value/mod.rs6
-rw-r--r--tvix/eval/src/vm.rs4
2 files changed, 7 insertions, 3 deletions
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index 911af9d6ae12..2c839484145a 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -10,6 +10,7 @@ mod list;
 mod string;
 
 use crate::errors::{ErrorKind, EvalResult};
+use crate::opcode::StackIdx;
 pub use attrs::NixAttrs;
 pub use builtin::Builtin;
 pub use function::{Closure, Lambda};
@@ -36,6 +37,7 @@ pub enum Value {
     AttrNotFound,
     DynamicUpvalueMissing(NixString),
     Blueprint(Rc<Lambda>),
+    DeferredUpvalue(StackIdx),
 }
 
 impl Value {
@@ -59,7 +61,8 @@ impl Value {
             Value::AttrPath(_)
             | Value::AttrNotFound
             | Value::DynamicUpvalueMissing(_)
-            | Value::Blueprint(_) => "internal",
+            | Value::Blueprint(_)
+            | Value::DeferredUpvalue(_) => "internal",
         }
     }
 
@@ -169,6 +172,7 @@ impl Display for Value {
             Value::AttrPath(path) => write!(f, "internal[attrpath({})]", path.len()),
             Value::AttrNotFound => f.write_str("internal[not found]"),
             Value::Blueprint(_) => f.write_str("internal[blueprint]"),
+            Value::DeferredUpvalue(_) => f.write_str("internal[deferred_upvalue]"),
             Value::DynamicUpvalueMissing(name) => {
                 write!(f, "internal[no_dyn_upvalue({name})]")
             }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 33ea81087f64..d4eb0657251a 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -426,8 +426,8 @@ impl VM {
                                 closure.push_upvalue(value);
                             }
 
-                            OpCode::DataDeferredLocal(_idx) => {
-                                todo!("deferred local initialisation")
+                            OpCode::DataDeferredLocal(idx) => {
+                                closure.push_upvalue(Value::DeferredUpvalue(idx));
                             }
 
                             _ => panic!("compiler error: missing closure operand"),