sp1_core_executor/
minimal.rs1#![allow(clippy::items_after_statements)]
2use std::sync::Arc;
3
4use crate::{Program, SupervisorMode, UserMode};
5pub use arch::*;
6pub use postprocess::chunked_memory_init_events;
7pub use sp1_jit::{MemValue, TraceChunkRaw};
8
9mod arch;
10mod debug;
11mod ecall;
12mod hint;
13mod postprocess;
14mod precompiles;
15mod write;
16
17#[cfg(test)]
18mod tests;
19
20pub enum MinimalExecutorEnum {
22 Supervisor(MinimalExecutor<SupervisorMode>),
24 User(MinimalExecutor<UserMode>),
26}
27
28impl MinimalExecutorEnum {
29 #[must_use]
31 pub fn new(program: Arc<Program>, debug: bool, max_trace_entries: Option<u64>) -> Self {
32 if program.enable_untrusted_programs {
33 Self::User(MinimalExecutor::<UserMode>::new(program, debug, max_trace_entries))
34 } else {
35 Self::Supervisor(MinimalExecutor::<SupervisorMode>::new(
36 program,
37 debug,
38 max_trace_entries,
39 ))
40 }
41 }
42
43 #[cfg(sp1_use_portable_executor)]
45 #[must_use]
46 pub fn new_with_limit(
47 program: Arc<Program>,
48 debug: bool,
49 max_trace_size: Option<u64>,
50 memory_limit: Option<u64>,
51 ) -> Self {
52 if program.enable_untrusted_programs {
53 Self::User(MinimalExecutor::<UserMode>::new_with_limit(
54 program,
55 debug,
56 max_trace_size,
57 memory_limit,
58 ))
59 } else {
60 Self::Supervisor(MinimalExecutor::<SupervisorMode>::new_with_limit(
61 program,
62 debug,
63 max_trace_size,
64 memory_limit,
65 ))
66 }
67 }
68
69 #[cfg(not(sp1_use_portable_executor))]
71 #[must_use]
72 pub fn new_with_limit(
73 program: Arc<Program>,
74 debug: bool,
75 max_trace_size: Option<u64>,
76 _memory_limit: Option<u64>,
77 ) -> Self {
78 Self::new(program, debug, max_trace_size)
79 }
80
81 pub fn with_input(&mut self, input: &[u8]) {
83 match self {
84 Self::Supervisor(e) => e.with_input(input),
85 Self::User(e) => e.with_input(input),
86 }
87 }
88
89 pub fn execute_chunk(&mut self) -> Option<TraceChunkRaw> {
91 match self {
92 Self::Supervisor(e) => e.execute_chunk(),
93 Self::User(e) => e.execute_chunk(),
94 }
95 }
96
97 #[must_use]
99 pub fn global_clk(&self) -> u64 {
100 match self {
101 Self::Supervisor(e) => e.global_clk(),
102 Self::User(e) => e.global_clk(),
103 }
104 }
105
106 #[must_use]
108 pub fn exit_code(&self) -> u32 {
109 match self {
110 Self::Supervisor(e) => e.exit_code(),
111 Self::User(e) => e.exit_code(),
112 }
113 }
114
115 #[must_use]
117 pub fn pc(&self) -> u64 {
118 match self {
119 Self::Supervisor(e) => e.pc(),
120 Self::User(e) => e.pc(),
121 }
122 }
123
124 #[must_use]
126 pub fn registers(&self) -> [u64; 32] {
127 match self {
128 Self::Supervisor(e) => e.registers(),
129 Self::User(e) => e.registers(),
130 }
131 }
132
133 #[must_use]
135 pub fn clk(&self) -> u64 {
136 match self {
137 Self::Supervisor(e) => e.clk(),
138 Self::User(e) => e.clk(),
139 }
140 }
141
142 #[must_use]
144 pub fn public_values_stream(&self) -> &Vec<u8> {
145 match self {
146 Self::Supervisor(e) => e.public_values_stream(),
147 Self::User(e) => e.public_values_stream(),
148 }
149 }
150
151 #[must_use]
153 pub fn into_public_values_stream(self) -> Vec<u8> {
154 match self {
155 Self::Supervisor(e) => e.into_public_values_stream(),
156 Self::User(e) => e.into_public_values_stream(),
157 }
158 }
159
160 #[must_use]
162 pub fn public_value_digest(&self) -> [u32; sp1_jit::PUBLIC_VALUE_DIGEST_WORDS] {
163 match self {
164 Self::Supervisor(e) => e.public_value_digest(),
165 Self::User(e) => e.public_value_digest(),
166 }
167 }
168
169 #[must_use]
171 pub fn hints(&self) -> &[(u64, Vec<u8>)] {
172 match self {
173 Self::Supervisor(e) => e.hints(),
174 Self::User(e) => e.hints(),
175 }
176 }
177
178 #[must_use]
180 pub fn hint_lens(&self) -> Vec<usize> {
181 match self {
182 Self::Supervisor(e) => e.hint_lens(),
183 Self::User(e) => e.hint_lens(),
184 }
185 }
186
187 #[must_use]
189 pub fn get_memory_value(&self, addr: u64) -> MemValue {
190 match self {
191 Self::Supervisor(e) => e.get_memory_value(addr),
192 Self::User(e) => e.get_memory_value(addr),
193 }
194 }
195
196 #[must_use]
198 pub fn is_done(&self) -> bool {
199 match self {
200 Self::Supervisor(e) => e.is_done(),
201 Self::User(e) => e.is_done(),
202 }
203 }
204
205 #[must_use]
207 pub fn program(&self) -> Arc<Program> {
208 match self {
209 Self::Supervisor(e) => e.program(),
210 Self::User(e) => e.program(),
211 }
212 }
213
214 #[must_use]
216 pub fn unsafe_memory(&self) -> UnsafeMemory {
217 match self {
218 Self::Supervisor(e) => e.unsafe_memory(),
219 Self::User(e) => e.unsafe_memory(),
220 }
221 }
222
223 pub fn reset(&mut self) {
225 match self {
226 Self::Supervisor(e) => e.reset(),
227 Self::User(e) => e.reset(),
228 }
229 }
230
231 #[cfg(sp1_use_portable_executor)]
233 pub fn try_execute_chunk(&mut self) -> Result<Option<TraceChunkRaw>, crate::ExecutionError> {
234 match self {
235 Self::Supervisor(e) => e.try_execute_chunk(),
236 Self::User(e) => e.try_execute_chunk(),
237 }
238 }
239
240 #[cfg(not(sp1_use_portable_executor))]
242 pub fn try_execute_chunk(&mut self) -> Result<Option<TraceChunkRaw>, crate::ExecutionError> {
243 Ok(self.execute_chunk())
244 }
245
246 #[must_use]
248 pub fn get_page_prot_record(&self, page_idx: u64) -> Option<sp1_jit::PageProtValue> {
249 match self {
250 Self::Supervisor(e) => e.get_page_prot_record(page_idx),
251 Self::User(e) => e.get_page_prot_record(page_idx),
252 }
253 }
254
255 #[cfg(feature = "profiling")]
257 #[must_use]
258 pub fn take_cycle_tracker_totals(&mut self) -> hashbrown::HashMap<String, u64> {
259 match self {
260 Self::Supervisor(e) => e.take_cycle_tracker_totals(),
261 Self::User(e) => e.take_cycle_tracker_totals(),
262 }
263 }
264
265 #[cfg(feature = "profiling")]
267 #[must_use]
268 pub fn take_invocation_tracker(&mut self) -> hashbrown::HashMap<String, u64> {
269 match self {
270 Self::Supervisor(e) => e.take_invocation_tracker(),
271 Self::User(e) => e.take_invocation_tracker(),
272 }
273 }
274}