use alloc::{sync::Arc, vec::Vec};
use core::future::Future;
use miden_core::{
Word,
advice::{AdviceMap, AdviceStack},
crypto::merkle::InnerNodeInfo,
events::{EventId, EventName},
};
use miden_debug_types::{Location, SourceFile, SourceSpan};
use crate::ProcessorState;
pub(super) mod advice;
pub mod debug;
pub mod default;
pub mod handlers;
use handlers::{EventError, TraceError};
mod mast_forest_store;
pub use mast_forest_store::{LoadedMastForest, MastForestStore, MemMastForestStore};
#[derive(Debug, PartialEq, Eq)]
pub enum AdviceMutation {
ExtendStack { stack: AdviceStack },
ExtendMap { other: AdviceMap },
ExtendMerkleStore { infos: Vec<InnerNodeInfo> },
}
impl AdviceMutation {
pub fn extend_advice_stack(stack: AdviceStack) -> Self {
Self::ExtendStack { stack }
}
pub fn extend_map(other: AdviceMap) -> Self {
Self::ExtendMap { other }
}
pub fn extend_merkle_store(infos: impl IntoIterator<Item = InnerNodeInfo>) -> Self {
Self::ExtendMerkleStore { infos: Vec::from_iter(infos) }
}
}
pub trait BaseHost {
fn get_label_and_source_file(
&self,
location: &Location,
) -> (SourceSpan, Option<Arc<SourceFile>>);
fn resolve_event(&self, _event_id: EventId) -> Option<&EventName> {
None
}
fn resolve_trace(&self, _trace_id: EventId) -> Option<&EventName> {
None
}
}
impl<T: BaseHost + ?Sized> BaseHost for &mut T {
fn get_label_and_source_file(
&self,
location: &Location,
) -> (SourceSpan, Option<Arc<SourceFile>>) {
(**self).get_label_and_source_file(location)
}
fn resolve_event(&self, event_id: EventId) -> Option<&EventName> {
(**self).resolve_event(event_id)
}
fn resolve_trace(&self, trace_id: EventId) -> Option<&EventName> {
(**self).resolve_trace(trace_id)
}
}
pub trait SyncHost: BaseHost {
fn get_mast_forest(&self, node_digest: &Word) -> Option<LoadedMastForest>;
fn on_event(&mut self, process: &ProcessorState<'_>)
-> Result<Vec<AdviceMutation>, EventError>;
fn on_trace(&mut self, _process: &ProcessorState<'_>) -> Result<(), TraceError> {
Ok(())
}
}
pub trait Host: BaseHost {
fn get_mast_forest(&self, node_digest: &Word)
-> impl FutureMaybeSend<Option<LoadedMastForest>>;
fn on_event(
&mut self,
process: &ProcessorState<'_>,
) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>>;
fn on_trace(
&mut self,
_process: &ProcessorState<'_>,
) -> impl FutureMaybeSend<Result<(), TraceError>> {
async move { Ok(()) }
}
}
impl<T> Host for T
where
T: SyncHost,
{
fn get_mast_forest(
&self,
node_digest: &Word,
) -> impl FutureMaybeSend<Option<LoadedMastForest>> {
let result = SyncHost::get_mast_forest(self, node_digest);
async move { result }
}
fn on_event(
&mut self,
process: &ProcessorState<'_>,
) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>> {
let result = SyncHost::on_event(self, process);
async move { result }
}
fn on_trace(
&mut self,
process: &ProcessorState<'_>,
) -> impl FutureMaybeSend<Result<(), TraceError>> {
let result = SyncHost::on_trace(self, process);
async move { result }
}
}
#[cfg(target_family = "wasm")]
pub trait FutureMaybeSend<O>: Future<Output = O> {}
#[cfg(target_family = "wasm")]
impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> {}
#[cfg(not(target_family = "wasm"))]
pub trait FutureMaybeSend<O>: Future<Output = O> + Send {}
#[cfg(not(target_family = "wasm"))]
impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> + Send {}