about summary refs log tree commit diff
path: root/tvix/eval/src/disassembler.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-09-04T13·56+0300
committertazjin <tazjin@tvl.su>2022-09-09T21·10+0000
commit8ee4d6d5db44d93c0fff67db87dcb4ae9f885351 (patch)
tree070d533eb3f1c775011695dc25a96c55aad05a8c /tvix/eval/src/disassembler.rs
parent7ae45342df28c7f3feb50334aee535a1d36e2bec (diff)
feat(tvix/eval): implement DisassemblingObserver for compiler r/4775
This type implements an observer that is called whenever the compiler
emits a chunk (after the toplevel, thunks, or lambdas) and prints the
output of the disassembler to its internal writer.

This replaces half of the uses of the `disassembler` feature, which
has been removed from the Cargo configuration.

Note that at this commit runtime tracing is not yet implemented as an
observer.

Change-Id: I7894ca1ba445761aba4ad51d98e4a7b6445f1aea
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6449
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/disassembler.rs')
-rw-r--r--tvix/eval/src/disassembler.rs44
1 files changed, 16 insertions, 28 deletions
diff --git a/tvix/eval/src/disassembler.rs b/tvix/eval/src/disassembler.rs
index 9894dea652e8..d7c9c8895c2e 100644
--- a/tvix/eval/src/disassembler.rs
+++ b/tvix/eval/src/disassembler.rs
@@ -1,13 +1,13 @@
 //! Implements methods for disassembling and printing a representation
 //! of compiled code, as well as tracing the runtime stack during
 //! execution.
+use codemap::CodeMap;
 use std::io::{Stderr, Write};
-use std::rc::Rc;
 use tabwriter::TabWriter;
 
 use crate::chunk::Chunk;
 use crate::opcode::{CodeIdx, OpCode};
-use crate::value::{Lambda, Value};
+use crate::value::Value;
 
 /// Helper struct to trace runtime values and automatically flush the
 /// output after the value is dropped (i.e. in both success and
@@ -42,38 +42,26 @@ impl Drop for Tracer {
     }
 }
 
-fn disassemble_op(tw: &mut TabWriter<Stderr>, chunk: &Chunk, width: usize, offset: usize) {
-    let _ = write!(tw, "{:0width$}\t ", offset, width = width);
+pub fn disassemble_op<W: Write>(
+    tw: &mut W,
+    codemap: &CodeMap,
+    chunk: &Chunk,
+    width: usize,
+    idx: CodeIdx,
+) {
+    let _ = write!(tw, "{:#width$x}\t ", idx.0, width = width);
 
-    let line = chunk.get_line(CodeIdx(offset));
-
-    if offset > 0 && chunk.get_line(CodeIdx(offset - 1)) == line {
+    // Print continuation character if the previous operation was at
+    // the same line, otherwise print the line.
+    let line = chunk.get_line(codemap, idx);
+    if idx.0 > 0 && chunk.get_line(codemap, CodeIdx(idx.0 - 1)) == line {
         write!(tw, "   |\t").unwrap();
     } else {
         write!(tw, "{:4}\t", line).unwrap();
     }
 
-    let _ = match chunk.code[offset] {
-        OpCode::OpConstant(idx) => writeln!(tw, "OpConstant({})", chunk.constant(idx)),
+    let _ = match chunk[idx] {
+        OpCode::OpConstant(idx) => writeln!(tw, "OpConstant({}@{})", chunk[idx], idx.0),
         op => writeln!(tw, "{:?}", op),
     };
 }
-
-/// Disassemble an entire lambda, printing its address and its
-/// operations in human-readable format.
-pub fn disassemble_lambda(lambda: Rc<Lambda>) {
-    let mut tw = TabWriter::new(std::io::stderr());
-    let _ = writeln!(
-        &mut tw,
-        "=== compiled code (@{:p}, {} ops) ===",
-        lambda,
-        lambda.chunk.code.len()
-    );
-
-    let width = format!("{}", lambda.chunk.code.len()).len();
-    for (idx, _) in lambda.chunk.code.iter().enumerate() {
-        disassemble_op(&mut tw, &lambda.chunk, width, idx);
-    }
-
-    let _ = tw.flush();
-}