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 <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-08-28 16:59:08 +03:00 committed by tazjin
parent 6c1948a71a
commit 1bfe32f412
2 changed files with 7 additions and 3 deletions

View file

@ -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})]")
}

View file

@ -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"),