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:
parent
60f24c3c53
commit
c9bf7c4cf1
1 changed files with 17 additions and 1 deletions
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in a new issue