feat(tvix/eval): track source spans for builtin access

As of this commit, the source spans of all emitted bytecode are fully
tracked.

Change-Id: I4c83deee0fc3f5e6fd6acad5a39047aec693b388
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6403
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-09-01 19:24:07 +03:00 committed by tazjin
parent 6cbd580ba5
commit 8033300900
2 changed files with 9 additions and 26 deletions

View file

@ -29,12 +29,6 @@ pub struct Chunk {
}
impl Chunk {
pub fn push_op_old(&mut self, data: OpCode) -> CodeIdx {
let idx = self.code.len();
self.code.push(data);
CodeIdx(idx)
}
pub fn push_op(&mut self, data: OpCode, span: codemap::Span) -> CodeIdx {
let idx = self.code.len();
self.code.push(data);

View file

@ -57,7 +57,7 @@ impl LambdaCtx {
/// Alias for the map of globally available functions that should
/// implicitly be resolvable in the global scope.
type GlobalsMap = HashMap<&'static str, Rc<dyn Fn(&mut Compiler)>>;
type GlobalsMap = HashMap<&'static str, Rc<dyn Fn(&mut Compiler, rnix::ast::Ident)>>;
struct Compiler<'code> {
contexts: Vec<LambdaCtx>,
@ -103,11 +103,6 @@ impl Compiler<'_> {
&mut self.context_mut().scope
}
/// Push a single instruction to the current bytecode chunk.
fn push_op_old(&mut self, data: OpCode) -> CodeIdx {
self.chunk().push_op_old(data)
}
/// Push a single instruction to the current bytecode chunk and
/// track the source span from which it was compiled.
fn push_op<T: AstNode>(&mut self, data: OpCode, node: &T) -> CodeIdx {
@ -122,12 +117,6 @@ impl Compiler<'_> {
self.chunk().push_op(data, span)
}
/// Emit a single constant to the current bytecode chunk.
fn emit_constant_old(&mut self, value: Value) {
let idx = self.chunk().push_constant(value);
self.push_op_old(OpCode::OpConstant(idx));
}
/// Emit a single constant to the current bytecode chunk and track
/// the source span from which it was compiled.
fn emit_constant<T: AstNode>(&mut self, value: Value, node: &T) {
@ -765,7 +754,7 @@ impl Compiler<'_> {
// the global directly.
if let Some(global) = self.globals.get(ident.text()) {
if !self.scope().is_poisoned(ident.text()) {
global.clone()(self);
global.clone()(self, node.clone());
return;
}
}
@ -1292,29 +1281,29 @@ fn prepare_globals(additional: HashMap<&'static str, Value>) -> GlobalsMap {
globals.insert(
"true",
Rc::new(|compiler| {
compiler.chunk().push_op_old(OpCode::OpTrue);
Rc::new(|compiler, node| {
compiler.push_op(OpCode::OpTrue, &node);
}),
);
globals.insert(
"false",
Rc::new(|compiler| {
compiler.chunk().push_op_old(OpCode::OpFalse);
Rc::new(|compiler, node| {
compiler.push_op(OpCode::OpFalse, &node);
}),
);
globals.insert(
"null",
Rc::new(|compiler| {
compiler.chunk().push_op_old(OpCode::OpNull);
Rc::new(|compiler, node| {
compiler.push_op(OpCode::OpNull, &node);
}),
);
for (ident, value) in additional.into_iter() {
globals.insert(
ident,
Rc::new(move |compiler| compiler.emit_constant_old(value.clone())),
Rc::new(move |compiler, node| compiler.emit_constant(value.clone(), &node)),
);
}