miden_debug_engine/exec/
host.rs1use std::{collections::VecDeque, num::NonZeroU32, sync::Arc};
2
3use miden_assembly::SourceManager;
4use miden_core::{
5 Word,
6 events::{EventId, EventName},
7};
8use miden_debug_types::{Location, SourceFile, SourceSpan};
9use miden_mast_package::Package;
10use miden_processor::{
11 BaseHost, ExecutionError, FutureMaybeSend, Host, LoadedMastForest, MastForestStore,
12 MemMastForestStore, ProcessorState,
13 advice::AdviceMutation,
14 event::{EventError, EventHandler, EventHandlerRegistry},
15};
16
17use super::advice::clone_advice_mutations;
18
19pub struct DebuggerHost<S: SourceManager + ?Sized> {
23 store: MemMastForestStore,
24 event_handlers: EventHandlerRegistry,
25 #[allow(clippy::type_complexity)]
26 on_assert_failed: Option<Box<dyn FnMut(&ProcessorState<'_>, u32)>>,
27 source_manager: Arc<S>,
28 event_replay: VecDeque<Vec<AdviceMutation>>,
29 event_recording: Option<Vec<Vec<AdviceMutation>>>,
30}
31impl<S> DebuggerHost<S>
32where
33 S: SourceManager + ?Sized,
34{
35 pub fn new(source_manager: Arc<S>) -> Self {
37 Self {
38 store: Default::default(),
39 event_handlers: EventHandlerRegistry::default(),
40 on_assert_failed: None,
41 source_manager,
42 event_replay: VecDeque::new(),
43 event_recording: None,
44 }
45 }
46
47 pub fn set_event_replay(&mut self, events: VecDeque<Vec<AdviceMutation>>) {
53 self.event_replay = events;
54 }
55
56 pub fn with_event_advice_mutations_recording(mut self) -> Self {
66 self.event_recording = Some(Vec::new());
67 self
68 }
69
70 pub fn take_recorded_event_mutations(&mut self) -> Vec<Vec<AdviceMutation>> {
75 self.event_recording.as_mut().map(core::mem::take).unwrap_or_default()
76 }
77
78 pub fn register_assert_failed_tracer<F>(&mut self, callback: F)
80 where
81 F: FnMut(&ProcessorState<'_>, u32) + 'static,
82 {
83 self.on_assert_failed = Some(Box::new(callback));
84 }
85
86 pub fn handle_assert_failed(
91 &mut self,
92 process: &ProcessorState<'_>,
93 err_code: Option<NonZeroU32>,
94 ) {
95 if let Some(handler) = self.on_assert_failed.as_mut() {
96 handler(process, err_code.map(|nz| nz.get()).unwrap_or_default());
97 }
98 }
99
100 pub fn load_package(&mut self, package: Arc<Package>) {
102 let mast = package.mast_forest().clone();
103 let debug_info = package.debug_info();
104 self.store
105 .insert_loaded(LoadedMastForest::with_package_debug_info(mast, debug_info));
106 }
107
108 pub fn load_mast_forest(&mut self, forest: LoadedMastForest) {
110 self.store.insert_loaded(forest);
111 }
112
113 pub fn register_event_handler(
115 &mut self,
116 event: EventName,
117 handler: Arc<dyn EventHandler>,
118 ) -> Result<(), ExecutionError> {
119 self.event_handlers.register(event, handler)
120 }
121}
122
123impl<S> BaseHost for DebuggerHost<S>
124where
125 S: SourceManager + ?Sized,
126{
127 fn get_label_and_source_file(
128 &self,
129 location: &Location,
130 ) -> (SourceSpan, Option<Arc<SourceFile>>) {
131 let maybe_file = self.source_manager.get_by_uri(location.uri());
132 let span = self.source_manager.location_to_span(location.clone()).unwrap_or_default();
133 (span, maybe_file)
134 }
135
136 fn resolve_event(&self, event_id: EventId) -> Option<&EventName> {
137 self.event_handlers.resolve_event(event_id)
138 }
139}
140
141impl<S> Host for DebuggerHost<S>
142where
143 S: SourceManager + ?Sized,
144{
145 fn get_mast_forest(
146 &self,
147 node_digest: &Word,
148 ) -> impl FutureMaybeSend<Option<LoadedMastForest>> {
149 std::future::ready(self.store.get(node_digest))
150 }
151
152 fn on_event(
153 &mut self,
154 process: &ProcessorState<'_>,
155 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
156 if !self.event_replay.is_empty() {
157 let mutations = self.event_replay.pop_front().unwrap_or_default();
158 return std::future::ready(Ok(mutations));
159 }
160
161 let event_id = EventId::from_felt(process.get_stack_item(0));
162 let result = match self.event_handlers.handle_event(event_id, process) {
163 Ok(Some(mutations)) => Ok(mutations),
164 Ok(None) => {
165 #[derive(Debug, thiserror::Error)]
166 #[error("no event handler registered")]
167 struct UnhandledEvent;
168
169 Err(UnhandledEvent.into())
170 }
171 Err(err) => Err(err),
172 };
173 if let (Some(log), Ok(mutations)) = (self.event_recording.as_mut(), &result) {
174 log.push(clone_advice_mutations(mutations));
175 }
176 std::future::ready(result)
177 }
178}