diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28de76a45..cd4ec77e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -361,10 +361,9 @@ jobs: - name: Run tests working-directory: ./debug_utils/sierra-emu run: make test-no-corelib - - name: Run corelib's tests (WIP) + - name: Run corelib's tests working-directory: ./debug_utils/sierra-emu run: cargo test test_corelib -- --nocapture - continue-on-error: true # ignore result for now. When sierra-emu is fully implemented this should be removed build-sierra2casm-dbg: name: Build sierra2casm-dbg diff --git a/debug_utils/sierra-emu/src/lib.rs b/debug_utils/sierra-emu/src/lib.rs index 9aab69f83..bf1656dfa 100644 --- a/debug_utils/sierra-emu/src/lib.rs +++ b/debug_utils/sierra-emu/src/lib.rs @@ -10,6 +10,7 @@ use cairo_lang_sierra::{ program::{GenFunction, Program, StatementIdx}, program_registry::ProgramRegistry, }; +use debug::type_to_name; use starknet::StubSyscallHandler; pub use self::{dump::*, gas::BuiltinCosts, value::*, vm::VirtualMachine}; @@ -132,7 +133,8 @@ pub fn run_program( } _ => todo!(), }, - _ => todo!(), + CoreTypeConcrete::EcOp(_) => Value::Unit, + _ => todo!("{}", type_to_name(type_id, vm.registry())), } }) .collect::>(), diff --git a/debug_utils/sierra-emu/src/utils.rs b/debug_utils/sierra-emu/src/utils.rs index a2b5cc141..029a88ece 100644 --- a/debug_utils/sierra-emu/src/utils.rs +++ b/debug_utils/sierra-emu/src/utils.rs @@ -3,13 +3,14 @@ use cairo_lang_sierra::{ core::{CoreLibfunc, CoreType, CoreTypeConcrete}, utils::Range, }, + ids::ConcreteTypeId, program_registry::ProgramRegistry, }; use num_bigint::BigInt; use num_traits::{Bounded, One, ToPrimitive}; use starknet_types_core::felt::CAIRO_PRIME_BIGINT; -use crate::Value; +use crate::{debug::type_to_name, Value}; /// Receives a vector of values, filters any which is non numeric and returns a `Vec` /// Useful when a binary operation takes generic values (like with bounded ints). @@ -29,21 +30,20 @@ pub fn get_numeric_args_as_bigints(args: &[Value]) -> Vec { Value::U128(value) => BigInt::from(*value), Value::Felt(value) => value.to_bigint(), Value::Bytes31(value) => value.to_bigint(), - value => panic!("argument should be an integer: {:?}", value), + value => panic!("Argument should be an integer: {:?}", value), }) .collect() } pub fn get_value_from_integer( registry: &ProgramRegistry, - ty: &CoreTypeConcrete, + ty_id: &ConcreteTypeId, value: BigInt, ) -> Value { + let ty = registry.get_type(ty_id).unwrap(); + match ty { - CoreTypeConcrete::NonZero(info) => { - let ty = registry.get_type(&info.ty).unwrap(); - get_value_from_integer(registry, ty, value) - } + CoreTypeConcrete::NonZero(info) => get_value_from_integer(registry, &info.ty, value), CoreTypeConcrete::Sint8(_) => Value::I8(value.to_i8().unwrap()), CoreTypeConcrete::Sint16(_) => Value::I16(value.to_i16().unwrap()), CoreTypeConcrete::Sint32(_) => Value::I32(value.to_i32().unwrap()), @@ -62,12 +62,15 @@ pub fn get_value_from_integer( } } CoreTypeConcrete::Felt252(_) => Value::Felt(value.into()), - _ => panic!("cannot get integer value for a non-integer type"), + _ => panic!( + "Cannot get integer value for a non-integer type: {}", + type_to_name(ty_id, registry) + ), } } pub fn integer_range( - ty: &CoreTypeConcrete, + ty_id: &ConcreteTypeId, registry: &ProgramRegistry, ) -> Range { fn range_of() -> Range @@ -80,6 +83,8 @@ pub fn integer_range( } } + let ty = registry.get_type(ty_id).unwrap(); + match ty { CoreTypeConcrete::Uint8(_) => range_of::(), CoreTypeConcrete::Uint16(_) => range_of::(), @@ -100,14 +105,11 @@ pub fn integer_range( lower: BigInt::ZERO, upper: BigInt::one() << 248, }, - CoreTypeConcrete::Const(info) => { - let ty = registry.get_type(&info.inner_ty).unwrap(); - integer_range(ty, registry) - } - CoreTypeConcrete::NonZero(info) => { - let ty = registry.get_type(&info.ty).unwrap(); - integer_range(ty, registry) - } - _ => panic!("cannot get integer range value for a non-integer type"), + CoreTypeConcrete::Const(info) => integer_range(&info.inner_ty, registry), + CoreTypeConcrete::NonZero(info) => integer_range(&info.ty, registry), + _ => panic!( + "Cannot get integer range value for a non-integer type {}", + type_to_name(ty_id, registry) + ), } } diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index 7c3f64c61..2689ab0fa 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -101,13 +101,17 @@ impl Value { index: 0, payload: Box::new(Value::default_for_type(registry, &info.variants[0])), }, + CoreTypeConcrete::Array(info) => Value::Array { + ty: info.ty.clone(), + data: vec![], + }, CoreTypeConcrete::Struct(info) => Value::Struct( info.members .iter() .map(|member| Value::default_for_type(registry, member)) .collect(), ), - CoreTypeConcrete::Nullable(info) => Value::default_for_type(registry, &info.ty), + CoreTypeConcrete::Nullable(_) => Value::Null, x => panic!("type {:?} has no default value implementation", x.info()), } } diff --git a/debug_utils/sierra-emu/src/vm.rs b/debug_utils/sierra-emu/src/vm.rs index e445f2fcd..24a83ebba 100644 --- a/debug_utils/sierra-emu/src/vm.rs +++ b/debug_utils/sierra-emu/src/vm.rs @@ -471,7 +471,6 @@ fn eval<'a>( CoreConcreteLibfunc::Circuit(selector) => self::circuit::eval(registry, selector, args), CoreConcreteLibfunc::Const(selector) => self::r#const::eval(registry, selector, args), CoreConcreteLibfunc::Coupon(selector) => self::coupon::eval(registry, selector, args), - CoreConcreteLibfunc::CouponCall(_) => todo!(), CoreConcreteLibfunc::Debug(_) => todo!(), CoreConcreteLibfunc::Drop(info) => self::drop::eval(registry, info, args), CoreConcreteLibfunc::Dup(info) => self::dup::eval(registry, info, args), @@ -484,7 +483,12 @@ fn eval<'a>( CoreConcreteLibfunc::Felt252DictEntry(selector) => { self::felt252_dict_entry::eval(registry, selector, args) } - CoreConcreteLibfunc::FunctionCall(info) => self::function_call::eval(registry, info, args), + CoreConcreteLibfunc::FunctionCall(info) => { + self::function_call::eval_function_call(registry, info, args) + } + CoreConcreteLibfunc::CouponCall(info) => { + self::function_call::eval_coupon_call(registry, info, args) + } CoreConcreteLibfunc::Gas(selector) => { self::gas::eval(registry, selector, args, gas, *statement_idx, builtin_costs) } diff --git a/debug_utils/sierra-emu/src/vm/array.rs b/debug_utils/sierra-emu/src/vm/array.rs index d857892dc..4391b1807 100644 --- a/debug_utils/sierra-emu/src/vm/array.rs +++ b/debug_utils/sierra-emu/src/vm/array.rs @@ -297,13 +297,10 @@ fn eval_snapshot_multi_pop_back( }; if data.len() >= popped_cty.members.len() { - let new_data = data.split_off(data.len() - popped_cty.members.len()); - let value = Value::Struct(data); + let popped_data = data.split_off(data.len() - popped_cty.members.len()); + let value = Value::Struct(popped_data); assert!(value.is(registry, &info.popped_ty)); - EvalAction::NormalBranch( - 0, - smallvec![rangecheck, Value::Array { data: new_data, ty }, value], - ) + EvalAction::NormalBranch(0, smallvec![rangecheck, Value::Array { data, ty }, value]) } else { EvalAction::NormalBranch(1, smallvec![rangecheck, Value::Array { data, ty }]) } diff --git a/debug_utils/sierra-emu/src/vm/bounded_int.rs b/debug_utils/sierra-emu/src/vm/bounded_int.rs index 55d4955d5..31ac13750 100644 --- a/debug_utils/sierra-emu/src/vm/bounded_int.rs +++ b/debug_utils/sierra-emu/src/vm/bounded_int.rs @@ -1,5 +1,8 @@ use super::EvalAction; -use crate::{utils::get_numeric_args_as_bigints, Value}; +use crate::{ + utils::{get_numeric_args_as_bigints, get_value_from_integer}, + Value, +}; use cairo_lang_sierra::{ extensions::{ bounded_int::{ @@ -126,8 +129,10 @@ pub fn eval_div_rem( info: &BoundedIntDivRemConcreteLibfunc, args: Vec, ) -> EvalAction { - let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - + let range_check @ Value::Unit: Value = args[0].clone() else { + panic!() + }; + let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); let quo = &lhs / &rhs; let rem = lhs % rhs; @@ -151,7 +156,7 @@ pub fn eval_div_rem( EvalAction::NormalBranch( 0, smallvec![ - Value::Unit, // range_check + range_check, Value::BoundedInt { range: quo_range, value: quo, @@ -169,14 +174,10 @@ pub fn eval_constrain( info: &BoundedIntConstrainConcreteLibfunc, args: Vec, ) -> EvalAction { - let [range_check @ Value::Unit, value]: [Value; 2] = args.try_into().unwrap() else { + let range_check @ Value::Unit: Value = args[0].clone() else { panic!() }; - - let value = match value { - Value::I8(value) => value.into(), - _ => todo!(), - }; + let [value]: [BigInt; 1] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); if value < info.boundary { let range = match registry @@ -224,19 +225,19 @@ pub fn eval_constrain( } pub fn eval_is_zero( - _registry: &ProgramRegistry, - _info: &SignatureOnlyConcreteLibfunc, + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - let [value] = args.try_into().unwrap(); - let is_zero = match value { - Value::I8(value) => value == 0, - _ => todo!(), - }; + let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap(); + let is_zero = value == 0.into(); + + let int_ty = &info.branch_signatures()[1].vars[0].ty; if is_zero { EvalAction::NormalBranch(0, smallvec![]) } else { + let value = get_value_from_integer(registry, int_ty, value); EvalAction::NormalBranch(1, smallvec![value]) } } diff --git a/debug_utils/sierra-emu/src/vm/cast.rs b/debug_utils/sierra-emu/src/vm/cast.rs index 8718dca64..4fac4867a 100644 --- a/debug_utils/sierra-emu/src/vm/cast.rs +++ b/debug_utils/sierra-emu/src/vm/cast.rs @@ -35,13 +35,15 @@ fn eval_downcast( }; let [value] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry.get_type(&info.to_ty).unwrap(); - let range = info.to_range.lower.clone()..info.to_range.upper.clone(); + if range.contains(&value) { EvalAction::NormalBranch( 0, - smallvec![range_check, get_value_from_integer(registry, int_ty, value)], + smallvec![ + range_check, + get_value_from_integer(registry, &info.to_ty, value) + ], ) } else { EvalAction::NormalBranch(1, smallvec![range_check]) @@ -54,12 +56,10 @@ fn eval_upcast( args: Vec, ) -> EvalAction { let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - let int_ty = registry - .get_type(&info.branch_signatures()[0].vars[0].ty) - .unwrap(); + let int_ty_id = &info.branch_signatures()[0].vars[0].ty; EvalAction::NormalBranch( 0, - smallvec![get_value_from_integer(registry, int_ty, value)], + smallvec![get_value_from_integer(registry, int_ty_id, value)], ) } diff --git a/debug_utils/sierra-emu/src/vm/function_call.rs b/debug_utils/sierra-emu/src/vm/function_call.rs index 3b7298544..df70eae0a 100644 --- a/debug_utils/sierra-emu/src/vm/function_call.rs +++ b/debug_utils/sierra-emu/src/vm/function_call.rs @@ -8,7 +8,7 @@ use cairo_lang_sierra::{ program_registry::ProgramRegistry, }; -pub fn eval( +pub fn eval_function_call( registry: &ProgramRegistry, info: &SignatureAndFunctionConcreteLibfunc, args: Vec, @@ -21,3 +21,20 @@ pub fn eval( EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect()) } + +pub fn eval_coupon_call( + registry: &ProgramRegistry, + info: &SignatureAndFunctionConcreteLibfunc, + mut args: Vec, +) -> EvalAction { + // Don't check the last arg since it is not actually an argument for the function call itself + assert_eq!(args.len() - 1, info.function.params.len()); + assert!(args + .iter() + .zip(&info.function.params) + .all(|(value, param)| value.is(registry, ¶m.ty))); + + args.pop(); + + EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect()) +} diff --git a/debug_utils/sierra-emu/src/vm/int.rs b/debug_utils/sierra-emu/src/vm/int.rs index 88d360ef0..1a56c2ba3 100644 --- a/debug_utils/sierra-emu/src/vm/int.rs +++ b/debug_utils/sierra-emu/src/vm/int.rs @@ -14,12 +14,14 @@ use cairo_lang_sierra::{ is_zero::IsZeroTraits, lib_func::SignatureOnlyConcreteLibfunc, }, + ids::ConcreteTypeId, program_registry::ProgramRegistry, }; -use num_bigint::{BigInt, BigUint}; +use num_bigint::{BigInt, BigUint, ToBigInt}; use num_traits::ops::overflowing::{OverflowingAdd, OverflowingSub}; use smallvec::smallvec; use starknet_crypto::Felt; +use starknet_types_core::felt::NonZeroFelt; use crate::{ utils::{get_numeric_args_as_bigints, get_value_from_integer, integer_range}, @@ -29,7 +31,8 @@ use crate::{ use super::EvalAction; fn apply_overflowing_op_for_type( - ty: &CoreTypeConcrete, + registry: &ProgramRegistry, + ty: &ConcreteTypeId, lhs: BigInt, rhs: BigInt, op: IntOperator, @@ -50,8 +53,10 @@ fn apply_overflowing_op_for_type( (result.into(), had_overflow) } + let ty = registry.get_type(ty).unwrap(); + match ty { - CoreTypeConcrete::Sint8(_) => overflowing_op::(lhs, rhs, op), + CoreTypeConcrete::Sint8(_) => overflowing_op::(lhs, rhs, op), CoreTypeConcrete::Sint16(_) => overflowing_op::(lhs, rhs, op), CoreTypeConcrete::Sint32(_) => overflowing_op::(lhs, rhs, op), CoreTypeConcrete::Sint64(_) => overflowing_op::(lhs, rhs, op), @@ -132,7 +137,7 @@ pub fn eval_uint128( Uint128Concrete::SquareRoot(info) => eval_square_root(registry, info, args), Uint128Concrete::Equal(info) => eval_equal(registry, info, args), Uint128Concrete::ToFelt252(info) => eval_to_felt(registry, info, args), - Uint128Concrete::FromFelt252(info) => eval_from_felt(registry, info, args), + Uint128Concrete::FromFelt252(info) => eval_u128_from_felt(registry, info, args), Uint128Concrete::IsZero(info) => eval_is_zero(registry, info, args), Uint128Concrete::Divmod(info) => eval_divmod(registry, info, args), Uint128Concrete::Bitwise(info) => eval_bitwise(registry, info, args), @@ -147,9 +152,7 @@ fn eval_const( info: &IntConstConcreteLibfunc, _args: Vec, ) -> EvalAction { - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[0].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[0].ty; EvalAction::NormalBranch( 0, @@ -167,9 +170,7 @@ fn eval_bitwise( }; let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; let and = get_value_from_integer(registry, int_ty, &lhs & &rhs); let or = get_value_from_integer(registry, int_ty, &lhs | &rhs); @@ -188,15 +189,13 @@ fn eval_diff( }; let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; - let overflow = (lhs >= rhs) as usize; - let (res, _) = apply_overflowing_op_for_type(int_ty, lhs, rhs, IntOperator::OverflowingSub); + let (res, had_overflow) = + apply_overflowing_op_for_type(registry, int_ty, lhs, rhs, IntOperator::OverflowingSub); let res = get_value_from_integer(registry, int_ty, res); - EvalAction::NormalBranch(overflow, smallvec![range_check, res]) + EvalAction::NormalBranch(had_overflow as usize, smallvec![range_check, res]) } fn eval_divmod( @@ -209,9 +208,7 @@ fn eval_divmod( }; let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; let res = &lhs / &rhs; let rem = lhs % rhs; @@ -242,15 +239,22 @@ fn eval_from_felt( panic!() }; - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let prime = Felt::prime(); + let half_prime = &prime / BigUint::from(2u8); - let range = integer_range(int_ty, registry); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; - let value = value_felt.to_bigint(); + let range = integer_range(int_ty, registry); - if value > range.lower && value <= range.upper { + let value = { + let value_bigint = value_felt.to_biguint(); + if value_bigint > half_prime { + (prime - value_bigint).to_bigint().unwrap() * BigInt::from(-1) + } else { + value_felt.to_bigint() + } + }; + if value >= range.lower && value < range.upper { let value = get_value_from_integer(registry, int_ty, value); EvalAction::NormalBranch(0, smallvec![range_check, value]) } else { @@ -258,6 +262,33 @@ fn eval_from_felt( } } +pub fn eval_u128_from_felt( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [range_check @ Value::Unit, Value::Felt(value)]: [Value; 2] = args.try_into().unwrap() + else { + panic!() + }; + + let bound = Felt::from(u128::MAX) + 1; + + if value < bound { + let value: u128 = value.to_biguint().try_into().unwrap(); + EvalAction::NormalBranch(0, smallvec![range_check, Value::U128(value)]) + } else { + let (new_value, overflow) = value.div_rem(&NonZeroFelt::try_from(bound).unwrap()); + + let overflow: u128 = overflow.to_biguint().try_into().unwrap(); + let new_value: u128 = new_value.to_biguint().try_into().unwrap(); + EvalAction::NormalBranch( + 1, + smallvec![range_check, Value::U128(new_value), Value::U128(overflow)], + ) + } +} + fn eval_is_zero( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, @@ -265,9 +296,7 @@ fn eval_is_zero( ) -> EvalAction { let [value]: [BigInt; 1] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[1].vars[0].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[1].vars[0].ty; if value == 0.into() { EvalAction::NormalBranch(0, smallvec![]) @@ -288,11 +317,10 @@ fn eval_operation( panic!() }; let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; - let (res, had_overflow) = apply_overflowing_op_for_type(int_ty, lhs, rhs, info.operator); + let (res, had_overflow) = + apply_overflowing_op_for_type(registry, int_ty, lhs, rhs, info.operator); let res = get_value_from_integer(registry, int_ty, res); EvalAction::NormalBranch(had_overflow as usize, smallvec![range_check, res]) @@ -308,9 +336,7 @@ fn eval_square_root( }; let [value]: [BigInt; 1] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[1].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[1].ty; let res = value.sqrt(); @@ -337,9 +363,7 @@ fn eval_widemul( ) -> EvalAction { let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - let int_ty = registry - .get_type(&info.signature.branch_signatures[0].vars[0].ty) - .unwrap(); + let int_ty = &info.signature.branch_signatures[0].vars[0].ty; let res = lhs * rhs; diff --git a/debug_utils/sierra-emu/src/vm/int_range.rs b/debug_utils/sierra-emu/src/vm/int_range.rs index 50b794bd2..e71bb6cd4 100644 --- a/debug_utils/sierra-emu/src/vm/int_range.rs +++ b/debug_utils/sierra-emu/src/vm/int_range.rs @@ -1,6 +1,6 @@ use cairo_lang_sierra::{ extensions::{ - core::{CoreLibfunc, CoreType}, + core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::SignatureOnlyConcreteLibfunc, range::IntRangeConcreteLibfunc, ConcreteLibfunc, @@ -38,12 +38,12 @@ fn eval_try_new( }; let [x, y]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); + let int_ty_id = &info.param_signatures()[1].ty; // if x >= y then the range is not valid and we return [y, y) (empty range) if x < y { - let x = get_value_from_integer(registry, int_ty, x); - let y = get_value_from_integer(registry, int_ty, y); + let x = get_value_from_integer(registry, int_ty_id, x); + let y = get_value_from_integer(registry, int_ty_id, y); EvalAction::NormalBranch( 0, smallvec![ @@ -55,7 +55,7 @@ fn eval_try_new( ], ) } else { - let y = get_value_from_integer(registry, int_ty, y); + let y = get_value_from_integer(registry, int_ty_id, y); EvalAction::NormalBranch( 1, smallvec![ @@ -78,15 +78,17 @@ fn eval_pop_front( panic!() }; let [x, y]: [BigInt; 2] = get_numeric_args_as_bigints(&[*x, *y]).try_into().unwrap(); - let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); + let int_ty_id = match registry.get_type(&info.param_signatures()[0].ty).unwrap() { + CoreTypeConcrete::IntRange(info) => &info.ty, + _ => panic!(), + }; if x < y { - let x_plus_1 = get_value_from_integer(registry, int_ty, &x + 1); - let x = get_value_from_integer(registry, int_ty, x); - let y = get_value_from_integer(registry, int_ty, y); - + let x_plus_1 = get_value_from_integer(registry, int_ty_id, &x + 1); + let x = get_value_from_integer(registry, int_ty_id, x); + let y = get_value_from_integer(registry, int_ty_id, y); EvalAction::NormalBranch( - 0, + 1, smallvec![ Value::IntRange { x: Box::new(x_plus_1), @@ -96,6 +98,6 @@ fn eval_pop_front( ], ) } else { - EvalAction::NormalBranch(1, smallvec![]) + EvalAction::NormalBranch(0, smallvec![]) } } diff --git a/debug_utils/sierra-emu/src/vm/uint256.rs b/debug_utils/sierra-emu/src/vm/uint256.rs index b2e37359a..6e25cf465 100644 --- a/debug_utils/sierra-emu/src/vm/uint256.rs +++ b/debug_utils/sierra-emu/src/vm/uint256.rs @@ -48,6 +48,10 @@ fn eval_inv_mod_n( let modulo = u256_to_biguint(mod_lo, mod_hi); match x.modinv(&modulo) { + None => EvalAction::NormalBranch(1, smallvec![range_check, Value::Unit, Value::Unit]), + Some(r) if r == 0u8.into() => { + EvalAction::NormalBranch(1, smallvec![range_check, Value::Unit, Value::Unit]) + } Some(r) => EvalAction::NormalBranch( 0, smallvec![ @@ -63,7 +67,6 @@ fn eval_inv_mod_n( Value::Unit ], ), - None => EvalAction::NormalBranch(1, smallvec![range_check, Value::Unit, Value::Unit]), } } @@ -104,8 +107,10 @@ pub fn u516_to_value(value: BigUint) -> Value { let upper_u256: BigUint = &value >> 256u32; let hi1: u128 = (&upper_u256 >> 128u32).try_into().unwrap(); let lo1: u128 = (upper_u256 & BigUint::from(u128::MAX)).try_into().unwrap(); - let hi: u128 = (&value >> 128u32).try_into().unwrap(); - let lo: u128 = (value & BigUint::from(u128::MAX)).try_into().unwrap(); + let lower_mask = BigUint::from_bytes_le(&[0xFF; 32]); + let lower_u256: BigUint = value & lower_mask; + let hi: u128 = (&lower_u256 >> 128u32).try_into().unwrap(); + let lo: u128 = (lower_u256 & BigUint::from(u128::MAX)).try_into().unwrap(); Value::Struct(vec![ Value::U128(lo), Value::U128(hi),