miden_assembly/instruction/
procedures.rs1use miden_assembly_syntax::{
2 Word,
3 ast::{InvocationTarget, InvokeKind},
4 diagnostics::Report,
5};
6use miden_core::{Operation, mast::MastNodeId};
7use smallvec::SmallVec;
8
9use crate::{
10 Assembler, ProcedureContext, basic_block_builder::BasicBlockBuilder,
11 mast_forest_builder::MastForestBuilder,
12};
13
14impl Assembler {
16 pub(super) fn invoke(
22 &self,
23 kind: InvokeKind,
24 callee: &InvocationTarget,
25 proc_ctx: &ProcedureContext,
26 mast_forest_builder: &mut MastForestBuilder,
27 ) -> Result<MastNodeId, Report> {
28 let invoked_proc_node_id =
29 self.resolve_target(kind, callee, proc_ctx, mast_forest_builder)?;
30
31 match kind {
32 InvokeKind::ProcRef | InvokeKind::Exec => Ok(invoked_proc_node_id),
33 InvokeKind::Call => mast_forest_builder.ensure_call(invoked_proc_node_id),
34 InvokeKind::SysCall => mast_forest_builder.ensure_syscall(invoked_proc_node_id),
35 }
36 }
37
38 pub(super) fn dynexec(
40 &self,
41 mast_forest_builder: &mut MastForestBuilder,
42 ) -> Result<Option<MastNodeId>, Report> {
43 let dyn_node_id = mast_forest_builder.ensure_dyn()?;
44
45 Ok(Some(dyn_node_id))
46 }
47
48 pub(super) fn dyncall(
50 &self,
51 mast_forest_builder: &mut MastForestBuilder,
52 ) -> Result<Option<MastNodeId>, Report> {
53 let dyn_call_node_id = mast_forest_builder.ensure_dyncall()?;
54
55 Ok(Some(dyn_call_node_id))
56 }
57
58 pub(super) fn procref(
59 &self,
60 callee: &InvocationTarget,
61 proc_ctx: &mut ProcedureContext,
62 block_builder: &mut BasicBlockBuilder,
63 ) -> Result<(), Report> {
64 let mast_root = {
65 let proc_body_id = self.resolve_target(
66 InvokeKind::ProcRef,
67 callee,
68 proc_ctx,
69 block_builder.mast_forest_builder_mut(),
70 )?;
71 block_builder
74 .mast_forest_builder()
75 .get_mast_node(proc_body_id)
76 .unwrap()
77 .digest()
78 };
79
80 self.procref_mast_root(mast_root, block_builder)
81 }
82
83 fn procref_mast_root(
84 &self,
85 mast_root: Word,
86 block_builder: &mut BasicBlockBuilder,
87 ) -> Result<(), Report> {
88 let ops = mast_root
90 .iter()
91 .map(|elem| Operation::Push(*elem))
92 .collect::<SmallVec<[_; 4]>>();
93 block_builder.push_ops(ops);
94 Ok(())
95 }
96}