Skip to content

Commit 255bc69

Browse files
committed
Merge branch 'main' of github.com:lambdaclass/cairo-rs-py into dict-manager
2 parents 525c200 + 207bbbf commit 255bc69

File tree

3 files changed

+166
-2
lines changed

3 files changed

+166
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ default = ["pyo3/num-bigint", "pyo3/auto-initialize"]
1313

1414
[dependencies]
1515
pyo3 = { version = "0.16.5" }
16-
cairo-rs = { git = "https://github.com/lambdaclass/cairo-rs.git", rev = "8c47dda53e874545895b34d675be6254878a9e7b" }
16+
cairo-rs = { git = "https://github.com/lambdaclass/cairo-rs.git", rev = "2ddf78e20cc25e660263a0c9c1b942780d95a0e6" }
1717
num-bigint = "0.4"
1818
lazy_static = "1.4.0"
1919

src/cairo_runner.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,13 @@ impl PyCairoRunner {
541541
.collect::<Vec<_>>()
542542
.to_object(py))
543543
}
544+
545+
/// Add (or replace if already present) a custom hash builtin.
546+
/// Returns a Relocatable with the new hash builtin base.
547+
pub fn add_additional_hash_builtin(&self) -> PyRelocatable {
548+
let mut vm = (*self.pyvm.vm).borrow_mut();
549+
self.inner.add_additional_hash_builtin(&mut vm).into()
550+
}
544551
}
545552

546553
#[pyclass]
@@ -1221,6 +1228,10 @@ mod test {
12211228
segment_index: 6,
12221229
offset: 0,
12231230
})],
1231+
vec![RelocatableValue(PyRelocatable {
1232+
segment_index: 7,
1233+
offset: 0,
1234+
})],
12241235
];
12251236

12261237
Python::with_gil(|py| {
@@ -1522,4 +1533,43 @@ mod test {
15221533
);
15231534
});
15241535
}
1536+
1537+
/// Test that add_additional_hash_builtin() returns successfully.
1538+
#[test]
1539+
fn add_additional_hash_builtin() {
1540+
Python::with_gil(|_| {
1541+
let program = fs::read_to_string("cairo_programs/fibonacci.json").unwrap();
1542+
let runner = PyCairoRunner::new(
1543+
program,
1544+
Some("main".to_string()),
1545+
Some("small".to_string()),
1546+
false,
1547+
)
1548+
.unwrap();
1549+
1550+
let expected_relocatable = PyRelocatable {
1551+
segment_index: 0,
1552+
offset: 0,
1553+
};
1554+
let relocatable = runner.add_additional_hash_builtin();
1555+
assert_eq!(expected_relocatable, relocatable);
1556+
1557+
assert_eq!(
1558+
(*runner.pyvm.vm)
1559+
.borrow()
1560+
.get_builtin_runners()
1561+
.last()
1562+
.map(|(key, _)| key.as_str()),
1563+
Some("hash_builtin"),
1564+
);
1565+
1566+
let mut vm = (*runner.pyvm.vm).borrow_mut();
1567+
// Check that the segment exists by writing to it.
1568+
vm.insert_value(
1569+
&Relocatable::from((0, 0)),
1570+
MaybeRelocatable::Int(bigint!(42)),
1571+
)
1572+
.expect("memory insert failed");
1573+
});
1574+
}
15251575
}

src/memory.rs

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
use crate::{
22
relocatable::{PyMaybeRelocatable, PyRelocatable},
3+
utils::to_py_error,
34
vm_core::PyVM,
45
};
56
use cairo_rs::{
67
types::relocatable::{MaybeRelocatable, Relocatable},
78
vm::vm_core::VirtualMachine,
89
};
10+
use num_bigint::BigInt;
911
use pyo3::{
1012
exceptions::{PyTypeError, PyValueError},
1113
prelude::*,
1214
};
13-
use std::{cell::RefCell, rc::Rc};
15+
use std::{borrow::Cow, cell::RefCell, rc::Rc};
1416

1517
const MEMORY_GET_ERROR_MSG: &str = "Failed to get value from Cairo memory";
1618
const MEMORY_SET_ERROR_MSG: &str = "Failed to set value to Cairo memory";
@@ -69,6 +71,18 @@ impl PyMemory {
6971
.collect::<Vec<PyMaybeRelocatable>>()
7072
.to_object(py))
7173
}
74+
75+
/// Return a continuous section of memory as a vector of integers.
76+
pub fn get_range_as_ints(&self, addr: PyRelocatable, size: usize) -> PyResult<Vec<BigInt>> {
77+
Ok(self
78+
.vm
79+
.borrow()
80+
.get_integer_range(&Relocatable::from(&addr), size)
81+
.map_err(to_py_error)?
82+
.into_iter()
83+
.map(Cow::into_owned)
84+
.collect())
85+
}
7286
}
7387

7488
#[cfg(test)]
@@ -282,4 +296,104 @@ assert memory[ap] == fp
282296
assert_eq!(range.unwrap_err(), expected_error);
283297
});
284298
}
299+
300+
// Test that get_range_as_ints() works as intended.
301+
#[test]
302+
fn get_range_as_ints() {
303+
let vm = PyVM::new(
304+
BigInt::new(Sign::Plus, vec![1, 0, 0, 0, 0, 0, 17, 134217728]),
305+
false,
306+
);
307+
let memory = PyMemory::new(&vm);
308+
309+
let addr = {
310+
let mut vm = vm.vm.borrow_mut();
311+
let addr = vm.add_memory_segment();
312+
313+
vm.load_data(
314+
&MaybeRelocatable::from(&addr),
315+
vec![
316+
bigint!(1).into(),
317+
bigint!(2).into(),
318+
bigint!(3).into(),
319+
bigint!(4).into(),
320+
],
321+
)
322+
.expect("memory insertion failed");
323+
324+
addr
325+
};
326+
327+
assert_eq!(
328+
memory
329+
.get_range_as_ints(addr.into(), 4)
330+
.expect("get_range_as_ints() failed"),
331+
vec![bigint!(1), bigint!(2), bigint!(3), bigint!(4)],
332+
);
333+
}
334+
335+
// Test that get_range_as_ints() fails when not all values are integers.
336+
#[test]
337+
fn get_range_as_ints_mixed() {
338+
let vm = PyVM::new(
339+
BigInt::new(Sign::Plus, vec![1, 0, 0, 0, 0, 0, 17, 134217728]),
340+
false,
341+
);
342+
let memory = PyMemory::new(&vm);
343+
344+
let addr = {
345+
let mut vm = vm.vm.borrow_mut();
346+
let addr = vm.add_memory_segment();
347+
348+
vm.load_data(
349+
&MaybeRelocatable::from(&addr),
350+
vec![
351+
bigint!(1).into(),
352+
bigint!(2).into(),
353+
MaybeRelocatable::RelocatableValue((1, 2).into()),
354+
bigint!(4).into(),
355+
],
356+
)
357+
.expect("memory insertion failed");
358+
359+
addr
360+
};
361+
362+
memory
363+
.get_range_as_ints(addr.into(), 4)
364+
.expect_err("get_range_as_ints() succeeded (should have failed)");
365+
}
366+
367+
// Test that get_range_as_ints() fails when the requested range is larger than the available
368+
// segments.
369+
#[test]
370+
fn get_range_as_ints_incomplete() {
371+
let vm = PyVM::new(
372+
BigInt::new(Sign::Plus, vec![1, 0, 0, 0, 0, 0, 17, 134217728]),
373+
false,
374+
);
375+
let memory = PyMemory::new(&vm);
376+
377+
let addr = {
378+
let mut vm = vm.vm.borrow_mut();
379+
let addr = vm.add_memory_segment();
380+
381+
vm.load_data(
382+
&MaybeRelocatable::from(&addr),
383+
vec![
384+
bigint!(1).into(),
385+
bigint!(2).into(),
386+
bigint!(3).into(),
387+
bigint!(4).into(),
388+
],
389+
)
390+
.expect("memory insertion failed");
391+
392+
addr
393+
};
394+
395+
memory
396+
.get_range_as_ints(addr.into(), 8)
397+
.expect_err("get_range_as_ints() succeeded (should have failed)");
398+
}
285399
}

0 commit comments

Comments
 (0)