lambdaclass / cairo_native

A compiler to convert Cairo's intermediate representation "Sierra" code to MLIR.
https://lambdaclass.github.io/cairo_native/cairo_native
Apache License 2.0
122 stars 43 forks source link

Upgrade to Starknet 2.6.3 #494

Closed edg-l closed 5 months ago

edg-l commented 7 months ago

TODO:

Initial PR: https://github.com/lambdaclass/cairo_native/pull/440

Const libfunc task list

Both do the same, but as box puts the value in a box.

Values to create:

Casm implementation: https://github.com/starkware-libs/cairo/blob/v2.6.3/crates/cairo-lang-sierra-to-casm/src/invocations/const_type.rs

To get the const values from the types we need to do the following (a.k.a what the casm compiler does):

Store the following field somewhere, maybe in the metadata (source):

pub const_data_values: &'a dyn Fn(&ConcreteTypeId) -> Vec<BigInt>,

These values seem extracted using the method extract_const_value (source, source to the method):

Note: What should be passed to this method is the const_type, not the inner type of the const_type! You should pass the CoreTypeConcrete::Const(...) type, not the type it wraps, to get the const value.

Expand me to see source code ```rust /// Gets a concrete type, if it is a const type returns a vector of the values to be stored in the /// const segment. fn extract_const_value( registry: &ProgramRegistry, type_sizes: &TypeSizeMap, ty: &ConcreteTypeId, ) -> Result, CompilationError> { let mut values = Vec::new(); let mut types_stack = vec![ty.clone()]; while let Some(ty) = types_stack.pop() { let CoreTypeConcrete::Const(const_type) = registry.get_type(&ty).unwrap() else { return Err(CompilationError::UnsupportedConstType); }; let inner_type = registry.get_type(&const_type.inner_ty).unwrap(); match inner_type { CoreTypeConcrete::Struct(_) => { // Add the struct members' types to the stack in reverse order. for arg in const_type.inner_data.iter().rev() { match arg { GenericArg::Type(arg_ty) => types_stack.push(arg_ty.clone()), _ => return Err(CompilationError::ConstDataMismatch), } } } CoreTypeConcrete::Enum(enm) => { // The first argument is the variant selector, the second is the variant data. match &const_type.inner_data[..] { [GenericArg::Value(variant_index), GenericArg::Type(ty)] => { let variant_index = variant_index.to_usize().unwrap(); values.push( get_variant_selector(enm.variants.len(), variant_index).unwrap().into(), ); let full_enum_size: usize = type_sizes[&const_type.inner_ty].into_or_panic(); let variant_size: usize = type_sizes[&enm.variants[variant_index]].into_or_panic(); // Padding with zeros to full enum size. values.extend(itertools::repeat_n( BigInt::zero(), // Subtract 1 due to the variant selector. full_enum_size - variant_size - 1, )); types_stack.push(ty.clone()); } _ => return Err(CompilationError::ConstDataMismatch), } } CoreTypeConcrete::NonZero(_) => match &const_type.inner_data[..] { [GenericArg::Type(inner)] => { types_stack.push(inner.clone()); } _ => return Err(CompilationError::ConstDataMismatch), }, _ => match &const_type.inner_data[..] { [GenericArg::Value(value)] => { values.push(value.clone()); } _ => return Err(CompilationError::ConstDataMismatch), }, }; } Ok(values) } ```

Coupon libfunc task list and info

These are the new libfuncs:

The coupon call has the following info in the source code: /// Libfunc used to call user functions.

The coupon has the following info in the source code:

/// Libfunc for buying a coupon for a function. The cost of the coupon is the cost of running the
/// function (not including the `call` and `ret` instructions).
/// The coupon can be used to pay in advance for running the function, and run it later for
/// free (paying only for the `call` and `ret` instructions) using `coupon_call`.
#[derive(Default)]
pub struct CouponBuyLibfunc {}

/// Libfunc for getting a refund for an unused coupon. The refund is the cost of the function
/// and it is added back to the gas wallet.
#[derive(Default)]
pub struct CouponRefundLibfunc {}

Related structures to implement

CouponType

Coupon type Coupon<function> (function::Coupon) which represents that the cost of a function was paid, without calling the function yet. Using the coupon the function can be called without paying the cost.

BranchCostSign

pub enum BranchCostSign {
/// Adds the cost to the wallet (e.g., in `coupon_refund`).
Add,
/// Subtracts the cost from the wallet (e.g., in `function_call`).
Subtract,
}
ebukizy1 commented 6 months ago

would love to be assign this.. can i jump on this

edg-l commented 6 months ago

would love to be assign this.. can i jump on this

Sorry, this issue isn't open to odhack and it's being done by me currently.