cairo_lang_sierra_to_casm/environment/
mod.rs

1use cairo_lang_sierra::program::StatementIdx;
2use frame_state::{FrameState, FrameStateError};
3use thiserror::Error;
4
5use self::frame_state::validate_final_frame_state;
6use self::gas_wallet::GasWallet;
7
8pub mod ap_tracking;
9pub mod frame_state;
10pub mod gas_wallet;
11
12#[derive(Error, Debug, Eq, PartialEq)]
13pub enum EnvironmentError {
14    #[error("Inconsistent ap tracking.")]
15    InconsistentApTracking,
16    #[error("Inconsistent frame state.")]
17    InconsistentFrameState,
18    #[error("Inconsistent gas wallet state.")]
19    InconsistentGasWallet,
20    #[error("{0}")]
21    InvalidFinalFrameState(FrameStateError),
22}
23
24#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum ApTrackingBase {
26    /// The base is a statement that enabled ap tracking.
27    Statement(StatementIdx),
28    /// The base is the beginning of the function.
29    FunctionStart,
30}
31
32#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub enum ApTracking {
34    Disabled,
35    Enabled {
36        /// The ap change between `base` and the current statement.
37        ap_change: usize,
38        /// The statement that enabled the ap tracking.
39        base: ApTrackingBase,
40    },
41}
42
43/// Part of the program annotations that libfuncs may access as part of their run.
44#[derive(Clone, Debug)]
45pub struct Environment {
46    /// The ap tracking information of the current statement.
47    pub ap_tracking: ApTracking,
48    /// The size of the continuous known stack.
49    pub stack_size: usize,
50    pub frame_state: FrameState,
51    pub gas_wallet: GasWallet,
52}
53impl Environment {
54    pub fn new(gas_wallet: GasWallet) -> Self {
55        Self {
56            ap_tracking: ApTracking::Enabled { ap_change: 0, base: ApTrackingBase::FunctionStart },
57            stack_size: 0,
58            frame_state: FrameState::BeforeAllocation,
59            gas_wallet,
60        }
61    }
62}
63
64// Validates that the environments match and returns appropriate error if not.
65pub fn validate_environment_equality(
66    a: &Environment,
67    b: &Environment,
68) -> Result<(), EnvironmentError> {
69    if a.ap_tracking != b.ap_tracking {
70        Err(EnvironmentError::InconsistentApTracking)
71    } else if a.frame_state != b.frame_state {
72        Err(EnvironmentError::InconsistentFrameState)
73    } else if a.gas_wallet != b.gas_wallet {
74        Err(EnvironmentError::InconsistentGasWallet)
75    } else {
76        Ok(())
77    }
78}
79
80// Validates that the state at the end of a function is valid.
81pub fn validate_final_environment(env: &Environment) -> Result<(), EnvironmentError> {
82    validate_final_frame_state(&env.frame_state).map_err(EnvironmentError::InvalidFinalFrameState)
83}