about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tvix/eval/src/vm.rs32
1 files changed, 16 insertions, 16 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index c851ad83ccad..4ce3505cdb9a 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -126,7 +126,7 @@ impl VM {
         #[cfg(feature = "disassembler")]
         let mut tracer = Tracer::new();
 
-        'dispatch: loop {
+        loop {
             if self.frame().ip == self.chunk().code.len() {
                 // If this is the end of the top-level function,
                 // return, otherwise pop the call frame.
@@ -330,21 +330,8 @@ impl VM {
 
                 OpCode::OpResolveWith => {
                     let ident = self.pop().to_string()?;
-
-                    // Attempt to resolve the variable, starting at
-                    // the back of the with_stack.
-                    'with: for idx in self.with_stack.iter().rev() {
-                        let with = self.stack[*idx].as_attrs()?;
-                        match with.select(ident.as_str()) {
-                            None => continue 'with,
-                            Some(val) => {
-                                self.push(val.clone());
-                                continue 'dispatch;
-                            }
-                        }
-                    }
-
-                    return Err(ErrorKind::UnknownDynamicVariable(ident.to_string()).into());
+                    let value = self.resolve_with(ident.as_str())?;
+                    self.push(value)
                 }
 
                 OpCode::OpAssert => {
@@ -450,6 +437,19 @@ impl VM {
         self.push(Value::String(out.into()));
         Ok(())
     }
+
+    /// Resolve a dynamic identifier through the with-stack at runtime.
+    fn resolve_with(&self, ident: &str) -> EvalResult<Value> {
+        for idx in self.with_stack.iter().rev() {
+            let with = self.stack[*idx].as_attrs()?;
+            match with.select(ident) {
+                None => continue,
+                Some(val) => return Ok(val.clone()),
+            }
+        }
+
+        Err(ErrorKind::UnknownDynamicVariable(ident.to_string()).into())
+    }
 }
 
 // TODO: use Rc::unwrap_or_clone once it is stabilised.