use alloc::sync::Arc;
use miden_core::mast::{ExternalNode, MastForest, MastNodeExt, MastNodeId};
use crate::{
AsyncHost, ExecutionError,
continuation_stack::ContinuationStack,
fast::{FastProcessor, Tracer},
};
impl FastProcessor {
#[inline(always)]
pub(super) async fn execute_external_node(
&mut self,
external_node_id: MastNodeId,
current_forest: &mut Arc<MastForest>,
continuation_stack: &mut ContinuationStack,
host: &mut impl AsyncHost,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
self.execute_before_enter_decorators(external_node_id, current_forest, host)?;
let external_node = current_forest[external_node_id].unwrap_external();
let (resolved_node_id, new_mast_forest) =
self.resolve_external_node(external_node, host).await?;
tracer.record_mast_forest_resolution(resolved_node_id, &new_mast_forest);
continuation_stack.push_finish_external(external_node_id);
continuation_stack.push_enter_forest(current_forest.clone());
continuation_stack.push_start_node(resolved_node_id);
*current_forest = new_mast_forest;
Ok(())
}
async fn resolve_external_node(
&mut self,
external_node: &ExternalNode,
host: &mut impl AsyncHost,
) -> Result<(MastNodeId, Arc<MastForest>), ExecutionError> {
let (root_id, mast_forest) = self
.load_mast_forest(
external_node.digest(),
host,
ExecutionError::no_mast_forest_with_procedure,
&(),
)
.await?;
if mast_forest[root_id].is_external() {
return Err(ExecutionError::CircularExternalNode(external_node.digest()));
}
Ok((root_id, mast_forest))
}
}