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

Document public api #1278

Closed
wants to merge 8 commits into from
Closed
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
9 changes: 6 additions & 3 deletions vm/src/vm/context/run_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ pub struct RunContext {
}

impl RunContext {
/// Returns the current value of the allocation pointer
pub fn get_ap(&self) -> Relocatable {
Relocatable::from((1, self.ap))
}
/// Returns the current value of the frame pointer
pub fn get_fp(&self) -> Relocatable {
Relocatable::from((1, self.fp))
}
/// Returns the current value of the program counter
pub fn get_pc(&self) -> Relocatable {
self.pc
}

pub fn compute_dst_addr(
pub(crate) fn compute_dst_addr(
&self,
instruction: &Instruction,
) -> Result<Relocatable, VirtualMachineError> {
Expand All @@ -41,7 +44,7 @@ impl RunContext {
}
}

pub fn compute_op0_addr(
pub(crate) fn compute_op0_addr(
&self,
instruction: &Instruction,
) -> Result<Relocatable, VirtualMachineError> {
Expand All @@ -56,7 +59,7 @@ impl RunContext {
}
}

pub fn compute_op1_addr(
pub(crate) fn compute_op1_addr(
&self,
instruction: &Instruction,
op0: Option<&MaybeRelocatable>,
Expand Down
2 changes: 1 addition & 1 deletion vm/src/vm/decoding/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
// 15|14 13 12| 11 10| 9 8 7| 6 5|4 3 2| 1| 0

/// Decodes an instruction. The encoding is little endian, so flags go from bit 63 to 48.
pub fn decode_instruction(encoded_instr: u64) -> Result<Instruction, VirtualMachineError> {
pub(crate) fn decode_instruction(encoded_instr: u64) -> Result<Instruction, VirtualMachineError> {
const HIGH_BIT: u64 = 1u64 << 63;
const DST_REG_MASK: u64 = 0x0001;
const DST_REG_OFF: u64 = 0;
Expand Down
2 changes: 1 addition & 1 deletion vm/src/vm/decoding/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod decoder;
pub(crate) mod decoder;
2 changes: 1 addition & 1 deletion vm/src/vm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod context;
pub mod decoding;
pub(crate) mod decoding;
pub mod errors;
pub mod runners;
pub mod security;
Expand Down
12 changes: 10 additions & 2 deletions vm/src/vm/runners/cairo_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl From<Vec<MaybeRelocatable>> for CairoArg {
// RunResources
// ================

/// Maintains the resources of a cairo run. Can be used across multiple runners.
/// Keeps track of the resources used by cairo run. Can be used across multiple runners.
#[derive(Clone, Default, Debug, PartialEq)]
pub struct RunResources {
n_steps: Option<usize>,
Expand All @@ -87,19 +87,23 @@ impl RunResources {
}
}

/// Returns true if the resources have been consumed
/// no more steps can be run if the resources are consumed
pub fn consumed(&self) -> bool {
if self.n_steps == Some(0) {
return true;
}
false
}

/// Consumes a single step
pub fn consume_step(&mut self) {
if let Some(n_steps) = self.n_steps {
self.n_steps = Some(n_steps.saturating_sub(1));
}
}

/// Returns the number of remaining steps
pub fn get_n_steps(&self) -> Option<usize> {
self.n_steps
}
Expand Down Expand Up @@ -167,6 +171,7 @@ impl CairoRunner {
})
}

/// Performs the full initialization step, including builtins, segments and vm
pub fn initialize(&mut self, vm: &mut VirtualMachine) -> Result<Relocatable, RunnerError> {
self.initialize_builtins(vm)?;
self.initialize_segments(vm, None);
Expand All @@ -175,6 +180,7 @@ impl CairoRunner {
Ok(end)
}

/// Initializes the builtins according to the cairo layout and program builtins
pub fn initialize_builtins(&self, vm: &mut VirtualMachine) -> Result<(), RunnerError> {
let builtin_ordered_list = vec![
BuiltinName::output,
Expand Down Expand Up @@ -335,7 +341,7 @@ impl CairoRunner {
Ok(())
}

///Creates the necessary segments for the program, execution, and each builtin on the MemorySegmentManager and stores the first adress of each of this new segments as each owner's base
/// Creates the necessary segments for the program, execution, and each builtin on the MemorySegmentManager and stores the first adress of each of this new segments as each owner's base
pub fn initialize_segments(
&mut self,
vm: &mut VirtualMachine,
Expand Down Expand Up @@ -385,6 +391,7 @@ impl CairoRunner {
Ok(())
}

/// Initializes the given function entrypoint with the given args and returns the end pc
pub fn initialize_function_entrypoint(
&mut self,
vm: &mut VirtualMachine,
Expand Down Expand Up @@ -472,6 +479,7 @@ impl CairoRunner {
}
}

// Initializes the vm's run_context and validation rules, validates the existing memory
pub fn initialize_vm(&mut self, vm: &mut VirtualMachine) -> Result<(), RunnerError> {
vm.run_context.pc = *self.initial_pc.as_ref().ok_or(RunnerError::NoPC)?;
vm.run_context.ap = self.initial_ap.as_ref().ok_or(RunnerError::NoAP)?.offset;
Expand Down
63 changes: 45 additions & 18 deletions vm/src/vm/vm_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ use super::runners::cairo_runner::RunResources;
const MAX_TRACEBACK_ENTRIES: u32 = 20;

#[derive(PartialEq, Eq, Debug)]
pub struct Operands {
struct Operands {
dst: MaybeRelocatable,
res: Option<MaybeRelocatable>,
op0: MaybeRelocatable,
op1: MaybeRelocatable,
}

#[derive(PartialEq, Eq, Debug)]
pub struct OperandsAddresses {
struct OperandsAddresses {
dst_addr: Relocatable,
op0_addr: Relocatable,
op1_addr: Relocatable,
}

#[derive(Default, Debug, Clone, Copy)]
pub struct DeducedOperands(u8);
struct DeducedOperands(u8);

impl DeducedOperands {
fn set_dst(&mut self, value: bool) {
Expand Down Expand Up @@ -118,6 +118,7 @@ impl VirtualMachine {
}
}

#[doc(hidden)]
pub fn compute_segments_effective_sizes(&mut self) {
self.segments.compute_effective_sizes();
}
Expand Down Expand Up @@ -443,6 +444,7 @@ impl VirtualMachine {
decode_instruction(instruction)
}

#[doc(hidden)]
pub fn step_hint(
&mut self,
hint_executor: &mut dyn HintProcessor,
Expand All @@ -461,6 +463,7 @@ impl VirtualMachine {
Ok(())
}

#[doc(hidden)]
pub fn step_instruction(&mut self) -> Result<(), VirtualMachineError> {
let pc = self.run_context.pc.offset;

Expand All @@ -482,6 +485,7 @@ impl VirtualMachine {
Ok(())
}

/// Executes the hints at the current pc + the next cairo instruction
pub fn step(
&mut self,
hint_executor: &mut dyn HintProcessor,
Expand Down Expand Up @@ -578,9 +582,9 @@ impl VirtualMachine {
Ok(dst)
}

/// Compute operands and result, trying to deduce them if normal memory access returns a None
/// value.
pub fn compute_operands(
//Compute operands and result, trying to deduce them if normal memory access returns a None
// value.
fn compute_operands(
&self,
instruction: &Instruction,
) -> Result<(Operands, OperandsAddresses, DeducedOperands), VirtualMachineError> {
Expand Down Expand Up @@ -669,8 +673,8 @@ impl VirtualMachine {
Ok(())
}

//Makes sure that the value at the given address is consistent with the auto deduction rules.
pub fn verify_auto_deductions_for_addr(
// Makes sure that the value at the given address is consistent with the auto deduction rules.
pub(crate) fn verify_auto_deductions_for_addr(
&self,
addr: Relocatable,
builtin: &BuiltinRunner,
Expand Down Expand Up @@ -702,6 +706,8 @@ impl VirtualMachine {
}
}

/// Marks the memory addresses from base to base + len as accessed
/// Accessed addresses are accounted for when calculating memory holes
pub fn mark_address_range_as_accessed(
&mut self,
base: Relocatable,
Expand Down Expand Up @@ -773,52 +779,55 @@ impl VirtualMachine {
entries
}

///Adds a new segment and to the memory and returns its starting location as a Relocatable value.
/// Adds a new segment to the memory and returns its starting location as a Relocatable value.
pub fn add_memory_segment(&mut self) -> Relocatable {
self.segments.add()
}

/// Returns the current value of the allocation pointer
pub fn get_ap(&self) -> Relocatable {
self.run_context.get_ap()
}

/// Returns the current value of the frame pointer
pub fn get_fp(&self) -> Relocatable {
self.run_context.get_fp()
}

/// Returns the current value of the program counter
pub fn get_pc(&self) -> Relocatable {
self.run_context.get_pc()
}

///Gets the integer value corresponding to the Relocatable address
/// Gets the felt value stored in the memory address indicated by `key`
pub fn get_integer(&self, key: Relocatable) -> Result<Cow<Felt252>, MemoryError> {
self.segments.memory.get_integer(key)
}

///Gets the relocatable value corresponding to the Relocatable address
/// Gets the relocatable value stored in the memory address indicated by `key`
pub fn get_relocatable(&self, key: Relocatable) -> Result<Relocatable, MemoryError> {
self.segments.memory.get_relocatable(key)
}

///Gets a MaybeRelocatable value from memory indicated by a generic address
/// Gets the MaybeRelocatable value from memory indicated by a generic address
pub fn get_maybe<'a, 'b: 'a, K: 'a>(&'b self, key: &'a K) -> Option<MaybeRelocatable>
where
Relocatable: TryFrom<&'a K>,
{
self.segments.memory.get(key).map(|x| x.into_owned())
}

/// Returns a reference to the vector with all builtins present in the virtual machine
/// Returns a reference to the vector with all builtin runners present in the VM
pub fn get_builtin_runners(&self) -> &Vec<BuiltinRunner> {
&self.builtin_runners
}

/// Returns a mutable reference to the vector with all builtins present in the virtual machine
/// Returns a mutable reference to the vector with all builtins present in the VM
pub fn get_builtin_runners_as_mut(&mut self) -> &mut Vec<BuiltinRunner> {
&mut self.builtin_runners
}

///Inserts a value into a memory address given by a Relocatable value
/// Inserts a value into a memory address given by a Relocatable value
pub fn insert_value<T: Into<MaybeRelocatable>>(
&mut self,
key: Relocatable,
Expand All @@ -827,7 +836,7 @@ impl VirtualMachine {
self.segments.memory.insert_value(key, val)
}

///Writes data into the memory from address ptr and returns the first address after the data.
/// Writes data into the memory from address ptr and returns the first address after the data.
pub fn load_data(
&mut self,
ptr: Relocatable,
Expand All @@ -848,10 +857,12 @@ impl VirtualMachine {
self.segments.write_arg(ptr, arg)
}

/// Compares the memory at two ranges indicated by their base and length
pub fn memcmp(&self, lhs: Relocatable, rhs: Relocatable, len: usize) -> (Ordering, usize) {
self.segments.memory.memcmp(lhs, rhs, len)
}

/// Checks if the memory at two ranges indicated by their base and length is equal
pub fn mem_eq(&self, lhs: Relocatable, rhs: Relocatable, len: usize) -> bool {
self.segments.memory.mem_eq(lhs, rhs, len)
}
Expand Down Expand Up @@ -886,6 +897,8 @@ impl VirtualMachine {
self.segments.memory.get_integer_range(addr, size)
}

#[doc(hidden)]
// Returns a reference to the range_check builtin if present
pub fn get_range_check_builtin(&self) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> {
for builtin in &self.builtin_runners {
if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin {
Expand All @@ -895,6 +908,8 @@ impl VirtualMachine {
Err(VirtualMachineError::NoRangeCheckBuiltin)
}

#[doc(hidden)]
// Returns a reference to the signature builtin if present
pub fn get_signature_builtin(
&mut self,
) -> Result<&mut SignatureBuiltinRunner, VirtualMachineError> {
Expand All @@ -906,6 +921,8 @@ impl VirtualMachine {

Err(VirtualMachineError::NoSignatureBuiltin)
}

#[doc(hidden)]
pub fn disable_trace(&mut self) {
self.trace = None
}
Expand All @@ -930,19 +947,24 @@ impl VirtualMachine {
self.run_context.set_pc(pc)
}

/// Returns the size of a memory segment indicated by its index
pub fn get_segment_used_size(&self, index: usize) -> Option<usize> {
self.segments.get_segment_used_size(index)
}

/// Returns the finalized size of a given segment. If the segment has not been finalized,
/// returns its used size.
pub fn get_segment_size(&self, index: usize) -> Option<usize> {
self.segments.get_segment_size(index)
}

/// Adds a new temporary segment to the memory and returns its starting location as a Relocatable value.
/// temporary segments have a negative index and are not present in the relocated memory unless a relocation rule is added for that segment
pub fn add_temporary_segment(&mut self) -> Relocatable {
self.segments.add_temporary_segment()
}

/// Add a new relocation rule.
/// Adds a new relocation rule.
///
/// Will return an error if any of the following conditions are not met:
/// - Source address's segment must be negative (temporary).
Expand All @@ -956,6 +978,9 @@ impl VirtualMachine {
self.segments.memory.add_relocation_rule(src_ptr, dst_ptr)
}

/// Converts args to Cairo-friendly ones.
/// Currently accepts only `MaybeRelocatable`, `Vec<MaybeRelocatable` and `Vec<Relocatable>`, other inputs will fail
/// If an argument is a `Vec`, it is written into a new memory segment and it's base is returned
pub fn gen_arg(&mut self, arg: &dyn Any) -> Result<MaybeRelocatable, MemoryError> {
self.segments.gen_arg(arg)
}
Expand Down Expand Up @@ -997,7 +1022,7 @@ impl VirtualMachine {
Ok(())
}

///Relocates the VM's trace, turning relocatable registers to numbered ones
/// Relocates the VM's trace, turning relocatable registers to numbered ones
pub fn relocate_trace(&mut self, relocation_table: &[usize]) -> Result<(), TraceError> {
if let Some(ref mut trace) = self.trace {
if self.trace_relocated {
Expand All @@ -1017,6 +1042,8 @@ impl VirtualMachine {
Ok(())
}

/// Returns the relocated trace
/// Fails if the trace has not been relocated
pub fn get_relocated_trace(&self) -> Result<&Vec<TraceEntry>, TraceError> {
if self.trace_relocated {
self.trace.as_ref().ok_or(TraceError::TraceNotEnabled)
Expand Down
3 changes: 3 additions & 0 deletions vm/src/vm/vm_memory/memory_segments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ impl MemorySegmentManager {
Ok(relocation_table)
}

/// Converts args to Cairo-friendly ones.
/// Currently accepts only `MaybeRelocatable`, `Vec<MaybeRelocatable` and `Vec<Relocatable>`, other inputs will fail
/// If an argument is a `Vec`, it is written into a new memory segment and it's base is returned
pub fn gen_arg(&mut self, arg: &dyn Any) -> Result<MaybeRelocatable, MemoryError> {
if let Some(value) = arg.downcast_ref::<MaybeRelocatable>() {
Ok(value.clone())
Expand Down