miden_processor/fast/
step.rs1use alloc::sync::Arc;
4use core::ops::ControlFlow;
5
6use miden_core::{mast::MastForest, program::Kernel};
7use miden_mast_package::debug_info::{DebugSourceNodeId, PackageDebugInfo};
8
9use crate::{
10 ExecutionError, FastProcessor, 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: Kernel,
24 pub(crate) package_debug_info: Option<Arc<PackageDebugInfo>>,
25}
26
27impl ResumeContext {
28 pub fn continuation_stack(&self) -> &ContinuationStack<Arc<MastForest>> {
30 &self.continuation_stack
31 }
32
33 pub fn current_forest(&self) -> &Arc<MastForest> {
35 &self.current_forest
36 }
37
38 pub fn debug_info(&self) -> Option<Arc<PackageDebugInfo>> {
40 self.package_debug_info.clone()
41 }
42
43 pub fn kernel(&self) -> &Kernel {
45 &self.kernel
46 }
47}
48
49pub struct NeverStopper;
55
56impl Stopper for NeverStopper {
57 type Processor = FastProcessor;
58 type Forest = Arc<MastForest>;
59
60 #[inline(always)]
61 fn should_stop(
62 &self,
63 processor: &FastProcessor,
64 continuation_stack: &ContinuationStack<Arc<MastForest>>,
65 _continuation_after_stop: impl FnOnce() -> Option<(
66 Continuation<Arc<MastForest>>,
67 Option<DebugSourceNodeId>,
68 )>,
69 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
70 check_if_max_cycles_exceeded(processor)?;
71 check_if_continuation_stack_too_large(processor, continuation_stack)
72 }
73}
74
75pub struct StepStopper;
78
79impl Stopper for StepStopper {
80 type Processor = FastProcessor;
81 type Forest = Arc<MastForest>;
82
83 #[inline(always)]
84 fn should_stop(
85 &self,
86 processor: &FastProcessor,
87 continuation_stack: &ContinuationStack<Arc<MastForest>>,
88 continuation_after_stop: impl FnOnce() -> Option<(
89 Continuation<Arc<MastForest>>,
90 Option<DebugSourceNodeId>,
91 )>,
92 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
93 check_if_max_cycles_exceeded(processor)?;
94 check_if_continuation_stack_too_large(processor, continuation_stack)?;
95
96 ControlFlow::Break(BreakReason::Stopped(continuation_after_stop()))
97 }
98}
99
100#[inline(always)]
102fn check_if_max_cycles_exceeded<F>(processor: &FastProcessor) -> ControlFlow<BreakReason<F>> {
103 if processor.clk > processor.options.max_cycles() as usize {
104 ControlFlow::Break(BreakReason::Err(ExecutionError::CycleLimitExceeded(
105 processor.options.max_cycles(),
106 )))
107 } else {
108 ControlFlow::Continue(())
109 }
110}
111
112#[inline(always)]
115fn check_if_continuation_stack_too_large<F>(
116 processor: &FastProcessor,
117 continuation_stack: &ContinuationStack<F>,
118) -> ControlFlow<BreakReason<F>> {
119 if continuation_stack.len() > processor.options.max_num_continuations() {
120 ControlFlow::Break(BreakReason::Err(ExecutionError::Internal(
121 "continuation stack size exceeded the allowed maximum",
122 )))
123 } else {
124 ControlFlow::Continue(())
125 }
126}
127
128#[derive(Debug)]
133pub enum BreakReason<F> {
134 Err(ExecutionError),
136 Stopped(Option<(Continuation<F>, Option<DebugSourceNodeId>)>),
146}