From 65825fbbc8e5040da9d1e9ca1e58f5057c4d4874 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 3 Oct 2024 09:13:54 -0300 Subject: [PATCH 1/6] implement some signed int libfuncts --- src/value.rs | 6 ++- src/vm.rs | 5 +- src/vm/cast.rs | 3 ++ src/vm/const.rs | 43 +++++++++++++++- src/vm/int128.rs | 129 ++++++++++++++++++++++++++++++++++++++++++++++ src/vm/uint128.rs | 1 + 6 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 src/vm/int128.rs diff --git a/src/value.rs b/src/value.rs index 79ad98a..b0fbb32 100644 --- a/src/value.rs +++ b/src/value.rs @@ -52,6 +52,8 @@ pub enum Value { x1: Felt, y1: Felt, }, + I128(i128), + I32(i32), I8(i8), Struct(Vec), U256(u128, u128), @@ -105,6 +107,8 @@ impl Value { } CoreTypeConcrete::GasBuiltin(_) => matches!(self, Self::U128(_)), CoreTypeConcrete::NonZero(info) => self.is(registry, &info.ty), + CoreTypeConcrete::Sint128(_) => matches!(self, Self::I128(_)), + CoreTypeConcrete::Sint32(_) => matches!(self, Self::I32(_)), CoreTypeConcrete::Sint8(_) => matches!(self, Self::I8(_)), CoreTypeConcrete::Snapshot(info) => self.is(registry, &info.ty), CoreTypeConcrete::StarkNet( @@ -154,9 +158,7 @@ impl Value { CoreTypeConcrete::Uint64(_) => matches!(self, Self::U64(_)), CoreTypeConcrete::Uint128MulGuarantee(_) => matches!(self, Self::Unit), CoreTypeConcrete::Sint16(_) => todo!(), - CoreTypeConcrete::Sint32(_) => todo!(), CoreTypeConcrete::Sint64(_) => todo!(), - CoreTypeConcrete::Sint128(_) => todo!(), CoreTypeConcrete::Nullable(info) => self.is(registry, &info.ty), CoreTypeConcrete::Uninitialized(_) => todo!(), CoreTypeConcrete::Felt252DictEntry(_) => todo!(), diff --git a/src/vm.rs b/src/vm.rs index ac1327d..ce24f45 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -40,6 +40,7 @@ mod felt252_dict; mod felt252_dict_entry; mod function_call; mod gas; +mod int128; mod jump; mod mem; mod pedersen; @@ -331,7 +332,7 @@ fn eval<'a>( CoreConcreteLibfunc::Nullable(_) => todo!(), CoreConcreteLibfunc::Pedersen(selector) => self::pedersen::eval(registry, selector, args), CoreConcreteLibfunc::Poseidon(selector) => self::poseidon::eval(registry, selector, args), - CoreConcreteLibfunc::Sint128(_) => todo!(), + CoreConcreteLibfunc::Sint128(selector) => {self::int128::eval(registry, selector, args)}, CoreConcreteLibfunc::Sint16(_) => todo!(), CoreConcreteLibfunc::Sint32(_) => todo!(), CoreConcreteLibfunc::Sint64(_) => todo!(), @@ -341,7 +342,7 @@ fn eval<'a>( self::starknet::eval(registry, selector, args, syscall_handler) } CoreConcreteLibfunc::Struct(selector) => self::r#struct::eval(registry, selector, args), - CoreConcreteLibfunc::Uint128(selector) => self::uint128::eval(registry, selector, args), + CoreConcreteLibfunc::Uint128(selector) => {self::uint128::eval(registry, selector, args)}, CoreConcreteLibfunc::Uint16(selector) => self::uint16::eval(registry, selector, args), CoreConcreteLibfunc::Uint256(selector) => self::uint252::eval(registry, selector, args), CoreConcreteLibfunc::Uint32(selector) => self::uint32::eval(registry, selector, args), diff --git a/src/vm/cast.rs b/src/vm/cast.rs index c442c9e..30a1d03 100644 --- a/src/vm/cast.rs +++ b/src/vm/cast.rs @@ -50,6 +50,7 @@ pub fn eval_downcast( range_check, match registry.get_type(&info.to_ty).unwrap() { CoreTypeConcrete::Sint8(_) => Value::I8(value.try_into().unwrap()), + CoreTypeConcrete::Sint128(_) => Value::I128(value.try_into().unwrap()), CoreTypeConcrete::Uint8(_) => Value::U8(value.try_into().unwrap()), CoreTypeConcrete::Uint16(_) => Value::U16(value.try_into().unwrap()), CoreTypeConcrete::Uint32(_) => Value::U32(value.try_into().unwrap()), @@ -89,6 +90,8 @@ pub fn eval_upcast( .unwrap() { CoreTypeConcrete::Sint8(_) => Value::I8(value.try_into().unwrap()), + CoreTypeConcrete::Sint32(_) => Value::I32(value.try_into().unwrap()), + CoreTypeConcrete::Sint128(_) => Value::I128(value.try_into().unwrap()), CoreTypeConcrete::Uint8(_) => Value::U8(value.try_into().unwrap()), CoreTypeConcrete::Uint16(_) => Value::U16(value.try_into().unwrap()), CoreTypeConcrete::Uint32(_) => Value::U32(value.try_into().unwrap()), diff --git a/src/vm/const.rs b/src/vm/const.rs index 77e3f20..b9e9e6e 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -56,6 +56,14 @@ pub fn eval_as_immediate( _ => unreachable!(), }, CoreTypeConcrete::NonZero(info) => inner(registry, &info.ty, inner_data), + CoreTypeConcrete::Sint128(_) => match inner_data { + [GenericArg::Value(value)] => Value::I128(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Sint32(_) => match inner_data { + [GenericArg::Value(value)] => Value::I32(value.try_into().unwrap()), + _ => unreachable!(), + }, CoreTypeConcrete::Sint8(_) => match inner_data { [GenericArg::Value(value)] => Value::I8(value.try_into().unwrap()), _ => unreachable!(), @@ -95,7 +103,40 @@ pub fn eval_as_immediate( Value::Struct(fields) } - _ => todo!("{:?}", type_id), + CoreTypeConcrete::Array(_) => todo!("1"), + CoreTypeConcrete::Coupon(_) => todo!("2"), + CoreTypeConcrete::Bitwise(_) => todo!("3"), + CoreTypeConcrete::Box(_) => todo!("4"), + CoreTypeConcrete::Circuit(_) => todo!("5"), + CoreTypeConcrete::Const(_) => todo!("6"), + CoreTypeConcrete::EcOp(_) => todo!("7"), + CoreTypeConcrete::EcPoint(_) => todo!("8"), + CoreTypeConcrete::EcState(_) => todo!("9"), + CoreTypeConcrete::GasBuiltin(_) => todo!("10"), + CoreTypeConcrete::BuiltinCosts(_) => todo!("11"), + CoreTypeConcrete::Uint16(_) => todo!("12"), + CoreTypeConcrete::Uint64(_) => match inner_data { + [GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()), + _ => unreachable!(), + }, + CoreTypeConcrete::Uint128MulGuarantee(_) => todo!("14"), + CoreTypeConcrete::Sint16(_) => todo!("15"), + CoreTypeConcrete::Sint64(_) => todo!("17"), + CoreTypeConcrete::Nullable(_) => todo!("19"), + CoreTypeConcrete::RangeCheck(_) => todo!("20"), + CoreTypeConcrete::RangeCheck96(_) => todo!("21"), + CoreTypeConcrete::Uninitialized(_) => todo!("22"), + CoreTypeConcrete::Enum(_) => todo!("23"), + CoreTypeConcrete::Felt252Dict(_) => todo!("24"), + CoreTypeConcrete::Felt252DictEntry(_) => todo!("25"), + CoreTypeConcrete::SquashedFelt252Dict(_) => todo!("26"), + CoreTypeConcrete::Pedersen(_) => todo!("27"), + CoreTypeConcrete::Poseidon(_) => todo!("28"), + CoreTypeConcrete::Span(_) => todo!("29"), + CoreTypeConcrete::StarkNet(_) => todo!("30"), + CoreTypeConcrete::SegmentArena(_) => todo!("31"), + CoreTypeConcrete::Snapshot(_) => todo!("32"), + CoreTypeConcrete::Bytes31(_) => todo!("33"), } } diff --git a/src/vm/int128.rs b/src/vm/int128.rs new file mode 100644 index 0000000..eb19fcd --- /dev/null +++ b/src/vm/int128.rs @@ -0,0 +1,129 @@ +use cairo_lang_sierra::{ + extensions::{ + core::{CoreLibfunc, CoreType}, + int::{signed128::Sint128Concrete, IntOperationConcreteLibfunc, IntOperator}, + lib_func::SignatureOnlyConcreteLibfunc, + }, + program_registry::ProgramRegistry, +}; +use num_bigint::{BigInt, BigUint, ToBigInt}; +use smallvec::smallvec; +use starknet_crypto::Felt; + +use crate::Value; + +use super::EvalAction; + +pub fn eval( + registry: &ProgramRegistry, + selector: &Sint128Concrete, + args: Vec, +) -> EvalAction { + match selector { + Sint128Concrete::Const(info) => todo!("1"), + Sint128Concrete::Operation(info) => eval_operation(registry, info, args), + Sint128Concrete::Equal(info) => eval_equal(registry, info, args), + Sint128Concrete::ToFelt252(info) => eval_to_felt(registry, info, args), + Sint128Concrete::FromFelt252(info) => eval_from_felt(registry, info, args), + Sint128Concrete::IsZero(info) => todo!("6"), + Sint128Concrete::Diff(info) => eval_diff(registry, info, args), + } +} + +fn eval_diff( + _registry: &ProgramRegistry, + selector: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [range_check @ Value::Unit, Value::I128(lhs), Value::I128(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + if lhs >= rhs { + EvalAction::NormalBranch( + 0, + smallvec![range_check, Value::I128(lhs - rhs)], + ) + } else { + EvalAction::NormalBranch(1, smallvec![range_check, Value::I128(lhs.wrapping_sub(rhs))]) + } +} + +fn eval_operation( + _registry: &ProgramRegistry, + selector: &IntOperationConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [range_check @ Value::Unit, Value::I128(lhs), Value::I128(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let (result, overflow) = match selector.operator { + IntOperator::OverflowingAdd => lhs.overflowing_add(rhs), + IntOperator::OverflowingSub => lhs.overflowing_sub(rhs), + }; + + EvalAction::NormalBranch( + overflow as usize, + smallvec![range_check, Value::I128(result)], + ) +} + +fn eval_equal( + _registry: &ProgramRegistry, + _selector: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [Value::I128(lhs), Value::I128(rhs)]: [Value; 2] = args.try_into().unwrap() else { + panic!() + }; + + EvalAction::NormalBranch((lhs == rhs) as usize, smallvec![]) +} + +pub fn eval_to_felt( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [Value::I128(value)]: [Value; 1] = args.try_into().unwrap() else { + panic!() + }; + + EvalAction::NormalBranch(0, smallvec![Value::Felt(value.into())]) +} + +pub fn eval_from_felt( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [range_check @ Value::Unit, Value::Felt(value_felt)]: [Value; 2] = args.try_into().unwrap() + else { + panic!() + }; + let prime = Felt::prime(); + let half_prime = &prime / BigUint::from(2u8); + + let min = Felt::from(i128::MIN).to_bigint(); + let max = Felt::from(i128::MAX).to_bigint(); + + let value = { + if value_felt.to_biguint() > half_prime { + (prime - value_felt.to_biguint()).to_bigint().unwrap() * BigInt::from(-1) + } else { + value_felt.to_bigint() + } + }; + + if value >= min || value <= max { + let value: i128 = value.try_into().unwrap(); + EvalAction::NormalBranch(0, smallvec![range_check, Value::I128(value)]) + } else { + EvalAction::NormalBranch(1, smallvec![range_check]) + } +} diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index d36e932..4b5d065 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -21,6 +21,7 @@ pub fn eval( selector: &Uint128Concrete, args: Vec, ) -> EvalAction { + dbg!(&args); match selector { Uint128Concrete::Const(info) => eval_const(registry, info, args), Uint128Concrete::Operation(info) => eval_operation(registry, info, args), From 69aa734eb2efe542b6f0ab0bf75907b4478131ab Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 3 Oct 2024 10:31:35 -0300 Subject: [PATCH 2/6] fix i128 diff operation --- src/vm.rs | 2 +- src/vm/int128.rs | 6 ++++-- src/vm/uint128.rs | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vm.rs b/src/vm.rs index ce24f45..98d54c0 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -342,7 +342,7 @@ fn eval<'a>( self::starknet::eval(registry, selector, args, syscall_handler) } CoreConcreteLibfunc::Struct(selector) => self::r#struct::eval(registry, selector, args), - CoreConcreteLibfunc::Uint128(selector) => {self::uint128::eval(registry, selector, args)}, + CoreConcreteLibfunc::Uint128(selector) => self::uint128::eval(registry, selector, args), CoreConcreteLibfunc::Uint16(selector) => self::uint16::eval(registry, selector, args), CoreConcreteLibfunc::Uint256(selector) => self::uint252::eval(registry, selector, args), CoreConcreteLibfunc::Uint32(selector) => self::uint32::eval(registry, selector, args), diff --git a/src/vm/int128.rs b/src/vm/int128.rs index eb19fcd..587687a 100644 --- a/src/vm/int128.rs +++ b/src/vm/int128.rs @@ -1,3 +1,5 @@ +use std::u128; + use cairo_lang_sierra::{ extensions::{ core::{CoreLibfunc, CoreType}, @@ -44,10 +46,10 @@ fn eval_diff( if lhs >= rhs { EvalAction::NormalBranch( 0, - smallvec![range_check, Value::I128(lhs - rhs)], + smallvec![range_check, Value::U128((lhs - rhs).try_into().unwrap())], ) } else { - EvalAction::NormalBranch(1, smallvec![range_check, Value::I128(lhs.wrapping_sub(rhs))]) + EvalAction::NormalBranch(1, smallvec![range_check, Value::U128(lhs.wrapping_sub(rhs).try_into().unwrap())]) } } diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index 4b5d065..d36e932 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -21,7 +21,6 @@ pub fn eval( selector: &Uint128Concrete, args: Vec, ) -> EvalAction { - dbg!(&args); match selector { Uint128Concrete::Const(info) => eval_const(registry, info, args), Uint128Concrete::Operation(info) => eval_operation(registry, info, args), From 4619278f34b4eab4f12deaaad8059286e01e5b0b Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 3 Oct 2024 10:36:12 -0300 Subject: [PATCH 3/6] format --- src/vm.rs | 2 +- src/vm/const.rs | 39 +++++---------------------------------- src/vm/int128.rs | 8 +++++++- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/vm.rs b/src/vm.rs index 98d54c0..507b124 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -332,7 +332,7 @@ fn eval<'a>( CoreConcreteLibfunc::Nullable(_) => todo!(), CoreConcreteLibfunc::Pedersen(selector) => self::pedersen::eval(registry, selector, args), CoreConcreteLibfunc::Poseidon(selector) => self::poseidon::eval(registry, selector, args), - CoreConcreteLibfunc::Sint128(selector) => {self::int128::eval(registry, selector, args)}, + CoreConcreteLibfunc::Sint128(selector) => self::int128::eval(registry, selector, args), CoreConcreteLibfunc::Sint16(_) => todo!(), CoreConcreteLibfunc::Sint32(_) => todo!(), CoreConcreteLibfunc::Sint64(_) => todo!(), diff --git a/src/vm/const.rs b/src/vm/const.rs index b9e9e6e..66ad442 100644 --- a/src/vm/const.rs +++ b/src/vm/const.rs @@ -68,6 +68,10 @@ pub fn eval_as_immediate( [GenericArg::Value(value)] => Value::I8(value.try_into().unwrap()), _ => unreachable!(), }, + CoreTypeConcrete::Uint64(_) => match inner_data { + [GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()), + _ => unreachable!(), + }, CoreTypeConcrete::Uint32(_) => match inner_data { [GenericArg::Value(value)] => Value::U32(value.try_into().unwrap()), _ => unreachable!(), @@ -103,40 +107,7 @@ pub fn eval_as_immediate( Value::Struct(fields) } - CoreTypeConcrete::Array(_) => todo!("1"), - CoreTypeConcrete::Coupon(_) => todo!("2"), - CoreTypeConcrete::Bitwise(_) => todo!("3"), - CoreTypeConcrete::Box(_) => todo!("4"), - CoreTypeConcrete::Circuit(_) => todo!("5"), - CoreTypeConcrete::Const(_) => todo!("6"), - CoreTypeConcrete::EcOp(_) => todo!("7"), - CoreTypeConcrete::EcPoint(_) => todo!("8"), - CoreTypeConcrete::EcState(_) => todo!("9"), - CoreTypeConcrete::GasBuiltin(_) => todo!("10"), - CoreTypeConcrete::BuiltinCosts(_) => todo!("11"), - CoreTypeConcrete::Uint16(_) => todo!("12"), - CoreTypeConcrete::Uint64(_) => match inner_data { - [GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()), - _ => unreachable!(), - }, - CoreTypeConcrete::Uint128MulGuarantee(_) => todo!("14"), - CoreTypeConcrete::Sint16(_) => todo!("15"), - CoreTypeConcrete::Sint64(_) => todo!("17"), - CoreTypeConcrete::Nullable(_) => todo!("19"), - CoreTypeConcrete::RangeCheck(_) => todo!("20"), - CoreTypeConcrete::RangeCheck96(_) => todo!("21"), - CoreTypeConcrete::Uninitialized(_) => todo!("22"), - CoreTypeConcrete::Enum(_) => todo!("23"), - CoreTypeConcrete::Felt252Dict(_) => todo!("24"), - CoreTypeConcrete::Felt252DictEntry(_) => todo!("25"), - CoreTypeConcrete::SquashedFelt252Dict(_) => todo!("26"), - CoreTypeConcrete::Pedersen(_) => todo!("27"), - CoreTypeConcrete::Poseidon(_) => todo!("28"), - CoreTypeConcrete::Span(_) => todo!("29"), - CoreTypeConcrete::StarkNet(_) => todo!("30"), - CoreTypeConcrete::SegmentArena(_) => todo!("31"), - CoreTypeConcrete::Snapshot(_) => todo!("32"), - CoreTypeConcrete::Bytes31(_) => todo!("33"), + _ => todo!("{}", type_id), } } diff --git a/src/vm/int128.rs b/src/vm/int128.rs index 587687a..7390996 100644 --- a/src/vm/int128.rs +++ b/src/vm/int128.rs @@ -49,7 +49,13 @@ fn eval_diff( smallvec![range_check, Value::U128((lhs - rhs).try_into().unwrap())], ) } else { - EvalAction::NormalBranch(1, smallvec![range_check, Value::U128(lhs.wrapping_sub(rhs).try_into().unwrap())]) + EvalAction::NormalBranch( + 1, + smallvec![ + range_check, + Value::U128(lhs.wrapping_sub(rhs).try_into().unwrap()) + ], + ) } } From 602b37b371a5b5031752ad4eb959ddc092c4f5cd Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 4 Oct 2024 15:36:50 -0300 Subject: [PATCH 4/6] add simple tests --- Cargo.toml | 3 ++ src/lib.rs | 1 + src/test_utils.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++ src/vm/int128.rs | 67 +++++++++++++++++++++++++++++- src/vm/starknet.rs | 4 ++ 5 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 src/test_utils.rs diff --git a/Cargo.toml b/Cargo.toml index 2b4d952..d1f290c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] +cairo-lang-compiler = "2.8.2" +cairo-lang-filesystem = "2.8.2" cairo-lang-sierra = "2.8.0" cairo-lang-sierra-ap-change = "2.8.0" cairo-lang-sierra-gas = "2.8.0" @@ -23,6 +25,7 @@ smallvec = "1.13.2" starknet-crypto = "0.7.1" starknet-curve = "0.5.0" starknet-types-core = "0.1.2" +tempfile = "3.13.0" thiserror = "1.0.63" tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } diff --git a/src/lib.rs b/src/lib.rs index beb9a56..de8ec91 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod debug; mod dump; mod gas; pub mod starknet; +mod test_utils; mod value; mod vm; diff --git a/src/test_utils.rs b/src/test_utils.rs new file mode 100644 index 0000000..ae9d8f7 --- /dev/null +++ b/src/test_utils.rs @@ -0,0 +1,100 @@ +use std::{fs, path::Path, sync::Arc}; + +use cairo_lang_compiler::{ + compile_prepared_db, db::RootDatabase, diagnostics::DiagnosticsReporter, + project::setup_project, CompilerConfig, +}; +use cairo_lang_filesystem::db::init_dev_corelib; +use cairo_lang_sierra::{extensions::{circuit::CircuitTypeConcrete, core::CoreTypeConcrete, starknet::StarkNetTypeConcrete}, program::Program}; + +use crate::{find_entry_point_by_idx, ProgramTrace, StateDump, Value, VirtualMachine}; + +#[macro_export] +macro_rules! load_cairo { + ( $( $program:tt )+ ) => { + $crate::test_utils::load_cairo_from_str(stringify!($($program)+)) + }; +} + +pub(crate) fn load_cairo_from_str(cairo_str: &str) -> (String, Program) { + let mut file = tempfile::Builder::new() + .prefix("test_") + .suffix(".cairo") + .tempfile() + .unwrap(); + let mut db = RootDatabase::default(); + + fs::write(&mut file, cairo_str).unwrap(); + + init_dev_corelib( + &mut db, + Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("corelib/src"), + ); + + let main_crate_ids = setup_project(&mut db, file.path()).unwrap(); + + let sierra_with_dbg = compile_prepared_db( + &db, + main_crate_ids, + CompilerConfig { + diagnostics_reporter: DiagnosticsReporter::stderr(), + replace_ids: true, + ..Default::default() + }, + ) + .unwrap(); + + let module_name = file.path().with_extension(""); + let module_name = module_name.file_name().unwrap().to_str().unwrap(); + (module_name.to_string(), sierra_with_dbg.program) +} + +pub fn run_test_program(sierra_program: Program) -> Vec { + let function = find_entry_point_by_idx(&sierra_program, 0).unwrap(); + + let mut vm = VirtualMachine::new(Arc::new(sierra_program.clone())); + + let initial_gas = 1000000; + + vm.push_frame( + function.id.clone(), + function + .signature + .param_types + .iter() + .map(|type_id| { + let type_info = vm.registry().get_type(type_id).unwrap(); + match type_info { + CoreTypeConcrete::GasBuiltin(_) => crate::Value::U128(initial_gas), + CoreTypeConcrete::StarkNet(StarkNetTypeConcrete::System(_)) => Value::Unit, + CoreTypeConcrete::RangeCheck(_) + | CoreTypeConcrete::RangeCheck96(_) + | CoreTypeConcrete::Pedersen(_) + | CoreTypeConcrete::Poseidon(_) + | CoreTypeConcrete::Bitwise(_) + | CoreTypeConcrete::BuiltinCosts(_) + | CoreTypeConcrete::SegmentArena(_) + | CoreTypeConcrete::Circuit( + CircuitTypeConcrete::AddMod(_) | CircuitTypeConcrete::MulMod(_), + ) => Value::Unit, + _ => unreachable!(), + } + }) + .collect::>(), + ); + + let mut trace = ProgramTrace::new(); + + while let Some((statement_idx, state)) = vm.step() { + trace.push(StateDump::new(statement_idx, state)); + } + + trace + .states + .last() + .unwrap() + .items + .values() + .cloned() + .collect() +} diff --git a/src/vm/int128.rs b/src/vm/int128.rs index 7390996..6410d44 100644 --- a/src/vm/int128.rs +++ b/src/vm/int128.rs @@ -21,6 +21,7 @@ pub fn eval( selector: &Sint128Concrete, args: Vec, ) -> EvalAction { + match selector { Sint128Concrete::Const(info) => todo!("1"), Sint128Concrete::Operation(info) => eval_operation(registry, info, args), @@ -34,7 +35,7 @@ pub fn eval( fn eval_diff( _registry: &ProgramRegistry, - selector: &SignatureOnlyConcreteLibfunc, + _selector: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { let [range_check @ Value::Unit, Value::I128(lhs), Value::I128(rhs)]: [Value; 3] = @@ -43,6 +44,13 @@ fn eval_diff( panic!() }; + dbg!(_selector + .signature + .branch_signatures + .iter() + .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) + .collect::>()); + if lhs >= rhs { EvalAction::NormalBranch( 0, @@ -135,3 +143,60 @@ pub fn eval_from_felt( EvalAction::NormalBranch(1, smallvec![range_check]) } } + +#[cfg(test)] +mod tests { + use crate::{load_cairo, test_utils::run_test_program, Value}; + + #[test] + fn test_eval_diff() { + let (_, program) = load_cairo!( + use core::integer; + + fn main() -> u128 { + integer::i128_diff(2, 1).unwrap() + } + ); + + let result = run_test_program(program); + + let Value::Enum { + self_ty: _, + index: _, + payload, + } = result.last().unwrap() + else { + panic!("No output"); + }; + + let expected = Value::Struct(vec![Value::U128(1)]); + + assert_eq!(**payload, expected); + } + + #[test] + fn test_eval_from_felt() { + let (_, program) = load_cairo!( + use core::integer; + + fn main() -> i128 { + 0x7fffffffffffffffffffffffffffffff_felt252.try_into().unwrap() + } + ); + + let result = run_test_program(program); + + let Value::Enum { + self_ty: _, + index: _, + payload, + } = result.last().unwrap() + else { + panic!("No output"); + }; + + let expected = Value::Struct(vec![Value::I128(0x7fffffffffffffffffffffffffffffff)]); + + assert_eq!(**payload, expected); + } +} diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index 75fee73..d72c021 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -367,6 +367,10 @@ fn eval_storage_write( let [Value::U128(mut gas), system, Value::U32(address_domain), Value::Felt(storage_key), Value::Felt(value)]: [Value; 5] = args.try_into().unwrap() else { panic!() }; + println!("============================="); + println!("Key {}", &storage_key.to_hex_string()); + println!("Value {}", &value.to_hex_string()); + println!("============================="); let error_felt_ty = { match registry .get_type(&info.branch_signatures()[1].vars[2].ty) From 80d280e3f21cb141a6d39d033e99514cb78dc65f Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 4 Oct 2024 15:39:35 -0300 Subject: [PATCH 5/6] format --- src/test_utils.rs | 7 ++++++- src/vm/int128.rs | 12 +++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/test_utils.rs b/src/test_utils.rs index ae9d8f7..672ccec 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -5,7 +5,12 @@ use cairo_lang_compiler::{ project::setup_project, CompilerConfig, }; use cairo_lang_filesystem::db::init_dev_corelib; -use cairo_lang_sierra::{extensions::{circuit::CircuitTypeConcrete, core::CoreTypeConcrete, starknet::StarkNetTypeConcrete}, program::Program}; +use cairo_lang_sierra::{ + extensions::{ + circuit::CircuitTypeConcrete, core::CoreTypeConcrete, starknet::StarkNetTypeConcrete, + }, + program::Program, +}; use crate::{find_entry_point_by_idx, ProgramTrace, StateDump, Value, VirtualMachine}; diff --git a/src/vm/int128.rs b/src/vm/int128.rs index 6410d44..e1cfd1a 100644 --- a/src/vm/int128.rs +++ b/src/vm/int128.rs @@ -21,7 +21,6 @@ pub fn eval( selector: &Sint128Concrete, args: Vec, ) -> EvalAction { - match selector { Sint128Concrete::Const(info) => todo!("1"), Sint128Concrete::Operation(info) => eval_operation(registry, info, args), @@ -44,13 +43,6 @@ fn eval_diff( panic!() }; - dbg!(_selector - .signature - .branch_signatures - .iter() - .map(|x| x.vars.iter().map(|x| &x.ty).collect::>()) - .collect::>()); - if lhs >= rhs { EvalAction::NormalBranch( 0, @@ -180,7 +172,9 @@ mod tests { use core::integer; fn main() -> i128 { - 0x7fffffffffffffffffffffffffffffff_felt252.try_into().unwrap() + 0x7fffffffffffffffffffffffffffffff_felt252 + .try_into() + .unwrap() } ); From 734b3415aef61a0d04343aed2123e7b69bfbbf85 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 7 Oct 2024 12:06:03 -0300 Subject: [PATCH 6/6] remove unwanted code --- src/vm/starknet.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vm/starknet.rs b/src/vm/starknet.rs index d72c021..fa1401b 100644 --- a/src/vm/starknet.rs +++ b/src/vm/starknet.rs @@ -367,10 +367,7 @@ fn eval_storage_write( let [Value::U128(mut gas), system, Value::U32(address_domain), Value::Felt(storage_key), Value::Felt(value)]: [Value; 5] = args.try_into().unwrap() else { panic!() }; - println!("============================="); - println!("Key {}", &storage_key.to_hex_string()); - println!("Value {}", &value.to_hex_string()); - println!("============================="); + let error_felt_ty = { match registry .get_type(&info.branch_signatures()[1].vars[2].ty)