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