chore(tvix/eval): return detailed TvixBug if an upvalue is missing

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>
This commit is contained in:
Vincent Ambo 2022-10-22 17:26:29 +03:00 committed by tazjin
parent 60f24c3c53
commit c9bf7c4cf1

View file

@ -1,6 +1,7 @@
//! This module implements the virtual (or abstract) machine that runs //! This module implements the virtual (or abstract) machine that runs
//! Tvix bytecode. //! Tvix bytecode.
use serde_json::json;
use std::{ops::DerefMut, path::PathBuf, rc::Rc}; use std::{ops::DerefMut, path::PathBuf, rc::Rc};
use crate::{ use crate::{
@ -818,7 +819,22 @@ impl<'o> VM<'o> {
match self.inc_ip() { match self.inc_ip() {
OpCode::DataLocalIdx(StackIdx(local_idx)) => { OpCode::DataLocalIdx(StackIdx(local_idx)) => {
let idx = self.frame().stack_offset + 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) => { OpCode::DataUpvalueIdx(upv_idx) => {