Skip to content

Commit 4b17118

Browse files
authored
Remove unsafe impl of Add<usize> for &'a Relocatable (#1718)
* Remove unsafe impl of `Add<usize> for &Relocatable` * Add changelog entry * Add error handling to RelocateValue trait
1 parent b05b541 commit 4b17118

File tree

5 files changed

+75
-69
lines changed

5 files changed

+75
-69
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#### Upcoming Changes
44

5+
* fix(BREAKING): Remove unsafe impl of `Add<usize> for &'a Relocatable`[#1718](https://github.com/lambdaclass/cairo-vm/pull/1718)
6+
57
* fix(BREAKING): Handle triple dereference references[#1708](https://github.com/lambdaclass/cairo-vm/pull/1708)
68
* Replace `ValueAddress` boolean field `dereference` with boolean fields `outer_dereference` & `inner_dereference`
79
* Replace `HintReference` boolean field `dereference` with boolean fields `outer_dereference` & `inner_dereference`

vm/src/types/relocatable.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,6 @@ impl MaybeRelocatable {
356356
}
357357
}
358358

359-
impl<'a> Add<usize> for &'a Relocatable {
360-
type Output = Relocatable;
361-
362-
fn add(self, other: usize) -> Self::Output {
363-
Relocatable {
364-
segment_index: self.segment_index,
365-
offset: self.offset + other,
366-
}
367-
}
368-
}
369-
370359
/// Turns a MaybeRelocatable into a Felt252 value.
371360
/// If the value is an Int, it will extract the Felt252 value from it.
372361
/// If the value is RelocatableValue, it will relocate it according to the relocation_table

vm/src/vm/runners/builtin_runner/signature.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,12 @@ impl SignatureBuiltinRunner {
183183
pub fn air_private_input(&self, memory: &Memory) -> Vec<PrivateInput> {
184184
let mut private_inputs = vec![];
185185
for (addr, signature) in self.signatures.borrow().iter() {
186-
if let (Ok(pubkey), Ok(msg)) = (memory.get_integer(*addr), memory.get_integer(addr + 1))
187-
{
186+
if let (Ok(pubkey), Some(msg)) = (
187+
memory.get_integer(*addr),
188+
(*addr + 1_usize)
189+
.ok()
190+
.and_then(|addr| memory.get_integer(addr).ok()),
191+
) {
188192
private_inputs.push(PrivateInput::Signature(PrivateInputSignature {
189193
index: addr
190194
.offset

vm/src/vm/runners/cairo_runner.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,7 @@ impl CairoRunner {
568568
} else {
569569
let mut stack_prefix = vec![
570570
Into::<MaybeRelocatable>::into(
571-
self.execution_base
572-
.as_ref()
573-
.ok_or(RunnerError::NoExecBase)?
574-
+ target_offset,
571+
(self.execution_base.ok_or(RunnerError::NoExecBase)? + target_offset)?,
575572
),
576573
MaybeRelocatable::from(Felt252::zero()),
577574
];
@@ -589,20 +586,16 @@ impl CairoRunner {
589586
)?;
590587
}
591588

592-
self.initial_fp = Some(
593-
self.execution_base
594-
.as_ref()
595-
.ok_or(RunnerError::NoExecBase)?
596-
+ target_offset,
597-
);
589+
self.initial_fp =
590+
Some((self.execution_base.ok_or(RunnerError::NoExecBase)? + target_offset)?);
598591

599592
self.initial_ap = self.initial_fp;
600-
return Ok(self.program_base.as_ref().ok_or(RunnerError::NoProgBase)?
593+
return Ok((self.program_base.ok_or(RunnerError::NoProgBase)?
601594
+ self
602595
.program
603596
.shared_program_data
604597
.end
605-
.ok_or(RunnerError::NoProgramEnd)?);
598+
.ok_or(RunnerError::NoProgramEnd)?)?);
606599
}
607600

608601
let return_fp = vm.segments.add();

vm/src/vm/vm_memory/memory.rs

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -178,24 +178,23 @@ impl Memory {
178178
&self.data
179179
};
180180
let (i, j) = from_relocatable_to_indexes(relocatable);
181-
Some(self.relocate_value(data.get(i)?.get(j)?.as_ref()?.get_value()))
181+
self.relocate_value(data.get(i)?.get(j)?.as_ref()?.get_value())
182+
.ok()
182183
}
183184

184185
// Version of Memory.relocate_value() that doesn't require a self reference
185186
fn relocate_address(
186187
addr: Relocatable,
187188
relocation_rules: &HashMap<usize, Relocatable>,
188-
) -> MaybeRelocatable {
189-
let segment_idx = addr.segment_index;
190-
if segment_idx >= 0 {
191-
return addr.into();
192-
}
193-
194-
// Adjust the segment index to begin at zero, as per the struct field's
195-
match relocation_rules.get(&(-(segment_idx + 1) as usize)) {
196-
Some(x) => (x + addr.offset).into(),
197-
None => addr.into(),
189+
) -> Result<MaybeRelocatable, MemoryError> {
190+
if addr.segment_index < 0 {
191+
// Adjust the segment index to begin at zero, as per the struct field's
192+
// comment.
193+
if let Some(x) = relocation_rules.get(&(-(addr.segment_index + 1) as usize)) {
194+
return Ok((*x + addr.offset)?.into());
195+
}
198196
}
197+
Ok(addr.into())
199198
}
200199

201200
/// Relocates the memory according to the relocation rules and clears `self.relocaction_rules`.
@@ -209,7 +208,7 @@ impl Memory {
209208
let value = cell.get_value_mut();
210209
match value {
211210
MaybeRelocatable::RelocatableValue(addr) if addr.segment_index < 0 => {
212-
*value = Memory::relocate_address(*addr, &self.relocation_rules);
211+
*value = Memory::relocate_address(*addr, &self.relocation_rules)?;
213212
}
214213
_ => {}
215214
}
@@ -581,39 +580,42 @@ impl fmt::Display for Memory {
581580

582581
/// Applies `relocation_rules` to a value
583582
pub(crate) trait RelocateValue<'a, Input: 'a, Output: 'a> {
584-
fn relocate_value(&self, value: Input) -> Output;
583+
fn relocate_value(&self, value: Input) -> Result<Output, MemoryError>;
585584
}
586585

587586
impl RelocateValue<'_, Relocatable, Relocatable> for Memory {
588-
fn relocate_value(&self, addr: Relocatable) -> Relocatable {
589-
let segment_idx = addr.segment_index;
590-
if segment_idx >= 0 {
591-
return addr;
592-
}
593-
594-
// Adjust the segment index to begin at zero, as per the struct field's
595-
// comment.
596-
match self.relocation_rules.get(&(-(segment_idx + 1) as usize)) {
597-
Some(x) => x + addr.offset,
598-
None => addr,
587+
fn relocate_value(&self, addr: Relocatable) -> Result<Relocatable, MemoryError> {
588+
if addr.segment_index < 0 {
589+
// Adjust the segment index to begin at zero, as per the struct field's
590+
// comment.
591+
if let Some(x) = self
592+
.relocation_rules
593+
.get(&(-(addr.segment_index + 1) as usize))
594+
{
595+
return (*x + addr.offset).map_err(MemoryError::Math);
596+
}
599597
}
598+
Ok(addr)
600599
}
601600
}
602601

603602
impl<'a> RelocateValue<'a, &'a Felt252, &'a Felt252> for Memory {
604-
fn relocate_value(&self, value: &'a Felt252) -> &'a Felt252 {
605-
value
603+
fn relocate_value(&self, value: &'a Felt252) -> Result<&'a Felt252, MemoryError> {
604+
Ok(value)
606605
}
607606
}
608607

609608
impl<'a> RelocateValue<'a, &'a MaybeRelocatable, Cow<'a, MaybeRelocatable>> for Memory {
610-
fn relocate_value(&self, value: &'a MaybeRelocatable) -> Cow<'a, MaybeRelocatable> {
611-
match value {
609+
fn relocate_value(
610+
&self,
611+
value: &'a MaybeRelocatable,
612+
) -> Result<Cow<'a, MaybeRelocatable>, MemoryError> {
613+
Ok(match value {
612614
MaybeRelocatable::Int(_) => Cow::Borrowed(value),
613615
MaybeRelocatable::RelocatableValue(addr) => {
614-
Cow::Owned(self.relocate_value(*addr).into())
616+
Cow::Owned(self.relocate_value(*addr)?.into())
615617
}
616-
}
618+
})
617619
}
618620
}
619621

@@ -1043,7 +1045,9 @@ mod memory_tests {
10431045

10441046
// Test when value is Some(BigInt):
10451047
assert_eq!(
1046-
memory.relocate_value(&MaybeRelocatable::Int(Felt252::from(0))),
1048+
memory
1049+
.relocate_value(&MaybeRelocatable::Int(Felt252::from(0)))
1050+
.unwrap(),
10471051
Cow::Owned(MaybeRelocatable::Int(Felt252::from(0))),
10481052
);
10491053
}
@@ -1061,11 +1065,15 @@ mod memory_tests {
10611065

10621066
// Test when value is Some(MaybeRelocatable) with segment_index >= 0:
10631067
assert_eq!(
1064-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((0, 0).into())),
1068+
memory
1069+
.relocate_value(&MaybeRelocatable::RelocatableValue((0, 0).into()))
1070+
.unwrap(),
10651071
Cow::Owned(MaybeRelocatable::RelocatableValue((0, 0).into())),
10661072
);
10671073
assert_eq!(
1068-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((5, 0).into())),
1074+
memory
1075+
.relocate_value(&MaybeRelocatable::RelocatableValue((5, 0).into()))
1076+
.unwrap(),
10691077
Cow::Owned(MaybeRelocatable::RelocatableValue((5, 0).into())),
10701078
);
10711079
}
@@ -1084,7 +1092,9 @@ mod memory_tests {
10841092
// Test when value is Some(MaybeRelocatable) with segment_index < 0 and
10851093
// there are no applicable relocation rules:
10861094
assert_eq!(
1087-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((-5, 0).into())),
1095+
memory
1096+
.relocate_value(&MaybeRelocatable::RelocatableValue((-5, 0).into()))
1097+
.unwrap(),
10881098
Cow::Owned(MaybeRelocatable::RelocatableValue((-5, 0).into())),
10891099
);
10901100
}
@@ -1103,19 +1113,27 @@ mod memory_tests {
11031113
// Test when value is Some(MaybeRelocatable) with segment_index < 0 and
11041114
// there are applicable relocation rules:
11051115
assert_eq!(
1106-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((-1, 0).into())),
1116+
memory
1117+
.relocate_value(&MaybeRelocatable::RelocatableValue((-1, 0).into()))
1118+
.unwrap(),
11071119
Cow::Owned(MaybeRelocatable::RelocatableValue((2, 0).into())),
11081120
);
11091121
assert_eq!(
1110-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((-2, 0).into())),
1122+
memory
1123+
.relocate_value(&MaybeRelocatable::RelocatableValue((-2, 0).into()))
1124+
.unwrap(),
11111125
Cow::Owned(MaybeRelocatable::RelocatableValue((2, 2).into())),
11121126
);
11131127
assert_eq!(
1114-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((-1, 5).into())),
1128+
memory
1129+
.relocate_value(&MaybeRelocatable::RelocatableValue((-1, 5).into()))
1130+
.unwrap(),
11151131
Cow::Owned(MaybeRelocatable::RelocatableValue((2, 5).into())),
11161132
);
11171133
assert_eq!(
1118-
memory.relocate_value(&MaybeRelocatable::RelocatableValue((-2, 5).into())),
1134+
memory
1135+
.relocate_value(&MaybeRelocatable::RelocatableValue((-2, 5).into()))
1136+
.unwrap(),
11191137
Cow::Owned(MaybeRelocatable::RelocatableValue((2, 7).into())),
11201138
);
11211139
}
@@ -1498,11 +1516,11 @@ mod memory_tests {
14981516
.unwrap();
14991517

15001518
assert_eq!(
1501-
Memory::relocate_address((-1, 0).into(), &memory.relocation_rules),
1519+
Memory::relocate_address((-1, 0).into(), &memory.relocation_rules).unwrap(),
15021520
MaybeRelocatable::RelocatableValue((2, 0).into()),
15031521
);
15041522
assert_eq!(
1505-
Memory::relocate_address((-2, 1).into(), &memory.relocation_rules),
1523+
Memory::relocate_address((-2, 1).into(), &memory.relocation_rules).unwrap(),
15061524
MaybeRelocatable::RelocatableValue((2, 3).into()),
15071525
);
15081526
}
@@ -1512,11 +1530,11 @@ mod memory_tests {
15121530
fn relocate_address_no_rules() {
15131531
let memory = Memory::new();
15141532
assert_eq!(
1515-
Memory::relocate_address((-1, 0).into(), &memory.relocation_rules),
1533+
Memory::relocate_address((-1, 0).into(), &memory.relocation_rules).unwrap(),
15161534
MaybeRelocatable::RelocatableValue((-1, 0).into()),
15171535
);
15181536
assert_eq!(
1519-
Memory::relocate_address((-2, 1).into(), &memory.relocation_rules),
1537+
Memory::relocate_address((-2, 1).into(), &memory.relocation_rules).unwrap(),
15201538
MaybeRelocatable::RelocatableValue((-2, 1).into()),
15211539
);
15221540
}
@@ -1526,11 +1544,11 @@ mod memory_tests {
15261544
fn relocate_address_real_addr() {
15271545
let memory = Memory::new();
15281546
assert_eq!(
1529-
Memory::relocate_address((1, 0).into(), &memory.relocation_rules),
1547+
Memory::relocate_address((1, 0).into(), &memory.relocation_rules).unwrap(),
15301548
MaybeRelocatable::RelocatableValue((1, 0).into()),
15311549
);
15321550
assert_eq!(
1533-
Memory::relocate_address((1, 1).into(), &memory.relocation_rules),
1551+
Memory::relocate_address((1, 1).into(), &memory.relocation_rules).unwrap(),
15341552
MaybeRelocatable::RelocatableValue((1, 1).into()),
15351553
);
15361554
}

0 commit comments

Comments
 (0)