about summary refs log tree commit diff
path: root/tvix/eval/src/compiler/scope.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-27T16·55+0300
committertazjin <tazjin@tvl.su>2022-09-04T17·53+0000
commit932a70d0c25a3d7b8cfb31788348e850648e2aa1 (patch)
tree867c9c42124ca14f002f422caf6150125898b98a /tvix/eval/src/compiler/scope.rs
parent2cd08d136e2a87bbaecbebd5e42216d7e5256906 (diff)
refactor(tvix/eval): track with stack size as a simple integer r/4643
The `With` struct no longer contained any internals after the cleanup
logic for the stack had been moved into Compiler::compile_with,
leaving the `Vec<With>` to essentially act as a counter for the number
of things on the with stack.

That's inefficient of course, so with this commit it actually becomes
an integer (with an encapsulated API within scope::Scope).

Change-Id: I67a00987fc8b46b30d369a96d41e83c8af5b1998
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6311
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src/compiler/scope.rs')
-rw-r--r--tvix/eval/src/compiler/scope.rs25
1 files changed, 18 insertions, 7 deletions
diff --git a/tvix/eval/src/compiler/scope.rs b/tvix/eval/src/compiler/scope.rs
index 93aa39a0d8..e295731e32 100644
--- a/tvix/eval/src/compiler/scope.rs
+++ b/tvix/eval/src/compiler/scope.rs
@@ -65,10 +65,6 @@ pub struct Local {
     pub used: bool,
 }
 
-/// Represents an entry on the runtime with-stack.
-#[derive(Debug)]
-pub struct With {}
-
 /// Represents the current position of a local as resolved in a scope.
 pub enum LocalPosition {
     /// Local is not known in this scope.
@@ -112,9 +108,8 @@ pub struct Scope {
     // How many scopes "deep" are these locals?
     pub scope_depth: usize,
 
-    // Stack indices of attribute sets currently in scope through
-    // `with`.
-    pub with_stack: Vec<With>,
+    // Current size of the `with`-stack at runtime.
+    with_stack_size: usize,
 
     // Users are allowed to override globally defined symbols like
     // `true`, `false` or `null` in scopes. We call this "scope
@@ -151,6 +146,22 @@ impl Scope {
             .retain(|_, poisoned_at| *poisoned_at != depth);
     }
 
+    /// Increase the `with`-stack size of this scope.
+    pub fn push_with(&mut self) {
+        self.with_stack_size += 1;
+    }
+
+    /// Decrease the `with`-stack size of this scope.
+    pub fn pop_with(&mut self) {
+        self.with_stack_size -= 1;
+    }
+
+    /// Does this scope currently require dynamic runtime resolution
+    /// of identifiers that could not be found?
+    pub fn has_with(&self) -> bool {
+        self.with_stack_size > 0
+    }
+
     /// Resolve the stack index of a statically known local.
     pub fn resolve_local(&mut self, name: &str) -> LocalPosition {
         for (idx, local) in self.locals.iter_mut().enumerate().rev() {