1use crate::stdlib::prelude::*;
2use crate::types::relocatable::Relocatable;
3use lazy_static::lazy_static;
4use num_bigint::BigUint;
5use num_traits::Num;
6
7pub const PRIME_STR: &str = "0x800000000000011000000000000000000000000000000000000000000000001";
8
9#[macro_export]
10macro_rules! relocatable {
11 ($val1 : expr, $val2 : expr) => {
12 Relocatable {
13 segment_index: $val1,
14 offset: $val2,
15 }
16 };
17}
18
19lazy_static! {
20 pub static ref CAIRO_PRIME: BigUint = BigUint::from_str_radix(&PRIME_STR[2..], 16).unwrap();
21}
22
23#[macro_export]
24macro_rules! any_box {
25 ($val : expr) => {
26 $crate::stdlib::boxed::Box::new($val) as $crate::stdlib::boxed::Box<dyn core::any::Any>
27 };
28}
29
30pub fn is_subsequence<T: PartialEq>(subsequence: &[T], mut sequence: &[T]) -> bool {
31 for search in subsequence {
32 if let Some(index) = sequence.iter().position(|element| search == element) {
33 sequence = &sequence[index + 1..];
34 } else {
35 return false;
36 }
37 }
38 true
39}
40
41pub fn from_relocatable_to_indexes(relocatable: Relocatable) -> (usize, usize) {
42 if relocatable.segment_index.is_negative() {
43 (
44 -(relocatable.segment_index + 1) as usize,
45 relocatable.offset,
46 )
47 } else {
48 (relocatable.segment_index as usize, relocatable.offset)
49 }
50}
51
52#[cfg(test)]
53#[macro_use]
54pub mod test_utils {
55 use crate::types::exec_scope::ExecutionScopes;
56 use crate::types::relocatable::MaybeRelocatable;
57 use crate::vm::trace::trace_entry::TraceEntry;
58
59 #[macro_export]
60 macro_rules! felt_hex {
61 ($val: expr) => {
62 $crate::Felt252::from_hex($val).expect("Couldn't parse bytes")
63 };
64 }
65
66 #[macro_export]
67 macro_rules! felt_str {
68 ($val: expr) => {
69 $crate::Felt252::from_dec_str($val).expect("Couldn't parse bytes")
70 };
71 }
72
73 #[macro_export]
74 macro_rules! bigint {
75 ($val : expr) => {
76 Into::<num_bigint::BigInt>::into($val)
77 };
78 }
79 pub(crate) use bigint;
80
81 #[macro_export]
82 macro_rules! bigint_str {
83 ($val: expr) => {
84 num_bigint::BigInt::parse_bytes($val.as_bytes(), 10).expect("Couldn't parse bytes")
85 };
86 ($val: expr, $opt: expr) => {
87 num_bigint::BigInt::parse_bytes($val.as_bytes(), $opt).expect("Couldn't parse bytes")
88 };
89 }
90 pub(crate) use bigint_str;
91
92 #[macro_export]
93 macro_rules! biguint {
94 ($val : expr) => {
95 Into::<num_bigint::BigUint>::into($val as u128)
96 };
97 }
98 pub(crate) use biguint;
99
100 #[macro_export]
101 macro_rules! biguint_str {
102 ($val: expr) => {
103 num_bigint::BigUint::parse_bytes($val.as_bytes(), 10).expect("Couldn't parse bytes")
104 };
105 ($val: expr, $opt: expr) => {
106 num_bigint::BigUint::parse_bytes($val.as_bytes(), $opt).expect("Couldn't parse bytes")
107 };
108 }
109 pub(crate) use biguint_str;
110
111 impl From<(&str, u8)> for MaybeRelocatable {
112 fn from((string, radix): (&str, u8)) -> Self {
113 match radix {
114 16 => MaybeRelocatable::Int(crate::felt_hex!(string)),
115 10 => MaybeRelocatable::Int(crate::felt_str!(string)),
116 _ => panic!(" Invalid radix"),
117 }
118 }
119 }
120
121 macro_rules! segments {
122 ($( (($si:expr, $off:expr), $val:tt) ),* $(,)? ) => {
123 {
124 let mut segments = $crate::vm::vm_memory::memory_segments::MemorySegmentManager::new();
125 segments.memory = memory!($( (($si, $off), $val) ),*);
126 segments
127 }
128
129 };
130 }
131 pub(crate) use segments;
132
133 macro_rules! memory {
134 ( $( (($si:expr, $off:expr), $val:tt) ),* ) => {
135 {
136 let mut memory = $crate::vm::vm_memory::memory::Memory::new();
137 memory_from_memory!(memory, ( $( (($si, $off), $val) ),* ));
138 memory
139 }
140 };
141 }
142 pub(crate) use memory;
143
144 macro_rules! memory_from_memory {
145 ($mem: expr, ( $( (($si:expr, $off:expr), $val:tt) ),* )) => {
146 {
147 $(
148 memory_inner!($mem, ($si, $off), $val);
149 )*
150 }
151 };
152 }
153 pub(crate) use memory_from_memory;
154
155 macro_rules! memory_inner {
156 ($mem:expr, ($si:expr, $off:expr), ($sival:expr, $offval: expr)) => {
157 let (k, v) = (($si, $off).into(), &mayberelocatable!($sival, $offval));
158 let mut res = $mem.insert(k, v);
159 while matches!(
160 res,
161 Err($crate::vm::errors::memory_errors::MemoryError::UnallocatedSegment(_))
162 ) {
163 if $si < 0 {
164 $mem.temp_data.push($crate::stdlib::vec::Vec::new())
165 } else {
166 $mem.data.push($crate::stdlib::vec::Vec::new());
167 }
168 res = $mem.insert(k, v);
169 }
170 };
171 ($mem:expr, ($si:expr, $off:expr), $val:expr) => {
172 let (k, v) = (($si, $off).into(), &mayberelocatable!($val));
173 let mut res = $mem.insert(k, v);
174 while matches!(
175 res,
176 Err($crate::vm::errors::memory_errors::MemoryError::UnallocatedSegment(_))
177 ) {
178 if $si < 0 {
179 $mem.temp_data.push($crate::stdlib::vec::Vec::new())
180 } else {
181 $mem.data.push($crate::stdlib::vec::Vec::new());
182 }
183 res = $mem.insert(k, v);
184 }
185 };
186 }
187 pub(crate) use memory_inner;
188
189 macro_rules! check_memory {
190 ( $mem: expr, $( (($si:expr, $off:expr), $val:tt) ),* $(,)? ) => {
191 $(
192 check_memory_address!($mem, ($si, $off), $val);
193 )*
194 };
195 }
196 pub(crate) use check_memory;
197
198 macro_rules! check_memory_address {
199 ($mem:expr, ($si:expr, $off:expr), ($sival:expr, $offval: expr)) => {
200 assert_eq!(
201 $mem.get(&mayberelocatable!($si, $off)).unwrap().as_ref(),
202 &mayberelocatable!($sival, $offval)
203 )
204 };
205 ($mem:expr, ($si:expr, $off:expr), $val:expr) => {
206 assert_eq!(
207 $mem.get(&mayberelocatable!($si, $off)).unwrap().as_ref(),
208 &mayberelocatable!($val)
209 )
210 };
211 }
212 pub(crate) use check_memory_address;
213
214 macro_rules! mayberelocatable {
215 ($val1 : expr, $val2 : expr) => {
216 $crate::types::relocatable::MaybeRelocatable::from(($val1, $val2))
217 };
218 ($val1 : expr) => {
219 $crate::types::relocatable::MaybeRelocatable::from(crate::Felt252::from($val1 as i128))
220 };
221 }
222 pub(crate) use mayberelocatable;
223
224 macro_rules! references {
225 ($num: expr) => {{
226 let mut references = crate::stdlib::collections::HashMap::<usize, HintReference>::new();
227 for i in 0..$num {
228 references.insert(i as usize, HintReference::new_simple((i as i32 - $num)));
229 }
230 references
231 }};
232 }
233 pub(crate) use references;
234
235 macro_rules! vm_with_range_check {
236 () => {{
237 let mut vm = VirtualMachine::new(false, false);
238 vm.builtin_runners = vec![
239 $crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner::<8>::new(
240 Some(8),
241 true,
242 )
243 .into(),
244 ];
245 vm
246 }};
247 }
248 pub(crate) use vm_with_range_check;
249
250 macro_rules! cairo_runner {
251 ($program:expr) => {
252 crate::vm::runners::cairo_runner::CairoRunner::new(
253 &$program,
254 crate::types::layout_name::LayoutName::all_cairo,
255 None,
256 false,
257 false,
258 false,
259 )
260 .unwrap()
261 };
262 ($program:expr, $layout:expr) => {
263 crate::vm::runners::cairo_runner::CairoRunner::new(
264 &$program, $layout, None, false, false, false,
265 )
266 .unwrap()
267 };
268 ($program:expr, $layout:expr, $proof_mode:expr) => {
269 crate::vm::runners::cairo_runner::CairoRunner::new(
270 &$program,
271 $layout,
272 None,
273 $proof_mode,
274 false,
275 false,
276 )
277 .unwrap()
278 };
279 ($program:expr, $layout:expr, $proof_mode:expr, $trace_enabled:expr) => {
280 crate::vm::runners::cairo_runner::CairoRunner::new(
281 &$program,
282 $layout,
283 None,
284 $proof_mode,
285 $trace_enabled,
286 false,
287 )
288 .unwrap()
289 };
290 }
291 pub(crate) use cairo_runner;
292
293 pub(crate) use crate::stdlib::{collections::BTreeMap, sync::Arc};
294 pub(crate) use crate::types::program::HintsCollection;
295 pub(crate) use crate::types::program::Program;
296 pub(crate) use crate::types::program::SharedProgramData;
297 macro_rules! program {
298 () => {
300 Program::default()
301 };
302 ( $( $builtin_name: expr ),* ) => {{
304 let shared_program_data = SharedProgramData {
305 data: crate::stdlib::vec::Vec::new(),
306 hints_collection: HintsCollection::new(&BTreeMap::new(), 0).unwrap(),
307 main: None,
308 start: None,
309 end: None,
310 error_message_attributes: crate::stdlib::vec::Vec::new(),
311 instruction_locations: None,
312 identifiers: crate::stdlib::collections::HashMap::new(),
313 reference_manager: Program::get_reference_list(&ReferenceManager {
314 references: crate::stdlib::vec::Vec::new(),
315 }),
316 };
317 Program {
318 shared_program_data: Arc::new(shared_program_data),
319 constants: crate::stdlib::collections::HashMap::new(),
320 builtins: vec![$( $builtin_name ),*],
321 }
322 }};
323 ($($field:ident = $value:expr),* $(,)?) => {{
324
325 let program_flat = crate::utils::test_utils::ProgramFlat {
326 $(
327 $field: $value,
328 )*
329 ..Default::default()
330 };
331
332 Into::<Program>::into(program_flat)
333 }};
334 }
335
336 pub(crate) use program;
337
338 pub(crate) struct ProgramFlat {
339 pub(crate) data: crate::utils::Vec<MaybeRelocatable>,
340 pub(crate) hints: crate::stdlib::collections::BTreeMap<
341 usize,
342 crate::utils::Vec<crate::serde::deserialize_program::HintParams>,
343 >,
344 pub(crate) main: Option<usize>,
345 pub(crate) start: Option<usize>,
347 pub(crate) end: Option<usize>,
348 pub(crate) error_message_attributes:
349 crate::utils::Vec<crate::serde::deserialize_program::Attribute>,
350 pub(crate) instruction_locations: Option<
351 crate::stdlib::collections::HashMap<
352 usize,
353 crate::serde::deserialize_program::InstructionLocation,
354 >,
355 >,
356 pub(crate) identifiers: crate::stdlib::collections::HashMap<
357 crate::stdlib::string::String,
358 crate::serde::deserialize_program::Identifier,
359 >,
360 pub(crate) constants:
361 crate::stdlib::collections::HashMap<crate::stdlib::string::String, crate::Felt252>,
362 pub(crate) builtins: crate::utils::Vec<crate::types::builtin_name::BuiltinName>,
363 pub(crate) reference_manager: crate::serde::deserialize_program::ReferenceManager,
364 }
365
366 impl Default for ProgramFlat {
367 fn default() -> Self {
368 Self {
369 data: Default::default(),
370 hints: Default::default(),
371 main: Default::default(),
372 start: Default::default(),
373 end: Default::default(),
374 error_message_attributes: Default::default(),
375 instruction_locations: Default::default(),
376 identifiers: Default::default(),
377 constants: Default::default(),
378 builtins: Default::default(),
379 reference_manager: crate::serde::deserialize_program::ReferenceManager {
380 references: crate::utils::Vec::new(),
381 },
382 }
383 }
384 }
385
386 impl From<ProgramFlat> for Program {
387 fn from(val: ProgramFlat) -> Self {
388 let hints_collection =
390 HintsCollection::new(&val.hints, val.data.len()).expect("hints are valid");
391 Program {
392 shared_program_data: Arc::new(SharedProgramData {
393 data: val.data,
394 hints_collection,
395 main: val.main,
396 start: val.start,
397 end: val.end,
398 error_message_attributes: val.error_message_attributes,
399 instruction_locations: val.instruction_locations,
400 identifiers: val.identifiers,
401 reference_manager: Program::get_reference_list(&val.reference_manager),
402 }),
403 constants: val.constants,
404 builtins: val.builtins,
405 }
406 }
407 }
408
409 macro_rules! vm {
410 () => {{
411 crate::vm::vm_core::VirtualMachine::new(false, false)
412 }};
413
414 ($use_trace:expr) => {{
415 crate::vm::vm_core::VirtualMachine::new($use_trace, false)
416 }};
417 }
418 pub(crate) use vm;
419
420 macro_rules! run_context {
421 ( $vm: expr, $pc: expr, $ap: expr, $fp: expr ) => {
422 $vm.run_context.pc = Relocatable::from((0, $pc));
423 $vm.run_context.ap = $ap;
424 $vm.run_context.fp = $fp;
425 };
426 }
427 pub(crate) use run_context;
428
429 macro_rules! ids_data {
430 ( $( $name: expr ),* ) => {
431 {
432 let ids_names = vec![$( $name ),*];
433 let references = references!(ids_names.len() as i32);
434 let mut ids_data = crate::stdlib::collections::HashMap::<crate::stdlib::string::String, HintReference>::new();
435 for (i, name) in ids_names.iter().enumerate() {
436 ids_data.insert(crate::stdlib::string::ToString::to_string(name), references.get(&i).unwrap().clone());
437 }
438 ids_data
439 }
440 };
441 }
442 pub(crate) use ids_data;
443
444 macro_rules! non_continuous_ids_data {
445 ( $( ($name: expr, $offset:expr) ),* $(,)? ) => {
446 {
447 let mut ids_data = crate::stdlib::collections::HashMap::<crate::stdlib::string::String, HintReference>::new();
448 $(
449 ids_data.insert(crate::stdlib::string::String::from($name), HintReference::new_simple($offset));
450 )*
451 ids_data
452 }
453 };
454 }
455 pub(crate) use non_continuous_ids_data;
456
457 #[track_caller]
458 pub(crate) fn trace_check(
459 actual: &[TraceEntry],
460 expected: &[(crate::utils::Relocatable, usize, usize)],
461 ) {
462 assert_eq!(actual.len(), expected.len());
463 for (entry, expected) in actual.iter().zip(expected.iter()) {
464 assert_eq!(&(entry.pc, entry.ap, entry.fp), expected);
465 }
466 }
467
468 macro_rules! exec_scopes_ref {
469 () => {
470 &mut crate::types::exec_scope::ExecutionScopes::new()
471 };
472 }
473 pub(crate) use exec_scopes_ref;
474
475 macro_rules! run_hint {
476 ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr, $constants:expr) => {{
477 let hint_data = HintProcessorData::new_default($hint_code.to_string(), $ids_data);
478 let mut hint_processor = BuiltinHintProcessor::new_empty();
479 hint_processor.execute_hint(&mut $vm, $exec_scopes, &any_box!(hint_data), $constants)
480 }};
481 ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr) => {{
482 let hint_data = HintProcessorData::new_default(
483 crate::stdlib::string::ToString::to_string($hint_code),
484 $ids_data,
485 );
486 let mut hint_processor = BuiltinHintProcessor::new_empty();
487 hint_processor.execute_hint(
488 &mut $vm,
489 $exec_scopes,
490 &any_box!(hint_data),
491 &crate::stdlib::collections::HashMap::new(),
492 )
493 }};
494 ($vm:expr, $ids_data:expr, $hint_code:expr) => {{
495 let hint_data = HintProcessorData::new_default(
496 crate::stdlib::string::ToString::to_string($hint_code),
497 $ids_data,
498 );
499 let mut hint_processor = BuiltinHintProcessor::new_empty();
500 hint_processor.execute_hint(
501 &mut $vm,
502 exec_scopes_ref!(),
503 &any_box!(hint_data),
504 &crate::stdlib::collections::HashMap::new(),
505 )
506 }};
507 }
508 pub(crate) use run_hint;
509
510 macro_rules! add_segments {
511 ($vm:expr, $n:expr) => {
512 for _ in 0..$n {
513 $vm.segments.add();
514 }
515 };
516 }
517 pub(crate) use add_segments;
518
519 macro_rules! check_scope {
520 ( $exec_scope: expr, [ $( ($name: expr, $val: expr)),*$(,)? ] $(,)? ) => {
521 $(
522 check_scope_value($exec_scope, $name, $val);
523 )*
524 };
525 }
526 pub(crate) use check_scope;
527
528 macro_rules! scope {
529 () => { ExecutionScopes::new() };
530 ( $( ($name: expr, $val: expr)),* $(,)? ) => {
531 {
532 let mut exec_scopes = ExecutionScopes::new();
533 $(
534 exec_scopes.assign_or_update_variable(
535 $name,
536 any_box!($val),
537 );
538 )*
539 exec_scopes
540 }
541 };
542 }
543 pub(crate) use scope;
544
545 macro_rules! check_dictionary {
546 ( $exec_scopes: expr, $tracker_num:expr, $( ($key:expr, $val:expr )),* ) => {
547 $(
548 assert_matches::assert_matches!(
549 $exec_scopes
550 .get_dict_manager()
551 .unwrap()
552 .borrow_mut()
553 .trackers
554 .get_mut(&$tracker_num)
555 .unwrap()
556 .get_value(&MaybeRelocatable::from($key)),
557 Ok(x) if x == &MaybeRelocatable::from($val)
558 ));
559 *
560 };
561 }
562 pub(crate) use check_dictionary;
563
564 macro_rules! check_dict_ptr {
565 ($exec_scopes: expr, $tracker_num: expr, ($i:expr, $off:expr)) => {
566 assert_eq!(
567 $exec_scopes
568 .get_dict_manager()
569 .unwrap()
570 .borrow()
571 .trackers
572 .get(&$tracker_num)
573 .unwrap()
574 .current_ptr,
575 relocatable!($i, $off)
576 );
577 };
578 }
579 pub(crate) use check_dict_ptr;
580
581 macro_rules! dict_manager {
582 ($exec_scopes:expr, $tracker_num:expr, $( ($key:expr, $val:expr )),* ) => {
583 let mut tracker = DictTracker::new_empty(relocatable!($tracker_num, 0));
584 $(
585 tracker.insert_value(&MaybeRelocatable::from($key), &MaybeRelocatable::from($val));
586 )*
587 let mut dict_manager = DictManager::new();
588 dict_manager.trackers.insert(2, tracker);
589 $exec_scopes.insert_value("dict_manager", crate::stdlib::rc::Rc::new(core::cell::RefCell::new(dict_manager)))
590 };
591 ($exec_scopes:expr, $tracker_num:expr) => {
592 let tracker = DictTracker::new_empty(relocatable!($tracker_num, 0));
593 let mut dict_manager = DictManager::new();
594 dict_manager.trackers.insert(2, tracker);
595 $exec_scopes.insert_value("dict_manager", crate::stdlib::rc::Rc::new(core::cell::RefCell::new(dict_manager)))
596 };
597
598 }
599 pub(crate) use dict_manager;
600
601 macro_rules! dict_manager_default {
602 ($exec_scopes:expr, $tracker_num:expr,$default:expr, $( ($key:expr, $val:expr )),* ) => {
603 let mut tracker = DictTracker::new_default_dict(relocatable!($tracker_num, 0), &MaybeRelocatable::from($default), None);
604 $(
605 tracker.insert_value(&MaybeRelocatable::from($key), &MaybeRelocatable::from($val));
606 )*
607 let mut dict_manager = DictManager::new();
608 dict_manager.trackers.insert(2, tracker);
609 $exec_scopes.insert_value("dict_manager", crate::stdlib::rc::Rc::new(core::cell::RefCell::new(dict_manager)))
610 };
611 ($exec_scopes:expr, $tracker_num:expr,$default:expr) => {
612 let tracker = DictTracker::new_default_dict(relocatable!($tracker_num, 0), &MaybeRelocatable::from($default), None);
613 let mut dict_manager = DictManager::new();
614 dict_manager.trackers.insert(2, tracker);
615 $exec_scopes.insert_value("dict_manager", crate::stdlib::rc::Rc::new(core::cell::RefCell::new(dict_manager)))
616 };
617 }
618 pub(crate) use dict_manager_default;
619
620 macro_rules! vec_data {
621 ( $( ($val:tt) ),* ) => {
622 vec![$( vec_data_inner!($val) ),*]
623 };
624 }
625 pub(crate) use vec_data;
626
627 macro_rules! vec_data_inner {
628 (( $val1:expr, $val2:expr )) => {
629 mayberelocatable!($val1, $val2)
630 };
631 ( $val:expr ) => {
632 mayberelocatable!($val)
633 };
634 }
635 pub(crate) use vec_data_inner;
636
637 pub fn check_scope_value<T: core::fmt::Debug + core::cmp::PartialEq + 'static>(
638 scopes: &ExecutionScopes,
639 name: &str,
640 value: T,
641 ) {
642 let scope_value = scopes.get_any_boxed_ref(name).unwrap();
643 assert_eq!(scope_value.downcast_ref::<T>(), Some(&value));
644 }
645}
646
647#[cfg(test)]
648mod test {
649 use crate::hint_processor::hint_processor_definition::HintProcessorLogic;
650 use crate::stdlib::{cell::RefCell, collections::HashMap, rc::Rc, string::String, vec::Vec};
651 use crate::types::builtin_name::BuiltinName;
652 use crate::types::program::HintsCollection;
653 use crate::{
654 hint_processor::{
655 builtin_hint_processor::{
656 builtin_hint_processor_definition::{BuiltinHintProcessor, HintProcessorData},
657 dict_manager::{DictManager, DictTracker},
658 },
659 hint_processor_definition::HintReference,
660 },
661 serde::deserialize_program::ReferenceManager,
662 types::{exec_scope::ExecutionScopes, program::Program, relocatable::MaybeRelocatable},
663 utils::test_utils::*,
664 vm::{trace::trace_entry::TraceEntry, vm_memory::memory::Memory},
665 };
666
667 #[cfg(target_arch = "wasm32")]
668 use wasm_bindgen_test::*;
669
670 use super::*;
671
672 #[test]
673 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
674 fn memory_macro_test() {
675 let mut memory = Memory::new();
676 for _ in 0..2 {
677 memory.data.push(Vec::new());
678 }
679 memory
680 .insert(
681 Relocatable::from((1, 2)),
682 &MaybeRelocatable::from(crate::Felt252::ONE),
683 )
684 .unwrap();
685 memory
686 .insert(Relocatable::from((1, 1)), &MaybeRelocatable::from((1, 0)))
687 .unwrap();
688 let mem = memory![((1, 2), 1), ((1, 1), (1, 0))];
689 assert_eq!(memory.data, mem.data);
690 }
691
692 #[test]
693 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
694 fn check_memory_macro_test() {
695 let mut memory = Memory::new();
696 for _ in 0..2 {
697 memory.data.push(Vec::new());
698 }
699 memory
700 .insert(Relocatable::from((1, 1)), &MaybeRelocatable::from((1, 0)))
701 .unwrap();
702
703 memory
704 .insert(
705 Relocatable::from((1, 2)),
706 &MaybeRelocatable::from(crate::Felt252::ONE),
707 )
708 .unwrap();
709
710 check_memory![memory, ((1, 1), (1, 0)), ((1, 2), 1)];
711 }
712
713 #[test]
714 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
715 fn check_memory_address_macro_test() {
716 let mut memory = Memory::new();
717 for _ in 0..2 {
718 memory.data.push(Vec::new());
719 }
720 memory
721 .insert(Relocatable::from((1, 1)), &MaybeRelocatable::from((1, 0)))
722 .unwrap();
723
724 memory
725 .insert(
726 Relocatable::from((1, 2)),
727 &MaybeRelocatable::from(crate::Felt252::ONE),
728 )
729 .unwrap();
730
731 check_memory_address!(memory, (1, 1), (1, 0));
732 check_memory_address!(memory, (1, 2), 1);
733 }
734
735 #[test]
736 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
737 fn create_run_context() {
738 let mut vm = vm!();
739 run_context!(vm, 2, 6, 10);
740
741 assert_eq!(vm.run_context.pc, Relocatable::from((0, 2)));
742 assert_eq!(vm.run_context.ap, 6);
743 assert_eq!(vm.run_context.fp, 10);
744 }
745
746 #[test]
747 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
748 fn assert_trace() {
749 let trace = vec![
750 TraceEntry {
751 pc: (0, 2).into(),
752 ap: 7,
753 fp: 1,
754 },
755 TraceEntry {
756 pc: (0, 5).into(),
757 ap: 1,
758 fp: 0,
759 },
760 TraceEntry {
761 pc: (0, 9).into(),
762 ap: 5,
763 fp: 7,
764 },
765 ];
766 trace_check(
767 &trace,
768 &[
769 ((0, 2).into(), 7, 1),
770 ((0, 5).into(), 1, 0),
771 ((0, 9).into(), 5, 7),
772 ],
773 );
774 }
775
776 #[test]
777 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
778 fn test_non_continuous_ids_data() {
779 let ids_data_macro = non_continuous_ids_data![("a", -2), ("", -6)];
780 let ids_data_verbose = HashMap::from([
781 ("a".to_string(), HintReference::new_simple(-2)),
782 ("".to_string(), HintReference::new_simple(-6)),
783 ]);
784 assert_eq!(ids_data_macro, ids_data_verbose);
785 }
786
787 #[test]
788 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
789 fn run_hint_alloc() {
790 let hint_code = "memory[ap] = segments.add()";
791 let mut vm = vm!();
792 add_segments!(vm, 1);
793 assert_matches::assert_matches!(run_hint!(vm, HashMap::new(), hint_code), Ok(()));
794 assert_eq!(vm.segments.memory.data.len(), 2);
796 }
797
798 #[test]
799 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
800 fn check_scope_test_pass() {
801 let mut exec_scopes = ExecutionScopes::new();
802 exec_scopes.assign_or_update_variable("a", any_box!(String::from("Hello")));
803 exec_scopes.assign_or_update_variable(
804 "",
805 any_box!(Rc::new(RefCell::new(HashMap::<usize, Vec<usize>>::new()))),
806 );
807 exec_scopes.assign_or_update_variable("c", any_box!(vec![1, 2, 3, 4]));
808 check_scope!(
809 &exec_scopes,
810 [
811 ("a", String::from("Hello")),
812 (
813 "",
814 Rc::new(RefCell::new(HashMap::<usize, Vec<usize>>::new()))
815 ),
816 ("c", vec![1, 2, 3, 4])
817 ]
818 );
819 }
820
821 #[test]
822 #[should_panic]
823 fn check_scope_test_fail() {
824 let mut exec_scopes = ExecutionScopes::new();
825 exec_scopes.assign_or_update_variable("a", any_box!(String::from("Hello")));
826 exec_scopes.assign_or_update_variable(
827 "",
828 any_box!(Rc::new(RefCell::new(HashMap::<usize, Vec<usize>>::new()))),
829 );
830 exec_scopes.assign_or_update_variable("c", any_box!(vec![1, 2, 3, 4]));
831 check_scope!(
832 &exec_scopes,
833 [
834 ("a", String::from("Hello")),
835 (
836 "",
837 Rc::new(RefCell::new(HashMap::<usize, Vec<usize>>::new()))
838 ),
839 ("c", vec![1, 2, 3, 5])
840 ]
841 );
842 }
843
844 #[test]
845 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
846 fn scope_macro_test() {
847 let scope_from_macro = scope![("a", crate::Felt252::ONE)];
848 let mut scope_verbose = ExecutionScopes::new();
849 scope_verbose.assign_or_update_variable("a", any_box!(crate::Felt252::ONE));
850 assert_eq!(scope_from_macro.data.len(), scope_verbose.data.len());
851 assert_eq!(scope_from_macro.data[0].len(), scope_verbose.data[0].len());
852 assert_eq!(
853 scope_from_macro.data[0].get("a").unwrap().downcast_ref(),
854 Some(&crate::Felt252::ONE)
855 );
856 }
857
858 #[test]
859 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
860 fn check_dictionary_pass() {
861 let mut tracker = DictTracker::new_empty(relocatable!(2, 0));
862 tracker.insert_value(
863 &MaybeRelocatable::from(crate::Felt252::from(5)),
864 &MaybeRelocatable::from(crate::Felt252::from(10)),
865 );
866 let mut dict_manager = DictManager::new();
867 dict_manager.trackers.insert(2, tracker);
868 let mut exec_scopes = ExecutionScopes::new();
869 exec_scopes.assign_or_update_variable(
870 "dict_manager",
871 any_box!(Rc::new(RefCell::new(dict_manager))),
872 );
873 check_dictionary!(&exec_scopes, 2, (5, 10));
874 }
875
876 #[test]
877 #[should_panic]
878 fn check_dictionary_fail() {
879 let mut tracker = DictTracker::new_empty(relocatable!(2, 0));
880 tracker.insert_value(&MaybeRelocatable::from(5), &MaybeRelocatable::from(10));
881 let mut dict_manager = DictManager::new();
882 dict_manager.trackers.insert(2, tracker);
883 let mut exec_scopes = ExecutionScopes::new();
884 exec_scopes.assign_or_update_variable(
885 "dict_manager",
886 any_box!(Rc::new(RefCell::new(dict_manager))),
887 );
888 check_dictionary!(&exec_scopes, 2, (5, 11));
889 }
890
891 #[test]
892 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
893 fn check_dict_ptr_pass() {
894 let tracker = DictTracker::new_empty(relocatable!(2, 0));
895 let mut dict_manager = DictManager::new();
896 dict_manager.trackers.insert(2, tracker);
897 let mut exec_scopes = ExecutionScopes::new();
898 exec_scopes.assign_or_update_variable(
899 "dict_manager",
900 any_box!(Rc::new(RefCell::new(dict_manager))),
901 );
902 check_dict_ptr!(&exec_scopes, 2, (2, 0));
903 }
904
905 #[test]
906 #[should_panic]
907 fn check_dict_ptr_fail() {
908 let tracker = DictTracker::new_empty(relocatable!(2, 0));
909 let mut dict_manager = DictManager::new();
910 dict_manager.trackers.insert(2, tracker);
911 let mut exec_scopes = ExecutionScopes::new();
912 exec_scopes.assign_or_update_variable(
913 "dict_manager",
914 any_box!(Rc::new(RefCell::new(dict_manager))),
915 );
916 check_dict_ptr!(&exec_scopes, 2, (3, 0));
917 }
918
919 #[test]
920 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
921 fn dict_manager_macro() {
922 let tracker = DictTracker::new_empty(relocatable!(2, 0));
923 let mut dict_manager = DictManager::new();
924 dict_manager.trackers.insert(2, tracker);
925 let mut exec_scopes = ExecutionScopes::new();
926 dict_manager!(exec_scopes, 2);
927 assert_matches::assert_matches!(
928 exec_scopes.get_dict_manager(),
929 Ok(x) if x == Rc::new(RefCell::new(dict_manager))
930 );
931 }
932
933 #[test]
934 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
935 fn dict_manager_default_macro() {
936 let tracker = DictTracker::new_default_dict(
937 relocatable!(2, 0),
938 &MaybeRelocatable::from(crate::Felt252::from(17)),
939 None,
940 );
941 let mut dict_manager = DictManager::new();
942 dict_manager.trackers.insert(2, tracker);
943 let mut exec_scopes = ExecutionScopes::new();
944 dict_manager_default!(exec_scopes, 2, 17);
945 assert_matches::assert_matches!(
946 exec_scopes.get_dict_manager(),
947 Ok(x) if x == Rc::new(RefCell::new(dict_manager))
948 );
949 }
950
951 #[test]
952 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
953 fn data_vec_test() {
954 let data = vec_data!((1), ((2, 2)), (("49128305", 10)), (("3b6f00a9", 16)));
955 assert_eq!(data[0], mayberelocatable!(1));
956 assert_eq!(data[1], mayberelocatable!(2, 2));
957 assert_eq!(data[2], mayberelocatable!(49128305));
958 assert_eq!(data[3], mayberelocatable!(997130409));
959 }
960 #[test]
961 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
962 fn from_relocatable_to_indexes_test() {
963 let reloc_1 = relocatable!(1, 5);
964 let reloc_2 = relocatable!(0, 5);
965 let reloc_3 = relocatable!(-1, 5);
966 assert_eq!((1, 5), from_relocatable_to_indexes(reloc_1));
967 assert_eq!((0, 5), from_relocatable_to_indexes(reloc_2));
968 assert_eq!((0, 5), from_relocatable_to_indexes(reloc_3));
969 }
970
971 #[test]
972 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
973 fn program_macro() {
974 let shared_data = SharedProgramData {
975 data: Vec::new(),
976 hints_collection: HintsCollection::new(&BTreeMap::new(), 0).unwrap(),
977 main: None,
978 start: None,
979 end: None,
980 error_message_attributes: Vec::new(),
981 instruction_locations: None,
982 identifiers: HashMap::new(),
983 reference_manager: Program::get_reference_list(&ReferenceManager {
984 references: Vec::new(),
985 }),
986 };
987 let program = Program {
988 shared_program_data: Arc::new(shared_data),
989 constants: HashMap::new(),
990 builtins: Vec::new(),
991 };
992 assert_eq!(program, program!())
993 }
994
995 #[test]
996 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
997 fn program_macro_with_builtin() {
998 let shared_data = SharedProgramData {
999 data: Vec::new(),
1000 hints_collection: HintsCollection::new(&BTreeMap::new(), 0).unwrap(),
1001 main: None,
1002 start: None,
1003 end: None,
1004 error_message_attributes: Vec::new(),
1005 instruction_locations: None,
1006 identifiers: HashMap::new(),
1007 reference_manager: Program::get_reference_list(&ReferenceManager {
1008 references: Vec::new(),
1009 }),
1010 };
1011 let program = Program {
1012 shared_program_data: Arc::new(shared_data),
1013 constants: HashMap::new(),
1014 builtins: vec![BuiltinName::range_check],
1015 };
1016
1017 assert_eq!(program, program![BuiltinName::range_check])
1018 }
1019
1020 #[test]
1021 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
1022 fn program_macro_custom_definition() {
1023 let shared_data = SharedProgramData {
1024 data: Vec::new(),
1025 hints_collection: HintsCollection::new(&BTreeMap::new(), 0).unwrap(),
1026 main: Some(2),
1027 start: None,
1028 end: None,
1029 error_message_attributes: Vec::new(),
1030 instruction_locations: None,
1031 identifiers: HashMap::new(),
1032 reference_manager: Program::get_reference_list(&ReferenceManager {
1033 references: Vec::new(),
1034 }),
1035 };
1036 let program = Program {
1037 shared_program_data: Arc::new(shared_data),
1038 constants: HashMap::new(),
1039 builtins: vec![BuiltinName::range_check],
1040 };
1041
1042 assert_eq!(
1043 program,
1044 program!(builtins = vec![BuiltinName::range_check], main = Some(2),)
1045 )
1046 }
1047}