diff options
author | Vincent Ambo <mail@tazj.in> | 2023-03-10T11·22+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2023-03-13T20·30+0000 |
commit | cd447e185989494200552c05b8b859fd72cefe95 (patch) | |
tree | 9f2e206799776cfb720e65c0a2fc480f51d5345c | |
parent | d00229753d32de2a38b52a3ae5feddc6ee10cefd (diff) |
feat(tvix/eval): add generator-related functions to RuntimeObserver r/5962
These functions will be used by the changes in the VM to observe the runtime execution of generator frames, and provide a more linear view of the execution of the Tvix VM. Change-Id: I10b1b1933dedc065e7c61d5d6062f0aaeee0097e Reviewed-on: https://cl.tvl.fyi/c/depot/+/8240 Tested-by: BuildkiteCI Reviewed-by: Adam Joseph <adam@westernsemico.com>
-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 } |