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