miden_processor/host/mod.rs
1use alloc::{sync::Arc, vec::Vec};
2use core::future::Future;
3
4use miden_core::{
5 AdviceMap, DebugOptions, Felt, Word, crypto::merkle::InnerNodeInfo, mast::MastForest,
6};
7use miden_debug_types::{Location, SourceFile, SourceSpan};
8
9use crate::{EventError, ExecutionError, ProcessState};
10
11pub(super) mod advice;
12
13#[cfg(feature = "std")]
14mod debug;
15
16pub mod default;
17use default::DefaultDebugHandler;
18
19pub mod handlers;
20use handlers::DebugHandler;
21
22mod mast_forest_store;
23pub use mast_forest_store::{MastForestStore, MemMastForestStore};
24
25// ADVICE MAP MUTATIONS
26// ================================================================================================
27
28/// Any possible way an event can modify the advice map
29#[derive(Debug, PartialEq, Eq)]
30pub enum AdviceMutation {
31 ExtendStack { values: Vec<Felt> },
32 ExtendMap { other: AdviceMap },
33 ExtendMerkleStore { infos: Vec<InnerNodeInfo> },
34}
35
36impl AdviceMutation {
37 pub fn extend_stack(iter: impl IntoIterator<Item = Felt>) -> Self {
38 Self::ExtendStack { values: Vec::from_iter(iter) }
39 }
40
41 pub fn extend_map(other: AdviceMap) -> Self {
42 Self::ExtendMap { other }
43 }
44
45 pub fn extend_merkle_store(infos: impl IntoIterator<Item = InnerNodeInfo>) -> Self {
46 Self::ExtendMerkleStore { infos: Vec::from_iter(infos) }
47 }
48}
49// HOST TRAIT
50// ================================================================================================
51
52/// Defines the common interface between [SyncHost] and [AsyncHost], by which the VM can interact
53/// with the host.
54///
55/// There are three main categories of interactions between the VM and the host:
56/// 1. getting a library's MAST forest,
57/// 2. handling VM events (which can mutate the process' advice provider), and
58/// 3. handling debug and trace events.
59pub trait BaseHost {
60 // REQUIRED METHODS
61 // --------------------------------------------------------------------------------------------
62
63 /// Returns the [`SourceSpan`] and optional [`SourceFile`] for the provided location.
64 fn get_label_and_source_file(
65 &self,
66 location: &Location,
67 ) -> (SourceSpan, Option<Arc<SourceFile>>);
68
69 /// Handles the debug request from the VM.
70 fn on_debug(
71 &mut self,
72 process: &mut ProcessState,
73 options: &DebugOptions,
74 ) -> Result<(), ExecutionError> {
75 DefaultDebugHandler.on_debug(process, options)
76 }
77
78 /// Handles the trace emitted from the VM.
79 fn on_trace(
80 &mut self,
81 process: &mut ProcessState,
82 trace_id: u32,
83 ) -> Result<(), ExecutionError> {
84 DefaultDebugHandler.on_trace(process, trace_id)
85 }
86
87 /// Handles the failure of the assertion instruction.
88 fn on_assert_failed(&mut self, _process: &ProcessState, _err_code: Felt) {}
89}
90
91/// Defines an interface by which the VM can interact with the host.
92///
93/// There are four main categories of interactions between the VM and the host:
94/// 1. accessing the advice provider,
95/// 2. getting a library's MAST forest,
96/// 3. handling VM events (which can mutate the process' advice provider), and
97/// 4. handling debug and trace events.
98pub trait SyncHost: BaseHost {
99 // REQUIRED METHODS
100 // --------------------------------------------------------------------------------------------
101
102 /// Returns MAST forest corresponding to the specified digest, or None if the MAST forest for
103 /// this digest could not be found in this host.
104 fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>>;
105
106 /// Invoked when the VM encounters an `EMIT` operation.
107 ///
108 /// The event ID is available at the top of the stack (position 0) when this handler is called.
109 /// This allows the handler to access both the event ID and any additional context data that
110 /// may have been pushed onto the stack prior to the emit operation.
111 fn on_event(&mut self, process: &ProcessState) -> Result<Vec<AdviceMutation>, EventError>;
112}
113
114// ASYNC HOST trait
115// ================================================================================================
116
117/// Analogous to the [SyncHost] trait, but designed for asynchronous execution contexts.
118pub trait AsyncHost: BaseHost {
119 // REQUIRED METHODS
120 // --------------------------------------------------------------------------------------------
121
122 // Note: we don't use the `async` keyword in this method, since we need to specify the `+ Send`
123 // bound to the returned Future, and `async` doesn't allow us to do that.
124
125 /// Returns MAST forest corresponding to the specified digest, or None if the MAST forest for
126 /// this digest could not be found in this host.
127 fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend<Option<Arc<MastForest>>>;
128
129 /// Handles the event emitted from the VM and provides advice mutations to be applied to
130 /// the advice provider.
131 ///
132 /// The event ID is available at the top of the stack (position 0) when this handler is called.
133 /// This allows the handler to access both the event ID and any additional context data that
134 /// may have been pushed onto the stack prior to the emit operation.
135 fn on_event(
136 &mut self,
137 process: &ProcessState<'_>,
138 ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>>;
139}
140
141/// Alias for a `Future`
142///
143/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
144/// `wasm` compilation targets there is no `Send` bound.
145///
146/// We also provide a blank implementation of this trait for all features.
147#[cfg(target_family = "wasm")]
148pub trait FutureMaybeSend<O>: Future<Output = O> {}
149
150#[cfg(target_family = "wasm")]
151impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> {}
152
153/// Alias for a `Future`
154///
155/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
156/// `wasm` compilation targets there is no `Send` bound.
157///
158/// We also provide a blank implementation of this trait for all features.
159#[cfg(not(target_family = "wasm"))]
160pub trait FutureMaybeSend<O>: Future<Output = O> + Send {}
161
162#[cfg(not(target_family = "wasm"))]
163impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> + Send {}