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, mast::MastNodeId};
8
9use super::GlobalItemIndex;
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 fn into_procedure(self, mast_root: Word, mast_node_id: MastNodeId) -> Procedure {
122 let is_syscall = self.is_kernel && self.visibility.is_public();
123 Procedure::new(
124 self.path,
125 self.visibility,
126 self.signature,
127 is_syscall,
128 self.num_locals as u32,
129 mast_root,
130 mast_node_id,
131 )
132 .with_span(self.span)
133 }
134}
135
136impl Spanned for ProcedureContext {
137 fn span(&self) -> SourceSpan {
138 self.span
139 }
140}
141
142#[derive(Clone, Debug)]
155pub struct Procedure {
156 span: SourceSpan,
157 path: Arc<Path>,
158 signature: Option<Arc<FunctionType>>,
159 visibility: Visibility,
160 is_syscall: bool,
161 num_locals: u32,
162 mast_root: Word,
164 body_node_id: MastNodeId,
166}
167
168impl Procedure {
171 fn new(
172 path: Arc<Path>,
173 visibility: Visibility,
174 signature: Option<Arc<FunctionType>>,
175 is_syscall: bool,
176 num_locals: u32,
177 mast_root: Word,
178 body_node_id: MastNodeId,
179 ) -> Self {
180 Self {
181 span: SourceSpan::default(),
182 path,
183 visibility,
184 signature,
185 is_syscall,
186 num_locals,
187 mast_root,
188 body_node_id,
189 }
190 }
191
192 pub(crate) fn with_span(mut self, span: SourceSpan) -> Self {
193 self.span = span;
194 self
195 }
196}
197
198impl Procedure {
201 pub fn path(&self) -> &Arc<Path> {
203 &self.path
204 }
205
206 #[inline(always)]
208 pub const fn is_syscall(&self) -> bool {
209 self.is_syscall
210 }
211
212 pub fn visibility(&self) -> Visibility {
214 self.visibility
215 }
216
217 pub fn module(&self) -> &Path {
219 self.path.parent().unwrap()
220 }
221
222 pub fn signature(&self) -> Option<Arc<FunctionType>> {
224 self.signature.clone()
225 }
226
227 pub fn num_locals(&self) -> u32 {
229 self.num_locals
230 }
231
232 pub fn mast_root(&self) -> Word {
234 self.mast_root
235 }
236
237 pub fn body_node_id(&self) -> MastNodeId {
239 self.body_node_id
240 }
241}
242
243impl Spanned for Procedure {
244 fn span(&self) -> SourceSpan {
245 self.span
246 }
247}