Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

AllocConstantSize hint #415

Merged
merged 14 commits into from
Apr 27, 2023
62 changes: 46 additions & 16 deletions crates/cairo-1-hint-processor/src/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ use cairo_rs::{
};
use felt::Felt252;
use num_integer::Integer;
use num_traits::identities::Zero;
use num_traits::{identities::Zero, ToPrimitive};
use std::{collections::HashMap, ops::Mul};

/// HintProcessor for Cairo 1 compiler hints.
struct Cairo1HintProcessor {}

/// Execution scope for constant memory allocation.
struct MemoryExecScope {
/// The first free address in the segment.
next_address: Relocatable,
}

fn cell_ref_to_relocatable(cell_ref: &CellRef, vm: &VirtualMachine) -> Relocatable {
let base = match cell_ref.register {
Register::AP => vm.get_ap(),
Expand Down Expand Up @@ -101,21 +107,6 @@ impl Cairo1HintProcessor {
.map_err(HintError::from)
}

fn square_root(
&self,
vm: &mut VirtualMachine,
value: &ResOperand,
dst: &CellRef,
) -> Result<(), HintError> {
let value = res_operand_get_val(vm, value)?;
let result = value.sqrt();
vm.insert_value(
cell_ref_to_relocatable(dst, vm),
MaybeRelocatable::from(result),
)
.map_err(HintError::from)
}

fn test_less_than_or_equal(
&self,
vm: &mut VirtualMachine,
Expand Down Expand Up @@ -262,6 +253,39 @@ impl Cairo1HintProcessor {

Ok(())
}

fn alloc_constant_size(
&self,
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
size: &ResOperand,
dst: &CellRef,
) -> Result<(), HintError> {
let object_size = res_operand_get_val(vm, size)?
.to_usize()
.expect("Object size too large.");
let memory_exec_scope =
match exec_scopes.get_mut_ref::<MemoryExecScope>("memory_exec_scope") {
Ok(memory_exec_scope) => memory_exec_scope,
Err(_) => {
exec_scopes.assign_or_update_variable(
"memory_exec_scope",
Box::new(MemoryExecScope {
next_address: vm.add_memory_segment(),
}),
);
exec_scopes.get_mut_ref::<MemoryExecScope>("memory_exec_scope")?
}
};

vm.insert_value(
cell_ref_to_relocatable(dst, vm),
memory_exec_scope.next_address,
)?;

memory_exec_scope.next_address.offset += object_size;
Ok(())
}
}

impl HintProcessor for Cairo1HintProcessor {
Expand All @@ -281,7 +305,13 @@ impl HintProcessor for Cairo1HintProcessor {
let hint = hint_data.downcast_ref::<Hint>().unwrap();
match hint {
Hint::AllocSegment { dst } => self.alloc_segment(vm, dst),
Hint::AllocConstantSize { size, dst } => {
self.alloc_constant_size(vm, exec_scopes, size, dst)
}
Hint::TestLessThan { lhs, rhs, dst } => self.test_less_than(vm, lhs, rhs, dst),
Hint::TestLessThanOrEqual { lhs, rhs, dst } => {
self.test_less_than_or_equal(vm, lhs, rhs, dst)
}
Hint::SquareRoot { value, dst } => self.square_root(vm, value, dst),
Hint::TestLessThanOrEqual { lhs, rhs, dst } => {
self.test_less_than_or_equal(vm, lhs, rhs, dst)
Expand Down