Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for subtractions contenting references as right hand side operands #1898

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#### [2.0.0-rc2] - 2024-12-12

* feat: Add support for subtractions contenting references as right hand side operands [#1898](https://github.com/lambdaclass/cairo-vm/pull/1898)

* fix: Change wildcard getrandom dependency.

* Update starknet-crypto to 0.7.3, removing the old FieldElement completly in favour of the new Felt (that is Copy).
Expand Down
7 changes: 5 additions & 2 deletions examples/custom_hint/custom_hint.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
func main() {
let a = 17;
// Use custom hint to print the value of a
alloc_locals;
local tmp = 3;
let a = 17 - tmp;

%{ print(ids.a) %}

return ();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file shouldn't be changed, right?

Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ mod tests {
fn get_ptr_from_var_name_immediate_value() {
let mut vm = vm!();
vm.segments = segments![((1, 0), (0, 0))];
let mut hint_ref = HintReference::new(0, 0, true, false);
let mut hint_ref = HintReference::new(0, 0, true, false, true);
hint_ref.offset2 = OffsetValue::Value(2);
let ids_data = HashMap::from([("imm".to_string(), hint_ref)]);

Expand Down
70 changes: 56 additions & 14 deletions vm/src/hint_processor/builtin_hint_processor/math_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2053,8 +2053,14 @@ mod tests {
//Create ids
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand Down Expand Up @@ -2131,8 +2137,14 @@ mod tests {
//Create ids_data & hint_data
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);

//Execute the hint
Expand Down Expand Up @@ -2175,8 +2187,14 @@ mod tests {
//Create ids_data & hint_data
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand Down Expand Up @@ -2213,8 +2231,14 @@ mod tests {
//Create ids_data & hint_data
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand Down Expand Up @@ -2251,8 +2275,14 @@ mod tests {
//Create ids
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand All @@ -2277,8 +2307,14 @@ mod tests {
//Create ids
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand Down Expand Up @@ -2315,8 +2351,14 @@ mod tests {
//Create ids
let ids_data = HashMap::from([
("value".to_string(), HintReference::new_simple(-4)),
("low".to_string(), HintReference::new(-3, 0, true, true)),
("high".to_string(), HintReference::new(-3, 1, true, true)),
(
"low".to_string(),
HintReference::new(-3, 0, true, true, true),
),
(
"high".to_string(),
HintReference::new(-3, 1, true, true, true),
),
]);
//Execute the hint
assert_matches!(
Expand Down
16 changes: 11 additions & 5 deletions vm/src/hint_processor/hint_processor_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct HintReference {
impl HintReference {
pub fn new_simple(offset1: i32) -> Self {
HintReference {
offset1: OffsetValue::Reference(Register::FP, offset1, false),
offset1: OffsetValue::Reference(Register::FP, offset1, false, true),
offset2: OffsetValue::Value(0),
ap_tracking_data: None,
outer_dereference: true,
Expand All @@ -121,9 +121,15 @@ impl HintReference {
}
}

pub fn new(offset1: i32, offset2: i32, inner_dereference: bool, dereference: bool) -> Self {
pub fn new(
offset1: i32,
offset2: i32,
inner_dereference: bool,
dereference: bool,
is_positive: bool,
) -> Self {
HintReference {
offset1: OffsetValue::Reference(Register::FP, offset1, inner_dereference),
offset1: OffsetValue::Reference(Register::FP, offset1, inner_dereference, is_positive),
offset2: OffsetValue::Value(offset2),
ap_tracking_data: None,
outer_dereference: dereference,
Expand All @@ -145,8 +151,8 @@ impl From<Reference> for HintReference {
&reference.value_address.offset1,
&reference.value_address.offset2,
) {
(OffsetValue::Reference(Register::AP, _, _), _)
| (_, OffsetValue::Reference(Register::AP, _, _)) => {
(OffsetValue::Reference(Register::AP, _, _, _), _)
| (_, OffsetValue::Reference(Register::AP, _, _, _)) => {
Some(reference.ap_tracking_data.clone())
}
_ => None,
Expand Down
35 changes: 20 additions & 15 deletions vm/src/hint_processor/hint_processor_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@
&hint_reference.ap_tracking_data,
ap_tracking,
)?;
let mut val = offset1.add(&offset2).ok()?;
let mut val = match hint_reference.offset2 {
OffsetValue::Reference(_, _, _, true)
| OffsetValue::Immediate(_)
| OffsetValue::Value(_) => offset1.add(&offset2).ok()?,
OffsetValue::Reference(_, _, _, false) => offset1.sub(&offset2).ok()?,

Check warning on line 77 in vm/src/hint_processor/hint_processor_utils.rs

View check run for this annotation

Codecov / codecov/patch

vm/src/hint_processor/hint_processor_utils.rs#L77

Added line #L77 was not covered by tests
};
if hint_reference.inner_dereference && hint_reference.outer_dereference {
val = vm.get_maybe(&val)?;
}
Expand Down Expand Up @@ -139,7 +144,7 @@
match offset_value {
OffsetValue::Immediate(f) => Some(f.into()),
OffsetValue::Value(v) => Some(Felt252::from(*v).into()),
OffsetValue::Reference(register, offset, deref) => {
OffsetValue::Reference(register, offset, deref, _) => {
let addr = (if matches!(register, Register::FP) {
vm.get_fp()
} else {
Expand Down Expand Up @@ -176,7 +181,7 @@
// Reference: cast(2, felt)
let mut vm = vm!();
vm.segments = segments![((1, 0), 0)];
let mut hint_ref = HintReference::new(0, 0, false, false);
let mut hint_ref = HintReference::new(0, 0, false, false, true);
hint_ref.offset1 = OffsetValue::Immediate(Felt252::from(2));

assert_eq!(
Expand All @@ -191,8 +196,8 @@
fn get_offset_value_reference_valid() {
let mut vm = vm!();
vm.segments = segments![((1, 0), 0)];
let mut hint_ref = HintReference::new(0, 0, false, true);
hint_ref.offset1 = OffsetValue::Reference(Register::FP, 2_i32, false);
let mut hint_ref = HintReference::new(0, 0, false, true, true);
hint_ref.offset1 = OffsetValue::Reference(Register::FP, 2_i32, false, true);

assert_matches!(
get_offset_value(&vm, &hint_ref.offset1, &hint_ref.ap_tracking_data, &ApTracking::new()),
Expand All @@ -205,8 +210,8 @@
fn get_offset_value_invalid() {
let mut vm = vm!();
vm.segments = segments![((1, 0), 0)];
let mut hint_ref = HintReference::new(0, 0, false, true);
hint_ref.offset1 = OffsetValue::Reference(Register::FP, -2_i32, false);
let mut hint_ref = HintReference::new(0, 0, false, true, true);
hint_ref.offset1 = OffsetValue::Reference(Register::FP, -2_i32, false, true);

assert_matches!(
get_offset_value(
Expand All @@ -228,7 +233,7 @@
assert_matches!(
get_ptr_from_reference(
&vm,
&HintReference::new(0, 0, false, false),
&HintReference::new(0, 0, false, false, true),
&ApTracking::new()
),
Ok(x) if x == relocatable!(1, 0)
Expand All @@ -244,7 +249,7 @@
assert_matches!(
get_ptr_from_reference(
&vm,
&HintReference::new(0, 0, false, true),
&HintReference::new(0, 0, false, true, true),
&ApTracking::new()
),
Ok(x) if x == relocatable!(3, 0)
Expand All @@ -256,7 +261,7 @@
fn get_ptr_from_reference_with_dereference_and_imm() {
let mut vm = vm!();
vm.segments = segments![((1, 0), (4, 0))];
let mut hint_ref = HintReference::new(0, 0, true, false);
let mut hint_ref = HintReference::new(0, 0, true, false, true);
hint_ref.offset2 = OffsetValue::Value(2);

assert_matches!(
Expand All @@ -270,7 +275,7 @@
fn compute_addr_from_reference_no_regiter_in_reference() {
let mut vm = vm!();
vm.segments = segments![((1, 0), (4, 0))];
let mut hint_reference = HintReference::new(0, 0, false, false);
let mut hint_reference = HintReference::new(0, 0, false, false, true);
hint_reference.offset1 = OffsetValue::Immediate(Felt252::from(2_i32));

assert!(compute_addr_from_reference(&hint_reference, &vm, &ApTracking::new()).is_none());
Expand All @@ -282,8 +287,8 @@
let mut vm = vm!();
vm.segments = segments![((1, 0), 4)];
// vm.run_context.fp = -1;
let mut hint_reference = HintReference::new(0, 0, false, false);
hint_reference.offset1 = OffsetValue::Reference(Register::FP, -1, true);
let mut hint_reference = HintReference::new(0, 0, false, false, true);
hint_reference.offset1 = OffsetValue::Reference(Register::FP, -1, true, true);

assert_matches!(
compute_addr_from_reference(&hint_reference, &vm, &ApTracking::new()),
Expand Down Expand Up @@ -356,7 +361,7 @@
((0, 5), 3) // [[[fp + 2] + 2]] -> [(0, 5)] -> 3
];
let hint_ref = HintReference {
offset1: OffsetValue::Reference(Register::FP, 2, true),
offset1: OffsetValue::Reference(Register::FP, 2, true, true),
offset2: OffsetValue::Value(2),
outer_dereference: true,
inner_dereference: true,
Expand All @@ -381,7 +386,7 @@
];
// [fp + 4] + (-5) = 8 - 5 = 3
let hint_ref = HintReference {
offset1: OffsetValue::Reference(Register::FP, 4, true),
offset1: OffsetValue::Reference(Register::FP, 4, true, true),
offset2: OffsetValue::Immediate(Felt252::from(-5)),
outer_dereference: false,
inner_dereference: false,
Expand Down
10 changes: 5 additions & 5 deletions vm/src/serde/deserialize_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ pub struct Reference {
pub enum OffsetValue {
Immediate(Felt252),
Value(i32),
Reference(Register, i32, bool),
Reference(Register, i32, bool, bool),
}

#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
Expand Down Expand Up @@ -714,7 +714,7 @@ mod tests {
},
pc: Some(0),
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -4, false),
offset1: OffsetValue::Reference(Register::FP, -4, false, true),
offset2: OffsetValue::Value(0),
outer_dereference: true,
inner_dereference: false,
Expand All @@ -728,7 +728,7 @@ mod tests {
},
pc: Some(0),
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -3, false),
offset1: OffsetValue::Reference(Register::FP, -3, false, true),
offset2: OffsetValue::Value(0),
outer_dereference: true,
inner_dereference: false,
Expand All @@ -742,7 +742,7 @@ mod tests {
},
pc: Some(0),
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -3, true),
offset1: OffsetValue::Reference(Register::FP, -3, true, true),
offset2: OffsetValue::Immediate(Felt252::from(2)),
outer_dereference: false,
inner_dereference: false,
Expand All @@ -756,7 +756,7 @@ mod tests {
},
pc: Some(0),
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, 0, false),
offset1: OffsetValue::Reference(Register::FP, 0, false, true),
offset2: OffsetValue::Value(0),
outer_dereference: true,
inner_dereference: false,
Expand Down
Loading
Loading