miden_processor/fast/
step.rs1use alloc::{sync::Arc, vec::Vec};
4use core::ops::ControlFlow;
5
6use miden_core::{mast::MastForest, program::KernelDescriptor};
7use miden_mast_package::debug_info::{DebugSourceNodeId, PackageDebugInfo};
8
9use crate::{
10 ExecutionError, FastProcessor, SourceInlineCallContext, Stopper,
11 continuation_stack::{Continuation, ContinuationStack},
12};
13
14#[derive(Debug)]
20pub struct ResumeContext {
21 pub(crate) current_forest: Arc<MastForest>,
22 pub(crate) continuation_stack: ContinuationStack<Arc<MastForest>>,
23 pub(crate) kernel: KernelDescriptor,
24 pub(crate) package_debug_info: Option<Arc<PackageDebugInfo>>,
25 pub(crate) inline_call_contexts: Vec<Option<SourceInlineCallContext>>,
26}
27
28impl ResumeContext {
29 pub fn continuation_stack(&self) -> &ContinuationStack<Arc<MastForest>> {
31 &self.continuation_stack
32 }
33
34 pub fn current_forest(&self) -> &Arc<MastForest> {
36 &self.current_forest
37 }
38
39 pub fn debug_info(&self) -> Option<Arc<PackageDebugInfo>> {
41 self.package_debug_info.clone()
42 }
43
44 pub fn next_source_node_id(&self) -> Option<DebugSourceNodeId> {
46 self.continuation_stack
47 .peek_continuation_with_source_node_id()
48 .and_then(|(_, source_node_id)| source_node_id)
49 }
50
51 pub fn inherited_inline_call_contexts(&self) -> impl Iterator<Item = &SourceInlineCallContext> {
54 let effective_depth = self.continuation_stack.iter_continuations_for_next_clock().fold(
55 self.inline_call_contexts.len(),
56 |depth, continuation| match continuation {
57 Continuation::EnterForest { inline_context_depth, .. } => *inline_context_depth,
58 Continuation::FinishDyn(_) => depth.saturating_sub(1),
59 _ => depth,
60 },
61 );
62 self.inline_call_contexts[..effective_depth.min(self.inline_call_contexts.len())]
63 .iter()
64 .rev()
65 .filter_map(Option::as_ref)
66 }
67
68 pub fn kernel(&self) -> &KernelDescriptor {
70 &self.kernel
71 }
72}
73
74pub struct NeverStopper;
80
81impl Stopper for NeverStopper {
82 type Processor = FastProcessor;
83 type Forest = Arc<MastForest>;
84
85 #[inline(always)]
86 fn should_stop(
87 &self,
88 processor: &FastProcessor,
89 continuation_stack: &ContinuationStack<Arc<MastForest>>,
90 _continuation_after_stop: impl FnOnce() -> Option<(
91 Continuation<Arc<MastForest>>,
92 Option<DebugSourceNodeId>,
93 )>,
94 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
95 check_if_max_cycles_exceeded(processor)?;
96 check_if_continuation_stack_too_large(processor, continuation_stack)
97 }
98}
99
100pub struct StepStopper;
103
104impl Stopper for StepStopper {
105 type Processor = FastProcessor;
106 type Forest = Arc<MastForest>;
107
108 #[inline(always)]
109 fn should_stop(
110 &self,
111 processor: &FastProcessor,
112 continuation_stack: &ContinuationStack<Arc<MastForest>>,
113 continuation_after_stop: impl FnOnce() -> Option<(
114 Continuation<Arc<MastForest>>,
115 Option<DebugSourceNodeId>,
116 )>,
117 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
118 check_if_max_cycles_exceeded(processor)?;
119 check_if_continuation_stack_too_large(processor, continuation_stack)?;
120
121 ControlFlow::Break(BreakReason::Stopped(continuation_after_stop()))
122 }
123}
124
125#[inline(always)]
127fn check_if_max_cycles_exceeded<F>(processor: &FastProcessor) -> ControlFlow<BreakReason<F>> {
128 if processor.clk > processor.options.max_cycles() as usize {
129 ControlFlow::Break(BreakReason::Err(ExecutionError::CycleLimitExceeded(
130 processor.options.max_cycles(),
131 )))
132 } else {
133 ControlFlow::Continue(())
134 }
135}
136
137#[inline(always)]
140fn check_if_continuation_stack_too_large<F>(
141 processor: &FastProcessor,
142 continuation_stack: &ContinuationStack<F>,
143) -> ControlFlow<BreakReason<F>> {
144 if continuation_stack.len() > processor.options.max_num_continuations() {
145 ControlFlow::Break(BreakReason::Err(ExecutionError::Internal(
146 "continuation stack size exceeded the allowed maximum",
147 )))
148 } else {
149 ControlFlow::Continue(())
150 }
151}
152
153#[derive(Debug)]
158pub enum BreakReason<F> {
159 Err(ExecutionError),
161 Stopped(Option<(Continuation<F>, Option<DebugSourceNodeId>)>),
171}