use alloc::vec::Vec;
use miden_core::{FMP_ADDR, FMP_INIT_VALUE, Felt, WORD_SIZE, operations::Operation};
use crate::push_value_ops;
pub(crate) fn fmp_initialization_sequence() -> Vec<Operation> {
vec![
Operation::Push(FMP_INIT_VALUE),
Operation::Push(FMP_ADDR),
Operation::MStore,
Operation::Drop,
]
}
pub(crate) fn fmp_start_frame_sequence(num_locals: u16) -> Vec<Operation> {
let locals_frame = Felt::from_u16(num_locals.next_multiple_of(WORD_SIZE as u16));
[Operation::Push(locals_frame)]
.into_iter()
.chain(add_fmp_to_stack_top())
.chain(store_stack_top_to_fmp())
.collect()
}
pub(crate) fn fmp_end_frame_sequence(num_locals: u16) -> Vec<Operation> {
let locals_frame = Felt::from_u16(num_locals.next_multiple_of(WORD_SIZE as u16));
[Operation::Push(-locals_frame)]
.into_iter()
.chain(add_fmp_to_stack_top())
.chain(store_stack_top_to_fmp())
.collect()
}
pub(crate) fn push_offset_fmp_sequence(offset: Felt) -> Vec<Operation> {
push_value_ops(offset).into_iter().chain(add_fmp_to_stack_top()).collect()
}
fn add_fmp_to_stack_top() -> impl Iterator<Item = Operation> {
[
Operation::Push(FMP_ADDR),
Operation::MLoad,
Operation::Add,
]
.into_iter()
}
fn store_stack_top_to_fmp() -> impl Iterator<Item = Operation> {
[Operation::Push(FMP_ADDR), Operation::MStore, Operation::Drop].into_iter()
}