use alloc::vec::Vec;
use miden_air::Felt;
use miden_core::{Word, ZERO};
use crate::ContextId;
#[derive(Debug, Default, Clone)]
pub struct BlockStack {
blocks: Vec<BlockInfo>,
}
impl BlockStack {
pub fn push(&mut self, addr: Felt, ctx_info: Option<ExecutionContextInfo>) -> Felt {
let parent_addr = match self.blocks.last() {
Some(parent) => parent.addr,
None => ZERO,
};
self.blocks.push(BlockInfo { addr, parent_addr, ctx_info });
parent_addr
}
pub fn pop(&mut self) -> BlockInfo {
self.blocks.pop().expect("block stack is empty")
}
pub fn is_empty(&self) -> bool {
self.blocks.is_empty()
}
pub fn peek(&self) -> &BlockInfo {
self.blocks.last().expect("block stack is empty")
}
pub fn peek_mut(&mut self) -> &mut BlockInfo {
self.blocks.last_mut().expect("block stack is empty")
}
}
#[derive(Debug, Clone)]
pub struct BlockInfo {
pub addr: Felt,
pub parent_addr: Felt,
pub ctx_info: Option<ExecutionContextInfo>,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct ExecutionContextInfo {
pub parent_ctx: ContextId,
pub parent_fn_hash: Word,
pub parent_stack_depth: u32,
pub parent_next_overflow_addr: Felt,
}
impl ExecutionContextInfo {
pub fn new(
parent_ctx: ContextId,
parent_fn_hash: Word,
parent_stack_depth: u32,
parent_next_overflow_addr: Felt,
) -> Self {
Self {
parent_fn_hash,
parent_ctx,
parent_stack_depth,
parent_next_overflow_addr,
}
}
}