1use alloc::{sync::Arc, vec::Vec};
2
3use miden_air::RowIndex;
4use miden_core::mast::{ExternalNode, MastForest, MastNodeId};
5pub use miden_core::utils::*;
8
9use super::{AdviceProvider, Felt};
10use crate::{AsyncHost, ExecutionError, SyncHost};
11
12pub(crate) fn get_trace_len(trace: &[Vec<Felt>]) -> usize {
18 trace[0].len()
19}
20
21#[inline(always)]
23pub(crate) fn split_element(value: Felt) -> (Felt, Felt) {
24 let value = value.as_int();
25 let lo = (value as u32) as u64;
26 let hi = value >> 32;
27 (Felt::new(hi), Felt::new(lo))
28}
29
30pub(crate) fn split_element_u32_into_u16(value: Felt) -> (Felt, Felt) {
33 let (hi, lo) = split_u32_into_u16(value.as_int());
34 (Felt::new(hi as u64), Felt::new(lo as u64))
35}
36
37pub(crate) fn split_u32_into_u16(value: u64) -> (u16, u16) {
42 const U32MAX: u64 = u32::MAX as u64;
43 debug_assert!(value <= U32MAX, "not a 32-bit value");
44
45 let lo = value as u16;
46 let hi = (value >> 16) as u16;
47
48 (hi, lo)
49}
50
51pub(crate) fn resolve_external_node(
57 external_node: &ExternalNode,
58 advice_provider: &mut AdviceProvider,
59 host: &impl SyncHost,
60) -> Result<(MastNodeId, Arc<MastForest>), ExecutionError> {
61 let node_digest = external_node.digest();
62 let mast_forest = host
63 .get_mast_forest(&node_digest)
64 .ok_or(ExecutionError::no_mast_forest_with_procedure(node_digest, &()))?;
65
66 let root_id = mast_forest
69 .find_procedure_root(node_digest)
70 .ok_or(ExecutionError::malfored_mast_forest_in_host(node_digest, &()))?;
71
72 if mast_forest[root_id].is_external() {
75 return Err(ExecutionError::CircularExternalNode(node_digest));
76 }
77
78 advice_provider
82 .merge_advice_map(mast_forest.advice_map())
83 .map_err(|err| ExecutionError::advice_error(err, RowIndex::from(0), &()))?;
84
85 Ok((root_id, mast_forest))
86}
87
88pub(crate) async fn resolve_external_node_async(
90 external_node: &ExternalNode,
91 advice_provider: &mut AdviceProvider,
92 host: &mut impl AsyncHost,
93) -> Result<(MastNodeId, Arc<MastForest>), ExecutionError> {
94 let node_digest = external_node.digest();
95 let mast_forest = host
96 .get_mast_forest(&node_digest)
97 .await
98 .ok_or(ExecutionError::no_mast_forest_with_procedure(node_digest, &()))?;
99
100 let root_id = mast_forest
103 .find_procedure_root(node_digest)
104 .ok_or(ExecutionError::malfored_mast_forest_in_host(node_digest, &()))?;
105
106 if mast_forest[root_id].is_external() {
109 return Err(ExecutionError::CircularExternalNode(node_digest));
110 }
111
112 advice_provider
116 .merge_advice_map(mast_forest.advice_map())
117 .map_err(|err| ExecutionError::advice_error(err, RowIndex::from(0), &()))?;
118
119 Ok((root_id, mast_forest))
120}