1use alloc::{boxed::Box, sync::Arc, vec::Vec};
2
3use miden_core::{DebugOptions, 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},
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,
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 (id, handler) in library.handlers {
65 self.event_handlers.register(id, 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 load_handler(
82 &mut self,
83 id: u32,
84 handler: impl EventHandler,
85 ) -> Result<(), ExecutionError> {
86 self.event_handlers.register(id, Box::new(handler))
87 }
88
89 pub fn unload_handler(&mut self, id: u32) -> bool {
92 self.event_handlers.unregister(id)
93 }
94
95 pub fn replace_handler(&mut self, id: u32, handler: impl EventHandler) -> bool {
98 let existed = self.event_handlers.unregister(id);
99 self.load_handler(id, handler).unwrap();
100 existed
101 }
102
103 pub fn with_debug_handler<H: DebugHandler>(self, handler: H) -> DefaultHost<H, S> {
105 DefaultHost::<H, S> {
106 store: self.store,
107 event_handlers: self.event_handlers,
108 debug_handler: handler,
109 source_manager: self.source_manager,
110 }
111 }
112}
113
114impl<D, S> BaseHost for DefaultHost<D, S>
115where
116 D: DebugHandler,
117 S: SourceManager,
118{
119 fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>> {
120 self.store.get(node_digest)
121 }
122
123 fn get_label_and_source_file(
124 &self,
125 location: &Location,
126 ) -> (SourceSpan, Option<Arc<SourceFile>>) {
127 let maybe_file = self.source_manager.get_by_uri(location.uri());
128 let span = self.source_manager.location_to_span(location.clone()).unwrap_or_default();
129 (span, maybe_file)
130 }
131
132 fn on_debug(
133 &mut self,
134 process: &mut ProcessState,
135 options: &DebugOptions,
136 ) -> Result<(), ExecutionError> {
137 self.debug_handler.on_debug(process, options)
138 }
139
140 fn on_trace(
141 &mut self,
142 process: &mut ProcessState,
143 trace_id: u32,
144 ) -> Result<(), ExecutionError> {
145 self.debug_handler.on_trace(process, trace_id)
146 }
147
148 fn on_assert_failed(&mut self, _process: &ProcessState, _err_code: Felt) {}
150}
151
152impl<D, S> SyncHost for DefaultHost<D, S>
153where
154 D: DebugHandler,
155 S: SourceManager,
156{
157 fn on_event(
158 &mut self,
159 process: &ProcessState,
160 event_id: u32,
161 ) -> Result<Vec<AdviceMutation>, EventError> {
162 if let Some(mutations) = self.event_handlers.handle_event(event_id, process)? {
163 return Ok(mutations);
165 }
166
167 #[derive(Debug, thiserror::Error)]
169 #[error("no event handler was registered with given id")]
170 struct UnhandledEvent;
171
172 Err(UnhandledEvent.into())
173 }
174}
175
176impl<D, S> AsyncHost for DefaultHost<D, S>
177where
178 D: DebugHandler,
179 S: SourceManagerSync,
180{
181 fn on_event(
182 &mut self,
183 process: &ProcessState<'_>,
184 event_id: u32,
185 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
186 let result = <Self as SyncHost>::on_event(self, process, event_id);
187 async move { result }
188 }
189}
190
191#[derive(Default)]
197pub struct HostLibrary {
198 pub mast_forest: Arc<MastForest>,
200 pub handlers: Vec<(u32, Box<dyn EventHandler>)>,
202}
203
204impl From<Arc<MastForest>> for HostLibrary {
205 fn from(mast_forest: Arc<MastForest>) -> Self {
206 Self { mast_forest, handlers: vec![] }
207 }
208}
209
210impl From<&Arc<MastForest>> for HostLibrary {
211 fn from(mast_forest: &Arc<MastForest>) -> Self {
212 Self {
213 mast_forest: mast_forest.clone(),
214 handlers: vec![],
215 }
216 }
217}
218
219#[derive(Clone, Default)]
224pub struct DefaultDebugHandler;
225
226impl DebugHandler for DefaultDebugHandler {}