1use alloc::{sync::Arc, vec::Vec};
2
3use miden_core::{DebugOptions, EventId, EventName, Felt, Word, mast::MastForest};
4use miden_debug_types::{
5 DefaultSourceManager, Location, SourceFile, SourceManager, SourceManagerSync, SourceSpan,
6};
7
8use crate::{
9 AdviceMutation, AsyncHost, BaseHost, DebugHandler, EventHandler, EventHandlerRegistry,
10 ExecutionError, MastForestStore, MemMastForestStore, ProcessState, SyncHost,
11 host::{EventError, FutureMaybeSend, debug::DefaultDebugHandler},
12};
13
14#[derive(Debug)]
19pub struct DefaultHost<
20 D: DebugHandler = DefaultDebugHandler,
21 S: SourceManager = DefaultSourceManager,
22> {
23 store: MemMastForestStore,
24 event_handlers: EventHandlerRegistry,
25 debug_handler: D,
26 source_manager: Arc<S>,
27}
28
29impl Default for DefaultHost {
30 fn default() -> Self {
31 Self {
32 store: MemMastForestStore::default(),
33 event_handlers: EventHandlerRegistry::default(),
34 debug_handler: DefaultDebugHandler::default(),
35 source_manager: Arc::new(DefaultSourceManager::default()),
36 }
37 }
38}
39
40impl<D, S> DefaultHost<D, S>
41where
42 D: DebugHandler,
43 S: SourceManager,
44{
45 pub fn with_source_manager<O>(self, source_manager: Arc<O>) -> DefaultHost<D, O>
48 where
49 O: SourceManager,
50 {
51 DefaultHost::<D, O> {
52 store: self.store,
53 event_handlers: self.event_handlers,
54 debug_handler: self.debug_handler,
55 source_manager,
56 }
57 }
58
59 pub fn load_library(&mut self, library: impl Into<HostLibrary>) -> Result<(), ExecutionError> {
61 let library = library.into();
62 self.store.insert(library.mast_forest);
63
64 for (event, handler) in library.handlers {
65 self.event_handlers.register(event, handler)?;
66 }
67 Ok(())
68 }
69
70 pub fn with_library(mut self, library: impl Into<HostLibrary>) -> Result<Self, ExecutionError> {
73 self.load_library(library)?;
74 Ok(self)
75 }
76
77 pub fn register_handler(
82 &mut self,
83 event: EventName,
84 handler: Arc<dyn EventHandler>,
85 ) -> Result<(), ExecutionError> {
86 self.event_handlers.register(event, handler)
87 }
88
89 pub fn unregister_handler(&mut self, id: EventId) -> bool {
92 self.event_handlers.unregister(id)
93 }
94
95 pub fn replace_handler(&mut self, event: EventName, handler: Arc<dyn EventHandler>) -> bool {
98 let event_id = event.to_event_id();
99 let existed = self.event_handlers.unregister(event_id);
100 self.register_handler(event, handler).unwrap();
101 existed
102 }
103
104 pub fn with_debug_handler<H: DebugHandler>(self, handler: H) -> DefaultHost<H, S> {
106 DefaultHost::<H, S> {
107 store: self.store,
108 event_handlers: self.event_handlers,
109 debug_handler: handler,
110 source_manager: self.source_manager,
111 }
112 }
113
114 pub fn debug_handler(&self) -> &D {
117 &self.debug_handler
118 }
119}
120
121impl<D, S> BaseHost for DefaultHost<D, S>
122where
123 D: DebugHandler,
124 S: SourceManager,
125{
126 fn get_label_and_source_file(
127 &self,
128 location: &Location,
129 ) -> (SourceSpan, Option<Arc<SourceFile>>) {
130 let maybe_file = self.source_manager.get_by_uri(location.uri());
131 let span = self.source_manager.location_to_span(location.clone()).unwrap_or_default();
132 (span, maybe_file)
133 }
134
135 fn on_debug(
136 &mut self,
137 process: &mut ProcessState,
138 options: &DebugOptions,
139 ) -> Result<(), ExecutionError> {
140 self.debug_handler.on_debug(process, options)
141 }
142
143 fn on_trace(
144 &mut self,
145 process: &mut ProcessState,
146 trace_id: u32,
147 ) -> Result<(), ExecutionError> {
148 self.debug_handler.on_trace(process, trace_id)
149 }
150
151 fn on_assert_failed(&mut self, _process: &ProcessState, _err_code: Felt) {}
153
154 fn resolve_event(&self, event_id: EventId) -> Option<&EventName> {
155 self.event_handlers.resolve_event(event_id)
156 }
157}
158
159impl<D, S> SyncHost for DefaultHost<D, S>
160where
161 D: DebugHandler,
162 S: SourceManager,
163{
164 fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>> {
165 self.store.get(node_digest)
166 }
167
168 fn on_event(&mut self, process: &ProcessState) -> Result<Vec<AdviceMutation>, EventError> {
169 let event_id = EventId::from_felt(process.get_stack_item(0));
170 if let Some(mutations) = self.event_handlers.handle_event(event_id, process)? {
171 return Ok(mutations);
173 }
174
175 #[derive(Debug, thiserror::Error)]
177 #[error("no event handler registered")]
178 struct UnhandledEvent;
179
180 Err(UnhandledEvent.into())
181 }
182}
183
184impl<D, S> AsyncHost for DefaultHost<D, S>
185where
186 D: DebugHandler,
187 S: SourceManagerSync,
188{
189 fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend<Option<Arc<MastForest>>> {
190 let result = <Self as SyncHost>::get_mast_forest(self, node_digest);
191 async move { result }
192 }
193
194 fn on_event(
195 &mut self,
196 process: &ProcessState<'_>,
197 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
198 let result = <Self as SyncHost>::on_event(self, process);
199 async move { result }
200 }
201}
202
203pub struct NoopHost;
208
209impl BaseHost for NoopHost {
210 #[inline(always)]
211 fn get_label_and_source_file(
212 &self,
213 _location: &Location,
214 ) -> (SourceSpan, Option<Arc<SourceFile>>) {
215 (SourceSpan::UNKNOWN, None)
216 }
217}
218
219impl SyncHost for NoopHost {
220 #[inline(always)]
221 fn get_mast_forest(&self, _node_digest: &Word) -> Option<Arc<MastForest>> {
222 None
223 }
224
225 #[inline(always)]
226 fn on_event(&mut self, _process: &ProcessState<'_>) -> Result<Vec<AdviceMutation>, EventError> {
227 Ok(Vec::new())
228 }
229}
230
231impl AsyncHost for NoopHost {
232 #[inline(always)]
233 fn get_mast_forest(
234 &self,
235 _node_digest: &Word,
236 ) -> impl FutureMaybeSend<Option<Arc<MastForest>>> {
237 async { None }
238 }
239
240 #[inline(always)]
241 fn on_event(
242 &mut self,
243 _process: &ProcessState<'_>,
244 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
245 async { Ok(Vec::new()) }
246 }
247}
248
249#[derive(Default)]
255pub struct HostLibrary {
256 pub mast_forest: Arc<MastForest>,
258 pub handlers: Vec<(EventName, Arc<dyn EventHandler>)>,
260}
261
262impl From<Arc<MastForest>> for HostLibrary {
263 fn from(mast_forest: Arc<MastForest>) -> Self {
264 Self { mast_forest, handlers: vec![] }
265 }
266}
267
268impl From<&Arc<MastForest>> for HostLibrary {
269 fn from(mast_forest: &Arc<MastForest>) -> Self {
270 Self {
271 mast_forest: mast_forest.clone(),
272 handlers: vec![],
273 }
274 }
275}