use alloc::vec::Vec;
use miden_core::{
Word,
mast::{MastNode, OpBatch},
utils::newtype_id,
};
use miden_mast_package::debug_info::{
DebugFunctionIdx, DebugSourceAsmOp, DebugSourceInlineCall, DebugSourceVar, SourceNodeIdMarker,
};
pub(super) type MastNodeKey = Word;
newtype_id!(
pub(crate) struct MastNodeRef;
);
newtype_id!(
pub(crate) struct SourceNodeRef;
);
impl SourceNodeIdMarker for SourceNodeRef {}
#[derive(Clone, Debug)]
pub(super) struct PendingMastNode {
pub(super) key: MastNodeKey,
pub(super) digest: Word,
pub(super) kind: PendingMastNodeKind,
pub(super) child_refs: Vec<MastNodeRef>,
pub(super) asm_ops: Vec<DebugSourceAsmOp>,
pub(super) debug_vars: Vec<DebugSourceVar>,
}
#[derive(Clone, Debug)]
pub(super) enum PendingMastNodeKind {
BasicBlock { op_batches: Vec<OpBatch> },
Join,
Split,
Loop,
Call { is_syscall: bool },
Dyn { is_dyncall: bool },
External,
}
impl PendingMastNodeKind {
pub(super) fn name(&self) -> &'static str {
match self {
Self::BasicBlock { .. } => "basic block",
Self::Join => "join",
Self::Split => "split",
Self::Loop => "loop",
Self::Call { .. } => "call",
Self::Dyn { .. } => "dyn",
Self::External => "external",
}
}
pub(super) fn from_node(node: MastNode) -> Self {
match node {
MastNode::Block(node) => Self::BasicBlock { op_batches: node.op_batches().to_vec() },
MastNode::Join(_) => Self::Join,
MastNode::Split(_) => Self::Split,
MastNode::Loop(_) => Self::Loop,
MastNode::Call(node) => Self::Call { is_syscall: node.is_syscall() },
MastNode::Dyn(node) => Self::Dyn { is_dyncall: node.is_dyncall() },
MastNode::External(_) => Self::External,
}
}
pub(super) fn basic_block_op_batches(&self) -> Option<&[OpBatch]> {
match self {
Self::BasicBlock { op_batches } => Some(op_batches),
_ => None,
}
}
pub(super) fn is_basic_block(&self) -> bool {
matches!(self, Self::BasicBlock { .. })
}
pub(super) fn is_external(&self) -> bool {
matches!(self, Self::External)
}
}
#[derive(Clone)]
pub(super) struct PendingMastNodeDraft {
pub(super) digest: Word,
pub(super) kind: PendingMastNodeKind,
pub(super) child_refs: Vec<MastNodeRef>,
pub(super) asm_ops: Vec<DebugSourceAsmOp>,
pub(super) debug_vars: Vec<DebugSourceVar>,
pub(super) inline_calls: Vec<DebugSourceInlineCall>,
pub(super) functions: Vec<DebugFunctionIdx>,
}
impl PendingMastNodeDraft {
pub(super) fn new(
kind: PendingMastNodeKind,
digest: Word,
child_refs: Vec<MastNodeRef>,
) -> Self {
Self {
digest,
kind,
child_refs,
asm_ops: Vec::new(),
debug_vars: Vec::new(),
inline_calls: Vec::new(),
functions: Vec::new(),
}
}
}