Skip to content

Commit d93c46b

Browse files
committed
fix: register event handlers with VM
1 parent 7508382 commit d93c46b

2 files changed

Lines changed: 57 additions & 6 deletions

File tree

src/exec/executor.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use miden_mast_package::{
1515
MemDependencyResolverByDigest, ResolvedDependency,
1616
};
1717
use miden_processor::{
18-
ContextId, ExecutionError, ExecutionOptions, FastProcessor, Felt, advice::AdviceInputs,
18+
ContextId, ExecutionError, ExecutionOptions, FastProcessor, Felt,
19+
advice::AdviceInputs,
20+
event::{EventHandler, EventName},
1921
trace::RowIndex,
2022
};
2123

@@ -33,6 +35,7 @@ pub struct Executor {
3335
advice: AdviceInputs,
3436
options: ExecutionOptions,
3537
libraries: Vec<Arc<Library>>,
38+
event_handlers: Vec<(EventName, Arc<dyn EventHandler>)>,
3639
dependency_resolver: MemDependencyResolverByDigest,
3740
}
3841
impl Executor {
@@ -63,6 +66,7 @@ impl Executor {
6366
advice: advice_inputs,
6467
options,
6568
libraries: Default::default(),
69+
event_handlers: Default::default(),
6670
dependency_resolver,
6771
}
6872
}
@@ -132,6 +136,16 @@ impl Executor {
132136
self
133137
}
134138

139+
/// Register a VM event handler to be available during execution.
140+
pub fn register_event_handler(
141+
&mut self,
142+
event: EventName,
143+
handler: Arc<dyn EventHandler>,
144+
) -> Result<&mut Self, ExecutionError> {
145+
self.event_handlers.push((event, handler));
146+
Ok(self)
147+
}
148+
135149
/// Convert this [Executor] into a [DebugExecutor], which captures much more information
136150
/// about the program being executed, and must be stepped manually.
137151
pub fn into_debug(
@@ -145,6 +159,10 @@ impl Executor {
145159
for lib in core::mem::take(&mut self.libraries) {
146160
host.load_mast_forest(lib.mast_forest().clone());
147161
}
162+
for (event, handler) in core::mem::take(&mut self.event_handlers) {
163+
host.register_event_handler(event, handler)
164+
.expect("failed to register debug executor event handler");
165+
}
148166

149167
let trace_events: Rc<RefCell<BTreeMap<RowIndex, TraceEvent>>> = Rc::new(Default::default());
150168
let frame_start_events = Rc::clone(&trace_events);

src/exec/host.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
use std::{collections::BTreeMap, num::NonZeroU32, sync::Arc};
22

33
use miden_assembly::SourceManager;
4-
use miden_core::Word;
4+
use miden_core::{
5+
Word,
6+
events::{EventId, EventName},
7+
};
58
use miden_debug_types::{Location, SourceFile, SourceSpan};
69
use miden_processor::{
7-
FutureMaybeSend, Host, MastForestStore, MemMastForestStore, ProcessorState, TraceError,
8-
advice::AdviceMutation, event::EventError, mast::MastForest, trace::RowIndex,
10+
ExecutionError, FutureMaybeSend, Host, MastForestStore, MemMastForestStore, ProcessorState,
11+
TraceError, advice::AdviceMutation,
12+
event::{EventError, EventHandler, EventHandlerRegistry},
13+
mast::MastForest,
14+
trace::RowIndex,
915
};
1016

1117
use super::{TraceEvent, TraceHandler};
@@ -15,6 +21,7 @@ use super::{TraceEvent, TraceHandler};
1521
/// events that record the entry or exit of a procedure call frame.
1622
pub struct DebuggerHost<S: SourceManager + ?Sized> {
1723
store: MemMastForestStore,
24+
event_handlers: EventHandlerRegistry,
1825
tracing_callbacks: BTreeMap<u32, Vec<Box<TraceHandler>>>,
1926
on_assert_failed: Option<Box<TraceHandler>>,
2027
source_manager: Arc<S>,
@@ -27,6 +34,7 @@ where
2734
pub fn new(source_manager: Arc<S>) -> Self {
2835
Self {
2936
store: Default::default(),
37+
event_handlers: EventHandlerRegistry::default(),
3038
tracing_callbacks: Default::default(),
3139
on_assert_failed: None,
3240
source_manager,
@@ -67,6 +75,15 @@ where
6775
pub fn load_mast_forest(&mut self, forest: Arc<MastForest>) {
6876
self.store.insert(forest);
6977
}
78+
79+
/// Registers an event handler for use during program execution.
80+
pub fn register_event_handler(
81+
&mut self,
82+
event: EventName,
83+
handler: Arc<dyn EventHandler>,
84+
) -> Result<(), ExecutionError> {
85+
self.event_handlers.register(event, handler)
86+
}
7087
}
7188

7289
impl<S> Host for DebuggerHost<S>
@@ -88,9 +105,21 @@ where
88105

89106
fn on_event(
90107
&mut self,
91-
_process: &ProcessorState<'_>,
108+
process: &ProcessorState<'_>,
92109
) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
93-
std::future::ready(Ok(Vec::new()))
110+
let event_id = EventId::from_felt(process.get_stack_item(0));
111+
let result = match self.event_handlers.handle_event(event_id, process) {
112+
Ok(Some(mutations)) => Ok(mutations),
113+
Ok(None) => {
114+
#[derive(Debug, thiserror::Error)]
115+
#[error("no event handler registered")]
116+
struct UnhandledEvent;
117+
118+
Err(UnhandledEvent.into())
119+
},
120+
Err(err) => Err(err),
121+
};
122+
std::future::ready(result)
94123
}
95124

96125
fn on_trace(&mut self, process: &ProcessorState<'_>, trace_id: u32) -> Result<(), TraceError> {
@@ -103,4 +132,8 @@ where
103132
}
104133
Ok(())
105134
}
135+
136+
fn resolve_event(&self, event_id: EventId) -> Option<&EventName> {
137+
self.event_handlers.resolve_event(event_id)
138+
}
106139
}

0 commit comments

Comments
 (0)