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