Skip to content

Commit 167934d

Browse files
FrancoGiachettagabrielbosioJulianGCalderon
authored andcommitted
[Sierra-Emu] implement some todos from const and cast libfuncs (#1191)
* Add sierra-emu as a debug utility * Change working dir in sierra-emu job * Remove repeated lines in sierra-emu gitignore * Exclude debug_utils from coverage job * remove some todos from value and implement Coupon libfunc * start adding corelib test * run tests from corelib * remove unwanted file * remove not related things * get return_value from trace * replace ids for debug info * add common folder for integration tests * fix tests * remove todo * ignore test for now * add enum in const::inner * remove todos and fix some failures * filter ignored tests * Update debug_utils/sierra-emu/tests/common/mod.rs Co-authored-by: Julian Gonzalez Calderon <[email protected]> * run ignored test from the ci * better ignoring * ignore test * fmt * remove debug_name in enums * refactor * remove unused dependency * More expressive naming for the workflow Co-authored-by: Gabriel Bosio <[email protected]> * reviews * reviews * fmt * fmt ci * revert last commit * fmt * accidentally removed rayon usage * avoid map's short-circuiting * catch panics the avoid loosing the test name * log ignored tests * clippy * Add "(WIP)" to corelib's test job Co-authored-by: Gabriel Bosio <[email protected]> * print progress as the test runs * fmt * format makefile Co-authored-by: Julian Gonzalez Calderon <[email protected]> * fix name test in ci * add dependencies removed in merge * dependencies * clippy * remove unused import * better indent in makefile * uppercase tests summary comment for better sight * fix clippy * clippy * remove unnecesary pubs * better docs * better panic message in get_numberic_args_as_bigints() Co-authored-by: Julian Gonzalez Calderon <[email protected]> * reviews * remove unnecessary comment Co-authored-by: Julian Gonzalez Calderon <[email protected]> * use slices in get_numeric_args_as_bigints * fmt * remove unnecesary to_vec * fmt * use iter instead of into_iter * reviews changes * better error message * fix typo --------- Co-authored-by: gabrielbosio <[email protected]> Co-authored-by: Julian Gonzalez Calderon <[email protected]> Co-authored-by: Gabriel Bosio <[email protected]>
1 parent 9cdfdd9 commit 167934d

File tree

5 files changed

+127
-100
lines changed

5 files changed

+127
-100
lines changed

debug_utils/sierra-emu/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod dump;
1919
mod gas;
2020
pub mod starknet;
2121
mod test_utils;
22+
mod utils;
2223
mod value;
2324
mod vm;
2425

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use cairo_lang_sierra::{
2+
extensions::core::{CoreLibfunc, CoreType, CoreTypeConcrete},
3+
program_registry::ProgramRegistry,
4+
};
5+
use num_bigint::BigInt;
6+
use num_traits::ToPrimitive;
7+
8+
use crate::Value;
9+
10+
/// Receives a vector of values, filters any which is non numeric and returns a `Vec<BigInt>`
11+
/// Useful when a binary operation takes generic values (like with bounded ints).
12+
pub fn get_numeric_args_as_bigints(args: &[Value]) -> Vec<BigInt> {
13+
args.iter()
14+
.map(|v| match v {
15+
Value::BoundedInt { value, .. } => value.to_owned(),
16+
Value::I8(value) => BigInt::from(*value),
17+
Value::I16(value) => BigInt::from(*value),
18+
Value::I32(value) => BigInt::from(*value),
19+
Value::I64(value) => BigInt::from(*value),
20+
Value::I128(value) => BigInt::from(*value),
21+
Value::U8(value) => BigInt::from(*value),
22+
Value::U16(value) => BigInt::from(*value),
23+
Value::U32(value) => BigInt::from(*value),
24+
Value::U64(value) => BigInt::from(*value),
25+
Value::U128(value) => BigInt::from(*value),
26+
Value::Felt(value) => value.to_bigint(),
27+
Value::Bytes31(value) => value.to_bigint(),
28+
value => panic!("argument should be an integer: {:?}", value),
29+
})
30+
.collect()
31+
}
32+
33+
pub fn get_value_from_integer(
34+
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
35+
ty: &CoreTypeConcrete,
36+
value: BigInt,
37+
) -> Value {
38+
match ty {
39+
CoreTypeConcrete::NonZero(info) => {
40+
let ty = registry.get_type(&info.ty).unwrap();
41+
get_value_from_integer(registry, ty, value)
42+
}
43+
CoreTypeConcrete::Sint8(_) => Value::I8(value.to_i8().unwrap()),
44+
CoreTypeConcrete::Sint16(_) => Value::I16(value.to_i16().unwrap()),
45+
CoreTypeConcrete::Sint32(_) => Value::I32(value.to_i32().unwrap()),
46+
CoreTypeConcrete::Sint64(_) => Value::I64(value.to_i64().unwrap()),
47+
CoreTypeConcrete::Sint128(_) => Value::I128(value.to_i128().unwrap()),
48+
CoreTypeConcrete::Uint8(_) => Value::U8(value.to_u8().unwrap()),
49+
CoreTypeConcrete::Uint16(_) => Value::U16(value.to_u16().unwrap()),
50+
CoreTypeConcrete::Uint32(_) => Value::U32(value.to_u32().unwrap()),
51+
CoreTypeConcrete::Uint64(_) => Value::U64(value.to_u64().unwrap()),
52+
CoreTypeConcrete::Uint128(_) => Value::U128(value.to_u128().unwrap()),
53+
_ => panic!("cannot get integer value for a non-integer type"),
54+
}
55+
}

debug_utils/sierra-emu/src/vm/bounded_int.rs

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::EvalAction;
2-
use crate::Value;
2+
use crate::{utils::get_numeric_args_as_bigints, Value};
33
use cairo_lang_sierra::{
44
extensions::{
55
bounded_int::{
@@ -15,29 +15,6 @@ use cairo_lang_sierra::{
1515
use num_bigint::BigInt;
1616
use smallvec::smallvec;
1717

18-
// All binary operations have generic arguments, this function takes their values
19-
// and builds bigints out of them (since Bigints are used to represent bounded ints' values)
20-
fn get_numberic_args_as_bigints(args: Vec<Value>) -> Vec<BigInt> {
21-
args.into_iter()
22-
// remove builtins, if any
23-
.filter(|v| !matches!(v, Value::Unit))
24-
.map(|v| match v {
25-
Value::BoundedInt { value, .. } => value,
26-
Value::I8(value) => BigInt::from(value),
27-
Value::I16(value) => BigInt::from(value),
28-
Value::I32(value) => BigInt::from(value),
29-
Value::I64(value) => BigInt::from(value),
30-
Value::I128(value) => BigInt::from(value),
31-
Value::U8(value) => BigInt::from(value),
32-
Value::U16(value) => BigInt::from(value),
33-
Value::U32(value) => BigInt::from(value),
34-
Value::U64(value) => BigInt::from(value),
35-
Value::U128(value) => BigInt::from(value),
36-
_ => panic!("Not a numeric value"),
37-
})
38-
.collect()
39-
}
40-
4118
pub fn eval(
4219
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
4320
selector: &BoundedIntConcreteLibfunc,
@@ -62,7 +39,7 @@ pub fn eval_add(
6239
info: &SignatureOnlyConcreteLibfunc,
6340
args: Vec<Value>,
6441
) -> EvalAction {
65-
let [lhs, rhs]: [BigInt; 2] = get_numberic_args_as_bigints(args).try_into().unwrap();
42+
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap();
6643

6744
let range = match registry
6845
.get_type(&info.signature.branch_signatures[0].vars[0].ty)
@@ -91,7 +68,7 @@ pub fn eval_sub(
9168
info: &SignatureOnlyConcreteLibfunc,
9269
args: Vec<Value>,
9370
) -> EvalAction {
94-
let [lhs, rhs]: [BigInt; 2] = get_numberic_args_as_bigints(args).try_into().unwrap();
71+
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap();
9572

9673
let range = match registry
9774
.get_type(&info.signature.branch_signatures[0].vars[0].ty)
@@ -120,7 +97,7 @@ pub fn eval_mul(
12097
info: &SignatureOnlyConcreteLibfunc,
12198
args: Vec<Value>,
12299
) -> EvalAction {
123-
let [lhs, rhs]: [BigInt; 2] = get_numberic_args_as_bigints(args).try_into().unwrap();
100+
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap();
124101

125102
let range = match registry
126103
.get_type(&info.signature.branch_signatures[0].vars[0].ty)
@@ -149,7 +126,7 @@ pub fn eval_div_rem(
149126
info: &BoundedIntDivRemConcreteLibfunc,
150127
args: Vec<Value>,
151128
) -> EvalAction {
152-
let [lhs, rhs]: [BigInt; 2] = get_numberic_args_as_bigints(args).try_into().unwrap();
129+
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap();
153130

154131
let quo = &lhs / &rhs;
155132
let rem = lhs % rhs;
Lines changed: 17 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
use super::EvalAction;
2-
use crate::Value;
2+
use crate::{
3+
utils::{get_numeric_args_as_bigints, get_value_from_integer},
4+
Value,
5+
};
36
use cairo_lang_sierra::{
47
extensions::{
58
casts::{CastConcreteLibfunc, DowncastConcreteLibfunc},
6-
core::{CoreLibfunc, CoreType, CoreTypeConcrete},
9+
core::{CoreLibfunc, CoreType},
710
lib_func::SignatureOnlyConcreteLibfunc,
8-
ConcreteType,
11+
ConcreteLibfunc,
912
},
1013
program_registry::ProgramRegistry,
1114
};
12-
use num_bigint::BigInt;
1315
use smallvec::smallvec;
1416

1517
pub fn eval(
@@ -23,85 +25,40 @@ pub fn eval(
2325
}
2426
}
2527

26-
pub fn eval_downcast(
28+
fn eval_downcast(
2729
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
2830
info: &DowncastConcreteLibfunc,
2931
args: Vec<Value>,
3032
) -> EvalAction {
31-
let [range_check @ Value::Unit, value]: [Value; 2] = args.try_into().unwrap() else {
33+
let range_check @ Value::Unit: Value = args[0].clone() else {
3234
panic!()
3335
};
36+
let [value] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap();
3437

35-
let value = match value {
36-
Value::BoundedInt { value, .. } => value,
37-
Value::U128(value) => BigInt::from(value),
38-
Value::U64(value) => BigInt::from(value),
39-
Value::U32(value) => BigInt::from(value),
40-
Value::U16(value) => BigInt::from(value),
41-
Value::U8(value) => BigInt::from(value),
42-
_ => todo!(),
43-
};
44-
38+
let int_ty = registry.get_type(&info.to_ty).unwrap();
4539
let range = info.to_range.lower.clone()..info.to_range.upper.clone();
4640
if range.contains(&value) {
4741
EvalAction::NormalBranch(
4842
0,
49-
smallvec![
50-
range_check,
51-
match registry.get_type(&info.to_ty).unwrap() {
52-
CoreTypeConcrete::Sint8(_) => Value::I8(value.try_into().unwrap()),
53-
CoreTypeConcrete::Sint128(_) => Value::I128(value.try_into().unwrap()),
54-
CoreTypeConcrete::Uint8(_) => Value::U8(value.try_into().unwrap()),
55-
CoreTypeConcrete::Uint16(_) => Value::U16(value.try_into().unwrap()),
56-
CoreTypeConcrete::Uint32(_) => Value::U32(value.try_into().unwrap()),
57-
CoreTypeConcrete::Uint64(_) => Value::U64(value.try_into().unwrap()),
58-
CoreTypeConcrete::Uint128(_) => Value::U128(value.try_into().unwrap()),
59-
CoreTypeConcrete::BoundedInt(_) => Value::BoundedInt { range, value },
60-
x => todo!("{:?}", x.info()),
61-
}
62-
],
43+
smallvec![range_check, get_value_from_integer(registry, int_ty, value)],
6344
)
6445
} else {
6546
EvalAction::NormalBranch(1, smallvec![range_check])
6647
}
6748
}
6849

69-
pub fn eval_upcast(
50+
fn eval_upcast(
7051
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
7152
info: &SignatureOnlyConcreteLibfunc,
7253
args: Vec<Value>,
7354
) -> EvalAction {
74-
let [value] = args.try_into().unwrap();
75-
76-
let value = match value {
77-
Value::BoundedInt { value, .. } => value,
78-
Value::U128(value) => BigInt::from(value),
79-
Value::U64(value) => BigInt::from(value),
80-
Value::U32(value) => BigInt::from(value),
81-
Value::U16(value) => BigInt::from(value),
82-
Value::U8(value) => BigInt::from(value),
83-
_ => todo!(),
84-
};
55+
let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap();
56+
let int_ty = registry
57+
.get_type(&info.branch_signatures()[0].vars[0].ty)
58+
.unwrap();
8559

8660
EvalAction::NormalBranch(
8761
0,
88-
smallvec![match registry
89-
.get_type(&info.signature.branch_signatures[0].vars[0].ty)
90-
.unwrap()
91-
{
92-
CoreTypeConcrete::Sint8(_) => Value::I8(value.try_into().unwrap()),
93-
CoreTypeConcrete::Sint32(_) => Value::I32(value.try_into().unwrap()),
94-
CoreTypeConcrete::Sint128(_) => Value::I128(value.try_into().unwrap()),
95-
CoreTypeConcrete::Uint8(_) => Value::U8(value.try_into().unwrap()),
96-
CoreTypeConcrete::Uint16(_) => Value::U16(value.try_into().unwrap()),
97-
CoreTypeConcrete::Uint32(_) => Value::U32(value.try_into().unwrap()),
98-
CoreTypeConcrete::Uint64(_) => Value::U64(value.try_into().unwrap()),
99-
CoreTypeConcrete::Uint128(_) => Value::U128(value.try_into().unwrap()),
100-
CoreTypeConcrete::Felt252(_) => Value::Felt(value.into()),
101-
CoreTypeConcrete::Sint16(_) => todo!("Sint16"),
102-
CoreTypeConcrete::Sint64(_) => todo!("Sint64"),
103-
CoreTypeConcrete::BoundedInt(_) => todo!("BoundedInt"),
104-
_ => todo!(),
105-
}],
62+
smallvec![get_value_from_integer(registry, int_ty, value)],
10663
)
10764
}

debug_utils/sierra-emu/src/vm/const.rs

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ use cairo_lang_sierra::{
66
ConstAsBoxConcreteLibfunc, ConstAsImmediateConcreteLibfunc, ConstConcreteLibfunc,
77
},
88
core::{CoreLibfunc, CoreType, CoreTypeConcrete},
9+
starknet::StarknetTypeConcrete,
910
},
1011
ids::ConcreteTypeId,
1112
program::GenericArg,
1213
program_registry::ProgramRegistry,
1314
};
15+
use num_traits::ToPrimitive;
1416
use smallvec::smallvec;
1517

1618
pub fn eval(
@@ -24,7 +26,7 @@ pub fn eval(
2426
}
2527
}
2628

27-
pub fn eval_as_immediate(
29+
fn eval_as_immediate(
2830
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
2931
info: &ConstAsImmediateConcreteLibfunc,
3032
args: Vec<Value>,
@@ -41,7 +43,7 @@ pub fn eval_as_immediate(
4143
)
4244
}
4345

44-
pub fn eval_as_box(
46+
fn eval_as_box(
4547
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
4648
info: &ConstAsBoxConcreteLibfunc,
4749
args: Vec<Value>,
@@ -89,52 +91,56 @@ fn inner(
8991
},
9092
_ => unreachable!(),
9193
},
94+
CoreTypeConcrete::Bytes31(_) => match inner_data {
95+
[GenericArg::Value(value)] => Value::Bytes31(value.into()),
96+
_ => unreachable!(),
97+
},
9298
CoreTypeConcrete::Sint128(_) => match inner_data {
93-
[GenericArg::Value(value)] => Value::I128(value.try_into().unwrap()),
99+
[GenericArg::Value(value)] => Value::I128(value.to_i128().unwrap()),
94100
_ => unreachable!(),
95101
},
96102
CoreTypeConcrete::Sint64(_) => match inner_data {
97-
[GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()),
103+
[GenericArg::Value(value)] => Value::I64(value.to_i64().unwrap()),
98104
_ => unreachable!(),
99105
},
100106
CoreTypeConcrete::Sint32(_) => match inner_data {
101-
[GenericArg::Value(value)] => Value::I32(value.try_into().unwrap()),
107+
[GenericArg::Value(value)] => Value::I32(value.to_i32().unwrap()),
102108
_ => unreachable!(),
103109
},
104110
CoreTypeConcrete::Sint16(_) => match inner_data {
105-
[GenericArg::Value(value)] => Value::I16(value.try_into().unwrap()),
111+
[GenericArg::Value(value)] => Value::I16(value.to_i16().unwrap()),
106112
_ => unreachable!(),
107113
},
108114
CoreTypeConcrete::Sint8(_) => match inner_data {
109-
[GenericArg::Value(value)] => Value::I8(value.try_into().unwrap()),
115+
[GenericArg::Value(value)] => Value::I8(value.to_i8().unwrap()),
110116
_ => unreachable!(),
111117
},
112118
CoreTypeConcrete::Uint128(_) => match inner_data {
113-
[GenericArg::Value(value)] => Value::U128(value.try_into().unwrap()),
119+
[GenericArg::Value(value)] => Value::U128(value.to_u128().unwrap()),
114120
[GenericArg::Type(type_id)] => match registry.get_type(type_id).unwrap() {
115121
CoreTypeConcrete::Const(info) => inner(registry, &info.inner_ty, &info.inner_data),
116122
_ => unreachable!(),
117123
},
118124
_ => unreachable!(),
119125
},
120126
CoreTypeConcrete::Uint64(_) => match inner_data {
121-
[GenericArg::Value(value)] => Value::U64(value.try_into().unwrap()),
127+
[GenericArg::Value(value)] => Value::U64(value.to_u64().unwrap()),
122128
_ => unreachable!(),
123129
},
124130
CoreTypeConcrete::Uint32(_) => match inner_data {
125-
[GenericArg::Value(value)] => Value::U32(value.try_into().unwrap()),
131+
[GenericArg::Value(value)] => Value::U32(value.to_u32().unwrap()),
126132
[GenericArg::Type(type_id)] => match registry.get_type(type_id).unwrap() {
127133
CoreTypeConcrete::Const(info) => inner(registry, &info.inner_ty, &info.inner_data),
128134
_ => unreachable!(),
129135
},
130136
_ => unreachable!(),
131137
},
132138
CoreTypeConcrete::Uint16(_) => match inner_data {
133-
[GenericArg::Value(value)] => Value::U16(value.try_into().unwrap()),
139+
[GenericArg::Value(value)] => Value::U16(value.to_u16().unwrap()),
134140
_ => unreachable!(),
135141
},
136142
CoreTypeConcrete::Uint8(_) => match inner_data {
137-
[GenericArg::Value(value)] => Value::U8(value.try_into().unwrap()),
143+
[GenericArg::Value(value)] => Value::U8(value.to_u8().unwrap()),
138144
_ => unreachable!(),
139145
},
140146
CoreTypeConcrete::Struct(_) => {
@@ -160,6 +166,37 @@ fn inner(
160166

161167
Value::Struct(fields)
162168
}
169+
CoreTypeConcrete::Enum(_) => match inner_data {
170+
[GenericArg::Value(value_idx), GenericArg::Type(payload_ty)] => {
171+
let payload_type = registry.get_type(payload_ty).unwrap();
172+
let const_payload_type = match payload_type {
173+
CoreTypeConcrete::Const(inner) => inner,
174+
_ => {
175+
panic!("matched an unexpected CoreTypeConcrete that is not a Const")
176+
}
177+
};
178+
let payload = inner(registry, payload_ty, &const_payload_type.inner_data);
179+
let index: usize = value_idx.to_usize().unwrap();
180+
181+
Value::Enum {
182+
self_ty: type_id.clone(),
183+
index,
184+
payload: Box::new(payload),
185+
}
186+
}
187+
_ => panic!("const data mismatch"),
188+
},
189+
CoreTypeConcrete::Const(info) => inner(registry, &info.inner_ty, &info.inner_data),
190+
CoreTypeConcrete::Starknet(selector) => match selector {
191+
StarknetTypeConcrete::ClassHash(_)
192+
| StarknetTypeConcrete::ContractAddress(_)
193+
| StarknetTypeConcrete::StorageAddress(_)
194+
| StarknetTypeConcrete::StorageBaseAddress(_) => match inner_data {
195+
[GenericArg::Value(value)] => Value::Felt(value.into()),
196+
_ => unreachable!(),
197+
},
198+
_ => todo!(""),
199+
},
163200
_ => todo!("{}", type_id),
164201
}
165202
}

0 commit comments

Comments
 (0)