about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-28T14·57+0300
committertazjin <tazjin@tvl.su>2022-09-06T14·58+0000
commit68aad6d4cf5c653154396356366f09dacea73495 (patch)
treeb6b2a81f3e7019923c16bac386db90b10f2df6a3 /tvix
parent5c4e102ac8551f6aaa58d54778a2442dc470b0e5 (diff)
feat(tvix/eval): emit OpFinalise when local scopes are complete r/4669
With this change, the runtime can correctly capture deferred upvalues.

Change-Id: I1e43b7b1ac2553b1812424adfc8bd08ef77bf1ea
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6339
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix')
-rw-r--r--tvix/eval/src/compiler/mod.rs8
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.nix4
3 files changed, 13 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index 458c7b4328..1df44bdfde 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -678,6 +678,7 @@ impl Compiler {
         }
 
         // Second pass to place the values in the correct stack slots.
+        let indices: Vec<usize> = entries.iter().map(|(idx, _)| *idx).collect();
         for (idx, value) in entries.into_iter() {
             self.compile(Some(idx), value);
 
@@ -686,6 +687,13 @@ impl Compiler {
             self.mark_initialised(idx);
         }
 
+        // Third pass to emit finaliser instructions if necessary.
+        for idx in indices {
+            if self.scope().locals[idx].needs_finaliser {
+                self.chunk().push_op(OpCode::OpFinalise(StackIdx(idx)));
+            }
+        }
+
         // Deal with the body, then clean up the locals afterwards.
         self.compile(None, node.body().unwrap());
         self.end_scope();
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.exp
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.exp
@@ -0,0 +1 @@
+42
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.nix
new file mode 100644
index 0000000000..dae170b06b
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-late-binding-closure.nix
@@ -0,0 +1,4 @@
+let
+  f = n: n + a;
+  a = 2;
+in f 40