miden_assembly/instruction/
procedures.rs1use miden_assembly_syntax::{
2 Word,
3 ast::{InvocationTarget, InvokeKind},
4 diagnostics::Report,
5};
6use miden_core::operations::{AssemblyOp, Operation};
7use smallvec::SmallVec;
8
9use crate::{
10 Assembler, GlobalItemIndex,
11 basic_block_builder::BasicBlockBuilder,
12 mast_forest_builder::{MastForestBuilder, MastNodeRef},
13};
14
15impl Assembler {
17 pub(super) fn invoke(
23 &self,
24 kind: InvokeKind,
25 callee: &InvocationTarget,
26 caller: GlobalItemIndex,
27 mast_forest_builder: &mut MastForestBuilder,
28 asm_op: Option<AssemblyOp>,
29 ) -> Result<MastNodeRef, Report> {
30 let resolved = self.resolve_target(kind, callee, caller.module, mast_forest_builder)?;
31
32 match kind {
33 InvokeKind::ProcRef | InvokeKind::Exec => Ok(resolved.node),
34 InvokeKind::Call | InvokeKind::SysCall => mast_forest_builder.ensure_call_node_ref(
35 resolved.node,
36 matches!(kind, InvokeKind::SysCall),
37 asm_op.expect("call and syscall invocations must provide an AssemblyOp"),
38 ),
39 }
40 }
41
42 pub(super) fn dynexec(
44 &self,
45 mast_forest_builder: &mut MastForestBuilder,
46 asm_op: AssemblyOp,
47 ) -> Result<Option<MastNodeRef>, Report> {
48 let dyn_node_ref = mast_forest_builder.ensure_dyn_node_ref(false, asm_op)?;
49
50 Ok(Some(dyn_node_ref))
51 }
52
53 pub(super) fn dyncall(
55 &self,
56 mast_forest_builder: &mut MastForestBuilder,
57 asm_op: AssemblyOp,
58 ) -> Result<Option<MastNodeRef>, Report> {
59 let dyn_call_node_ref = mast_forest_builder.ensure_dyn_node_ref(true, asm_op)?;
60
61 Ok(Some(dyn_call_node_ref))
62 }
63
64 pub(super) fn procref(
65 &self,
66 callee: &InvocationTarget,
67 caller: GlobalItemIndex,
68 block_builder: &mut BasicBlockBuilder,
69 ) -> Result<(), Report> {
70 let mast_root = {
71 let resolved = self.resolve_target(
72 InvokeKind::ProcRef,
73 callee,
74 caller.module,
75 block_builder.mast_forest_builder_mut(),
76 )?;
77 block_builder.mast_forest_builder().mast_root_for_ref(resolved.node).unwrap()
80 };
81
82 self.procref_mast_root(mast_root, block_builder);
83 Ok(())
84 }
85
86 fn procref_mast_root(&self, mast_root: Word, block_builder: &mut BasicBlockBuilder) {
87 let ops = mast_root
90 .iter()
91 .rev()
92 .map(|elem| Operation::Push(*elem))
93 .collect::<SmallVec<[_; 4]>>();
94 block_builder.push_ops(ops);
95 }
96}