feat(tvix/eval): implement OpThunk for runtime thunk construction

Implements an operation very similar to `OpClosure` which populates a
thunk's upvalues and leaves it on the stack.

Change-Id: I753b4dfeeaae6919316c7028ec361aaa13d87646
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6350
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-08-29 18:24:09 +03:00 committed by tazjin
parent ffbb05e738
commit 6c895d4b28

View file

@ -8,7 +8,7 @@ use crate::{
errors::{Error, ErrorKind, EvalResult},
opcode::{ConstantIdx, Count, JumpOffset, OpCode, StackIdx, UpvalueIdx},
upvalues::UpvalueCarrier,
value::{Closure, Lambda, NixAttrs, NixList, Value},
value::{Closure, Lambda, NixAttrs, NixList, Thunk, Value},
};
#[cfg(feature = "disassembler")]
@ -427,13 +427,28 @@ impl VM {
self.populate_upvalues(upvalue_count, upvalues)?;
}
OpCode::OpThunk(_idx) => todo!("runtime thunk construction"),
OpCode::OpThunk(idx) => {
let blueprint = match self.chunk().constant(idx) {
Value::Blueprint(lambda) => lambda.clone(),
_ => panic!("compiler bug: non-blueprint in blueprint slot"),
};
let upvalue_count = blueprint.upvalue_count;
let thunk = Thunk::new(blueprint);
let upvalues = thunk.upvalues_mut();
self.push(Value::Thunk(thunk.clone()));
self.populate_upvalues(upvalue_count, upvalues)?;
}
OpCode::OpFinalise(StackIdx(idx)) => {
match &self.stack[self.frame().stack_offset + idx] {
Value::Closure(closure) => closure
.resolve_deferred_upvalues(&self.stack[self.frame().stack_offset..]),
Value::Thunk(thunk) => thunk
.resolve_deferred_upvalues(&self.stack[self.frame().stack_offset..]),
v => {
#[cfg(feature = "disassembler")]
drop(tracer);