1use vm_core::{Felt, ZERO, mast::MastForest, sys_events::SystemEvent};
2
3use super::{ExecutionError, FastProcessor, ONE};
4use crate::{
5 FMP_MIN, Host, ProcessState,
6 errors::ErrorContext,
7 operations::sys_ops::sys_event_handlers::{
8 HDWORD_TO_MAP_WITH_DOMAIN_DOMAIN_OFFSET, copy_map_value_to_adv_stack,
9 copy_merkle_node_to_adv_stack, insert_hdword_into_adv_map, insert_hperm_into_adv_map,
10 insert_mem_values_into_adv_map, merge_merkle_nodes, push_ext2_intt_result,
11 push_ext2_inv_result, push_falcon_mod_result, push_ilog2, push_leading_ones,
12 push_leading_zeros, push_smtpeek_result, push_trailing_ones, push_trailing_zeros,
13 push_u64_div_result,
14 },
15 system::FMP_MAX,
16};
17
18impl FastProcessor {
19 pub fn op_assert(
21 &mut self,
22 err_code: Felt,
23 op_idx: usize,
24 host: &mut impl Host,
25 program: &MastForest,
26 ) -> Result<(), ExecutionError> {
27 if self.stack_get(0) != ONE {
28 host.on_assert_failed(ProcessState::new_fast(self, op_idx), err_code);
29 let err_msg = program.resolve_error_message(err_code);
30 return Err(ExecutionError::failed_assertion(
31 self.clk,
32 err_code,
33 err_msg,
34 &ErrorContext::default(),
35 ));
36 }
37 self.decrement_stack_size();
38 Ok(())
39 }
40
41 pub fn op_fmpadd(&mut self) {
43 let fmp = self.fmp;
44 let top = self.stack_get_mut(0);
45
46 *top += fmp;
47 }
48
49 pub fn op_fmpupdate(&mut self) -> Result<(), ExecutionError> {
51 let top = self.stack_get(0);
52
53 let new_fmp = self.fmp + top;
54 let new_fmp_int = new_fmp.as_int();
55 if !(FMP_MIN..=FMP_MAX).contains(&new_fmp_int) {
56 return Err(ExecutionError::InvalidFmpValue(self.fmp, new_fmp));
57 }
58
59 self.fmp = new_fmp;
60 self.decrement_stack_size();
61 Ok(())
62 }
63
64 pub fn op_sdepth(&mut self) {
66 let depth = self.stack_depth();
67 self.increment_stack_size();
68 self.stack_write(0, depth.into());
69 }
70
71 pub fn op_caller(&mut self) -> Result<(), ExecutionError> {
73 if !self.in_syscall {
74 return Err(ExecutionError::CallerNotInSyscall);
75 }
76
77 let caller_hash = self.caller_hash;
78 self.stack_write_word(0, &caller_hash);
79
80 Ok(())
81 }
82
83 pub fn op_clk(&mut self, op_idx: usize) -> Result<(), ExecutionError> {
85 self.increment_stack_size();
86 self.stack_write(0, (self.clk + op_idx).into());
87 Ok(())
88 }
89
90 pub fn op_emit(
92 &mut self,
93 event_id: u32,
94 op_idx: usize,
95 host: &mut impl Host,
96 ) -> Result<(), ExecutionError> {
97 if let Some(system_event) = SystemEvent::from_event_id(event_id) {
99 self.handle_system_event(system_event, op_idx, host)
100 } else {
101 host.on_event(ProcessState::new_fast(self, op_idx), event_id, &ErrorContext::default())
102 }
103 }
104
105 pub(super) fn handle_system_event(
109 &self,
110 system_event: SystemEvent,
111 op_idx: usize,
112 host: &mut impl Host,
113 ) -> Result<(), ExecutionError> {
114 let advice_provider = host.advice_provider_mut();
115 let process_state = ProcessState::new_fast(self, op_idx);
116 match system_event {
117 SystemEvent::MerkleNodeMerge => {
118 merge_merkle_nodes(advice_provider, process_state, &ErrorContext::default())
119 },
120 SystemEvent::MerkleNodeToStack => copy_merkle_node_to_adv_stack(
121 advice_provider,
122 process_state,
123 &ErrorContext::default(),
124 ),
125 SystemEvent::MapValueToStack => copy_map_value_to_adv_stack(
126 advice_provider,
127 process_state,
128 false,
129 &ErrorContext::default(),
130 ),
131 SystemEvent::MapValueToStackN => copy_map_value_to_adv_stack(
132 advice_provider,
133 process_state,
134 true,
135 &ErrorContext::default(),
136 ),
137 SystemEvent::U64Div => {
138 push_u64_div_result(advice_provider, process_state, &ErrorContext::default())
139 },
140 SystemEvent::FalconDiv => {
141 push_falcon_mod_result(advice_provider, process_state, &ErrorContext::default())
142 },
143 SystemEvent::Ext2Inv => {
144 push_ext2_inv_result(advice_provider, process_state, &ErrorContext::default())
145 },
146 SystemEvent::Ext2Intt => {
147 push_ext2_intt_result(advice_provider, process_state, &ErrorContext::default())
148 },
149 SystemEvent::SmtPeek => {
150 push_smtpeek_result(advice_provider, process_state, &ErrorContext::default())
151 },
152 SystemEvent::U32Clz => {
153 push_leading_zeros(advice_provider, process_state, &ErrorContext::default())
154 },
155 SystemEvent::U32Ctz => {
156 push_trailing_zeros(advice_provider, process_state, &ErrorContext::default())
157 },
158 SystemEvent::U32Clo => {
159 push_leading_ones(advice_provider, process_state, &ErrorContext::default())
160 },
161 SystemEvent::U32Cto => {
162 push_trailing_ones(advice_provider, process_state, &ErrorContext::default())
163 },
164 SystemEvent::ILog2 => {
165 push_ilog2(advice_provider, process_state, &ErrorContext::default())
166 },
167
168 SystemEvent::MemToMap => insert_mem_values_into_adv_map(advice_provider, process_state),
169 SystemEvent::HdwordToMap => {
170 insert_hdword_into_adv_map(advice_provider, process_state, ZERO)
171 },
172 SystemEvent::HdwordToMapWithDomain => {
173 let domain = self.stack_get(HDWORD_TO_MAP_WITH_DOMAIN_DOMAIN_OFFSET);
174 insert_hdword_into_adv_map(advice_provider, process_state, domain)
175 },
176 SystemEvent::HpermToMap => insert_hperm_into_adv_map(advice_provider, process_state),
177 }
178 }
179}