diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-29T15·24+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-06T16·54+0000 |
commit | 6c895d4b280e6376e833cec80a387c0729b898a3 (patch) | |
tree | f03da5a4f738f25515a6af2e1f4da18d5aa1515d | |
parent | ffbb05e7380e3fc20fa8d4bcacb85e70b29465b2 (diff) |
feat(tvix/eval): implement OpThunk for runtime thunk construction r/4681
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>
-rw-r--r-- | tvix/eval/src/vm.rs | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 68f08b077adf..e32c0d7f6b62 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -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); |