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

fix: Handle triple dereference references #1708

Merged
merged 14 commits into from
Apr 17, 2024
Next Next commit
Add outer & inner dereference
  • Loading branch information
fmoletta committed Apr 11, 2024
commit 1cba743236dae3b072ee21a3b2b8895bcec350dc
24 changes: 15 additions & 9 deletions vm/src/serde/deserialize_program.rs
Original file line number Diff line number Diff line change
@@ -323,10 +323,11 @@ pub enum OffsetValue {
#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))]
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct ValueAddress {
pub offset1: OffsetValue,
pub offset2: OffsetValue,
pub dereference: bool,
pub value_type: String,
pub offset1: OffsetValue, // A in cast(A + B, type)
pub offset2: OffsetValue, // B in cast(A + B, type)
pub outer_dereference: bool, // [] in [cast(A + B, type)]
pub inner_dereference: bool, // [] in cast([A + B], type)
pub value_type: String, // type in cast(A + B, type)
}

impl ValueAddress {
@@ -341,7 +342,8 @@ impl ValueAddress {
ValueAddress {
offset1: OffsetValue::Value(99),
offset2: OffsetValue::Value(99),
dereference: false,
outer_dereference: false,
inner_dereference: false,
value_type: String::from("felt"),
}
}
@@ -756,7 +758,8 @@ mod tests {
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -4, false),
offset2: OffsetValue::Value(0),
dereference: true,
outer_dereference: true,
inner_dereference: false,
value_type: "felt".to_string(),
},
},
@@ -769,7 +772,8 @@ mod tests {
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -3, false),
offset2: OffsetValue::Value(0),
dereference: true,
outer_dereference: true,
inner_dereference: false,
value_type: "felt".to_string(),
},
},
@@ -782,7 +786,8 @@ mod tests {
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, -3, true),
offset2: OffsetValue::Immediate(Felt252::from(2)),
dereference: false,
outer_dereference: false,
inner_dereference: false,
value_type: "felt".to_string(),
},
},
@@ -795,7 +800,8 @@ mod tests {
value_address: ValueAddress {
offset1: OffsetValue::Reference(Register::FP, 0, false),
offset2: OffsetValue::Value(0),
dereference: true,
outer_dereference: true,
inner_dereference: false,
value_type: "felt*".to_string(),
},
},
39 changes: 32 additions & 7 deletions vm/src/serde/deserialize_utils.rs
Original file line number Diff line number Diff line change
@@ -144,12 +144,16 @@ fn no_inner_dereference(input: &str) -> IResult<&str, OffsetValue> {
}

pub(crate) fn parse_value(input: &str) -> IResult<&str, ValueAddress> {
let (rem_input, (dereference, second_arg, fst_offset, snd_offset)) = tuple((
outer_brackets,
take_cast_first_arg,
opt(alt((inner_dereference, no_inner_dereference))),
opt(alt((inner_dereference, no_inner_dereference))),
))(input)?;
dbg!(&input);
let (rem_input, (outer_dereference, second_arg, inner_dereference, fst_offset, snd_offset)) =
tuple((
outer_brackets,
take_cast_first_arg,
outer_brackets,
opt(alt((inner_dereference, no_inner_dereference))),
opt(alt((inner_dereference, no_inner_dereference))),
))(input)
.unwrap();

let (indirection_level, (_, struct_)) =
tuple((tag(", "), take_till(|c: char| c == '*')))(second_arg)?;
@@ -185,7 +189,8 @@ pub(crate) fn parse_value(input: &str) -> IResult<&str, ValueAddress> {
let value_address = ValueAddress {
offset1,
offset2,
dereference,
outer_dereference,
inner_dereference,
value_type: type_,
};

@@ -633,6 +638,26 @@ mod tests {
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn parse_value_to_felt_with_triple_dereference() {
let value = "[cast([[fp + (-3)] + 5], felt*)]";
let parsed = parse_value(value);

assert_eq!(
parsed,
Ok((
"",
ValueAddress {
offset1: OffsetValue::Reference(Register::AP, 0_i32, true),
offset2: OffsetValue::Reference(Register::AP, 0_i32, true),
dereference: true,
value_type: "felt".to_string(),
}
))
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn parse_value_to_felt_with_doble_reference_and_offsets() {