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 kernel(&self) -> &Kernel {
40 &self.kernel
41 }
42}
43
44pub struct NeverStopper;
50
51impl Stopper for NeverStopper {
52 type Processor = FastProcessor;
53 type Forest = Arc<MastForest>;
54
55 #[inline(always)]
56 fn should_stop(
57 &self,
58 processor: &FastProcessor,
59 continuation_stack: &ContinuationStack<Arc<MastForest>>,
60 _continuation_after_stop: impl FnOnce() -> Option<(
61 Continuation<Arc<MastForest>>,
62 Option<DebugSourceNodeId>,
63 )>,
64 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
65 check_if_max_cycles_exceeded(processor)?;
66 check_if_continuation_stack_too_large(processor, continuation_stack)
67 }
68}
69
70pub struct StepStopper;
73
74impl Stopper for StepStopper {
75 type Processor = FastProcessor;
76 type Forest = Arc<MastForest>;
77
78 #[inline(always)]
79 fn should_stop(
80 &self,
81 processor: &FastProcessor,
82 continuation_stack: &ContinuationStack<Arc<MastForest>>,
83 continuation_after_stop: impl FnOnce() -> Option<(
84 Continuation<Arc<MastForest>>,
85 Option<DebugSourceNodeId>,
86 )>,
87 ) -> ControlFlow<BreakReason<Arc<MastForest>>> {
88 check_if_max_cycles_exceeded(processor)?;
89 check_if_continuation_stack_too_large(processor, continuation_stack)?;
90
91 ControlFlow::Break(BreakReason::Stopped(continuation_after_stop()))
92 }
93}
94
95#[inline(always)]
97fn check_if_max_cycles_exceeded<F>(processor: &FastProcessor) -> ControlFlow<BreakReason<F>> {
98 if processor.clk > processor.options.max_cycles() as usize {
99 ControlFlow::Break(BreakReason::Err(ExecutionError::CycleLimitExceeded(
100 processor.options.max_cycles(),
101 )))
102 } else {
103 ControlFlow::Continue(())
104 }
105}
106
107#[inline(always)]
110fn check_if_continuation_stack_too_large<F>(
111 processor: &FastProcessor,
112 continuation_stack: &ContinuationStack<F>,
113) -> ControlFlow<BreakReason<F>> {
114 if continuation_stack.len() > processor.options.max_num_continuations() {
115 ControlFlow::Break(BreakReason::Err(ExecutionError::Internal(
116 "continuation stack size exceeded the allowed maximum",
117 )))
118 } else {
119 ControlFlow::Continue(())
120 }
121}
122
123#[derive(Debug)]
128pub enum BreakReason<F> {
129 Err(ExecutionError),
131 Stopped(Option<(Continuation<F>, Option<DebugSourceNodeId>)>),
141}