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:
[x] Coupon
[x] Buy
[x] Refund
[x] Coupon Call
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,
}
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):
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: &ProgramRegistryCoupon 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:
Related structures to implement
CouponType
BranchCostSign