about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
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);