diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/observer.rs | 92 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 4 |
2 files changed, 89 insertions, 7 deletions
diff --git a/tvix/eval/src/observer.rs b/tvix/eval/src/observer.rs index 6bd4609b0998..533182f09531 100644 --- a/tvix/eval/src/observer.rs +++ b/tvix/eval/src/observer.rs @@ -13,6 +13,7 @@ use tabwriter::TabWriter; use crate::chunk::Chunk; use crate::opcode::{CodeIdx, OpCode}; use crate::value::Lambda; +use crate::vm::generators::GeneratorRequest; use crate::SourceCode; use crate::Value; @@ -39,10 +40,25 @@ pub trait CompilerObserver { /// the Tvix virtual machine at runtime. pub trait RuntimeObserver { /// Called when the runtime enters a new call frame. - fn observe_enter_frame(&mut self, _arg_count: usize, _: &Rc<Lambda>, _call_depth: usize) {} + fn observe_enter_call_frame(&mut self, _arg_count: usize, _: &Rc<Lambda>, _call_depth: usize) {} /// Called when the runtime exits a call frame. - fn observe_exit_frame(&mut self, _frame_at: usize, _stack: &[Value]) {} + fn observe_exit_call_frame(&mut self, _frame_at: usize, _stack: &[Value]) {} + + /// Called when the runtime suspends a call frame. + fn observe_suspend_call_frame(&mut self, _frame_at: usize, _stack: &[Value]) {} + + /// Called when the runtime enters a generator frame. + fn observe_enter_generator(&mut self, _frame_at: usize, _stack: &[Value]) {} + + /// Called when the runtime exits a generator frame. + fn observe_exit_generator(&mut self, _frame_at: usize, _stack: &[Value]) {} + + /// Called when the runtime suspends a generator frame. + fn observe_suspend_generator(&mut self, _frame_at: usize, _stack: &[Value]) {} + + /// Called when a generator requests an action from the VM. + fn observe_generator_request(&mut self, _msg: &GeneratorRequest) {} /// Called when the runtime replaces the current call frame for a /// tail call. @@ -136,7 +152,12 @@ impl<W: Write> TracingObserver<W> { } impl<W: Write> RuntimeObserver for TracingObserver<W> { - fn observe_enter_frame(&mut self, arg_count: usize, lambda: &Rc<Lambda>, call_depth: usize) { + fn observe_enter_call_frame( + &mut self, + arg_count: usize, + lambda: &Rc<Lambda>, + call_depth: usize, + ) { let _ = write!(&mut self.writer, "=== entering "); let _ = if arg_count == 0 { @@ -156,7 +177,8 @@ impl<W: Write> RuntimeObserver for TracingObserver<W> { ); } - fn observe_exit_frame(&mut self, frame_at: usize, stack: &[Value]) { + /// Called when the runtime exits a call frame. + fn observe_exit_call_frame(&mut self, frame_at: usize, stack: &[Value]) { let _ = write!(&mut self.writer, "=== exiting frame {} ===\t[ ", frame_at); for val in stack { @@ -166,6 +188,66 @@ impl<W: Write> RuntimeObserver for TracingObserver<W> { let _ = writeln!(&mut self.writer, "]"); } + fn observe_suspend_call_frame(&mut self, frame_at: usize, stack: &[Value]) { + let _ = write!( + &mut self.writer, + "=== suspending frame {} ===\t[ ", + frame_at + ); + + for val in stack { + let _ = write!(&mut self.writer, "{} ", val); + } + + let _ = writeln!(&mut self.writer, "]"); + } + + fn observe_enter_generator(&mut self, frame_at: usize, stack: &[Value]) { + let _ = write!( + &mut self.writer, + "=== entering generator frame {} ===\t[ ", + frame_at + ); + + for val in stack { + let _ = write!(&mut self.writer, "{} ", val); + } + + let _ = writeln!(&mut self.writer, "]"); + } + + fn observe_exit_generator(&mut self, frame_at: usize, stack: &[Value]) { + let _ = write!( + &mut self.writer, + "=== exiting generator {} ===\t[ ", + frame_at + ); + + for val in stack { + let _ = write!(&mut self.writer, "{} ", val); + } + + let _ = writeln!(&mut self.writer, "]"); + } + + fn observe_suspend_generator(&mut self, frame_at: usize, stack: &[Value]) { + let _ = write!( + &mut self.writer, + "=== suspending generator {} ===\t[ ", + frame_at + ); + + for val in stack { + let _ = write!(&mut self.writer, "{} ", val); + } + + let _ = writeln!(&mut self.writer, "]"); + } + + fn observe_generator_request(&mut self, msg: &GeneratorRequest) { + let _ = writeln!(&mut self.writer, "=== generator requested {} ===", msg); + } + fn observe_enter_builtin(&mut self, name: &'static str) { let _ = writeln!(&mut self.writer, "=== entering builtin {} ===", name); } @@ -184,7 +266,7 @@ impl<W: Write> RuntimeObserver for TracingObserver<W> { let _ = writeln!( &mut self.writer, "=== tail-calling {:p} in frame[{}] ===", - lambda, frame_at + *lambda, frame_at ); } diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 3e3052555639..f5107f9ed738 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -436,7 +436,7 @@ impl<'o> VM<'o> { arg_count: usize, ) -> EvalResult<()> { self.observer - .observe_enter_frame(arg_count, &lambda, self.frames.len() + 1); + .observe_enter_call_frame(arg_count, &lambda, self.frames.len() + 1); let frame = CallFrame { lambda, @@ -472,7 +472,7 @@ impl<'o> VM<'o> { }; self.observer - .observe_exit_frame(self.frames.len() + 1, &self.stack); + .observe_exit_call_frame(self.frames.len() + 1, &self.stack); result } |