about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-10-22T14·26+0300
committertazjin <tazjin@tvl.su>2022-10-23T15·50+0000
commitc9bf7c4cf1d4220b181ef7dc8e9a2b67a7c7ba9d (patch)
treea6a6ab28d998f67436033847c3bceef71af2640c /tvix/eval
parent60f24c3c53eae116bb3051f02f05b74a8ecf37af (diff)
chore(tvix/eval): return detailed TvixBug if an upvalue is missing r/5179
When capturing an upvalue, return a detailed TvixBug error that
contains metadata about what exactly was missing.

This particular thing helps with debugging some scope issues we still
seem to have.

Change-Id: I1089a1df4b3bbc63411a4907c3641a5dc3fad984
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7058
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/vm.rs18
1 files changed, 17 insertions, 1 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 75fe8b32acda..4d049c6d71b0 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -1,6 +1,7 @@
 //! This module implements the virtual (or abstract) machine that runs
 //! Tvix bytecode.
 
+use serde_json::json;
 use std::{ops::DerefMut, path::PathBuf, rc::Rc};
 
 use crate::{
@@ -818,7 +819,22 @@ impl<'o> VM<'o> {
             match self.inc_ip() {
                 OpCode::DataLocalIdx(StackIdx(local_idx)) => {
                     let idx = self.frame().stack_offset + local_idx;
-                    upvalues.deref_mut().push(self.stack[idx].clone());
+
+                    let val = match self.stack.get(idx) {
+                        Some(val) => val.clone(),
+                        None => {
+                            return Err(self.error(ErrorKind::TvixBug {
+                                msg: "upvalue to be captured was missing on stack",
+                                metadata: Some(Rc::new(json!({
+                                    "ip": format!("{:#x}", self.frame().ip.0 - 1),
+                                    "local_idx": local_idx,
+                                    "stack_idx": idx,
+                                }))),
+                            }))
+                        }
+                    };
+
+                    upvalues.deref_mut().push(val);
                 }
 
                 OpCode::DataUpvalueIdx(upv_idx) => {