diff --git a/src/hint_processor/builtin_hint_processor/blake2s_utils.rs b/src/hint_processor/builtin_hint_processor/blake2s_utils.rs index a262940dd2..576dae52b8 100644 --- a/src/hint_processor/builtin_hint_processor/blake2s_utils.rs +++ b/src/hint_processor/builtin_hint_processor/blake2s_utils.rs @@ -44,11 +44,10 @@ output_ptr should point to the middle of an instance, right after initial_state, which should all have a value at this point, and right before the output portion which will be written by this function.*/ fn compute_blake2s_func(vm: &mut VirtualMachine, output_rel: Relocatable) -> Result<(), HintError> { - let h = get_fixed_size_u32_array::<8>(&vm.get_integer_range(output_rel.sub_usize(26)?, 8)?)?; - let message = - get_fixed_size_u32_array::<16>(&vm.get_integer_range(output_rel.sub_usize(18)?, 16)?)?; - let t = felt_to_u32(vm.get_integer(output_rel.sub_usize(2)?)?.as_ref())?; - let f = felt_to_u32(vm.get_integer(output_rel.sub_usize(1)?)?.as_ref())?; + let h = get_fixed_size_u32_array::<8>(&vm.get_integer_range((output_rel - 26)?, 8)?)?; + let message = get_fixed_size_u32_array::<16>(&vm.get_integer_range((output_rel - 18)?, 16)?)?; + let t = felt_to_u32(vm.get_integer((output_rel - 2)?)?.as_ref())?; + let f = felt_to_u32(vm.get_integer((output_rel - 1)?)?.as_ref())?; let new_state = get_maybe_relocatable_array_from_u32(&blake2s_compress(&h, &message, t, 0, f, 0)); let output_ptr = MaybeRelocatable::RelocatableValue(output_rel); @@ -158,7 +157,7 @@ pub fn blake2s_add_uint256( //Insert second batch of data let data = get_maybe_relocatable_array_from_felt(&inner_data); vm.load_data( - &MaybeRelocatable::RelocatableValue(data_ptr).add_usize(4), + &MaybeRelocatable::RelocatableValue(data_ptr).add_usize(4)?, &data, ) .map_err(HintError::Memory)?; @@ -205,7 +204,7 @@ pub fn blake2s_add_uint256_bigend( //Insert second batch of data let data = get_maybe_relocatable_array_from_felt(&inner_data); vm.load_data( - &MaybeRelocatable::RelocatableValue(data_ptr).add_usize(4), + &MaybeRelocatable::RelocatableValue(data_ptr).add_usize(4)?, &data, ) .map_err(HintError::Memory)?; diff --git a/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index e3233abeb6..2d20e07c1b 100644 --- a/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -14,7 +14,7 @@ use crate::{ }; use felt::Felt; use num_traits::{ToPrimitive, Zero}; -use std::{borrow::Cow, collections::HashMap, ops::Add}; +use std::{borrow::Cow, collections::HashMap}; // Constants in package "starkware.cairo.common.cairo_keccak.keccak". const BYTES_IN_WORD: &str = "starkware.cairo.common.cairo_keccak.keccak.BYTES_IN_WORD"; @@ -53,7 +53,7 @@ pub fn keccak_write_args( .map_err(HintError::Memory)?; let high_args: Vec<_> = high_args.into_iter().map(MaybeRelocatable::from).collect(); - vm.write_arg(inputs_ptr.add(2_i32), &high_args) + vm.write_arg((inputs_ptr + 2_i32)?, &high_args) .map_err(HintError::Memory)?; Ok(()) @@ -145,7 +145,7 @@ pub fn block_permutation( let keccak_state_size_felts = keccak_state_size_felts.to_usize().unwrap(); let values = vm .get_range( - &MaybeRelocatable::RelocatableValue(keccak_ptr.sub_usize(keccak_state_size_felts)?), + &MaybeRelocatable::RelocatableValue((keccak_ptr - keccak_state_size_felts)?), keccak_state_size_felts, ) .map_err(HintError::Memory)?; diff --git a/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs b/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs index a8c576c1f6..ab222d1ecf 100644 --- a/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs @@ -138,7 +138,7 @@ pub fn dict_write( let tracker = dict.get_tracker_mut(dict_ptr)?; //dict_ptr is a pointer to a struct, with the ordered fields (key, prev_value, new_value), //dict_ptr.prev_value will be equal to dict_ptr + 1 - let dict_ptr_prev_value = dict_ptr + 1_i32; + let dict_ptr_prev_value = (dict_ptr + 1_i32)?; //Tracker set to track next dictionary entry tracker.current_ptr.offset += DICT_ACCESS_SIZE; //Get previous value diff --git a/src/hint_processor/builtin_hint_processor/find_element_hint.rs b/src/hint_processor/builtin_hint_processor/find_element_hint.rs index 49cb7094a9..1e559fa252 100644 --- a/src/hint_processor/builtin_hint_processor/find_element_hint.rs +++ b/src/hint_processor/builtin_hint_processor/find_element_hint.rs @@ -36,7 +36,7 @@ pub fn find_element( if let Some(find_element_index_value) = find_element_index { let find_element_index_usize = felt_to_usize(&find_element_index_value)?; let found_key = vm - .get_integer(array_start + (elm_size * find_element_index_usize)) + .get_integer((array_start + (elm_size * find_element_index_usize))?) .map_err(|_| HintError::KeyNotFound)?; if found_key.as_ref() != key.as_ref() { @@ -68,7 +68,7 @@ pub fn find_element( for i in 0..n_elms_iter { let iter_key = vm - .get_integer(array_start + (elm_size * i as usize)) + .get_integer((array_start + (elm_size * i as usize))?) .map_err(|_| HintError::KeyNotFound)?; if iter_key.as_ref() == key.as_ref() { diff --git a/src/hint_processor/builtin_hint_processor/keccak_utils.rs b/src/hint_processor/builtin_hint_processor/keccak_utils.rs index f6bbfee3a6..38a5bb348c 100644 --- a/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -144,7 +144,7 @@ pub fn unsafe_keccak_finalize( offset: keccak_state_ptr.offset + 1, })?; - let n_elems = end_ptr.sub(&start_ptr)?; + let n_elems = (end_ptr - start_ptr)?; let mut keccak_input = Vec::new(); let range = vm.get_integer_range(start_ptr, n_elems)?; diff --git a/src/hint_processor/builtin_hint_processor/math_utils.rs b/src/hint_processor/builtin_hint_processor/math_utils.rs index d51a88161e..0545373868 100644 --- a/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -120,10 +120,10 @@ pub fn assert_le_felt( let (q_0, r_0) = (lengths_and_indices[0].0).div_mod_floor(prime_over_3_high); let (q_1, r_1) = (lengths_and_indices[1].0).div_mod_floor(prime_over_2_high); - vm.insert_value(range_check_ptr + 1_i32, q_0)?; + vm.insert_value((range_check_ptr + 1_i32)?, q_0)?; vm.insert_value(range_check_ptr, r_0)?; - vm.insert_value(range_check_ptr + 3_i32, q_1)?; - vm.insert_value(range_check_ptr + 2_i32, r_1)?; + vm.insert_value((range_check_ptr + 3_i32)?, q_1)?; + vm.insert_value((range_check_ptr + 2_i32)?, r_1)?; Ok(()) } diff --git a/src/hint_processor/builtin_hint_processor/pow_utils.rs b/src/hint_processor/builtin_hint_processor/pow_utils.rs index cb903b1d3e..6de8b9e877 100644 --- a/src/hint_processor/builtin_hint_processor/pow_utils.rs +++ b/src/hint_processor/builtin_hint_processor/pow_utils.rs @@ -22,7 +22,9 @@ pub fn pow( ap_tracking: &ApTracking, ) -> Result<(), HintError> { let prev_locs_exp = vm - .get_integer(get_relocatable_from_var_name("prev_locs", vm, ids_data, ap_tracking)? + 4_i32) + .get_integer( + (get_relocatable_from_var_name("prev_locs", vm, ids_data, ap_tracking)? + 4_i32)?, + ) .map_err(|_| { HintError::IdentifierHasNoMember("prev_locs".to_string(), "exp".to_string()) })?; diff --git a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index e76f4e4dae..68670332bd 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -33,10 +33,10 @@ impl BigInt3<'_> { d0: vm.get_integer(addr).map_err(|_| { HintError::IdentifierHasNoMember(name.to_string(), "d0".to_string()) })?, - d1: vm.get_integer(addr + 1).map_err(|_| { + d1: vm.get_integer((addr + 1)?).map_err(|_| { HintError::IdentifierHasNoMember(name.to_string(), "d1".to_string()) })?, - d2: vm.get_integer(addr + 2).map_err(|_| { + d2: vm.get_integer((addr + 2)?).map_err(|_| { HintError::IdentifierHasNoMember(name.to_string(), "d2".to_string()) })?, }) @@ -91,7 +91,7 @@ pub fn bigint_to_uint256( ) -> Result<(), HintError> { let x_struct = get_relocatable_from_var_name("x", vm, ids_data, ap_tracking)?; let d0 = vm.get_integer(x_struct)?; - let d1 = vm.get_integer(x_struct + 1_i32)?; + let d1 = vm.get_integer((x_struct + 1_i32)?)?; let d0 = d0.as_ref(); let d1 = d1.as_ref(); let base_86 = constants diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index 6e1f3b3a17..cad7bd38a1 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -40,7 +40,7 @@ impl EcPoint<'_> { let point_addr = get_relocatable_from_var_name(name, vm, ids_data, ap_tracking)?; Ok(EcPoint { x: BigInt3::from_base_addr(point_addr, &format!("{}.x", name), vm)?, - y: BigInt3::from_base_addr(point_addr + 3, &format!("{}.y", name), vm)?, + y: BigInt3::from_base_addr((point_addr + 3)?, &format!("{}.y", name), vm)?, }) } } @@ -71,7 +71,7 @@ pub fn ec_negate( .to_bigint(); //ids.point - let point_y = get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)? + 3i32; + let point_y = (get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)? + 3i32)?; let y_bigint3 = BigInt3::from_base_addr(point_y, "point.y", vm)?; let y = pack(y_bigint3); let value = (-y).mod_floor(&secp_p); diff --git a/src/hint_processor/builtin_hint_processor/set.rs b/src/hint_processor/builtin_hint_processor/set.rs index a1a0145616..fec6462cfa 100644 --- a/src/hint_processor/builtin_hint_processor/set.rs +++ b/src/hint_processor/builtin_hint_processor/set.rs @@ -46,11 +46,11 @@ pub fn set_add( )); } - let range_limit = set_end_ptr.sub(&set_ptr)?; + let range_limit = (set_end_ptr - set_ptr)?; for i in (0..range_limit).step_by(elm_size) { let set_iter = vm - .get_range(&MaybeRelocatable::from(set_ptr + i), elm_size) + .get_range(&MaybeRelocatable::from((set_ptr + i)?), elm_size) .map_err(VirtualMachineError::Memory)?; if set_iter == elm { diff --git a/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/src/hint_processor/builtin_hint_processor/sha256_utils.rs index df8672e035..ee7f92a31f 100644 --- a/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -56,7 +56,7 @@ pub fn sha256_main( let mut message: Vec = Vec::with_capacity(4 * SHA256_INPUT_CHUNK_SIZE_FELTS); for i in 0..SHA256_INPUT_CHUNK_SIZE_FELTS { - let input_element = vm.get_integer(input_ptr + i)?; + let input_element = vm.get_integer((input_ptr + i)?)?; let bytes = felt_to_u32(input_element.as_ref())?.to_be_bytes(); message.extend(bytes); } diff --git a/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs b/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs index e24847c735..d12193e669 100644 --- a/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs +++ b/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs @@ -141,7 +141,7 @@ pub fn squash_dict_inner_continue_loop( }; //loop_temps.delta_minus1 = loop_temps + 3 as it is the fourth field of the struct //Insert loop_temps.delta_minus1 into memory - let should_continue_addr = loop_temps_addr + 3_i32; + let should_continue_addr = (loop_temps_addr + 3_i32)?; vm.insert_value(should_continue_addr, should_continue) .map_err(HintError::Memory) } @@ -265,7 +265,7 @@ pub fn squash_dict( //A map from key to the list of indices accessing it. let mut access_indices = HashMap::>::new(); for i in 0..n_accesses_usize { - let key_addr = address + DICT_ACCESS_SIZE * i; + let key_addr = (address + DICT_ACCESS_SIZE * i)?; let key = vm .get_integer(key_addr) .map_err(|_| MemoryError::ExpectedInteger(key_addr))?; diff --git a/src/hint_processor/builtin_hint_processor/uint256_utils.rs b/src/hint_processor/builtin_hint_processor/uint256_utils.rs index d7ba38457d..f358b78713 100644 --- a/src/hint_processor/builtin_hint_processor/uint256_utils.rs +++ b/src/hint_processor/builtin_hint_processor/uint256_utils.rs @@ -33,9 +33,9 @@ pub fn uint256_add( let a_relocatable = get_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?; let b_relocatable = get_relocatable_from_var_name("b", vm, ids_data, ap_tracking)?; let a_low = vm.get_integer(a_relocatable)?; - let a_high = vm.get_integer(a_relocatable + 1_usize)?; + let a_high = vm.get_integer((a_relocatable + 1_usize)?)?; let b_low = vm.get_integer(b_relocatable)?; - let b_high = vm.get_integer(b_relocatable + 1_usize)?; + let b_high = vm.get_integer((b_relocatable + 1_usize)?)?; let a_low = a_low.as_ref(); let a_high = a_high.as_ref(); let b_low = b_low.as_ref(); @@ -105,7 +105,7 @@ pub fn uint256_sqrt( let n_addr = get_relocatable_from_var_name("n", vm, ids_data, ap_tracking)?; let root_addr = get_relocatable_from_var_name("root", vm, ids_data, ap_tracking)?; let n_low = vm.get_integer(n_addr)?; - let n_high = vm.get_integer(n_addr + 1_usize)?; + let n_high = vm.get_integer((n_addr + 1_usize)?)?; let n_low = n_low.as_ref(); let n_high = n_high.as_ref(); @@ -127,7 +127,7 @@ pub fn uint256_sqrt( ))); } vm.insert_value(root_addr, Felt::new(root))?; - vm.insert_value(root_addr + 1_i32, Felt::zero()) + vm.insert_value((root_addr + 1_i32)?, Felt::zero()) .map_err(HintError::Memory) } @@ -141,7 +141,7 @@ pub fn uint256_signed_nn( ap_tracking: &ApTracking, ) -> Result<(), HintError> { let a_addr = get_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?; - let a_high = vm.get_integer(a_addr + 1_usize)?; + let a_high = vm.get_integer((a_addr + 1_usize)?)?; //Main logic //memory[ap] = 1 if 0 <= (ids.a.high % PRIME) < 2 ** 127 else 0 let result: Felt = if !a_high.is_negative() && a_high.as_ref() <= &Felt::new(i128::MAX) { @@ -176,9 +176,9 @@ pub fn uint256_unsigned_div_rem( let remainder_addr = get_relocatable_from_var_name("remainder", vm, ids_data, ap_tracking)?; let a_low = vm.get_integer(a_addr)?; - let a_high = vm.get_integer(a_addr + 1_usize)?; + let a_high = vm.get_integer((a_addr + 1_usize)?)?; let div_low = vm.get_integer(div_addr)?; - let div_high = vm.get_integer(div_addr + 1_usize)?; + let div_high = vm.get_integer((div_addr + 1_usize)?)?; let a_low = a_low.as_ref(); let a_high = a_high.as_ref(); let div_low = div_low.as_ref(); @@ -208,11 +208,11 @@ pub fn uint256_unsigned_div_rem( //Insert ids.quotient.low vm.insert_value(quotient_addr, quotient_low)?; //Insert ids.quotient.high - vm.insert_value(quotient_addr + 1_i32, quotient_high)?; + vm.insert_value((quotient_addr + 1_i32)?, quotient_high)?; //Insert ids.remainder.low vm.insert_value(remainder_addr, remainder_low)?; //Insert ids.remainder.high - vm.insert_value(remainder_addr + 1_i32, remainder_high)?; + vm.insert_value((remainder_addr + 1_i32)?, remainder_high)?; Ok(()) } diff --git a/src/hint_processor/builtin_hint_processor/usort.rs b/src/hint_processor/builtin_hint_processor/usort.rs index 5df0fee8bc..72c8b8d6be 100644 --- a/src/hint_processor/builtin_hint_processor/usort.rs +++ b/src/hint_processor/builtin_hint_processor/usort.rs @@ -48,7 +48,7 @@ pub fn usort_body( let mut positions_dict: HashMap> = HashMap::new(); let mut output: Vec = Vec::new(); for i in 0..input_len_u64 { - let val = vm.get_integer(input_ptr + i as usize)?.into_owned(); + let val = vm.get_integer((input_ptr + i as usize)?)?.into_owned(); if let Err(output_index) = output.binary_search(&val) { output.insert(output_index, val.clone()); } @@ -65,11 +65,11 @@ pub fn usort_body( let output_len = output.len(); for (i, sorted_element) in output.into_iter().enumerate() { - vm.insert_value(output_base + i, sorted_element)?; + vm.insert_value((output_base + i)?, sorted_element)?; } for (i, repetition_amount) in multiplicities.into_iter().enumerate() { - vm.insert_value(multiplicities_base + i, Felt::new(repetition_amount))?; + vm.insert_value((multiplicities_base + i)?, Felt::new(repetition_amount))?; } insert_value_from_var_name( diff --git a/src/hint_processor/hint_processor_utils.rs b/src/hint_processor/hint_processor_utils.rs index dce03881c3..0a846e8b4a 100644 --- a/src/hint_processor/hint_processor_utils.rs +++ b/src/hint_processor/hint_processor_utils.rs @@ -112,9 +112,9 @@ pub fn compute_addr_from_reference( &hint_reference.offset2, )?; - Some(offset1 + value.get_int_ref()?.to_usize()?) + Some((offset1 + value.get_int_ref()?.to_usize()?).ok()?) } - OffsetValue::Value(value) => Some(offset1 + *value), + OffsetValue::Value(value) => Some((offset1 + *value).ok()?), _ => None, } } @@ -129,7 +129,7 @@ fn apply_ap_tracking_correction( return None; } let ap_diff = hint_ap_tracking.offset - ref_ap_tracking.offset; - ap.sub_usize(ap_diff).ok() + (ap - ap_diff).ok() } //Tries to convert a Felt value to usize @@ -168,9 +168,9 @@ fn get_offset_value_reference( } if *deref { - vm.get_maybe(&(base_addr + *offset)) + vm.get_maybe(&(base_addr + *offset).ok()?) } else { - Some((base_addr + *offset).into()) + Some((base_addr + *offset).ok()?.into()) } } diff --git a/src/types/errors/math_errors.rs b/src/types/errors/math_errors.rs index 38c94792cd..bb7accb49a 100644 --- a/src/types/errors/math_errors.rs +++ b/src/types/errors/math_errors.rs @@ -6,6 +6,7 @@ use crate::types::relocatable::{MaybeRelocatable, Relocatable}; #[derive(Debug, Error, PartialEq)] pub enum MathError { + // Math functions #[error("Can't calculate the square root of negative number: {0})")] SqrtNegative(Felt), #[error("{0} is not divisible by {1}")] @@ -28,7 +29,9 @@ pub enum MathError { #[error("Operation failed: {0} - {1}, offsets cant be negative")] RelocatableSubNegOffset(Relocatable, usize), #[error("Operation failed: {0} + {1}, maximum offset value exceeded")] - RelocatableAddOffsetExceeded(Relocatable, Felt), + RelocatableAddFeltOffsetExceeded(Relocatable, Felt), + #[error("Operation failed: {0} + {1}, maximum offset value exceeded")] + RelocatableAddUsizeOffsetExceeded(Relocatable, usize), #[error("Operation failed: {0} + {1}, cant add two relocatable values")] RelocatableAdd(Relocatable, Relocatable), #[error("Operation failed: {0} - {1}, cant substract two relocatable values with different segment indexes")] diff --git a/src/types/relocatable.rs b/src/types/relocatable.rs index 0c40f2bf09..1123a3084d 100644 --- a/src/types/relocatable.rs +++ b/src/types/relocatable.rs @@ -6,7 +6,7 @@ use num_traits::{FromPrimitive, ToPrimitive, Zero}; use serde::{Deserialize, Serialize}; use std::{ fmt::{self, Display}, - ops::{Add, AddAssign}, + ops::{Add, AddAssign, Sub}, }; #[derive(Eq, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize)] @@ -88,12 +88,16 @@ impl Display for Relocatable { } impl Add for Relocatable { - type Output = Relocatable; - fn add(self, other: usize) -> Self { - relocatable!(self.segment_index, self.offset + other) + type Output = Result; + fn add(self, other: usize) -> Result { + self.offset + .checked_add(other) + .map(|x| Relocatable::from((self.segment_index, x))) + .ok_or(MathError::RelocatableAddUsizeOffsetExceeded(self, other)) } } +/// Warning: may panic if self.offset + rhs exceeds usize::MAX impl AddAssign for Relocatable { fn add_assign(&mut self, rhs: usize) { self.offset += rhs @@ -101,30 +105,65 @@ impl AddAssign for Relocatable { } impl Add for Relocatable { - type Output = Relocatable; - fn add(self, other: i32) -> Self { + type Output = Result; + fn add(self, other: i32) -> Result { if other >= 0 { - relocatable!(self.segment_index, self.offset + other as usize) + self + other as usize } else { - relocatable!( - self.segment_index, - self.offset - other.unsigned_abs() as usize - ) + self - other.unsigned_abs() as usize } } } +impl Add<&Felt> for Relocatable { + type Output = Result; + fn add(self, other: &Felt) -> Result { + let big_offset = other + self.offset; + let new_offset = big_offset + .to_usize() + .ok_or_else(|| MathError::RelocatableAddFeltOffsetExceeded(self, other.clone()))?; + Ok(Relocatable { + segment_index: self.segment_index, + offset: new_offset, + }) + } +} -impl Add for &Relocatable { - type Output = Relocatable; - fn add(self, other: i32) -> Relocatable { - if other >= 0 { - relocatable!(self.segment_index, self.offset + other as usize) - } else { - relocatable!( - self.segment_index, - self.offset - other.unsigned_abs() as usize - ) +/// Adds a MaybeRelocatable to self +/// Cant add two relocatable values +impl Add<&MaybeRelocatable> for Relocatable { + type Output = Result; + fn add(self, other: &MaybeRelocatable) -> Result { + let num_ref = match other { + MaybeRelocatable::RelocatableValue(rel) => { + return Err(MathError::RelocatableAdd(self, *rel)) + } + MaybeRelocatable::Int(num) => num, + }; + self + num_ref + } +} + +impl Sub for Relocatable { + type Output = Result; + fn sub(self, other: usize) -> Result { + if self.offset < other { + return Err(MathError::RelocatableSubNegOffset(self, other)); + } + let new_offset = self.offset - other; + Ok(relocatable!(self.segment_index, new_offset)) + } +} +impl Sub for Relocatable { + type Output = Result; + fn sub(self, other: Self) -> Result { + if self.segment_index != other.segment_index { + return Err(MathError::RelocatableSubDiffIndex(self, other)); + } + if self.offset < other.offset { + return Err(MathError::RelocatableSubNegOffset(self, other.offset)); } + let result = self.offset - other.offset; + Ok(result) } } @@ -154,51 +193,6 @@ impl TryFrom<&MaybeRelocatable> for Relocatable { } } -impl Relocatable { - pub fn sub_usize(&self, other: usize) -> Result { - if self.offset < other { - return Err(MathError::RelocatableSubNegOffset(*self, other)); - } - let new_offset = self.offset - other; - Ok(relocatable!(self.segment_index, new_offset)) - } - - ///Adds a Felt to self - pub fn add_int(&self, other: &Felt) -> Result { - let big_offset = other + self.offset; - let new_offset = big_offset - .to_usize() - .ok_or_else(|| MathError::RelocatableAddOffsetExceeded(*self, other.clone()))?; - Ok(Relocatable { - segment_index: self.segment_index, - offset: new_offset, - }) - } - - /// Adds a MaybeRelocatable to self - /// Cant add two relocatable values - pub fn add_maybe(&self, other: &MaybeRelocatable) -> Result { - let num_ref = match other { - MaybeRelocatable::RelocatableValue(rel) => { - return Err(MathError::RelocatableAdd(*self, *rel)) - } - MaybeRelocatable::Int(num) => num, - }; - self.add_int(num_ref) - } - - pub fn sub(&self, other: &Self) -> Result { - if self.segment_index != other.segment_index { - return Err(MathError::RelocatableSubDiffIndex(*self, *other)); - } - if self.offset < other.offset { - return Err(MathError::RelocatableSubNegOffset(*self, other.offset)); - } - let result = self.offset - other.offset; - Ok(result) - } -} - impl MaybeRelocatable { /// Adds a Felt to self pub fn add_int(&self, other: &Felt) -> Result { @@ -206,9 +200,9 @@ impl MaybeRelocatable { MaybeRelocatable::Int(ref value) => Ok(MaybeRelocatable::Int(value + other)), MaybeRelocatable::RelocatableValue(ref rel) => { let big_offset = other + rel.offset; - let new_offset = big_offset - .to_usize() - .ok_or_else(|| MathError::RelocatableAddOffsetExceeded(*rel, other.clone()))?; + let new_offset = big_offset.to_usize().ok_or_else(|| { + MathError::RelocatableAddFeltOffsetExceeded(*rel, other.clone()) + })?; Ok(MaybeRelocatable::RelocatableValue(Relocatable { segment_index: rel.segment_index, offset: new_offset, @@ -218,16 +212,11 @@ impl MaybeRelocatable { } /// Adds a usize to self - pub fn add_usize(&self, other: usize) -> MaybeRelocatable { - match *self { + pub fn add_usize(&self, other: usize) -> Result { + Ok(match *self { MaybeRelocatable::Int(ref value) => MaybeRelocatable::Int(value + other), - MaybeRelocatable::RelocatableValue(ref rel) => { - MaybeRelocatable::RelocatableValue(Relocatable { - segment_index: rel.segment_index, - offset: rel.offset + other, - }) - } - } + MaybeRelocatable::RelocatableValue(rel) => (rel + other)?.into(), + }) } /// Adds a MaybeRelocatable to self @@ -241,9 +230,9 @@ impl MaybeRelocatable { &MaybeRelocatable::RelocatableValue(rel_a), &MaybeRelocatable::RelocatableValue(rel_b), ) => Err(MathError::RelocatableAdd(rel_a, rel_b)), - (&MaybeRelocatable::RelocatableValue(ref rel), &MaybeRelocatable::Int(ref num_ref)) - | (&MaybeRelocatable::Int(ref num_ref), &MaybeRelocatable::RelocatableValue(ref rel)) => { - Ok(rel.add_int(num_ref)?.into()) + (&MaybeRelocatable::RelocatableValue(rel), &MaybeRelocatable::Int(ref num_ref)) + | (&MaybeRelocatable::Int(ref num_ref), &MaybeRelocatable::RelocatableValue(rel)) => { + Ok((rel + num_ref)?.into()) } } } @@ -261,9 +250,7 @@ impl MaybeRelocatable { MaybeRelocatable::RelocatableValue(rel_b), ) => { if rel_a.segment_index == rel_b.segment_index { - return Ok(MaybeRelocatable::from(Felt::new( - rel_a.offset - rel_b.offset, - ))); + return Ok(MaybeRelocatable::from(Felt::new((*rel_a - *rel_b)?))); } Err(MathError::RelocatableSubDiffIndex(*rel_a, *rel_b)) } @@ -271,7 +258,7 @@ impl MaybeRelocatable { Ok(MaybeRelocatable::from(( rel_a.segment_index, (rel_a.offset - num_b).to_usize().ok_or_else(|| { - MathError::RelocatableAddOffsetExceeded(*rel_a, num_b.clone()) + MathError::RelocatableAddFeltOffsetExceeded(*rel_a, num_b.clone()) })?, ))) } @@ -377,7 +364,7 @@ mod tests { #[test] fn add_usize_to_int() { let addr = MaybeRelocatable::from(Felt::new(7_i32)); - let added_addr = addr.add_usize(2); + let added_addr = addr.add_usize(2).unwrap(); assert_eq!(MaybeRelocatable::Int(Felt::new(9)), added_addr); } @@ -400,7 +387,7 @@ mod tests { let error = addr.add_int(&felt_str!("18446744073709551616")); assert_eq!( error, - Err(MathError::RelocatableAddOffsetExceeded( + Err(MathError::RelocatableAddFeltOffsetExceeded( relocatable!(0, 0), felt_str!("18446744073709551616") )) @@ -413,10 +400,10 @@ mod tests { let added_addr = addr.add_usize(2); assert_eq!( added_addr, - MaybeRelocatable::RelocatableValue(Relocatable { + Ok(MaybeRelocatable::RelocatableValue(Relocatable { segment_index: 7, offset: 67 - }) + })) ); } @@ -520,7 +507,7 @@ mod tests { let error = addr.add(&MaybeRelocatable::from(felt_str!("18446744073709551616"))); assert_eq!( error, - Err(MathError::RelocatableAddOffsetExceeded( + Err(MathError::RelocatableAddFeltOffsetExceeded( relocatable!(0, 0), felt_str!("18446744073709551616") )) @@ -537,7 +524,7 @@ mod tests { let error = addr.add(&MaybeRelocatable::RelocatableValue(relocatable)); assert_eq!( error, - Err(MathError::RelocatableAddOffsetExceeded( + Err(MathError::RelocatableAddFeltOffsetExceeded( relocatable!(0, 0), felt_str!("18446744073709551616") )) @@ -671,21 +658,15 @@ mod tests { #[test] fn relocatable_add_int() { - assert_eq!( - relocatable!(1, 2).add_int(&Felt::new(4)), - Ok(relocatable!(1, 6)) - ); - assert_eq!( - relocatable!(3, 2).add_int(&Felt::zero()), - Ok(relocatable!(3, 2)) - ); + assert_eq!(relocatable!(1, 2) + &Felt::new(4), Ok(relocatable!(1, 6))); + assert_eq!(relocatable!(3, 2) + &Felt::zero(), Ok(relocatable!(3, 2))); } #[test] fn relocatable_add_int_mod_offset_exceeded_error() { assert_eq!( - relocatable!(0, 0).add_int(&(Felt::new(usize::MAX) + 1_usize)), - Err(MathError::RelocatableAddOffsetExceeded( + relocatable!(0, 0) + &(Felt::new(usize::MAX) + 1_usize), + Err(MathError::RelocatableAddFeltOffsetExceeded( relocatable!(0, 0), Felt::new(usize::MAX) + 1_usize )) @@ -696,16 +677,18 @@ mod tests { fn relocatable_add_i32() { let reloc = relocatable!(1, 5); - assert_eq!(reloc + 3, relocatable!(1, 8)); - assert_eq!(reloc + (-3), relocatable!(1, 2)); + assert_eq!(reloc + 3, Ok(relocatable!(1, 8))); + assert_eq!(reloc + (-3), Ok(relocatable!(1, 2))); } #[test] - #[should_panic] fn relocatable_add_i32_with_overflow() { let reloc = relocatable!(1, 1); - let _panic = reloc + (-3); + assert_eq!( + reloc + (-3), + Err(MathError::RelocatableSubNegOffset(relocatable!(1, 1), 3)) + ); } #[test] @@ -721,9 +704,9 @@ mod tests { #[test] fn relocatable_sub_rel_test() { let reloc = relocatable!(7, 6); - assert_eq!(reloc.sub(&relocatable!(7, 5)), Ok(1)); + assert_eq!(reloc - relocatable!(7, 5), Ok(1)); assert_eq!( - reloc.sub(&relocatable!(7, 9)), + reloc - relocatable!(7, 9), Err(MathError::RelocatableSubNegOffset(relocatable!(7, 6), 9)) ); } @@ -732,29 +715,29 @@ mod tests { fn sub_rel_different_indexes() { let a = relocatable!(7, 6); let b = relocatable!(8, 6); - assert_eq!(a.sub(&b), Err(MathError::RelocatableSubDiffIndex(a, b))); + assert_eq!(a - b, Err(MathError::RelocatableSubDiffIndex(a, b))); } #[test] fn add_maybe_mod_ok() { assert_eq!( - relocatable!(1, 0).add_maybe(&mayberelocatable!(2)), + relocatable!(1, 0) + &mayberelocatable!(2), Ok(relocatable!(1, 2)) ); assert_eq!( - relocatable!(0, 29).add_maybe(&mayberelocatable!(100)), + relocatable!(0, 29) + &mayberelocatable!(100), Ok(relocatable!(0, 129)) ); assert_eq!( - relocatable!(2, 12).add_maybe(&mayberelocatable!(104)), + relocatable!(2, 12) + &mayberelocatable!(104), Ok(relocatable!(2, 116)) ); assert_eq!( - relocatable!(1, 0).add_maybe(&mayberelocatable!(0)), + relocatable!(1, 0) + &mayberelocatable!(0), Ok(relocatable!(1, 0)) ); assert_eq!( - relocatable!(1, 2).add_maybe(&mayberelocatable!(71)), + relocatable!(1, 2) + &mayberelocatable!(71), Ok(relocatable!(1, 73)) ); } @@ -762,7 +745,7 @@ mod tests { #[test] fn add_maybe_mod_add_two_relocatable_error() { assert_eq!( - relocatable!(1, 0).add_maybe(&mayberelocatable!(1, 2)), + relocatable!(1, 0) + &mayberelocatable!(1, 2), Err(MathError::RelocatableAdd( relocatable!(1, 0), relocatable!(1, 2) @@ -773,8 +756,8 @@ mod tests { #[test] fn add_maybe_mod_offset_exceeded_error() { assert_eq!( - relocatable!(1, 0).add_maybe(&mayberelocatable!(usize::MAX as i128 + 1)), - Err(MathError::RelocatableAddOffsetExceeded( + relocatable!(1, 0) + &mayberelocatable!(usize::MAX as i128 + 1), + Err(MathError::RelocatableAddFeltOffsetExceeded( relocatable!(1, 0), Felt::new(usize::MAX) + 1_usize )) diff --git a/src/vm/context/run_context.rs b/src/vm/context/run_context.rs index 56f92f2311..7a5839d634 100644 --- a/src/vm/context/run_context.rs +++ b/src/vm/context/run_context.rs @@ -35,9 +35,9 @@ impl RunContext { Register::FP => self.get_fp(), }; if instruction.off0 < 0 { - Ok(base_addr.sub_usize(abs(instruction.off0) as usize)?) + Ok((base_addr - abs(instruction.off0) as usize)?) } else { - Ok(base_addr + (instruction.off0 as usize)) + Ok((base_addr + (instruction.off0 as usize))?) } } @@ -50,9 +50,9 @@ impl RunContext { Register::FP => self.get_fp(), }; if instruction.off1 < 0 { - Ok(base_addr.sub_usize(abs(instruction.off1) as usize)?) + Ok((base_addr - abs(instruction.off1) as usize)?) } else { - Ok(base_addr + (instruction.off1 as usize)) + Ok((base_addr + (instruction.off1 as usize))?) } } @@ -75,9 +75,9 @@ impl RunContext { }, }; if instruction.off2 < 0 { - Ok(base_addr.sub_usize(abs(instruction.off2) as usize)?) + Ok((base_addr - abs(instruction.off2) as usize)?) } else { - Ok(base_addr + (instruction.off2 as usize)) + Ok((base_addr + (instruction.off2 as usize))?) } } diff --git a/src/vm/errors/memory_errors.rs b/src/vm/errors/memory_errors.rs index 13cc358c41..9c979e6915 100644 --- a/src/vm/errors/memory_errors.rs +++ b/src/vm/errors/memory_errors.rs @@ -1,9 +1,12 @@ use felt::Felt; use thiserror::Error; -use crate::types::relocatable::{MaybeRelocatable, Relocatable}; +use crate::types::{ + errors::math_errors::MathError, + relocatable::{MaybeRelocatable, Relocatable}, +}; -#[derive(Debug, PartialEq, Eq, Error)] +#[derive(Debug, PartialEq, Error)] pub enum MemoryError { #[error("Can't insert into segment #{0}; memory only has {1} segment")] UnallocatedSegment(usize, usize), @@ -81,6 +84,8 @@ pub enum MemoryError { AccessedAddressOffsetBiggerThanSegmentSize(Relocatable, usize), #[error("gen_arg: found argument of invalid type.")] GenArgInvalidType, + #[error(transparent)] + Math(#[from] MathError), // Memory.get() errors #[error("Expected integer at address {0}")] ExpectedInteger(Relocatable), diff --git a/src/vm/errors/runner_errors.rs b/src/vm/errors/runner_errors.rs index bcd21e25bb..28cd6da479 100644 --- a/src/vm/errors/runner_errors.rs +++ b/src/vm/errors/runner_errors.rs @@ -1,11 +1,14 @@ use std::collections::HashSet; use super::memory_errors::MemoryError; -use crate::types::relocatable::{MaybeRelocatable, Relocatable}; +use crate::types::{ + errors::math_errors::MathError, + relocatable::{MaybeRelocatable, Relocatable}, +}; use felt::Felt; use thiserror::Error; -#[derive(Debug, PartialEq, Eq, Error)] +#[derive(Debug, PartialEq, Error)] pub enum RunnerError { #[error("Can't initialize state without an execution base")] NoExecBase, @@ -85,6 +88,8 @@ pub enum RunnerError { FoundNonInt, #[error(transparent)] Memory(#[from] MemoryError), + #[error(transparent)] + Math(#[from] MathError), #[error("keccak_builtin: Failed to get first input address")] KeccakNoFirstInput, #[error("keccak_builtin: Failed to convert input cells to u64 values")] diff --git a/src/vm/errors/trace_errors.rs b/src/vm/errors/trace_errors.rs index 95ae2252b2..2f63144512 100644 --- a/src/vm/errors/trace_errors.rs +++ b/src/vm/errors/trace_errors.rs @@ -1,7 +1,7 @@ use crate::vm::errors::memory_errors::MemoryError; use thiserror::Error; -#[derive(Debug, PartialEq, Eq, Error)] +#[derive(Debug, PartialEq, Error)] pub enum TraceError { #[error("Trace is not enabled for this run")] TraceNotEnabled, diff --git a/src/vm/runners/builtin_runner/bitwise.rs b/src/vm/runners/builtin_runner/bitwise.rs index 8569f6b6f7..f8068f3c2e 100644 --- a/src/vm/runners/builtin_runner/bitwise.rs +++ b/src/vm/runners/builtin_runner/bitwise.rs @@ -77,7 +77,7 @@ impl BitwiseBuiltinRunner { return Ok(None); } let x_addr = Relocatable::from((address.segment_index, address.offset - index)); - let y_addr = x_addr + 1_usize; + let y_addr = (x_addr + 1_usize)?; let num_x = memory.get(&x_addr); let num_y = memory.get(&y_addr); @@ -183,9 +183,8 @@ impl BitwiseBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(BITWISE_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(BITWISE_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/ec_op.rs b/src/vm/runners/builtin_runner/ec_op.rs index 10de79728b..1c9ce96d61 100644 --- a/src/vm/runners/builtin_runner/ec_op.rs +++ b/src/vm/runners/builtin_runner/ec_op.rs @@ -158,7 +158,7 @@ impl EcOpBuiltinRunner { //If an input cell is not filled, return None let mut input_cells = Vec::<&Felt>::with_capacity(self.n_input_cells as usize); for i in 0..self.n_input_cells as usize { - match memory.get(&(instance + i)) { + match memory.get(&(instance + i)?) { None => return Ok(None), Some(addr) => { input_cells.push(match addr { @@ -166,7 +166,7 @@ impl EcOpBuiltinRunner { Cow::Borrowed(MaybeRelocatable::Int(ref num)) => num, _ => { return Err(RunnerError::Memory(MemoryError::ExpectedInteger( - instance + i, + (instance + i)?, ))) } }); @@ -275,9 +275,8 @@ impl EcOpBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/hash.rs b/src/vm/runners/builtin_runner/hash.rs index a30d8eca88..599f21363c 100644 --- a/src/vm/runners/builtin_runner/hash.rs +++ b/src/vm/runners/builtin_runner/hash.rs @@ -177,9 +177,8 @@ impl HashBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(EC_OP_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/keccak.rs b/src/vm/runners/builtin_runner/keccak.rs index 65e507c100..b365e06215 100644 --- a/src/vm/runners/builtin_runner/keccak.rs +++ b/src/vm/runners/builtin_runner/keccak.rs @@ -75,10 +75,7 @@ impl KeccakBuiltinRunner { return Ok(None); } - let first_input_addr = address - .sub_usize(index) - .map_err(|_| RunnerError::KeccakNoFirstInput)?; - + let first_input_addr = (address - index).map_err(|_| RunnerError::KeccakNoFirstInput)?; if self.verified_addresses.contains(&first_input_addr) { return Ok(None); } @@ -86,7 +83,7 @@ impl KeccakBuiltinRunner { let mut input_felts_u64 = vec![]; for i in 0..self.n_input_cells { - let val = match memory.get(&(first_input_addr + i as usize)) { + let val = match memory.get(&(first_input_addr + i as usize)?) { Some(val) => val .as_ref() .get_int_ref() @@ -99,10 +96,10 @@ impl KeccakBuiltinRunner { } if let Some((i, bits)) = self.state_rep.iter().enumerate().next() { - let val = memory.get_integer(first_input_addr + i)?; + let val = memory.get_integer((first_input_addr + i)?)?; if val.as_ref() >= &(Felt::one() << *bits) { return Err(RunnerError::IntegerBiggerThanPowerOfTwo( - (first_input_addr + i).into(), + (first_input_addr + i)?.into(), *bits, val.into_owned(), )); @@ -185,9 +182,8 @@ impl KeccakBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(KECCAK_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(KECCAK_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/output.rs b/src/vm/runners/builtin_runner/output.rs index 820942c4d5..618faa0f1a 100644 --- a/src/vm/runners/builtin_runner/output.rs +++ b/src/vm/runners/builtin_runner/output.rs @@ -84,9 +84,8 @@ impl OutputBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(OUTPUT_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(OUTPUT_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/range_check.rs b/src/vm/runners/builtin_runner/range_check.rs index c68f47ab8d..5c19b75342 100644 --- a/src/vm/runners/builtin_runner/range_check.rs +++ b/src/vm/runners/builtin_runner/range_check.rs @@ -201,9 +201,8 @@ impl RangeCheckBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(RANGE_CHECK_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(RANGE_CHECK_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/builtin_runner/signature.rs b/src/vm/runners/builtin_runner/signature.rs index 8019ef63a4..1095de4a93 100644 --- a/src/vm/runners/builtin_runner/signature.rs +++ b/src/vm/runners/builtin_runner/signature.rs @@ -103,8 +103,8 @@ impl SignatureBuiltinRunner { let cell_index = addr.offset % cells_per_instance as usize; let (pubkey_addr, message_addr) = match cell_index { - 0 => (addr, addr + 1), - 1 => match addr.sub_usize(1) { + 0 => (addr, (addr + 1)?), + 1 => match addr - 1 { Ok(prev_addr) => (prev_addr, addr), Err(_) => return Ok(vec![]), }, @@ -222,9 +222,8 @@ impl SignatureBuiltinRunner { pointer: Relocatable, ) -> Result { if self.included { - let stop_pointer_addr = pointer - .sub_usize(1) - .map_err(|_| RunnerError::NoStopPointer(SIGNATURE_BUILTIN_NAME))?; + let stop_pointer_addr = + (pointer - 1).map_err(|_| RunnerError::NoStopPointer(SIGNATURE_BUILTIN_NAME))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) diff --git a/src/vm/runners/cairo_runner.rs b/src/vm/runners/cairo_runner.rs index 8dfe5d8611..a31c48c4d8 100644 --- a/src/vm/runners/cairo_runner.rs +++ b/src/vm/runners/cairo_runner.rs @@ -4596,7 +4596,7 @@ mod tests { .unwrap(); vm.segments.compute_effective_sizes(); let initial_pointer = vm.get_ap(); - let expected_pointer = vm.get_ap().sub_usize(1).unwrap(); + let expected_pointer = (vm.get_ap() - 1).unwrap(); assert_eq!( runner.get_builtins_final_stack(&mut vm, initial_pointer), Ok(expected_pointer) @@ -4615,7 +4615,7 @@ mod tests { .unwrap(); vm.segments.compute_effective_sizes(); let initial_pointer = vm.get_ap(); - let expected_pointer = vm.get_ap().sub_usize(4).unwrap(); + let expected_pointer = (vm.get_ap() - 4).unwrap(); assert_eq!( runner.get_builtins_final_stack(&mut vm, initial_pointer), Ok(expected_pointer) diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index b724a519d7..cb2dba872b 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -146,7 +146,7 @@ impl VirtualMachine { _ => return Err(VirtualMachineError::InvalidInstructionEncoding), }; - let imm_addr = &self.run_context.pc + 1_i32; + let imm_addr = (self.run_context.pc + 1_i32)?; Ok((encoding_ref, self.segments.memory.get(&imm_addr))) } @@ -176,7 +176,7 @@ impl VirtualMachine { ) -> Result<(), VirtualMachineError> { let new_ap_offset: usize = match instruction.ap_update { ApUpdate::Add => match &operands.res { - Some(res) => self.run_context.get_ap().add_maybe(res)?.offset, + Some(res) => (self.run_context.get_ap() + res)?.offset, None => return Err(VirtualMachineError::UnconstrainedResAdd), }, ApUpdate::Add1 => self.run_context.ap + 1, @@ -193,21 +193,21 @@ impl VirtualMachine { operands: &Operands, ) -> Result<(), VirtualMachineError> { let new_pc: Relocatable = match instruction.pc_update { - PcUpdate::Regular => self.run_context.pc + instruction.size(), + PcUpdate::Regular => (self.run_context.pc + instruction.size())?, PcUpdate::Jump => match operands.res.as_ref().and_then(|x| x.get_relocatable()) { Some(ref res) => *res, None => return Err(VirtualMachineError::UnconstrainedResJump), }, PcUpdate::JumpRel => match operands.res.clone() { Some(res) => match res { - MaybeRelocatable::Int(num_res) => self.run_context.pc.add_int(&num_res)?, + MaybeRelocatable::Int(num_res) => (self.run_context.pc + &num_res)?, _ => return Err(VirtualMachineError::JumpRelNotInt), }, None => return Err(VirtualMachineError::UnconstrainedResJumpRel), }, PcUpdate::Jnz => match VirtualMachine::is_zero(&operands.dst) { - true => self.run_context.pc + instruction.size(), - false => (self.run_context.pc.add_maybe(&operands.op1))?, + true => (self.run_context.pc + instruction.size())?, + false => (self.run_context.pc + &operands.op1)?, }, }; self.run_context.pc = new_pc; @@ -246,7 +246,7 @@ impl VirtualMachine { match instruction.opcode { Opcode::Call => Ok(( Some(MaybeRelocatable::from( - self.run_context.pc + instruction.size(), + (self.run_context.pc + instruction.size())?, )), None, )), @@ -366,7 +366,7 @@ impl VirtualMachine { _ => Ok(()), }, Opcode::Call => { - let return_pc = MaybeRelocatable::from(self.run_context.pc + instruction.size()); + let return_pc = MaybeRelocatable::from((self.run_context.pc + instruction.size())?); if operands.op0 != return_pc { return Err(VirtualMachineError::CantWriteReturnPc( operands.op0.clone(), @@ -702,10 +702,15 @@ impl VirtualMachine { if !self.run_finished { return Err(VirtualMachineError::RunNotFinished); } + // Check for possible overflows when incrementing the base + if base.offset.checked_add(len).is_none() { + return Err(MathError::RelocatableAddUsizeOffsetExceeded(base, len).into()); + } self.accessed_addresses .as_mut() .ok_or(VirtualMachineError::MissingAccessedAddresses)? - .extend((0..len).map(|i: usize| base + i)); + // We checked for overflows before, so unwrapping here is safe + .extend((0..len).map(|i: usize| (base + i).unwrap())); Ok(()) } @@ -717,8 +722,7 @@ impl VirtualMachine { // Fetch the fp and pc traceback entries for _ in 0..MAX_TRACEBACK_ENTRIES { // Get return pc - let ret_pc = match fp - .sub_usize(1) + let ret_pc = match (fp - 1) .ok() .map(|r| self.segments.memory.get_relocatable(r)) { @@ -726,8 +730,7 @@ impl VirtualMachine { _ => break, }; // Get fp traceback - match fp - .sub_usize(2) + match (fp - 2) .ok() .map(|r| self.segments.memory.get_relocatable(r)) { @@ -736,23 +739,21 @@ impl VirtualMachine { } // Try to check if the call instruction is (instruction0, instruction1) or just // instruction1 (with no immediate). - let call_pc = match ret_pc - .sub_usize(1) + let call_pc = match (ret_pc - 1) .ok() .map(|r| self.segments.memory.get_integer(r)) { Some(Ok(instruction1)) => { match is_call_instruction(&instruction1, None) { - true => ret_pc.sub_usize(1).unwrap(), // This unwrap wont fail as it is checked before + true => (ret_pc - 1).unwrap(), // This unwrap wont fail as it is checked before false => { - match ret_pc - .sub_usize(2) + match (ret_pc - 2) .ok() .map(|r| self.segments.memory.get_integer(r)) { Some(Ok(instruction0)) => { match is_call_instruction(&instruction0, Some(&instruction1)) { - true => ret_pc.sub_usize(2).unwrap(), // This unwrap wont fail as it is checked before + true => (ret_pc - 2).unwrap(), // This unwrap wont fail as it is checked before false => break, } } @@ -844,10 +845,7 @@ impl VirtualMachine { ///Gets `n_ret` return values from memory pub fn get_return_values(&self, n_ret: usize) -> Result, MemoryError> { - let addr = &self - .run_context - .get_ap() - .sub_usize(n_ret) + let addr = (self.run_context.get_ap() - n_ret) .map_err(|_| MemoryError::FailedToGetReturnValues(n_ret, self.get_ap()))?; self.segments .memory diff --git a/src/vm/vm_memory/memory.rs b/src/vm/vm_memory/memory.rs index 2b47909f45..13eb8f8062 100644 --- a/src/vm/vm_memory/memory.rs +++ b/src/vm/vm_memory/memory.rs @@ -146,7 +146,7 @@ impl Memory { // Rely on Memory::insert to catch memory inconsistencies self.insert(&addr, &value)?; } - addr = addr + 1; + addr = (addr + 1)?; } } } @@ -251,7 +251,7 @@ impl Memory { let mut values = Vec::new(); for i in 0..size { - values.push(self.get(&addr.add_usize(i))); + values.push(self.get(&addr.add_usize(i)?)); } Ok(values) @@ -265,7 +265,7 @@ impl Memory { let mut values = Vec::with_capacity(size); for i in 0..size { - values.push(match self.get(&addr.add_usize(i)) { + values.push(match self.get(&addr.add_usize(i)?) { Some(elem) => elem.into_owned(), None => return Err(MemoryError::GetRangeMemoryGap), }); @@ -282,7 +282,7 @@ impl Memory { let mut values = Vec::new(); for i in 0..size { - values.push(self.get_integer(addr + i)?); + values.push(self.get_integer((addr + i)?)?); } Ok(values) diff --git a/src/vm/vm_memory/memory_segments.rs b/src/vm/vm_memory/memory_segments.rs index 72f9d0e8a3..d4aca03aea 100644 --- a/src/vm/vm_memory/memory_segments.rs +++ b/src/vm/vm_memory/memory_segments.rs @@ -60,9 +60,9 @@ impl MemorySegmentManager { data: &Vec, ) -> Result { for (num, value) in data.iter().enumerate() { - self.memory.insert(&ptr.add_usize(num), value)?; + self.memory.insert(&ptr.add_usize(num)?, value)?; } - Ok(ptr.add_usize(data.len())) + Ok(ptr.add_usize(data.len())?) } pub fn new() -> MemorySegmentManager {