Skip to content

Commit

Permalink
Merge pull request #15 from lambdaclass/more-libs
Browse files Browse the repository at this point in the history
Add more libs
  • Loading branch information
JulianGCalderon authored Oct 17, 2024
2 parents 18f9e75 + 19f2fc1 commit 071caea
Show file tree
Hide file tree
Showing 12 changed files with 626 additions and 49 deletions.
219 changes: 188 additions & 31 deletions src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
use cairo_lang_sierra::extensions::{
array::ArrayConcreteLibfunc,
boolean::BoolConcreteLibfunc,
bounded_int::BoundedIntConcreteLibfunc,
boxing::BoxConcreteLibfunc,
bytes31::Bytes31ConcreteLibfunc,
casts::CastConcreteLibfunc,
circuit::CircuitConcreteLibfunc,
const_type::ConstConcreteLibfunc,
core::CoreConcreteLibfunc,
coupon::CouponConcreteLibfunc,
debug::DebugConcreteLibfunc,
ec::EcConcreteLibfunc,
enm::EnumConcreteLibfunc,
felt252::{Felt252BinaryOperationConcrete, Felt252BinaryOperator, Felt252Concrete},
felt252_dict::{Felt252DictConcreteLibfunc, Felt252DictEntryConcreteLibfunc},
gas::GasConcreteLibfunc,
int::{
signed::SintConcrete, signed128::Sint128Concrete, unsigned::UintConcrete,
unsigned128::Uint128Concrete, unsigned256::Uint256Concrete, unsigned512::Uint512Concrete,
IntOperator,
use cairo_lang_sierra::{
extensions::{
array::ArrayConcreteLibfunc,
boolean::BoolConcreteLibfunc,
bounded_int::BoundedIntConcreteLibfunc,
boxing::BoxConcreteLibfunc,
bytes31::Bytes31ConcreteLibfunc,
casts::CastConcreteLibfunc,
circuit::{CircuitConcreteLibfunc, CircuitTypeConcrete},
const_type::ConstConcreteLibfunc,
core::{CoreConcreteLibfunc, CoreLibfunc, CoreType, CoreTypeConcrete},
coupon::CouponConcreteLibfunc,
debug::DebugConcreteLibfunc,
ec::EcConcreteLibfunc,
enm::EnumConcreteLibfunc,
felt252::{Felt252BinaryOperationConcrete, Felt252BinaryOperator, Felt252Concrete},
felt252_dict::{Felt252DictConcreteLibfunc, Felt252DictEntryConcreteLibfunc},
gas::GasConcreteLibfunc,
int::{
signed::SintConcrete, signed128::Sint128Concrete, unsigned::UintConcrete,
unsigned128::Uint128Concrete, unsigned256::Uint256Concrete,
unsigned512::Uint512Concrete, IntOperator,
},
lib_func::{BranchSignature, ParamSignature},
mem::MemConcreteLibfunc,
nullable::NullableConcreteLibfunc,
pedersen::PedersenConcreteLibfunc,
poseidon::PoseidonConcreteLibfunc,
starknet::{
secp256::{Secp256ConcreteLibfunc, Secp256OpConcreteLibfunc},
testing::TestingConcreteLibfunc,
StarkNetConcreteLibfunc, StarkNetTypeConcrete,
},
structure::StructConcreteLibfunc,
},
mem::MemConcreteLibfunc,
nullable::NullableConcreteLibfunc,
pedersen::PedersenConcreteLibfunc,
poseidon::PoseidonConcreteLibfunc,
starknet::{
secp256::{Secp256ConcreteLibfunc, Secp256OpConcreteLibfunc},
testing::TestingConcreteLibfunc,
StarkNetConcreteLibfunc,
},
structure::StructConcreteLibfunc,
ids::ConcreteTypeId,
program_registry::ProgramRegistry,
};

use crate::Value;

pub fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str {
match value {
CoreConcreteLibfunc::ApTracking(value) => match value {
Expand Down Expand Up @@ -409,3 +416,153 @@ pub fn libfunc_to_name(value: &CoreConcreteLibfunc) -> &'static str {
},
}
}

pub fn type_to_name(
ty_id: &ConcreteTypeId,
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
) -> String {
let ty = registry.get_type(ty_id).unwrap();
match ty {
CoreTypeConcrete::Array(info) => {
format!("Array<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Box(info) => {
format!("Box<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Uninitialized(info) => {
format!("Uninitialized<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::NonZero(info) => {
format!("NonZero<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Nullable(info) => {
format!("Nullable<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Span(info) => {
format!("Span<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Snapshot(info) => {
format!("Snapshot<{}>", type_to_name(&info.ty, registry))
}
CoreTypeConcrete::Struct(info) => {
let fields = info
.members
.iter()
.map(|ty_id| type_to_name(ty_id, registry))
.collect::<Vec<_>>();
let fields = fields.join(", ");

format!("Struct<{}>", fields)
}
CoreTypeConcrete::Enum(info) => {
let fields = info
.variants
.iter()
.map(|ty_id| type_to_name(ty_id, registry))
.collect::<Vec<_>>();
let fields = fields.join(", ");

format!("Enum<{}>", fields)
}
CoreTypeConcrete::Felt252Dict(_) => String::from("Felt252Dict"),
CoreTypeConcrete::Felt252DictEntry(_) => String::from("Felt252DictEntry"),
CoreTypeConcrete::SquashedFelt252Dict(_) => String::from("SquashedFelt252Dict"),
CoreTypeConcrete::StarkNet(selector) => match selector {
StarkNetTypeConcrete::ClassHash(_) => String::from("Starknet::ClassHash"),
StarkNetTypeConcrete::ContractAddress(_) => String::from("Starknet::ContractAddress"),
StarkNetTypeConcrete::StorageBaseAddress(_) => {
String::from("Starknet::StorageBaseAddress")
}
StarkNetTypeConcrete::StorageAddress(_) => String::from("Starknet::StorageAddress"),
StarkNetTypeConcrete::System(_) => String::from("Starknet::System"),
StarkNetTypeConcrete::Secp256Point(_) => String::from("Starknet::Secp256Point"),
StarkNetTypeConcrete::Sha256StateHandle(_) => {
String::from("Starknet::Sha256StateHandle")
}
},

CoreTypeConcrete::Bitwise(_) => String::from("Bitwise"),
CoreTypeConcrete::Circuit(selector) => match selector {
CircuitTypeConcrete::AddMod(_) => String::from("AddMod"),
CircuitTypeConcrete::MulMod(_) => String::from("MulMod"),
CircuitTypeConcrete::AddModGate(_) => String::from("AddModGate"),
CircuitTypeConcrete::Circuit(_) => String::from("Circuit"),
CircuitTypeConcrete::CircuitData(_) => String::from("CircuitData"),
CircuitTypeConcrete::CircuitOutputs(_) => String::from("CircuitOutputs"),
CircuitTypeConcrete::CircuitPartialOutputs(_) => String::from("CircuitPartialOutputs"),
CircuitTypeConcrete::CircuitDescriptor(_) => String::from("CircuitDescriptor"),
CircuitTypeConcrete::CircuitFailureGuarantee(_) => {
String::from("CircuitFailureGuarantee")
}
CircuitTypeConcrete::CircuitInput(_) => String::from("CircuitInput"),
CircuitTypeConcrete::CircuitInputAccumulator(_) => {
String::from("CircuitInputAccumulator")
}
CircuitTypeConcrete::CircuitModulus(_) => String::from("CircuitModulus"),
CircuitTypeConcrete::InverseGate(_) => String::from("InverseGate"),
CircuitTypeConcrete::MulModGate(_) => String::from("MulModGate"),
CircuitTypeConcrete::SubModGate(_) => String::from("SubModGate"),
CircuitTypeConcrete::U96Guarantee(_) => String::from("U96Guarantee"),
CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => {
String::from("U96LimbsLessThanGuarantee")
}
},
CoreTypeConcrete::Const(_) => String::from("Const"),
CoreTypeConcrete::Coupon(_) => String::from("Coupon"),
CoreTypeConcrete::EcOp(_) => String::from("EcOp"),
CoreTypeConcrete::EcPoint(_) => String::from("EcPoint"),
CoreTypeConcrete::EcState(_) => String::from("EcState"),
CoreTypeConcrete::Felt252(_) => String::from("Felt252"),
CoreTypeConcrete::GasBuiltin(_) => String::from("GasBuiltin"),
CoreTypeConcrete::BuiltinCosts(_) => String::from("BuiltinCosts"),
CoreTypeConcrete::Uint8(_) => String::from("Uint8"),
CoreTypeConcrete::Uint16(_) => String::from("Uint16"),
CoreTypeConcrete::Uint32(_) => String::from("Uint32"),
CoreTypeConcrete::Uint64(_) => String::from("Uint64"),
CoreTypeConcrete::Uint128(_) => String::from("Uint128"),
CoreTypeConcrete::Uint128MulGuarantee(_) => String::from("Uint128MulGuarantee"),
CoreTypeConcrete::Sint8(_) => String::from("Sint8"),
CoreTypeConcrete::Sint16(_) => String::from("Sint16"),
CoreTypeConcrete::Sint32(_) => String::from("Sint32"),
CoreTypeConcrete::Sint64(_) => String::from("Sint64"),
CoreTypeConcrete::Sint128(_) => String::from("Sint128"),
CoreTypeConcrete::RangeCheck(_) => String::from("RangeCheck"),
CoreTypeConcrete::RangeCheck96(_) => String::from("RangeCheck96"),
CoreTypeConcrete::Pedersen(_) => String::from("Pedersen"),
CoreTypeConcrete::Poseidon(_) => String::from("Poseidon"),
CoreTypeConcrete::SegmentArena(_) => String::from("SegmentArena"),
CoreTypeConcrete::Bytes31(_) => String::from("Bytes31"),
CoreTypeConcrete::BoundedInt(_) => String::from("BoundedInt"),
}
}

/// prints all the signature information, used while debugging to learn
/// how to implement a certain libfunc.
#[allow(dead_code)]
pub fn debug_signature(
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
params: &[ParamSignature],
branches: &[BranchSignature],
args: &[Value],
) {
println!(
"Params: {:#?}",
params
.iter()
.map(|p| type_to_name(&p.ty, registry))
.collect::<Vec<_>>()
);
println!(
"Branches: {:#?}",
branches
.iter()
.map(|b| {
b.vars
.iter()
.map(|vars| type_to_name(&vars.ty, registry))
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
);
println!("Args: {:#?}", args);
}
31 changes: 30 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use cairo_lang_sierra::program::{GenFunction, Program, StatementIdx};
use cairo_lang_sierra::{
extensions::core::{CoreLibfunc, CoreType},
ids::ConcreteTypeId,
program::{GenFunction, Program, StatementIdx},
program_registry::ProgramRegistry,
};

pub use self::{dump::*, value::*, vm::VirtualMachine};

Expand Down Expand Up @@ -29,3 +34,27 @@ pub fn find_entry_point_by_name<'a>(
.iter()
.find(|x| x.id.debug_name.as_ref().map(|x| x.as_str()) == Some(name))
}

// If type is invisible to sierra (i.e. a single element container),
// finds it's actual concrete type recursively.
// If not, returns the current type
pub fn find_real_type(
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
ty: &ConcreteTypeId,
) -> ConcreteTypeId {
match registry.get_type(ty).unwrap() {
cairo_lang_sierra::extensions::core::CoreTypeConcrete::Box(info) => {
find_real_type(registry, &info.ty)
}
cairo_lang_sierra::extensions::core::CoreTypeConcrete::Uninitialized(info) => {
find_real_type(registry, &info.ty)
}
cairo_lang_sierra::extensions::core::CoreTypeConcrete::Span(info) => {
find_real_type(registry, &info.ty)
}
cairo_lang_sierra::extensions::core::CoreTypeConcrete::Snapshot(info) => {
find_real_type(registry, &info.ty)
}
_ => ty.clone(),
}
}
9 changes: 9 additions & 0 deletions src/starknet/secp256k1_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@ impl Secp256k1Point {
Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]),
])
}

pub fn from_value(v: Value) -> Self {
let Value::Struct(mut v) = v else { panic!() };

let y = U256::from_value(v.remove(1));
let x = U256::from_value(v.remove(0));

Self { x, y }
}
}
9 changes: 9 additions & 0 deletions src/starknet/secp256r1_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@ impl Secp256r1Point {
Value::Struct(vec![Value::U128(self.y.lo), Value::U128(self.y.hi)]),
])
}

pub fn from_value(v: Value) -> Self {
let Value::Struct(mut v) = v else { panic!() };

let y = U256::from_value(v.remove(1));
let x = U256::from_value(v.remove(0));

Self { x, y }
}
}
8 changes: 8 additions & 0 deletions src/starknet/u256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ impl U256 {
pub(crate) fn into_value(self) -> Value {
Value::Struct(vec![Value::U128(self.lo), Value::U128(self.hi)])
}

pub fn from_value(v: Value) -> Self {
let Value::Struct(v) = v else { panic!() };
let Value::U128(lo) = v[0] else { panic!() };
let Value::U128(hi) = v[1] else { panic!() };

Self { lo, hi }
}
}
43 changes: 34 additions & 9 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use serde::Serialize;
use starknet_types_core::felt::Felt;
use std::{collections::HashMap, fmt::Debug, ops::Range};

use crate::debug::type_to_name;

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Value {
Array {
Expand Down Expand Up @@ -128,18 +130,14 @@ impl Value {
}
CoreTypeConcrete::Uint8(_) => matches!(self, Self::U8(_)),
CoreTypeConcrete::Uint32(_) => matches!(self, Self::U32(_)),
CoreTypeConcrete::Uint128(_)
| CoreTypeConcrete::Circuit(CircuitTypeConcrete::U96Guarantee(_)) => {
CoreTypeConcrete::Uint128(_) => {
matches!(self, Self::U128(_))
}

// Unused builtins (mapped to `Value::Unit`).
CoreTypeConcrete::RangeCheck(_)
| CoreTypeConcrete::SegmentArena(_)
| CoreTypeConcrete::RangeCheck96(_)
| CoreTypeConcrete::Circuit(
CircuitTypeConcrete::AddMod(_) | CircuitTypeConcrete::MulMod(_),
)
| CoreTypeConcrete::StarkNet(StarkNetTypeConcrete::System(_)) => {
matches!(self, Self::Unit)
}
Expand All @@ -148,7 +146,29 @@ impl Value {
CoreTypeConcrete::Coupon(_) => todo!(),
CoreTypeConcrete::Bitwise(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Box(info) => self.is(registry, &info.ty),
CoreTypeConcrete::Circuit(_) => todo!(),

// Circuit related types
CoreTypeConcrete::Circuit(selector) => match selector {
CircuitTypeConcrete::Circuit(_) => matches!(self, Self::Circuit(_)),
CircuitTypeConcrete::CircuitData(_) => matches!(self, Self::Circuit(_)),
CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::CircuitOutputs(_)),
CircuitTypeConcrete::CircuitInput(_) => matches!(self, Self::Unit),
CircuitTypeConcrete::CircuitInputAccumulator(_) => matches!(self, Self::Circuit(_)),
CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)),
CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)),
CircuitTypeConcrete::CircuitDescriptor(_)
| CircuitTypeConcrete::CircuitFailureGuarantee(_)
| CircuitTypeConcrete::AddMod(_)
| CircuitTypeConcrete::MulMod(_)
| CircuitTypeConcrete::AddModGate(_)
| CircuitTypeConcrete::CircuitPartialOutputs(_)
| CircuitTypeConcrete::InverseGate(_)
| CircuitTypeConcrete::MulModGate(_)
| CircuitTypeConcrete::SubModGate(_)
| CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => {
matches!(self, Self::Unit)
}
},
CoreTypeConcrete::Const(_) => todo!(),
CoreTypeConcrete::EcOp(_) => matches!(self, Self::Unit),
CoreTypeConcrete::EcPoint(_) => matches!(self, Self::EcPoint { .. }),
Expand All @@ -160,7 +180,7 @@ impl Value {
CoreTypeConcrete::Sint16(_) => todo!(),
CoreTypeConcrete::Sint64(_) => todo!(),
CoreTypeConcrete::Nullable(info) => self.is(registry, &info.ty),
CoreTypeConcrete::Uninitialized(_) => todo!(),
CoreTypeConcrete::Uninitialized(_) => matches!(self, Self::Uninitialized { .. }),
CoreTypeConcrete::Felt252DictEntry(_) => todo!(),
CoreTypeConcrete::SquashedFelt252Dict(_) => todo!(),
CoreTypeConcrete::Pedersen(_) => matches!(self, Self::Unit),
Expand All @@ -172,13 +192,18 @@ impl Value {
| StarkNetTypeConcrete::StorageBaseAddress(_)
| StarkNetTypeConcrete::StorageAddress(_) => matches!(self, Self::Felt(_)),
StarkNetTypeConcrete::System(_) => matches!(self, Self::Unit),
StarkNetTypeConcrete::Secp256Point(_) => todo!(),
StarkNetTypeConcrete::Secp256Point(_) => matches!(self, Self::Struct(_)),
StarkNetTypeConcrete::Sha256StateHandle(_) => matches!(self, Self::Struct { .. }),
},
};

if !res {
dbg!("value is mismatch", ty.info(), self);
dbg!(
"value is mismatch",
ty.info(),
self,
type_to_name(type_id, registry)
);
}

res
Expand Down
Loading

0 comments on commit 071caea

Please sign in to comment.