From 1bfe32f4129a1c8627a254fe0fefe18d15339d83 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 28 Aug 2022 16:59:08 +0300 Subject: feat(tvix/eval): set up deferred upvalues at runtime 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 --- tvix/eval/src/value/mod.rs | 6 +++++- tvix/eval/src/vm.rs | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'tvix') 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), + 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"), -- cgit 1.4.1