miden_assembly/
procedure.rs1use alloc::sync::Arc;
2
3use miden_assembly_syntax::{
4 ast::{Path, Visibility, types::FunctionType},
5 debuginfo::{SourceManager, SourceSpan, Spanned},
6};
7use miden_core::Word;
8
9use super::{GlobalItemIndex, mast_forest_builder::MastNodeRef};
10
11pub struct ProcedureContext {
16 source_manager: Arc<dyn SourceManager>,
17 gid: GlobalItemIndex,
18 is_program_entrypoint: bool,
19 span: SourceSpan,
20 path: Arc<Path>,
21 signature: Option<Arc<FunctionType>>,
22 visibility: Visibility,
23 is_kernel: bool,
24 num_locals: u16,
25}
26
27impl ProcedureContext {
30 pub fn new(
31 gid: GlobalItemIndex,
32 is_program_entrypoint: bool,
33 path: Arc<Path>,
34 visibility: Visibility,
35 signature: Option<Arc<FunctionType>>,
36 is_kernel: bool,
37 source_manager: Arc<dyn SourceManager>,
38 ) -> Self {
39 Self {
40 source_manager,
41 gid,
42 is_program_entrypoint,
43 span: SourceSpan::UNKNOWN,
44 path,
45 visibility,
46 signature,
47 is_kernel,
48 num_locals: 0,
49 }
50 }
51
52 pub fn with_num_locals(mut self, num_locals: u16) -> Self {
54 self.num_locals = num_locals;
55 self
56 }
57
58 pub fn with_span(mut self, span: SourceSpan) -> Self {
59 self.span = span;
60 self
61 }
62}
63
64impl ProcedureContext {
67 pub fn id(&self) -> GlobalItemIndex {
68 self.gid
69 }
70
71 pub fn is_program_entrypoint(&self) -> bool {
72 self.is_program_entrypoint
73 }
74
75 pub fn path(&self) -> &Arc<Path> {
76 &self.path
77 }
78
79 pub fn signature(&self) -> Option<Arc<FunctionType>> {
80 self.signature.clone()
81 }
82
83 pub fn set_signature(&mut self, signature: Option<Arc<FunctionType>>) {
84 self.signature = signature;
85 }
86
87 pub fn num_locals(&self) -> u16 {
88 self.num_locals
89 }
90
91 pub fn module(&self) -> &Path {
92 self.path.parent().unwrap()
93 }
94
95 pub fn is_kernel(&self) -> bool {
97 self.is_kernel
98 }
99
100 #[inline(always)]
101 pub fn source_manager(&self) -> &dyn SourceManager {
102 self.source_manager.as_ref()
103 }
104}
105
106impl ProcedureContext {
109 pub(crate) fn into_procedure(self, mast_root: Word, body_node_ref: MastNodeRef) -> Procedure {
119 let is_syscall = self.is_kernel && self.visibility.is_public();
120 Procedure::new(
121 self.path,
122 self.visibility,
123 self.signature,
124 is_syscall,
125 self.num_locals as u32,
126 mast_root,
127 body_node_ref,
128 )
129 .with_span(self.span)
130 }
131}
132
133impl Spanned for ProcedureContext {
134 fn span(&self) -> SourceSpan {
135 self.span
136 }
137}
138
139#[derive(Clone, Debug)]
152pub struct Procedure {
153 span: SourceSpan,
154 path: Arc<Path>,
155 signature: Option<Arc<FunctionType>>,
156 visibility: Visibility,
157 is_syscall: bool,
158 num_locals: u32,
159 mast_root: Word,
161 body_node_ref: MastNodeRef,
163}
164
165impl Procedure {
168 fn new(
169 path: Arc<Path>,
170 visibility: Visibility,
171 signature: Option<Arc<FunctionType>>,
172 is_syscall: bool,
173 num_locals: u32,
174 mast_root: Word,
175 body_node_ref: MastNodeRef,
176 ) -> Self {
177 Self {
178 span: SourceSpan::default(),
179 path,
180 visibility,
181 signature,
182 is_syscall,
183 num_locals,
184 mast_root,
185 body_node_ref,
186 }
187 }
188
189 pub(crate) fn with_span(mut self, span: SourceSpan) -> Self {
190 self.span = span;
191 self
192 }
193}
194
195impl Procedure {
198 pub fn span(&self) -> &SourceSpan {
200 &self.span
201 }
202
203 pub fn path(&self) -> &Arc<Path> {
205 &self.path
206 }
207
208 #[inline(always)]
210 pub const fn is_syscall(&self) -> bool {
211 self.is_syscall
212 }
213
214 pub fn visibility(&self) -> Visibility {
216 self.visibility
217 }
218
219 pub fn module(&self) -> &Path {
221 self.path.parent().unwrap()
222 }
223
224 pub fn signature(&self) -> Option<Arc<FunctionType>> {
226 self.signature.clone()
227 }
228
229 pub fn num_locals(&self) -> u32 {
231 self.num_locals
232 }
233
234 pub fn mast_root(&self) -> Word {
236 self.mast_root
237 }
238
239 pub(crate) fn body_node_ref(&self) -> MastNodeRef {
241 self.body_node_ref
242 }
243}
244
245impl Spanned for Procedure {
246 fn span(&self) -> SourceSpan {
247 self.span
248 }
249}