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 resolved = self.resolve_target(kind, callee, proc_ctx, mast_forest_builder)?;
29
30 match kind {
31 InvokeKind::ProcRef | InvokeKind::Exec => Ok(resolved.node),
32 InvokeKind::Call => mast_forest_builder.ensure_call(resolved.node),
33 InvokeKind::SysCall => mast_forest_builder.ensure_syscall(resolved.node),
34 }
35 }
36
37 pub(super) fn dynexec(
39 &self,
40 mast_forest_builder: &mut MastForestBuilder,
41 ) -> Result<Option<MastNodeId>, Report> {
42 let dyn_node_id = mast_forest_builder.ensure_dyn()?;
43
44 Ok(Some(dyn_node_id))
45 }
46
47 pub(super) fn dyncall(
49 &self,
50 mast_forest_builder: &mut MastForestBuilder,
51 ) -> Result<Option<MastNodeId>, Report> {
52 let dyn_call_node_id = mast_forest_builder.ensure_dyncall()?;
53
54 Ok(Some(dyn_call_node_id))
55 }
56
57 pub(super) fn procref(
58 &self,
59 callee: &InvocationTarget,
60 proc_ctx: &mut ProcedureContext,
61 block_builder: &mut BasicBlockBuilder,
62 ) -> Result<(), Report> {
63 let mast_root = {
64 let resolved = self.resolve_target(
65 InvokeKind::ProcRef,
66 callee,
67 proc_ctx,
68 block_builder.mast_forest_builder_mut(),
69 )?;
70 block_builder
73 .mast_forest_builder()
74 .get_mast_node(resolved.node)
75 .unwrap()
76 .digest()
77 };
78
79 self.procref_mast_root(mast_root, block_builder)
80 }
81
82 fn procref_mast_root(
83 &self,
84 mast_root: Word,
85 block_builder: &mut BasicBlockBuilder,
86 ) -> Result<(), Report> {
87 let ops = mast_root
89 .iter()
90 .map(|elem| Operation::Push(*elem))
91 .collect::<SmallVec<[_; 4]>>();
92 block_builder.push_ops(ops);
93 Ok(())
94 }
95}