miden_debug_engine/exec/
host.rs1use std::{
2 collections::{BTreeMap, VecDeque},
3 num::NonZeroU32,
4 sync::Arc,
5};
6
7use miden_assembly::SourceManager;
8use miden_core::{
9 Word,
10 events::{EventId, EventName},
11};
12use miden_debug_types::{Location, SourceFile, SourceSpan};
13use miden_processor::{
14 ExecutionError, FutureMaybeSend, Host, MastForestStore, MemMastForestStore, ProcessorState,
15 TraceError,
16 advice::AdviceMutation,
17 event::{EventError, EventHandler, EventHandlerRegistry},
18 mast::MastForest,
19 trace::RowIndex,
20};
21
22use super::{TraceEvent, TraceHandler};
23
24pub struct DebuggerHost<S: SourceManager + ?Sized> {
28 store: MemMastForestStore,
29 event_handlers: EventHandlerRegistry,
30 tracing_callbacks: BTreeMap<u32, Vec<Box<TraceHandler>>>,
31 on_assert_failed: Option<Box<TraceHandler>>,
32 source_manager: Arc<S>,
33 event_replay: VecDeque<Vec<AdviceMutation>>,
34}
35impl<S> DebuggerHost<S>
36where
37 S: SourceManager + ?Sized,
38{
39 pub fn new(source_manager: Arc<S>) -> Self {
41 Self {
42 store: Default::default(),
43 event_handlers: EventHandlerRegistry::default(),
44 tracing_callbacks: Default::default(),
45 on_assert_failed: None,
46 source_manager,
47 event_replay: VecDeque::new(),
48 }
49 }
50
51 pub fn set_event_replay(&mut self, events: VecDeque<Vec<AdviceMutation>>) {
57 self.event_replay = events;
58 }
59
60 pub fn register_trace_handler<F>(&mut self, event: TraceEvent, callback: F)
62 where
63 F: FnMut(RowIndex, TraceEvent) + 'static,
64 {
65 let key = match event {
66 TraceEvent::AssertionFailed(None) => u32::MAX,
67 ev => ev.into(),
68 };
69 self.tracing_callbacks.entry(key).or_default().push(Box::new(callback));
70 }
71
72 pub fn register_assert_failed_tracer<F>(&mut self, callback: F)
74 where
75 F: FnMut(RowIndex, TraceEvent) + 'static,
76 {
77 self.on_assert_failed = Some(Box::new(callback));
78 }
79
80 pub fn handle_assert_failed(&mut self, clk: RowIndex, err_code: Option<NonZeroU32>) {
85 if let Some(handler) = self.on_assert_failed.as_mut() {
86 handler(clk, TraceEvent::AssertionFailed(err_code));
87 }
88 }
89
90 pub fn load_mast_forest(&mut self, forest: Arc<MastForest>) {
92 self.store.insert(forest);
93 }
94
95 pub fn register_event_handler(
97 &mut self,
98 event: EventName,
99 handler: Arc<dyn EventHandler>,
100 ) -> Result<(), ExecutionError> {
101 self.event_handlers.register(event, handler)
102 }
103}
104
105impl<S> Host for DebuggerHost<S>
106where
107 S: SourceManager + ?Sized,
108{
109 fn get_label_and_source_file(
110 &self,
111 location: &Location,
112 ) -> (SourceSpan, Option<Arc<SourceFile>>) {
113 let maybe_file = self.source_manager.get_by_uri(location.uri());
114 let span = self.source_manager.location_to_span(location.clone()).unwrap_or_default();
115 (span, maybe_file)
116 }
117
118 fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend<Option<Arc<MastForest>>> {
119 std::future::ready(self.store.get(node_digest))
120 }
121
122 fn on_event(
123 &mut self,
124 process: &ProcessorState<'_>,
125 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
126 if !self.event_replay.is_empty() {
127 let mutations = self.event_replay.pop_front().unwrap_or_default();
128 return std::future::ready(Ok(mutations));
129 }
130
131 let event_id = EventId::from_felt(process.get_stack_item(0));
132 let result = match self.event_handlers.handle_event(event_id, process) {
133 Ok(Some(mutations)) => Ok(mutations),
134 Ok(None) => {
135 #[derive(Debug, thiserror::Error)]
136 #[error("no event handler registered")]
137 struct UnhandledEvent;
138
139 Err(UnhandledEvent.into())
140 }
141 Err(err) => Err(err),
142 };
143 std::future::ready(result)
144 }
145
146 fn on_trace(&mut self, process: &ProcessorState<'_>, trace_id: u32) -> Result<(), TraceError> {
147 let event = TraceEvent::from(trace_id);
148 let clk = process.clock();
149 if let Some(handlers) = self.tracing_callbacks.get_mut(&trace_id) {
150 for handler in handlers.iter_mut() {
151 handler(clk, event);
152 }
153 }
154 Ok(())
155 }
156
157 fn resolve_event(&self, event_id: EventId) -> Option<&EventName> {
158 self.event_handlers.resolve_event(event_id)
159 }
160}