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