Skip to content

Commit d4158fa

Browse files
[Serra-Emu] Fix some libfuncs (#1223)
* change initial gas due to overflows * fix some libfuncs in circuits * fix is() for circuits * remove Value::Unit from return values in get_output * match U96LimbsLessThanGuarantee correctly * some corrections to circuits * some corrections to circuits * fix failure_guarantee_verify to avoid panicking * fix circuits * more fixes to circuits + implement ec_zero libfunc * clippy * remove unnecesary tests * remove unnecesary file * fix branch index * add comment * fix eval_u96_limbs_less_than_guarantee_verify * remove circuit failure test * update trace dump with new Value::CircitOutputs * fmt * reviews + fix modulus in trace dump * remove unnecesary file * fix clippy * implement circuit_single_limb_less_than_guarantee_verify * fix trace dump for circuit outputs * fix felt_dict_get * fix felt_dict_get * implement U96LimbsLessThanGuarantee for trace dump * remove unnecessary code * fmt * fix felt_dict_entry_get * revert change in circuits.rs * remove unwanted file * revert unwanted change * revert unwanted change * fix cast and int range libfuncs * make trace dump for circuit outputs cleaner * remove unwanted code * increase felt dict count always during get() * doc function + merge main * fix some libfuncs * implement CouponCall not working * all tests passing * remove WIP for corelib tests in sierra-emu's ci * remove WIP for corelib tests in sierra-emu's ci * fmt! * pop unused argument in coupon_call * better error messages in utils
1 parent a51d1b5 commit d4158fa

File tree

12 files changed

+165
-108
lines changed

12 files changed

+165
-108
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,9 @@ jobs:
361361
- name: Run tests
362362
working-directory: ./debug_utils/sierra-emu
363363
run: make test-no-corelib
364-
- name: Run corelib's tests (WIP)
364+
- name: Run corelib's tests
365365
working-directory: ./debug_utils/sierra-emu
366366
run: cargo test test_corelib -- --nocapture
367-
continue-on-error: true # ignore result for now. When sierra-emu is fully implemented this should be removed
368367

369368
build-sierra2casm-dbg:
370369
name: Build sierra2casm-dbg

debug_utils/sierra-emu/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use cairo_lang_sierra::{
1010
program::{GenFunction, Program, StatementIdx},
1111
program_registry::ProgramRegistry,
1212
};
13+
use debug::type_to_name;
1314
use starknet::StubSyscallHandler;
1415

1516
pub use self::{dump::*, gas::BuiltinCosts, value::*, vm::VirtualMachine};
@@ -132,7 +133,8 @@ pub fn run_program(
132133
}
133134
_ => todo!(),
134135
},
135-
_ => todo!(),
136+
CoreTypeConcrete::EcOp(_) => Value::Unit,
137+
_ => todo!("{}", type_to_name(type_id, vm.registry())),
136138
}
137139
})
138140
.collect::<Vec<_>>(),

debug_utils/sierra-emu/src/utils.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use cairo_lang_sierra::{
33
core::{CoreLibfunc, CoreType, CoreTypeConcrete},
44
utils::Range,
55
},
6+
ids::ConcreteTypeId,
67
program_registry::ProgramRegistry,
78
};
89
use num_bigint::BigInt;
910
use num_traits::{Bounded, One, ToPrimitive};
1011
use starknet_types_core::felt::CAIRO_PRIME_BIGINT;
1112

12-
use crate::Value;
13+
use crate::{debug::type_to_name, Value};
1314

1415
/// Receives a vector of values, filters any which is non numeric and returns a `Vec<BigInt>`
1516
/// Useful when a binary operation takes generic values (like with bounded ints).
@@ -29,21 +30,20 @@ pub fn get_numeric_args_as_bigints(args: &[Value]) -> Vec<BigInt> {
2930
Value::U128(value) => BigInt::from(*value),
3031
Value::Felt(value) => value.to_bigint(),
3132
Value::Bytes31(value) => value.to_bigint(),
32-
value => panic!("argument should be an integer: {:?}", value),
33+
value => panic!("Argument should be an integer: {:?}", value),
3334
})
3435
.collect()
3536
}
3637

3738
pub fn get_value_from_integer(
3839
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
39-
ty: &CoreTypeConcrete,
40+
ty_id: &ConcreteTypeId,
4041
value: BigInt,
4142
) -> Value {
43+
let ty = registry.get_type(ty_id).unwrap();
44+
4245
match ty {
43-
CoreTypeConcrete::NonZero(info) => {
44-
let ty = registry.get_type(&info.ty).unwrap();
45-
get_value_from_integer(registry, ty, value)
46-
}
46+
CoreTypeConcrete::NonZero(info) => get_value_from_integer(registry, &info.ty, value),
4747
CoreTypeConcrete::Sint8(_) => Value::I8(value.to_i8().unwrap()),
4848
CoreTypeConcrete::Sint16(_) => Value::I16(value.to_i16().unwrap()),
4949
CoreTypeConcrete::Sint32(_) => Value::I32(value.to_i32().unwrap()),
@@ -62,12 +62,15 @@ pub fn get_value_from_integer(
6262
}
6363
}
6464
CoreTypeConcrete::Felt252(_) => Value::Felt(value.into()),
65-
_ => panic!("cannot get integer value for a non-integer type"),
65+
_ => panic!(
66+
"Cannot get integer value for a non-integer type: {}",
67+
type_to_name(ty_id, registry)
68+
),
6669
}
6770
}
6871

6972
pub fn integer_range(
70-
ty: &CoreTypeConcrete,
73+
ty_id: &ConcreteTypeId,
7174
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
7275
) -> Range {
7376
fn range_of<T>() -> Range
@@ -80,6 +83,8 @@ pub fn integer_range(
8083
}
8184
}
8285

86+
let ty = registry.get_type(ty_id).unwrap();
87+
8388
match ty {
8489
CoreTypeConcrete::Uint8(_) => range_of::<u8>(),
8590
CoreTypeConcrete::Uint16(_) => range_of::<u16>(),
@@ -100,14 +105,11 @@ pub fn integer_range(
100105
lower: BigInt::ZERO,
101106
upper: BigInt::one() << 248,
102107
},
103-
CoreTypeConcrete::Const(info) => {
104-
let ty = registry.get_type(&info.inner_ty).unwrap();
105-
integer_range(ty, registry)
106-
}
107-
CoreTypeConcrete::NonZero(info) => {
108-
let ty = registry.get_type(&info.ty).unwrap();
109-
integer_range(ty, registry)
110-
}
111-
_ => panic!("cannot get integer range value for a non-integer type"),
108+
CoreTypeConcrete::Const(info) => integer_range(&info.inner_ty, registry),
109+
CoreTypeConcrete::NonZero(info) => integer_range(&info.ty, registry),
110+
_ => panic!(
111+
"Cannot get integer range value for a non-integer type {}",
112+
type_to_name(ty_id, registry)
113+
),
112114
}
113115
}

debug_utils/sierra-emu/src/value.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,17 @@ impl Value {
101101
index: 0,
102102
payload: Box::new(Value::default_for_type(registry, &info.variants[0])),
103103
},
104+
CoreTypeConcrete::Array(info) => Value::Array {
105+
ty: info.ty.clone(),
106+
data: vec![],
107+
},
104108
CoreTypeConcrete::Struct(info) => Value::Struct(
105109
info.members
106110
.iter()
107111
.map(|member| Value::default_for_type(registry, member))
108112
.collect(),
109113
),
110-
CoreTypeConcrete::Nullable(info) => Value::default_for_type(registry, &info.ty),
114+
CoreTypeConcrete::Nullable(_) => Value::Null,
111115
x => panic!("type {:?} has no default value implementation", x.info()),
112116
}
113117
}

debug_utils/sierra-emu/src/vm.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ fn eval<'a>(
471471
CoreConcreteLibfunc::Circuit(selector) => self::circuit::eval(registry, selector, args),
472472
CoreConcreteLibfunc::Const(selector) => self::r#const::eval(registry, selector, args),
473473
CoreConcreteLibfunc::Coupon(selector) => self::coupon::eval(registry, selector, args),
474-
CoreConcreteLibfunc::CouponCall(_) => todo!(),
475474
CoreConcreteLibfunc::Debug(_) => todo!(),
476475
CoreConcreteLibfunc::Drop(info) => self::drop::eval(registry, info, args),
477476
CoreConcreteLibfunc::Dup(info) => self::dup::eval(registry, info, args),
@@ -484,7 +483,12 @@ fn eval<'a>(
484483
CoreConcreteLibfunc::Felt252DictEntry(selector) => {
485484
self::felt252_dict_entry::eval(registry, selector, args)
486485
}
487-
CoreConcreteLibfunc::FunctionCall(info) => self::function_call::eval(registry, info, args),
486+
CoreConcreteLibfunc::FunctionCall(info) => {
487+
self::function_call::eval_function_call(registry, info, args)
488+
}
489+
CoreConcreteLibfunc::CouponCall(info) => {
490+
self::function_call::eval_coupon_call(registry, info, args)
491+
}
488492
CoreConcreteLibfunc::Gas(selector) => {
489493
self::gas::eval(registry, selector, args, gas, *statement_idx, builtin_costs)
490494
}

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,10 @@ fn eval_snapshot_multi_pop_back(
297297
};
298298

299299
if data.len() >= popped_cty.members.len() {
300-
let new_data = data.split_off(data.len() - popped_cty.members.len());
301-
let value = Value::Struct(data);
300+
let popped_data = data.split_off(data.len() - popped_cty.members.len());
301+
let value = Value::Struct(popped_data);
302302
assert!(value.is(registry, &info.popped_ty));
303-
EvalAction::NormalBranch(
304-
0,
305-
smallvec![rangecheck, Value::Array { data: new_data, ty }, value],
306-
)
303+
EvalAction::NormalBranch(0, smallvec![rangecheck, Value::Array { data, ty }, value])
307304
} else {
308305
EvalAction::NormalBranch(1, smallvec![rangecheck, Value::Array { data, ty }])
309306
}

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use super::EvalAction;
2-
use crate::{utils::get_numeric_args_as_bigints, 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
bounded_int::{
@@ -126,8 +129,10 @@ pub fn eval_div_rem(
126129
info: &BoundedIntDivRemConcreteLibfunc,
127130
args: Vec<Value>,
128131
) -> EvalAction {
129-
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap();
130-
132+
let range_check @ Value::Unit: Value = args[0].clone() else {
133+
panic!()
134+
};
135+
let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap();
131136
let quo = &lhs / &rhs;
132137
let rem = lhs % rhs;
133138

@@ -151,7 +156,7 @@ pub fn eval_div_rem(
151156
EvalAction::NormalBranch(
152157
0,
153158
smallvec![
154-
Value::Unit, // range_check
159+
range_check,
155160
Value::BoundedInt {
156161
range: quo_range,
157162
value: quo,
@@ -169,14 +174,10 @@ pub fn eval_constrain(
169174
info: &BoundedIntConstrainConcreteLibfunc,
170175
args: Vec<Value>,
171176
) -> EvalAction {
172-
let [range_check @ Value::Unit, value]: [Value; 2] = args.try_into().unwrap() else {
177+
let range_check @ Value::Unit: Value = args[0].clone() else {
173178
panic!()
174179
};
175-
176-
let value = match value {
177-
Value::I8(value) => value.into(),
178-
_ => todo!(),
179-
};
180+
let [value]: [BigInt; 1] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap();
180181

181182
if value < info.boundary {
182183
let range = match registry
@@ -224,19 +225,19 @@ pub fn eval_constrain(
224225
}
225226

226227
pub fn eval_is_zero(
227-
_registry: &ProgramRegistry<CoreType, CoreLibfunc>,
228-
_info: &SignatureOnlyConcreteLibfunc,
228+
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
229+
info: &SignatureOnlyConcreteLibfunc,
229230
args: Vec<Value>,
230231
) -> EvalAction {
231-
let [value] = args.try_into().unwrap();
232-
let is_zero = match value {
233-
Value::I8(value) => value == 0,
234-
_ => todo!(),
235-
};
232+
let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap();
233+
let is_zero = value == 0.into();
234+
235+
let int_ty = &info.branch_signatures()[1].vars[0].ty;
236236

237237
if is_zero {
238238
EvalAction::NormalBranch(0, smallvec![])
239239
} else {
240+
let value = get_value_from_integer(registry, int_ty, value);
240241
EvalAction::NormalBranch(1, smallvec![value])
241242
}
242243
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ fn eval_downcast(
3535
};
3636
let [value] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap();
3737

38-
let int_ty = registry.get_type(&info.to_ty).unwrap();
39-
4038
let range = info.to_range.lower.clone()..info.to_range.upper.clone();
39+
4140
if range.contains(&value) {
4241
EvalAction::NormalBranch(
4342
0,
44-
smallvec![range_check, get_value_from_integer(registry, int_ty, value)],
43+
smallvec![
44+
range_check,
45+
get_value_from_integer(registry, &info.to_ty, value)
46+
],
4547
)
4648
} else {
4749
EvalAction::NormalBranch(1, smallvec![range_check])
@@ -54,12 +56,10 @@ fn eval_upcast(
5456
args: Vec<Value>,
5557
) -> EvalAction {
5658
let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap();
57-
let int_ty = registry
58-
.get_type(&info.branch_signatures()[0].vars[0].ty)
59-
.unwrap();
59+
let int_ty_id = &info.branch_signatures()[0].vars[0].ty;
6060

6161
EvalAction::NormalBranch(
6262
0,
63-
smallvec![get_value_from_integer(registry, int_ty, value)],
63+
smallvec![get_value_from_integer(registry, int_ty_id, value)],
6464
)
6565
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use cairo_lang_sierra::{
88
program_registry::ProgramRegistry,
99
};
1010

11-
pub fn eval(
11+
pub fn eval_function_call(
1212
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
1313
info: &SignatureAndFunctionConcreteLibfunc,
1414
args: Vec<Value>,
@@ -21,3 +21,20 @@ pub fn eval(
2121

2222
EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect())
2323
}
24+
25+
pub fn eval_coupon_call(
26+
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
27+
info: &SignatureAndFunctionConcreteLibfunc,
28+
mut args: Vec<Value>,
29+
) -> EvalAction {
30+
// Don't check the last arg since it is not actually an argument for the function call itself
31+
assert_eq!(args.len() - 1, info.function.params.len());
32+
assert!(args
33+
.iter()
34+
.zip(&info.function.params)
35+
.all(|(value, param)| value.is(registry, &param.ty)));
36+
37+
args.pop();
38+
39+
EvalAction::FunctionCall(info.function.id.clone(), args.into_iter().collect())
40+
}

0 commit comments

Comments
 (0)