about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-28T14·50+0300
committertazjin <tazjin@tvl.su>2022-09-06T14·58+0000
commit5c4e102ac8551f6aaa58d54778a2442dc470b0e5 (patch)
treebadcefd13ffccf7e4c3d4382174eaaeb7cb0b39b /tvix/eval
parent025a9a4a0a66c8593cd6b7e4b0f0fa7aea84c353 (diff)
feat(tvix/eval): track whether locals needs to be finalised r/4668
When encountering a deferred local upvalue, the compiler will now mark
the corresponding local as needing a finaliser which makes it possible
to emit the OpFinalise instruction for this stack slot a little bit
down the line.

Change-Id: I3962066f10fc6c6e1472722b8bdb415a811e0740
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6338
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/compiler/mod.rs8
-rw-r--r--tvix/eval/src/compiler/scope.rs4
2 files changed, 12 insertions, 0 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index 85a2309eb366..458c7b432899 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -844,6 +844,7 @@ impl Compiler {
                     // and can be finalised.
                     if slot.unwrap() < idx.0 {
                         self.chunk().push_op(OpCode::DataDeferredLocal(idx));
+                        self.mark_needs_finaliser(slot.unwrap());
                     } else {
                         self.chunk().push_op(OpCode::DataLocalIdx(idx));
                     }
@@ -987,6 +988,7 @@ impl Compiler {
             name,
             depth,
             initialised: false,
+            needs_finaliser: false,
             node: Some(node),
             phantom: false,
             used: false,
@@ -1002,6 +1004,7 @@ impl Compiler {
         self.scope_mut().locals.push(Local {
             depth,
             initialised: true,
+            needs_finaliser: false,
             name: "".into(),
             node: None,
             phantom: true,
@@ -1014,6 +1017,11 @@ impl Compiler {
         self.scope_mut().locals[local_idx].initialised = true;
     }
 
+    /// Mark local as needing a finaliser.
+    fn mark_needs_finaliser(&mut self, local_idx: usize) {
+        self.scope_mut().locals[local_idx].needs_finaliser = true;
+    }
+
     fn resolve_upvalue(&mut self, ctx_idx: usize, name: &str) -> Option<UpvalueIdx> {
         if ctx_idx == 0 {
             // There can not be any upvalue at the outermost context.
diff --git a/tvix/eval/src/compiler/scope.rs b/tvix/eval/src/compiler/scope.rs
index a76a411b461b..310f33d608cd 100644
--- a/tvix/eval/src/compiler/scope.rs
+++ b/tvix/eval/src/compiler/scope.rs
@@ -38,6 +38,10 @@ pub struct Local {
 
     // Is this local known to have been used at all?
     pub used: bool,
+
+    // Does this local need to be finalised after the enclosing scope
+    // is completely constructed?
+    pub needs_finaliser: bool,
 }
 
 impl Local {