about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-29T15·24+0300
committertazjin <tazjin@tvl.su>2022-09-06T16·54+0000
commit6c895d4b280e6376e833cec80a387c0729b898a3 (patch)
treef03da5a4f738f25515a6af2e1f4da18d5aa1515d /tvix/eval/src/vm.rs
parentffbb05e7380e3fc20fa8d4bcacb85e70b29465b2 (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>
Diffstat (limited to 'tvix/eval/src/vm.rs')
-rw-r--r--tvix/eval/src/vm.rs19
1 files changed, 17 insertions, 2 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 68f08b077a..e32c0d7f6b 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);