diff options
-rw-r--r-- | tvix/eval/src/vm.rs | 32 |
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. |