1747ad3c4Slazypassion //! Defines `Module` and related types.
2747ad3c4Slazypassion 
3747ad3c4Slazypassion // TODO: Should `ir::Function` really have a `name`?
4747ad3c4Slazypassion 
5747ad3c4Slazypassion // TODO: Factor out `ir::Function`'s `ext_funcs` and `global_values` into a struct
667c85b88Sbjorn3 // shared with `DataDescription`?
7747ad3c4Slazypassion 
8747ad3c4Slazypassion use super::HashMap;
967c85b88Sbjorn3 use crate::data_context::DataDescription;
108a9b1a90SBenjamin Bouvier use core::fmt::Display;
118a9b1a90SBenjamin Bouvier use cranelift_codegen::binemit::{CodeOffset, Reloc};
1290ac295eSAlex Crichton use cranelift_codegen::entity::{PrimaryMap, entity_impl};
139fc4a710SAfonso Bordado use cranelift_codegen::ir::ExternalName;
1490ac295eSAlex Crichton use cranelift_codegen::ir::function::{Function, VersionMarker};
15a2d356d4SAmanieu d'Antras use cranelift_codegen::settings::SetError;
16b23f534cSAfonso Bordado use cranelift_codegen::{
1790ac295eSAlex Crichton     CodegenError, CompileError, Context, FinalizedMachReloc, FinalizedRelocTarget, ir, isa,
18b23f534cSAfonso Bordado };
197eb89140SRemo Senekowitsch use cranelift_control::ControlPlane;
2091d1d246Sbjorn3 use std::borrow::{Cow, ToOwned};
218abaa75fSSpartan2909 use std::boxed::Box;
22747ad3c4Slazypassion use std::string::String;
23747ad3c4Slazypassion 
248a9b1a90SBenjamin Bouvier /// A module relocation.
258a9b1a90SBenjamin Bouvier #[derive(Clone)]
268a9b1a90SBenjamin Bouvier pub struct ModuleReloc {
278a9b1a90SBenjamin Bouvier     /// The offset at which the relocation applies, *relative to the
288a9b1a90SBenjamin Bouvier     /// containing section*.
298a9b1a90SBenjamin Bouvier     pub offset: CodeOffset,
308a9b1a90SBenjamin Bouvier     /// The kind of relocation.
318a9b1a90SBenjamin Bouvier     pub kind: Reloc,
328a9b1a90SBenjamin Bouvier     /// The external symbol / name to which this relocation refers.
33b23f534cSAfonso Bordado     pub name: ModuleRelocTarget,
348a9b1a90SBenjamin Bouvier     /// The addend to add to the symbol value.
358a9b1a90SBenjamin Bouvier     pub addend: i64,
368a9b1a90SBenjamin Bouvier }
378a9b1a90SBenjamin Bouvier 
388a9b1a90SBenjamin Bouvier impl ModuleReloc {
39b23f534cSAfonso Bordado     /// Converts a `FinalizedMachReloc` produced from a `Function` into a `ModuleReloc`.
from_mach_reloc( mach_reloc: &FinalizedMachReloc, func: &Function, func_id: FuncId, ) -> Self409fc4a710SAfonso Bordado     pub fn from_mach_reloc(
419fc4a710SAfonso Bordado         mach_reloc: &FinalizedMachReloc,
429fc4a710SAfonso Bordado         func: &Function,
439fc4a710SAfonso Bordado         func_id: FuncId,
449fc4a710SAfonso Bordado     ) -> Self {
45b23f534cSAfonso Bordado         let name = match mach_reloc.target {
46b23f534cSAfonso Bordado             FinalizedRelocTarget::ExternalName(ExternalName::User(reff)) => {
478a9b1a90SBenjamin Bouvier                 let name = &func.params.user_named_funcs()[reff];
48b23f534cSAfonso Bordado                 ModuleRelocTarget::user(name.namespace, name.index)
498a9b1a90SBenjamin Bouvier             }
50b23f534cSAfonso Bordado             FinalizedRelocTarget::ExternalName(ExternalName::TestCase(_)) => unimplemented!(),
51b23f534cSAfonso Bordado             FinalizedRelocTarget::ExternalName(ExternalName::LibCall(libcall)) => {
52b23f534cSAfonso Bordado                 ModuleRelocTarget::LibCall(libcall)
53b23f534cSAfonso Bordado             }
54b23f534cSAfonso Bordado             FinalizedRelocTarget::ExternalName(ExternalName::KnownSymbol(ks)) => {
55b23f534cSAfonso Bordado                 ModuleRelocTarget::KnownSymbol(ks)
56b23f534cSAfonso Bordado             }
57b23f534cSAfonso Bordado             FinalizedRelocTarget::Func(offset) => {
589fc4a710SAfonso Bordado                 ModuleRelocTarget::FunctionOffset(func_id, offset)
59b23f534cSAfonso Bordado             }
608a9b1a90SBenjamin Bouvier         };
618a9b1a90SBenjamin Bouvier         Self {
628a9b1a90SBenjamin Bouvier             offset: mach_reloc.offset,
638a9b1a90SBenjamin Bouvier             kind: mach_reloc.kind,
648a9b1a90SBenjamin Bouvier             name,
658a9b1a90SBenjamin Bouvier             addend: mach_reloc.addend,
668a9b1a90SBenjamin Bouvier         }
678a9b1a90SBenjamin Bouvier     }
688a9b1a90SBenjamin Bouvier }
698a9b1a90SBenjamin Bouvier 
70747ad3c4Slazypassion /// A function identifier for use in the `Module` interface.
71747ad3c4Slazypassion #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
729ec02f9dSChristopher Serr #[cfg_attr(
739ec02f9dSChristopher Serr     feature = "enable-serde",
749ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
759ec02f9dSChristopher Serr )]
76747ad3c4Slazypassion pub struct FuncId(u32);
77747ad3c4Slazypassion entity_impl!(FuncId, "funcid");
78747ad3c4Slazypassion 
79747ad3c4Slazypassion /// Function identifiers are namespace 0 in `ir::ExternalName`
80b23f534cSAfonso Bordado impl From<FuncId> for ModuleRelocTarget {
from(id: FuncId) -> Self81747ad3c4Slazypassion     fn from(id: FuncId) -> Self {
829f506692SPeter Huene         Self::User {
83747ad3c4Slazypassion             namespace: 0,
84747ad3c4Slazypassion             index: id.0,
85747ad3c4Slazypassion         }
86747ad3c4Slazypassion     }
87747ad3c4Slazypassion }
88747ad3c4Slazypassion 
89844a52e9Sbjorn3 impl FuncId {
90844a52e9Sbjorn3     /// Get the `FuncId` for the function named by `name`.
from_name(name: &ModuleRelocTarget) -> FuncId91b23f534cSAfonso Bordado     pub fn from_name(name: &ModuleRelocTarget) -> FuncId {
92b23f534cSAfonso Bordado         if let ModuleRelocTarget::User { namespace, index } = name {
938a9b1a90SBenjamin Bouvier             debug_assert_eq!(*namespace, 0);
948a9b1a90SBenjamin Bouvier             FuncId::from_u32(*index)
95844a52e9Sbjorn3         } else {
968a9b1a90SBenjamin Bouvier             panic!("unexpected name in DataId::from_name")
97844a52e9Sbjorn3         }
98844a52e9Sbjorn3     }
99844a52e9Sbjorn3 }
100844a52e9Sbjorn3 
101747ad3c4Slazypassion /// A data object identifier for use in the `Module` interface.
102747ad3c4Slazypassion #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1039ec02f9dSChristopher Serr #[cfg_attr(
1049ec02f9dSChristopher Serr     feature = "enable-serde",
1059ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
1069ec02f9dSChristopher Serr )]
107747ad3c4Slazypassion pub struct DataId(u32);
108747ad3c4Slazypassion entity_impl!(DataId, "dataid");
109747ad3c4Slazypassion 
110747ad3c4Slazypassion /// Data identifiers are namespace 1 in `ir::ExternalName`
111b23f534cSAfonso Bordado impl From<DataId> for ModuleRelocTarget {
from(id: DataId) -> Self112747ad3c4Slazypassion     fn from(id: DataId) -> Self {
1139f506692SPeter Huene         Self::User {
114747ad3c4Slazypassion             namespace: 1,
115747ad3c4Slazypassion             index: id.0,
116747ad3c4Slazypassion         }
117747ad3c4Slazypassion     }
118747ad3c4Slazypassion }
119747ad3c4Slazypassion 
120844a52e9Sbjorn3 impl DataId {
121844a52e9Sbjorn3     /// Get the `DataId` for the data object named by `name`.
from_name(name: &ModuleRelocTarget) -> DataId122b23f534cSAfonso Bordado     pub fn from_name(name: &ModuleRelocTarget) -> DataId {
123b23f534cSAfonso Bordado         if let ModuleRelocTarget::User { namespace, index } = name {
1248a9b1a90SBenjamin Bouvier             debug_assert_eq!(*namespace, 1);
1258a9b1a90SBenjamin Bouvier             DataId::from_u32(*index)
126844a52e9Sbjorn3         } else {
1278a9b1a90SBenjamin Bouvier             panic!("unexpected name in DataId::from_name")
128844a52e9Sbjorn3         }
129844a52e9Sbjorn3     }
130844a52e9Sbjorn3 }
131844a52e9Sbjorn3 
132747ad3c4Slazypassion /// Linkage refers to where an entity is defined and who can see it.
133e045a6dfSJoshua Nelson #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1349ec02f9dSChristopher Serr #[cfg_attr(
1359ec02f9dSChristopher Serr     feature = "enable-serde",
1369ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
1379ec02f9dSChristopher Serr )]
138747ad3c4Slazypassion pub enum Linkage {
139747ad3c4Slazypassion     /// Defined outside of a module.
140747ad3c4Slazypassion     Import,
141747ad3c4Slazypassion     /// Defined inside the module, but not visible outside it.
142747ad3c4Slazypassion     Local,
143747ad3c4Slazypassion     /// Defined inside the module, visible outside it, and may be preempted.
144747ad3c4Slazypassion     Preemptible,
145b4562c62Sbjorn3     /// Defined inside the module, visible inside the current static linkage unit, but not outside.
146b4562c62Sbjorn3     ///
147b4562c62Sbjorn3     /// A static linkage unit is the combination of all object files passed to a linker to create
148b4562c62Sbjorn3     /// an executable or dynamic library.
149b4562c62Sbjorn3     Hidden,
150747ad3c4Slazypassion     /// Defined inside the module, and visible outside it.
151747ad3c4Slazypassion     Export,
152747ad3c4Slazypassion }
153747ad3c4Slazypassion 
154747ad3c4Slazypassion impl Linkage {
merge(a: Self, b: Self) -> Self155747ad3c4Slazypassion     fn merge(a: Self, b: Self) -> Self {
156747ad3c4Slazypassion         match a {
1579f506692SPeter Huene             Self::Export => Self::Export,
158b4562c62Sbjorn3             Self::Hidden => match b {
159b4562c62Sbjorn3                 Self::Export => Self::Export,
160b4562c62Sbjorn3                 Self::Preemptible => Self::Preemptible,
161b4562c62Sbjorn3                 _ => Self::Hidden,
162b4562c62Sbjorn3             },
1639f506692SPeter Huene             Self::Preemptible => match b {
1649f506692SPeter Huene                 Self::Export => Self::Export,
1659f506692SPeter Huene                 _ => Self::Preemptible,
166747ad3c4Slazypassion             },
1679f506692SPeter Huene             Self::Local => match b {
1689f506692SPeter Huene                 Self::Export => Self::Export,
169b4562c62Sbjorn3                 Self::Hidden => Self::Hidden,
1709f506692SPeter Huene                 Self::Preemptible => Self::Preemptible,
171b4562c62Sbjorn3                 Self::Local | Self::Import => Self::Local,
172747ad3c4Slazypassion             },
1739f506692SPeter Huene             Self::Import => b,
174747ad3c4Slazypassion         }
175747ad3c4Slazypassion     }
176747ad3c4Slazypassion 
177747ad3c4Slazypassion     /// Test whether this linkage can have a definition.
is_definable(self) -> bool178747ad3c4Slazypassion     pub fn is_definable(self) -> bool {
179747ad3c4Slazypassion         match self {
1809f506692SPeter Huene             Self::Import => false,
181b4562c62Sbjorn3             Self::Local | Self::Preemptible | Self::Hidden | Self::Export => true,
182747ad3c4Slazypassion         }
183747ad3c4Slazypassion     }
184747ad3c4Slazypassion 
185329aaf78Sbjorn3     /// Test whether this linkage must have a definition.
requires_definition(self) -> bool186329aaf78Sbjorn3     pub fn requires_definition(self) -> bool {
187329aaf78Sbjorn3         match self {
188329aaf78Sbjorn3             Self::Import | Self::Preemptible => false,
189329aaf78Sbjorn3             Self::Local | Self::Hidden | Self::Export => true,
190329aaf78Sbjorn3         }
191329aaf78Sbjorn3     }
192329aaf78Sbjorn3 
193747ad3c4Slazypassion     /// Test whether this linkage will have a definition that cannot be preempted.
is_final(self) -> bool194747ad3c4Slazypassion     pub fn is_final(self) -> bool {
195747ad3c4Slazypassion         match self {
1969f506692SPeter Huene             Self::Import | Self::Preemptible => false,
197b4562c62Sbjorn3             Self::Local | Self::Hidden | Self::Export => true,
198747ad3c4Slazypassion         }
199747ad3c4Slazypassion     }
200747ad3c4Slazypassion }
201747ad3c4Slazypassion 
202747ad3c4Slazypassion /// A declared name may refer to either a function or data declaration
203747ad3c4Slazypassion #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
2049ec02f9dSChristopher Serr #[cfg_attr(
2059ec02f9dSChristopher Serr     feature = "enable-serde",
2069ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
2079ec02f9dSChristopher Serr )]
208747ad3c4Slazypassion pub enum FuncOrDataId {
209747ad3c4Slazypassion     /// When it's a FuncId
210747ad3c4Slazypassion     Func(FuncId),
211747ad3c4Slazypassion     /// When it's a DataId
212747ad3c4Slazypassion     Data(DataId),
213747ad3c4Slazypassion }
214747ad3c4Slazypassion 
2158a9b1a90SBenjamin Bouvier /// Mapping to `ModuleExtName` is trivial based on the `FuncId` and `DataId` mapping.
216b23f534cSAfonso Bordado impl From<FuncOrDataId> for ModuleRelocTarget {
from(id: FuncOrDataId) -> Self217747ad3c4Slazypassion     fn from(id: FuncOrDataId) -> Self {
218747ad3c4Slazypassion         match id {
219747ad3c4Slazypassion             FuncOrDataId::Func(funcid) => Self::from(funcid),
220747ad3c4Slazypassion             FuncOrDataId::Data(dataid) => Self::from(dataid),
221747ad3c4Slazypassion         }
222747ad3c4Slazypassion     }
223747ad3c4Slazypassion }
224747ad3c4Slazypassion 
225747ad3c4Slazypassion /// Information about a function which can be called.
2267a2a4bc9Sbjorn3 #[derive(Debug)]
2279ec02f9dSChristopher Serr #[cfg_attr(
2289ec02f9dSChristopher Serr     feature = "enable-serde",
2299ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
2309ec02f9dSChristopher Serr )]
231c3aa6a53SAlex Crichton #[expect(missing_docs, reason = "self-describing fields")]
232747ad3c4Slazypassion pub struct FunctionDeclaration {
23391d1d246Sbjorn3     pub name: Option<String>,
234747ad3c4Slazypassion     pub linkage: Linkage,
235747ad3c4Slazypassion     pub signature: ir::Signature,
236747ad3c4Slazypassion }
237747ad3c4Slazypassion 
238588a4be0Sbjorn3 impl FunctionDeclaration {
23991d1d246Sbjorn3     /// The linkage name of the function.
24091d1d246Sbjorn3     ///
24191d1d246Sbjorn3     /// Synthesized from the given function id if it is an anonymous function.
linkage_name(&self, id: FuncId) -> Cow<'_, str>24291d1d246Sbjorn3     pub fn linkage_name(&self, id: FuncId) -> Cow<'_, str> {
24391d1d246Sbjorn3         match &self.name {
24491d1d246Sbjorn3             Some(name) => Cow::Borrowed(name),
24591d1d246Sbjorn3             // Symbols starting with .L are completely omitted from the symbol table after linking.
24691d1d246Sbjorn3             // Using hexadecimal instead of decimal for slightly smaller symbol names and often
24791d1d246Sbjorn3             // slightly faster linking.
24891d1d246Sbjorn3             None => Cow::Owned(format!(".Lfn{:x}", id.as_u32())),
24991d1d246Sbjorn3         }
25091d1d246Sbjorn3     }
25191d1d246Sbjorn3 
merge( &mut self, id: FuncId, linkage: Linkage, sig: &ir::Signature, ) -> Result<(), ModuleError>25291d1d246Sbjorn3     fn merge(
25391d1d246Sbjorn3         &mut self,
25491d1d246Sbjorn3         id: FuncId,
25591d1d246Sbjorn3         linkage: Linkage,
25691d1d246Sbjorn3         sig: &ir::Signature,
25791d1d246Sbjorn3     ) -> Result<(), ModuleError> {
258588a4be0Sbjorn3         self.linkage = Linkage::merge(self.linkage, linkage);
259588a4be0Sbjorn3         if &self.signature != sig {
260588a4be0Sbjorn3             return Err(ModuleError::IncompatibleSignature(
26191d1d246Sbjorn3                 self.linkage_name(id).into_owned(),
262588a4be0Sbjorn3                 self.signature.clone(),
263588a4be0Sbjorn3                 sig.clone(),
264588a4be0Sbjorn3             ));
265588a4be0Sbjorn3         }
266588a4be0Sbjorn3         Ok(())
267588a4be0Sbjorn3     }
268588a4be0Sbjorn3 }
269588a4be0Sbjorn3 
270b0616944Sbjorn3 /// Error messages for all `Module` methods
271147cda3bSbjorn3 #[derive(Debug)]
272747ad3c4Slazypassion pub enum ModuleError {
273747ad3c4Slazypassion     /// Indicates an identifier was used before it was declared
274747ad3c4Slazypassion     Undeclared(String),
275147cda3bSbjorn3 
276747ad3c4Slazypassion     /// Indicates an identifier was used as data/function first, but then used as the other
277747ad3c4Slazypassion     IncompatibleDeclaration(String),
278147cda3bSbjorn3 
279747ad3c4Slazypassion     /// Indicates a function identifier was declared with a
280747ad3c4Slazypassion     /// different signature than declared previously
281747ad3c4Slazypassion     IncompatibleSignature(String, ir::Signature, ir::Signature),
282147cda3bSbjorn3 
283747ad3c4Slazypassion     /// Indicates an identifier was defined more than once
284747ad3c4Slazypassion     DuplicateDefinition(String),
285147cda3bSbjorn3 
286747ad3c4Slazypassion     /// Indicates an identifier was defined, but was declared as an import
287747ad3c4Slazypassion     InvalidImportDefinition(String),
288147cda3bSbjorn3 
289747ad3c4Slazypassion     /// Wraps a `cranelift-codegen` error
290147cda3bSbjorn3     Compilation(CodegenError),
291147cda3bSbjorn3 
292387426e7S11evan     /// Memory allocation failure from a backend
293387426e7S11evan     Allocation {
294387426e7S11evan         /// Io error the allocation failed with
295387426e7S11evan         err: std::io::Error,
296387426e7S11evan     },
297387426e7S11evan 
298747ad3c4Slazypassion     /// Wraps a generic error from a backend
299147cda3bSbjorn3     Backend(anyhow::Error),
300a2d356d4SAmanieu d'Antras 
301a2d356d4SAmanieu d'Antras     /// Wraps an error from a flag definition.
302a2d356d4SAmanieu d'Antras     Flag(SetError),
303147cda3bSbjorn3 }
304147cda3bSbjorn3 
305ff37c9d8SBenjamin Bouvier impl<'a> From<CompileError<'a>> for ModuleError {
from(err: CompileError<'a>) -> Self306ff37c9d8SBenjamin Bouvier     fn from(err: CompileError<'a>) -> Self {
307ff37c9d8SBenjamin Bouvier         Self::Compilation(err.inner)
308ff37c9d8SBenjamin Bouvier     }
309ff37c9d8SBenjamin Bouvier }
310ff37c9d8SBenjamin Bouvier 
31182f3ad4fSbjorn3 // This is manually implementing Error and Display instead of using thiserror to reduce the amount
31282f3ad4fSbjorn3 // of dependencies used by Cranelift.
313147cda3bSbjorn3 impl std::error::Error for ModuleError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>314147cda3bSbjorn3     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
315147cda3bSbjorn3         match self {
316147cda3bSbjorn3             Self::Undeclared { .. }
317147cda3bSbjorn3             | Self::IncompatibleDeclaration { .. }
318147cda3bSbjorn3             | Self::IncompatibleSignature { .. }
319147cda3bSbjorn3             | Self::DuplicateDefinition { .. }
320147cda3bSbjorn3             | Self::InvalidImportDefinition { .. } => None,
321147cda3bSbjorn3             Self::Compilation(source) => Some(source),
322*73ef034aSbjorn3             Self::Allocation { err: source } => Some(source),
323147cda3bSbjorn3             Self::Backend(source) => Some(&**source),
324a2d356d4SAmanieu d'Antras             Self::Flag(source) => Some(source),
325147cda3bSbjorn3         }
326147cda3bSbjorn3     }
327147cda3bSbjorn3 }
328147cda3bSbjorn3 
329147cda3bSbjorn3 impl std::fmt::Display for ModuleError {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result330147cda3bSbjorn3     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
331147cda3bSbjorn3         match self {
332147cda3bSbjorn3             Self::Undeclared(name) => {
333a0442ea0SHamir Mahal                 write!(f, "Undeclared identifier: {name}")
334147cda3bSbjorn3             }
335147cda3bSbjorn3             Self::IncompatibleDeclaration(name) => {
336a0442ea0SHamir Mahal                 write!(f, "Incompatible declaration of identifier: {name}",)
337147cda3bSbjorn3             }
338147cda3bSbjorn3             Self::IncompatibleSignature(name, prev_sig, new_sig) => {
339147cda3bSbjorn3                 write!(
340147cda3bSbjorn3                     f,
341a0442ea0SHamir Mahal                     "Function {name} signature {new_sig:?} is incompatible with previous declaration {prev_sig:?}",
342147cda3bSbjorn3                 )
343147cda3bSbjorn3             }
344147cda3bSbjorn3             Self::DuplicateDefinition(name) => {
345a0442ea0SHamir Mahal                 write!(f, "Duplicate definition of identifier: {name}")
346147cda3bSbjorn3             }
347147cda3bSbjorn3             Self::InvalidImportDefinition(name) => {
348147cda3bSbjorn3                 write!(
349147cda3bSbjorn3                     f,
350a0442ea0SHamir Mahal                     "Invalid to define identifier declared as an import: {name}",
351147cda3bSbjorn3                 )
352147cda3bSbjorn3             }
353147cda3bSbjorn3             Self::Compilation(err) => {
354a0442ea0SHamir Mahal                 write!(f, "Compilation error: {err}")
355147cda3bSbjorn3             }
356*73ef034aSbjorn3             Self::Allocation { err } => {
357*73ef034aSbjorn3                 write!(f, "Allocation error: {err}")
358387426e7S11evan             }
359a0442ea0SHamir Mahal             Self::Backend(err) => write!(f, "Backend error: {err}"),
360a0442ea0SHamir Mahal             Self::Flag(err) => write!(f, "Flag error: {err}"),
361147cda3bSbjorn3         }
362147cda3bSbjorn3     }
363147cda3bSbjorn3 }
364147cda3bSbjorn3 
365147cda3bSbjorn3 impl std::convert::From<CodegenError> for ModuleError {
from(source: CodegenError) -> Self366147cda3bSbjorn3     fn from(source: CodegenError) -> Self {
367147cda3bSbjorn3         Self::Compilation { 0: source }
368147cda3bSbjorn3     }
369747ad3c4Slazypassion }
370747ad3c4Slazypassion 
371a2d356d4SAmanieu d'Antras impl std::convert::From<SetError> for ModuleError {
from(source: SetError) -> Self372a2d356d4SAmanieu d'Antras     fn from(source: SetError) -> Self {
373a2d356d4SAmanieu d'Antras         Self::Flag { 0: source }
374a2d356d4SAmanieu d'Antras     }
375a2d356d4SAmanieu d'Antras }
376a2d356d4SAmanieu d'Antras 
377747ad3c4Slazypassion /// A convenient alias for a `Result` that uses `ModuleError` as the error type.
378747ad3c4Slazypassion pub type ModuleResult<T> = Result<T, ModuleError>;
379747ad3c4Slazypassion 
380747ad3c4Slazypassion /// Information about a data object which can be accessed.
3817a2a4bc9Sbjorn3 #[derive(Debug)]
3829ec02f9dSChristopher Serr #[cfg_attr(
3839ec02f9dSChristopher Serr     feature = "enable-serde",
3849ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
3859ec02f9dSChristopher Serr )]
386c3aa6a53SAlex Crichton #[expect(missing_docs, reason = "self-describing fields")]
387747ad3c4Slazypassion pub struct DataDeclaration {
38891d1d246Sbjorn3     pub name: Option<String>,
389747ad3c4Slazypassion     pub linkage: Linkage,
390747ad3c4Slazypassion     pub writable: bool,
3910a1bb3baSbjorn3     pub tls: bool,
392747ad3c4Slazypassion }
393747ad3c4Slazypassion 
394588a4be0Sbjorn3 impl DataDeclaration {
39591d1d246Sbjorn3     /// The linkage name of the data object.
39691d1d246Sbjorn3     ///
39791d1d246Sbjorn3     /// Synthesized from the given data id if it is an anonymous function.
linkage_name(&self, id: DataId) -> Cow<'_, str>39891d1d246Sbjorn3     pub fn linkage_name(&self, id: DataId) -> Cow<'_, str> {
39991d1d246Sbjorn3         match &self.name {
40091d1d246Sbjorn3             Some(name) => Cow::Borrowed(name),
40191d1d246Sbjorn3             // Symbols starting with .L are completely omitted from the symbol table after linking.
40291d1d246Sbjorn3             // Using hexadecimal instead of decimal for slightly smaller symbol names and often
40391d1d246Sbjorn3             // slightly faster linking.
40491d1d246Sbjorn3             None => Cow::Owned(format!(".Ldata{:x}", id.as_u32())),
40591d1d246Sbjorn3         }
40691d1d246Sbjorn3     }
40791d1d246Sbjorn3 
merge(&mut self, linkage: Linkage, writable: bool, tls: bool)40884c6ec32Sbjorn3     fn merge(&mut self, linkage: Linkage, writable: bool, tls: bool) {
409588a4be0Sbjorn3         self.linkage = Linkage::merge(self.linkage, linkage);
410588a4be0Sbjorn3         self.writable = self.writable || writable;
4110a1bb3baSbjorn3         assert_eq!(
412588a4be0Sbjorn3             self.tls, tls,
4130a1bb3baSbjorn3             "Can't change TLS data object to normal or in the opposite way",
4140a1bb3baSbjorn3         );
415747ad3c4Slazypassion     }
416747ad3c4Slazypassion }
417747ad3c4Slazypassion 
4188a9b1a90SBenjamin Bouvier /// A translated `ExternalName` into something global we can handle.
41967c85b88Sbjorn3 #[derive(Clone, Debug)]
4209ec02f9dSChristopher Serr #[cfg_attr(
4219ec02f9dSChristopher Serr     feature = "enable-serde",
4229ec02f9dSChristopher Serr     derive(serde_derive::Serialize, serde_derive::Deserialize)
4239ec02f9dSChristopher Serr )]
424b23f534cSAfonso Bordado pub enum ModuleRelocTarget {
4258a9b1a90SBenjamin Bouvier     /// User defined function, converted from `ExternalName::User`.
4268a9b1a90SBenjamin Bouvier     User {
4278a9b1a90SBenjamin Bouvier         /// Arbitrary.
4288a9b1a90SBenjamin Bouvier         namespace: u32,
4298a9b1a90SBenjamin Bouvier         /// Arbitrary.
4308a9b1a90SBenjamin Bouvier         index: u32,
4318a9b1a90SBenjamin Bouvier     },
4328a9b1a90SBenjamin Bouvier     /// Call into a library function.
4338a9b1a90SBenjamin Bouvier     LibCall(ir::LibCall),
4348a9b1a90SBenjamin Bouvier     /// Symbols known to the linker.
4358a9b1a90SBenjamin Bouvier     KnownSymbol(ir::KnownSymbol),
436b23f534cSAfonso Bordado     /// A offset inside a function
4379fc4a710SAfonso Bordado     FunctionOffset(FuncId, CodeOffset),
4388a9b1a90SBenjamin Bouvier }
4398a9b1a90SBenjamin Bouvier 
440b23f534cSAfonso Bordado impl ModuleRelocTarget {
4418a9b1a90SBenjamin Bouvier     /// Creates a user-defined external name.
user(namespace: u32, index: u32) -> Self4428a9b1a90SBenjamin Bouvier     pub fn user(namespace: u32, index: u32) -> Self {
4438a9b1a90SBenjamin Bouvier         Self::User { namespace, index }
4448a9b1a90SBenjamin Bouvier     }
4458a9b1a90SBenjamin Bouvier }
4468a9b1a90SBenjamin Bouvier 
447b23f534cSAfonso Bordado impl Display for ModuleRelocTarget {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result4488a9b1a90SBenjamin Bouvier     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4498a9b1a90SBenjamin Bouvier         match self {
450a0442ea0SHamir Mahal             Self::User { namespace, index } => write!(f, "u{namespace}:{index}"),
451a0442ea0SHamir Mahal             Self::LibCall(lc) => write!(f, "%{lc}"),
452a0442ea0SHamir Mahal             Self::KnownSymbol(ks) => write!(f, "{ks}"),
453b23f534cSAfonso Bordado             Self::FunctionOffset(fname, offset) => write!(f, "{fname}+{offset}"),
4548a9b1a90SBenjamin Bouvier         }
4558a9b1a90SBenjamin Bouvier     }
4568a9b1a90SBenjamin Bouvier }
4578a9b1a90SBenjamin Bouvier 
458b1187b55Sbjorn3 /// This provides a view to the state of a module which allows `ir::ExternalName`s to be translated
459b1187b55Sbjorn3 /// into `FunctionDeclaration`s and `DataDeclaration`s.
4607a2a4bc9Sbjorn3 #[derive(Debug, Default)]
461588a4be0Sbjorn3 pub struct ModuleDeclarations {
46291d1d246Sbjorn3     /// A version marker used to ensure that serialized clif ir is never deserialized with a
46391d1d246Sbjorn3     /// different version of Cranelift.
46491d1d246Sbjorn3     // Note: This must be the first field to ensure that Serde will deserialize it before
46591d1d246Sbjorn3     // attempting to deserialize other fields that are potentially changed between versions.
46691d1d246Sbjorn3     _version_marker: VersionMarker,
46791d1d246Sbjorn3 
46880f4ecf9Sbjorn3     names: HashMap<String, FuncOrDataId>,
469588a4be0Sbjorn3     functions: PrimaryMap<FuncId, FunctionDeclaration>,
470588a4be0Sbjorn3     data_objects: PrimaryMap<DataId, DataDeclaration>,
471747ad3c4Slazypassion }
472747ad3c4Slazypassion 
47391d1d246Sbjorn3 #[cfg(feature = "enable-serde")]
47491d1d246Sbjorn3 mod serialize {
47591d1d246Sbjorn3     // This is manually implementing Serialize and Deserialize to avoid serializing the names field,
47691d1d246Sbjorn3     // which can be entirely reconstructed from the functions and data_objects fields, saving space.
47791d1d246Sbjorn3 
47891d1d246Sbjorn3     use super::*;
47991d1d246Sbjorn3 
48091d1d246Sbjorn3     use serde::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Unexpected, Visitor};
48191d1d246Sbjorn3     use serde::ser::{Serialize, SerializeStruct, Serializer};
48291d1d246Sbjorn3     use std::fmt;
48391d1d246Sbjorn3 
get_names<E: Error>( functions: &PrimaryMap<FuncId, FunctionDeclaration>, data_objects: &PrimaryMap<DataId, DataDeclaration>, ) -> Result<HashMap<String, FuncOrDataId>, E>48491d1d246Sbjorn3     fn get_names<E: Error>(
48591d1d246Sbjorn3         functions: &PrimaryMap<FuncId, FunctionDeclaration>,
48691d1d246Sbjorn3         data_objects: &PrimaryMap<DataId, DataDeclaration>,
48791d1d246Sbjorn3     ) -> Result<HashMap<String, FuncOrDataId>, E> {
48891d1d246Sbjorn3         let mut names = HashMap::new();
48991d1d246Sbjorn3         for (func_id, decl) in functions.iter() {
49091d1d246Sbjorn3             if let Some(name) = &decl.name {
49191d1d246Sbjorn3                 let old = names.insert(name.clone(), FuncOrDataId::Func(func_id));
49291d1d246Sbjorn3                 if old.is_some() {
49391d1d246Sbjorn3                     return Err(E::invalid_value(
49491d1d246Sbjorn3                         Unexpected::Other("duplicate name"),
49591d1d246Sbjorn3                         &"FunctionDeclaration's with no duplicate names",
49691d1d246Sbjorn3                     ));
49791d1d246Sbjorn3                 }
49891d1d246Sbjorn3             }
49991d1d246Sbjorn3         }
50091d1d246Sbjorn3         for (data_id, decl) in data_objects.iter() {
50191d1d246Sbjorn3             if let Some(name) = &decl.name {
50291d1d246Sbjorn3                 let old = names.insert(name.clone(), FuncOrDataId::Data(data_id));
50391d1d246Sbjorn3                 if old.is_some() {
50491d1d246Sbjorn3                     return Err(E::invalid_value(
50591d1d246Sbjorn3                         Unexpected::Other("duplicate name"),
50691d1d246Sbjorn3                         &"DataDeclaration's with no duplicate names",
50791d1d246Sbjorn3                     ));
50891d1d246Sbjorn3                 }
50991d1d246Sbjorn3             }
51091d1d246Sbjorn3         }
51191d1d246Sbjorn3         Ok(names)
51291d1d246Sbjorn3     }
51391d1d246Sbjorn3 
51491d1d246Sbjorn3     impl Serialize for ModuleDeclarations {
serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error>51591d1d246Sbjorn3         fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
51691d1d246Sbjorn3             let ModuleDeclarations {
51791d1d246Sbjorn3                 _version_marker,
51891d1d246Sbjorn3                 functions,
51991d1d246Sbjorn3                 data_objects,
52091d1d246Sbjorn3                 names: _,
52191d1d246Sbjorn3             } = self;
52291d1d246Sbjorn3 
52391d1d246Sbjorn3             let mut state = s.serialize_struct("ModuleDeclarations", 4)?;
52491d1d246Sbjorn3             state.serialize_field("_version_marker", _version_marker)?;
52591d1d246Sbjorn3             state.serialize_field("functions", functions)?;
52691d1d246Sbjorn3             state.serialize_field("data_objects", data_objects)?;
52791d1d246Sbjorn3             state.end()
52891d1d246Sbjorn3         }
52991d1d246Sbjorn3     }
53091d1d246Sbjorn3 
53191d1d246Sbjorn3     enum ModuleDeclarationsField {
53291d1d246Sbjorn3         VersionMarker,
53391d1d246Sbjorn3         Functions,
53491d1d246Sbjorn3         DataObjects,
53591d1d246Sbjorn3         Ignore,
53691d1d246Sbjorn3     }
53791d1d246Sbjorn3 
53891d1d246Sbjorn3     struct ModuleDeclarationsFieldVisitor;
53991d1d246Sbjorn3 
54091d1d246Sbjorn3     impl<'de> serde::de::Visitor<'de> for ModuleDeclarationsFieldVisitor {
54191d1d246Sbjorn3         type Value = ModuleDeclarationsField;
54291d1d246Sbjorn3 
expecting(&self, f: &mut fmt::Formatter) -> fmt::Result54391d1d246Sbjorn3         fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
54491d1d246Sbjorn3             f.write_str("field identifier")
54591d1d246Sbjorn3         }
54691d1d246Sbjorn3 
visit_u64<E: Error>(self, val: u64) -> Result<Self::Value, E>54791d1d246Sbjorn3         fn visit_u64<E: Error>(self, val: u64) -> Result<Self::Value, E> {
54891d1d246Sbjorn3             match val {
54991d1d246Sbjorn3                 0u64 => Ok(ModuleDeclarationsField::VersionMarker),
55091d1d246Sbjorn3                 1u64 => Ok(ModuleDeclarationsField::Functions),
55191d1d246Sbjorn3                 2u64 => Ok(ModuleDeclarationsField::DataObjects),
55291d1d246Sbjorn3                 _ => Ok(ModuleDeclarationsField::Ignore),
55391d1d246Sbjorn3             }
55491d1d246Sbjorn3         }
55591d1d246Sbjorn3 
visit_str<E: Error>(self, val: &str) -> Result<Self::Value, E>55691d1d246Sbjorn3         fn visit_str<E: Error>(self, val: &str) -> Result<Self::Value, E> {
55791d1d246Sbjorn3             match val {
55891d1d246Sbjorn3                 "_version_marker" => Ok(ModuleDeclarationsField::VersionMarker),
55991d1d246Sbjorn3                 "functions" => Ok(ModuleDeclarationsField::Functions),
56091d1d246Sbjorn3                 "data_objects" => Ok(ModuleDeclarationsField::DataObjects),
56191d1d246Sbjorn3                 _ => Ok(ModuleDeclarationsField::Ignore),
56291d1d246Sbjorn3             }
56391d1d246Sbjorn3         }
56491d1d246Sbjorn3 
visit_bytes<E: Error>(self, val: &[u8]) -> Result<Self::Value, E>56591d1d246Sbjorn3         fn visit_bytes<E: Error>(self, val: &[u8]) -> Result<Self::Value, E> {
56691d1d246Sbjorn3             match val {
56791d1d246Sbjorn3                 b"_version_marker" => Ok(ModuleDeclarationsField::VersionMarker),
56891d1d246Sbjorn3                 b"functions" => Ok(ModuleDeclarationsField::Functions),
56991d1d246Sbjorn3                 b"data_objects" => Ok(ModuleDeclarationsField::DataObjects),
57091d1d246Sbjorn3                 _ => Ok(ModuleDeclarationsField::Ignore),
57191d1d246Sbjorn3             }
57291d1d246Sbjorn3         }
57391d1d246Sbjorn3     }
57491d1d246Sbjorn3 
57591d1d246Sbjorn3     impl<'de> Deserialize<'de> for ModuleDeclarationsField {
57691d1d246Sbjorn3         #[inline]
deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error>57791d1d246Sbjorn3         fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
57891d1d246Sbjorn3             d.deserialize_identifier(ModuleDeclarationsFieldVisitor)
57991d1d246Sbjorn3         }
58091d1d246Sbjorn3     }
58191d1d246Sbjorn3 
58291d1d246Sbjorn3     struct ModuleDeclarationsVisitor;
58391d1d246Sbjorn3 
58491d1d246Sbjorn3     impl<'de> Visitor<'de> for ModuleDeclarationsVisitor {
58591d1d246Sbjorn3         type Value = ModuleDeclarations;
58691d1d246Sbjorn3 
expecting(&self, f: &mut fmt::Formatter) -> fmt::Result58791d1d246Sbjorn3         fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
58891d1d246Sbjorn3             f.write_str("struct ModuleDeclarations")
58991d1d246Sbjorn3         }
59091d1d246Sbjorn3 
59191d1d246Sbjorn3         #[inline]
visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>59291d1d246Sbjorn3         fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
59391d1d246Sbjorn3             let _version_marker = match seq.next_element()? {
59491d1d246Sbjorn3                 Some(val) => val,
59591d1d246Sbjorn3                 None => {
59691d1d246Sbjorn3                     return Err(Error::invalid_length(
59791d1d246Sbjorn3                         0usize,
59891d1d246Sbjorn3                         &"struct ModuleDeclarations with 4 elements",
59991d1d246Sbjorn3                     ));
60091d1d246Sbjorn3                 }
60191d1d246Sbjorn3             };
60291d1d246Sbjorn3             let functions = match seq.next_element()? {
60391d1d246Sbjorn3                 Some(val) => val,
60491d1d246Sbjorn3                 None => {
60591d1d246Sbjorn3                     return Err(Error::invalid_length(
60691d1d246Sbjorn3                         2usize,
60791d1d246Sbjorn3                         &"struct ModuleDeclarations with 4 elements",
60891d1d246Sbjorn3                     ));
60991d1d246Sbjorn3                 }
61091d1d246Sbjorn3             };
61191d1d246Sbjorn3             let data_objects = match seq.next_element()? {
61291d1d246Sbjorn3                 Some(val) => val,
61391d1d246Sbjorn3                 None => {
61491d1d246Sbjorn3                     return Err(Error::invalid_length(
61591d1d246Sbjorn3                         3usize,
61691d1d246Sbjorn3                         &"struct ModuleDeclarations with 4 elements",
61791d1d246Sbjorn3                     ));
61891d1d246Sbjorn3                 }
61991d1d246Sbjorn3             };
62091d1d246Sbjorn3             let names = get_names(&functions, &data_objects)?;
62191d1d246Sbjorn3             Ok(ModuleDeclarations {
62291d1d246Sbjorn3                 _version_marker,
62391d1d246Sbjorn3                 names,
62491d1d246Sbjorn3                 functions,
62591d1d246Sbjorn3                 data_objects,
62691d1d246Sbjorn3             })
62791d1d246Sbjorn3         }
62891d1d246Sbjorn3 
62991d1d246Sbjorn3         #[inline]
visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error>63091d1d246Sbjorn3         fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
63191d1d246Sbjorn3             let mut _version_marker: Option<VersionMarker> = None;
63291d1d246Sbjorn3             let mut functions: Option<PrimaryMap<FuncId, FunctionDeclaration>> = None;
63391d1d246Sbjorn3             let mut data_objects: Option<PrimaryMap<DataId, DataDeclaration>> = None;
63491d1d246Sbjorn3             while let Some(key) = map.next_key::<ModuleDeclarationsField>()? {
63591d1d246Sbjorn3                 match key {
63691d1d246Sbjorn3                     ModuleDeclarationsField::VersionMarker => {
63791d1d246Sbjorn3                         if _version_marker.is_some() {
63891d1d246Sbjorn3                             return Err(Error::duplicate_field("_version_marker"));
63991d1d246Sbjorn3                         }
64091d1d246Sbjorn3                         _version_marker = Some(map.next_value()?);
64191d1d246Sbjorn3                     }
64291d1d246Sbjorn3                     ModuleDeclarationsField::Functions => {
64391d1d246Sbjorn3                         if functions.is_some() {
64491d1d246Sbjorn3                             return Err(Error::duplicate_field("functions"));
64591d1d246Sbjorn3                         }
64691d1d246Sbjorn3                         functions = Some(map.next_value()?);
64791d1d246Sbjorn3                     }
64891d1d246Sbjorn3                     ModuleDeclarationsField::DataObjects => {
64991d1d246Sbjorn3                         if data_objects.is_some() {
65091d1d246Sbjorn3                             return Err(Error::duplicate_field("data_objects"));
65191d1d246Sbjorn3                         }
65291d1d246Sbjorn3                         data_objects = Some(map.next_value()?);
65391d1d246Sbjorn3                     }
65491d1d246Sbjorn3                     _ => {
65591d1d246Sbjorn3                         map.next_value::<serde::de::IgnoredAny>()?;
65691d1d246Sbjorn3                     }
65791d1d246Sbjorn3                 }
65891d1d246Sbjorn3             }
65991d1d246Sbjorn3             let _version_marker = match _version_marker {
66091d1d246Sbjorn3                 Some(_version_marker) => _version_marker,
66191d1d246Sbjorn3                 None => return Err(Error::missing_field("_version_marker")),
66291d1d246Sbjorn3             };
66391d1d246Sbjorn3             let functions = match functions {
66491d1d246Sbjorn3                 Some(functions) => functions,
66591d1d246Sbjorn3                 None => return Err(Error::missing_field("functions")),
66691d1d246Sbjorn3             };
66791d1d246Sbjorn3             let data_objects = match data_objects {
66891d1d246Sbjorn3                 Some(data_objects) => data_objects,
66991d1d246Sbjorn3                 None => return Err(Error::missing_field("data_objects")),
67091d1d246Sbjorn3             };
67191d1d246Sbjorn3             let names = get_names(&functions, &data_objects)?;
67291d1d246Sbjorn3             Ok(ModuleDeclarations {
67391d1d246Sbjorn3                 _version_marker,
67491d1d246Sbjorn3                 names,
67591d1d246Sbjorn3                 functions,
67691d1d246Sbjorn3                 data_objects,
67791d1d246Sbjorn3             })
67891d1d246Sbjorn3         }
67991d1d246Sbjorn3     }
68091d1d246Sbjorn3 
68191d1d246Sbjorn3     impl<'de> Deserialize<'de> for ModuleDeclarations {
deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error>68291d1d246Sbjorn3         fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
68391d1d246Sbjorn3             d.deserialize_struct(
68491d1d246Sbjorn3                 "ModuleDeclarations",
68591d1d246Sbjorn3                 &["_version_marker", "functions", "data_objects"],
68691d1d246Sbjorn3                 ModuleDeclarationsVisitor,
68791d1d246Sbjorn3             )
68891d1d246Sbjorn3         }
68991d1d246Sbjorn3     }
69091d1d246Sbjorn3 }
69191d1d246Sbjorn3 
692588a4be0Sbjorn3 impl ModuleDeclarations {
69380f4ecf9Sbjorn3     /// Get the module identifier for a given name, if that name
69480f4ecf9Sbjorn3     /// has been declared.
get_name(&self, name: &str) -> Option<FuncOrDataId>69580f4ecf9Sbjorn3     pub fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
69680f4ecf9Sbjorn3         self.names.get(name).copied()
69780f4ecf9Sbjorn3     }
69880f4ecf9Sbjorn3 
69913c6bdd9SPat Hickey     /// Get an iterator of all function declarations
get_functions(&self) -> impl Iterator<Item = (FuncId, &FunctionDeclaration)>70013c6bdd9SPat Hickey     pub fn get_functions(&self) -> impl Iterator<Item = (FuncId, &FunctionDeclaration)> {
70113c6bdd9SPat Hickey         self.functions.iter()
70213c6bdd9SPat Hickey     }
70313c6bdd9SPat Hickey 
704844a52e9Sbjorn3     /// Return whether `name` names a function, rather than a data object.
is_function(name: &ModuleRelocTarget) -> bool705b23f534cSAfonso Bordado     pub fn is_function(name: &ModuleRelocTarget) -> bool {
7068a9b1a90SBenjamin Bouvier         match name {
707b23f534cSAfonso Bordado             ModuleRelocTarget::User { namespace, .. } => *namespace == 0,
708b23f534cSAfonso Bordado             ModuleRelocTarget::LibCall(_)
709b23f534cSAfonso Bordado             | ModuleRelocTarget::KnownSymbol(_)
710b23f534cSAfonso Bordado             | ModuleRelocTarget::FunctionOffset(..) => {
7118a9b1a90SBenjamin Bouvier                 panic!("unexpected module ext name")
7128a9b1a90SBenjamin Bouvier             }
713747ad3c4Slazypassion         }
714747ad3c4Slazypassion     }
7153293ca6bSPhilip Craig 
716588a4be0Sbjorn3     /// Get the `FunctionDeclaration` for the function named by `name`.
get_function_decl(&self, func_id: FuncId) -> &FunctionDeclaration717588a4be0Sbjorn3     pub fn get_function_decl(&self, func_id: FuncId) -> &FunctionDeclaration {
718405b9e28Sbjorn3         &self.functions[func_id]
719405b9e28Sbjorn3     }
720405b9e28Sbjorn3 
72113c6bdd9SPat Hickey     /// Get an iterator of all data declarations
get_data_objects(&self) -> impl Iterator<Item = (DataId, &DataDeclaration)>72213c6bdd9SPat Hickey     pub fn get_data_objects(&self) -> impl Iterator<Item = (DataId, &DataDeclaration)> {
72313c6bdd9SPat Hickey         self.data_objects.iter()
72413c6bdd9SPat Hickey     }
72513c6bdd9SPat Hickey 
7263293ca6bSPhilip Craig     /// Get the `DataDeclaration` for the data object named by `name`.
get_data_decl(&self, data_id: DataId) -> &DataDeclaration727588a4be0Sbjorn3     pub fn get_data_decl(&self, data_id: DataId) -> &DataDeclaration {
728588a4be0Sbjorn3         &self.data_objects[data_id]
729747ad3c4Slazypassion     }
730747ad3c4Slazypassion 
73180f4ecf9Sbjorn3     /// Declare a function in this module.
declare_function( &mut self, name: &str, linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult<(FuncId, Linkage)>73280f4ecf9Sbjorn3     pub fn declare_function(
73380f4ecf9Sbjorn3         &mut self,
73480f4ecf9Sbjorn3         name: &str,
73580f4ecf9Sbjorn3         linkage: Linkage,
73680f4ecf9Sbjorn3         signature: &ir::Signature,
737cc891114Sbjorn3     ) -> ModuleResult<(FuncId, Linkage)> {
73880f4ecf9Sbjorn3         // TODO: Can we avoid allocating names so often?
73980f4ecf9Sbjorn3         use super::hash_map::Entry::*;
74080f4ecf9Sbjorn3         match self.names.entry(name.to_owned()) {
74180f4ecf9Sbjorn3             Occupied(entry) => match *entry.get() {
74280f4ecf9Sbjorn3                 FuncOrDataId::Func(id) => {
74380f4ecf9Sbjorn3                     let existing = &mut self.functions[id];
74491d1d246Sbjorn3                     existing.merge(id, linkage, signature)?;
745cc891114Sbjorn3                     Ok((id, existing.linkage))
74680f4ecf9Sbjorn3                 }
74780f4ecf9Sbjorn3                 FuncOrDataId::Data(..) => {
74880f4ecf9Sbjorn3                     Err(ModuleError::IncompatibleDeclaration(name.to_owned()))
74980f4ecf9Sbjorn3                 }
75080f4ecf9Sbjorn3             },
75180f4ecf9Sbjorn3             Vacant(entry) => {
75280f4ecf9Sbjorn3                 let id = self.functions.push(FunctionDeclaration {
75391d1d246Sbjorn3                     name: Some(name.to_owned()),
75480f4ecf9Sbjorn3                     linkage,
75580f4ecf9Sbjorn3                     signature: signature.clone(),
75680f4ecf9Sbjorn3                 });
75780f4ecf9Sbjorn3                 entry.insert(FuncOrDataId::Func(id));
758cc891114Sbjorn3                 Ok((id, self.functions[id].linkage))
75980f4ecf9Sbjorn3             }
76080f4ecf9Sbjorn3         }
76180f4ecf9Sbjorn3     }
76280f4ecf9Sbjorn3 
763cc891114Sbjorn3     /// Declare an anonymous function in this module.
declare_anonymous_function( &mut self, signature: &ir::Signature, ) -> ModuleResult<FuncId>764cc891114Sbjorn3     pub fn declare_anonymous_function(
765cc891114Sbjorn3         &mut self,
766cc891114Sbjorn3         signature: &ir::Signature,
767cc891114Sbjorn3     ) -> ModuleResult<FuncId> {
768cc891114Sbjorn3         let id = self.functions.push(FunctionDeclaration {
76991d1d246Sbjorn3             name: None,
770cc891114Sbjorn3             linkage: Linkage::Local,
771cc891114Sbjorn3             signature: signature.clone(),
772cc891114Sbjorn3         });
773cc891114Sbjorn3         Ok(id)
774cc891114Sbjorn3     }
775cc891114Sbjorn3 
77680f4ecf9Sbjorn3     /// Declare a data object in this module.
declare_data( &mut self, name: &str, linkage: Linkage, writable: bool, tls: bool, ) -> ModuleResult<(DataId, Linkage)>77780f4ecf9Sbjorn3     pub fn declare_data(
77880f4ecf9Sbjorn3         &mut self,
77980f4ecf9Sbjorn3         name: &str,
78080f4ecf9Sbjorn3         linkage: Linkage,
78180f4ecf9Sbjorn3         writable: bool,
78280f4ecf9Sbjorn3         tls: bool,
783cc891114Sbjorn3     ) -> ModuleResult<(DataId, Linkage)> {
78480f4ecf9Sbjorn3         // TODO: Can we avoid allocating names so often?
78580f4ecf9Sbjorn3         use super::hash_map::Entry::*;
78680f4ecf9Sbjorn3         match self.names.entry(name.to_owned()) {
78780f4ecf9Sbjorn3             Occupied(entry) => match *entry.get() {
78880f4ecf9Sbjorn3                 FuncOrDataId::Data(id) => {
78980f4ecf9Sbjorn3                     let existing = &mut self.data_objects[id];
79084c6ec32Sbjorn3                     existing.merge(linkage, writable, tls);
791cc891114Sbjorn3                     Ok((id, existing.linkage))
79280f4ecf9Sbjorn3                 }
79380f4ecf9Sbjorn3 
79480f4ecf9Sbjorn3                 FuncOrDataId::Func(..) => {
79580f4ecf9Sbjorn3                     Err(ModuleError::IncompatibleDeclaration(name.to_owned()))
79680f4ecf9Sbjorn3                 }
79780f4ecf9Sbjorn3             },
79880f4ecf9Sbjorn3             Vacant(entry) => {
79980f4ecf9Sbjorn3                 let id = self.data_objects.push(DataDeclaration {
80091d1d246Sbjorn3                     name: Some(name.to_owned()),
80180f4ecf9Sbjorn3                     linkage,
80280f4ecf9Sbjorn3                     writable,
80380f4ecf9Sbjorn3                     tls,
80480f4ecf9Sbjorn3                 });
80580f4ecf9Sbjorn3                 entry.insert(FuncOrDataId::Data(id));
806cc891114Sbjorn3                 Ok((id, self.data_objects[id].linkage))
80780f4ecf9Sbjorn3             }
80880f4ecf9Sbjorn3         }
80980f4ecf9Sbjorn3     }
810cc891114Sbjorn3 
811cc891114Sbjorn3     /// Declare an anonymous data object in this module.
declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>812cc891114Sbjorn3     pub fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> {
813cc891114Sbjorn3         let id = self.data_objects.push(DataDeclaration {
81491d1d246Sbjorn3             name: None,
815cc891114Sbjorn3             linkage: Linkage::Local,
816cc891114Sbjorn3             writable,
817cc891114Sbjorn3             tls,
818cc891114Sbjorn3         });
819cc891114Sbjorn3         Ok(id)
820cc891114Sbjorn3     }
821747ad3c4Slazypassion }
822747ad3c4Slazypassion 
823d84ca235Sbjorn3 /// A `Module` is a utility for collecting functions and data objects, and linking them together.
824d84ca235Sbjorn3 pub trait Module {
825d84ca235Sbjorn3     /// Return the `TargetIsa` to compile for.
isa(&self) -> &dyn isa::TargetIsa826d84ca235Sbjorn3     fn isa(&self) -> &dyn isa::TargetIsa;
827d84ca235Sbjorn3 
828d84ca235Sbjorn3     /// Get all declarations in this module.
declarations(&self) -> &ModuleDeclarations829d84ca235Sbjorn3     fn declarations(&self) -> &ModuleDeclarations;
830747ad3c4Slazypassion 
831747ad3c4Slazypassion     /// Get the module identifier for a given name, if that name
832747ad3c4Slazypassion     /// has been declared.
get_name(&self, name: &str) -> Option<FuncOrDataId>833d84ca235Sbjorn3     fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
834d84ca235Sbjorn3         self.declarations().get_name(name)
835747ad3c4Slazypassion     }
836747ad3c4Slazypassion 
837747ad3c4Slazypassion     /// Return the target information needed by frontends to produce Cranelift IR
838747ad3c4Slazypassion     /// for the current target.
target_config(&self) -> isa::TargetFrontendConfig839d84ca235Sbjorn3     fn target_config(&self) -> isa::TargetFrontendConfig {
840c2ffcdc6Sbjorn3         self.isa().frontend_config()
841747ad3c4Slazypassion     }
842747ad3c4Slazypassion 
843747ad3c4Slazypassion     /// Create a new `Context` initialized for use with this `Module`.
844747ad3c4Slazypassion     ///
845747ad3c4Slazypassion     /// This ensures that the `Context` is initialized with the default calling
846747ad3c4Slazypassion     /// convention for the `TargetIsa`.
make_context(&self) -> Context847d84ca235Sbjorn3     fn make_context(&self) -> Context {
848747ad3c4Slazypassion         let mut ctx = Context::new();
849c2ffcdc6Sbjorn3         ctx.func.signature.call_conv = self.isa().default_call_conv();
850747ad3c4Slazypassion         ctx
851747ad3c4Slazypassion     }
852747ad3c4Slazypassion 
853747ad3c4Slazypassion     /// Clear the given `Context` and reset it for use with a new function.
854747ad3c4Slazypassion     ///
855747ad3c4Slazypassion     /// This ensures that the `Context` is initialized with the default calling
856747ad3c4Slazypassion     /// convention for the `TargetIsa`.
clear_context(&self, ctx: &mut Context)857d84ca235Sbjorn3     fn clear_context(&self, ctx: &mut Context) {
858747ad3c4Slazypassion         ctx.clear();
859c2ffcdc6Sbjorn3         ctx.func.signature.call_conv = self.isa().default_call_conv();
860747ad3c4Slazypassion     }
861747ad3c4Slazypassion 
862747ad3c4Slazypassion     /// Create a new empty `Signature` with the default calling convention for
863747ad3c4Slazypassion     /// the `TargetIsa`, to which parameter and return types can be added for
864747ad3c4Slazypassion     /// declaring a function to be called by this `Module`.
make_signature(&self) -> ir::Signature865d84ca235Sbjorn3     fn make_signature(&self) -> ir::Signature {
866c2ffcdc6Sbjorn3         ir::Signature::new(self.isa().default_call_conv())
867747ad3c4Slazypassion     }
868747ad3c4Slazypassion 
869747ad3c4Slazypassion     /// Clear the given `Signature` and reset for use with a new function.
870747ad3c4Slazypassion     ///
871747ad3c4Slazypassion     /// This ensures that the `Signature` is initialized with the default
872747ad3c4Slazypassion     /// calling convention for the `TargetIsa`.
clear_signature(&self, sig: &mut ir::Signature)873d84ca235Sbjorn3     fn clear_signature(&self, sig: &mut ir::Signature) {
874c2ffcdc6Sbjorn3         sig.clear(self.isa().default_call_conv());
875747ad3c4Slazypassion     }
876747ad3c4Slazypassion 
877747ad3c4Slazypassion     /// Declare a function in this module.
declare_function( &mut self, name: &str, linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult<FuncId>878d84ca235Sbjorn3     fn declare_function(
879747ad3c4Slazypassion         &mut self,
880747ad3c4Slazypassion         name: &str,
881747ad3c4Slazypassion         linkage: Linkage,
882747ad3c4Slazypassion         signature: &ir::Signature,
883d84ca235Sbjorn3     ) -> ModuleResult<FuncId>;
88445013a1dSiximeow 
885cc891114Sbjorn3     /// Declare an anonymous function in this module.
declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>886cc891114Sbjorn3     fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>;
887cc891114Sbjorn3 
888747ad3c4Slazypassion     /// Declare a data object in this module.
declare_data( &mut self, name: &str, linkage: Linkage, writable: bool, tls: bool, ) -> ModuleResult<DataId>889d84ca235Sbjorn3     fn declare_data(
890747ad3c4Slazypassion         &mut self,
891747ad3c4Slazypassion         name: &str,
892747ad3c4Slazypassion         linkage: Linkage,
893747ad3c4Slazypassion         writable: bool,
8940a1bb3baSbjorn3         tls: bool,
895d84ca235Sbjorn3     ) -> ModuleResult<DataId>;
896747ad3c4Slazypassion 
897cc891114Sbjorn3     /// Declare an anonymous data object in this module.
declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>898cc891114Sbjorn3     fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>;
899cc891114Sbjorn3 
900747ad3c4Slazypassion     /// Use this when you're building the IR of a function to reference a function.
901747ad3c4Slazypassion     ///
902747ad3c4Slazypassion     /// TODO: Coalesce redundant decls and signatures.
903747ad3c4Slazypassion     /// TODO: Look into ways to reduce the risk of using a FuncRef in the wrong function.
declare_func_in_func(&mut self, func_id: FuncId, func: &mut ir::Function) -> ir::FuncRef9048a9b1a90SBenjamin Bouvier     fn declare_func_in_func(&mut self, func_id: FuncId, func: &mut ir::Function) -> ir::FuncRef {
9058a9b1a90SBenjamin Bouvier         let decl = &self.declarations().functions[func_id];
9068a9b1a90SBenjamin Bouvier         let signature = func.import_signature(decl.signature.clone());
9078a9b1a90SBenjamin Bouvier         let user_name_ref = func.declare_imported_user_function(ir::UserExternalName {
9088a9b1a90SBenjamin Bouvier             namespace: 0,
9098a9b1a90SBenjamin Bouvier             index: func_id.as_u32(),
9108a9b1a90SBenjamin Bouvier         });
911747ad3c4Slazypassion         let colocated = decl.linkage.is_final();
9128a9b1a90SBenjamin Bouvier         func.import_function(ir::ExtFuncData {
9138a9b1a90SBenjamin Bouvier             name: ir::ExternalName::user(user_name_ref),
914747ad3c4Slazypassion             signature,
915747ad3c4Slazypassion             colocated,
91687ed3b60SChris Fallin             patchable: false,
917747ad3c4Slazypassion         })
918747ad3c4Slazypassion     }
919747ad3c4Slazypassion 
920747ad3c4Slazypassion     /// Use this when you're building the IR of a function to reference a data object.
921747ad3c4Slazypassion     ///
922747ad3c4Slazypassion     /// TODO: Same as above.
declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue923d84ca235Sbjorn3     fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
924d84ca235Sbjorn3         let decl = &self.declarations().data_objects[data];
925747ad3c4Slazypassion         let colocated = decl.linkage.is_final();
9268a9b1a90SBenjamin Bouvier         let user_name_ref = func.declare_imported_user_function(ir::UserExternalName {
9278a9b1a90SBenjamin Bouvier             namespace: 1,
9288a9b1a90SBenjamin Bouvier             index: data.as_u32(),
9298a9b1a90SBenjamin Bouvier         });
930747ad3c4Slazypassion         func.create_global_value(ir::GlobalValueData::Symbol {
9318a9b1a90SBenjamin Bouvier             name: ir::ExternalName::user(user_name_ref),
932747ad3c4Slazypassion             offset: ir::immediates::Imm64::new(0),
933747ad3c4Slazypassion             colocated,
9340a1bb3baSbjorn3             tls: decl.tls,
935747ad3c4Slazypassion         })
936747ad3c4Slazypassion     }
937747ad3c4Slazypassion 
938747ad3c4Slazypassion     /// TODO: Same as above.
declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef93967c85b88Sbjorn3     fn declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef {
940b23f534cSAfonso Bordado         data.import_function(ModuleRelocTarget::user(0, func_id.as_u32()))
941747ad3c4Slazypassion     }
942747ad3c4Slazypassion 
943747ad3c4Slazypassion     /// TODO: Same as above.
declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue94467c85b88Sbjorn3     fn declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue {
945b23f534cSAfonso Bordado         data.import_global_value(ModuleRelocTarget::user(1, data_id.as_u32()))
946747ad3c4Slazypassion     }
947747ad3c4Slazypassion 
948747ad3c4Slazypassion     /// Define a function, producing the function body from the given `Context`.
949615499baSbjorn3     ///
950420850adSLars T Hansen     /// Returns the size of the function's code and constant data.
951615499baSbjorn3     ///
952e1812b61Sbjorn3     /// Unlike [`define_function_with_control_plane`] this uses a default [`ControlPlane`] for
953e1812b61Sbjorn3     /// convenience.
954e1812b61Sbjorn3     ///
955615499baSbjorn3     /// Note: After calling this function the given `Context` will contain the compiled function.
956e1812b61Sbjorn3     ///
957e1812b61Sbjorn3     /// [`define_function_with_control_plane`]: Self::define_function_with_control_plane
define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()>95891d1d246Sbjorn3     fn define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()> {
959e1812b61Sbjorn3         self.define_function_with_control_plane(func, ctx, &mut ControlPlane::default())
960e1812b61Sbjorn3     }
961e1812b61Sbjorn3 
962e1812b61Sbjorn3     /// Define a function, producing the function body from the given `Context`.
963e1812b61Sbjorn3     ///
964e1812b61Sbjorn3     /// Returns the size of the function's code and constant data.
965e1812b61Sbjorn3     ///
966e1812b61Sbjorn3     /// Note: After calling this function the given `Context` will contain the compiled function.
define_function_with_control_plane( &mut self, func: FuncId, ctx: &mut Context, ctrl_plane: &mut ControlPlane, ) -> ModuleResult<()>967e1812b61Sbjorn3     fn define_function_with_control_plane(
968e1812b61Sbjorn3         &mut self,
969e1812b61Sbjorn3         func: FuncId,
970e1812b61Sbjorn3         ctx: &mut Context,
9717eb89140SRemo Senekowitsch         ctrl_plane: &mut ControlPlane,
97291d1d246Sbjorn3     ) -> ModuleResult<()>;
973747ad3c4Slazypassion 
97409c6c5dbSNathan Froyd     /// Define a function, taking the function body from the given `bytes`.
97509c6c5dbSNathan Froyd     ///
97609c6c5dbSNathan Froyd     /// This function is generally only useful if you need to precisely specify
97709c6c5dbSNathan Froyd     /// the emitted instructions for some reason; otherwise, you should use
97809c6c5dbSNathan Froyd     /// `define_function`.
97909c6c5dbSNathan Froyd     ///
98009c6c5dbSNathan Froyd     /// Returns the size of the function's code.
define_function_bytes( &mut self, func_id: FuncId, alignment: u64, bytes: &[u8], relocs: &[ModuleReloc], ) -> ModuleResult<()>981d84ca235Sbjorn3     fn define_function_bytes(
98209c6c5dbSNathan Froyd         &mut self,
9838a9b1a90SBenjamin Bouvier         func_id: FuncId,
984dde2c5a3STrevor Elliott         alignment: u64,
98509c6c5dbSNathan Froyd         bytes: &[u8],
986716ebceaSbjorn3         relocs: &[ModuleReloc],
98791d1d246Sbjorn3     ) -> ModuleResult<()>;
98809c6c5dbSNathan Froyd 
9899c3d1028Sbjorn3     /// Define a data object, producing the data contents from the given `DataDescription`.
define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>99067c85b88Sbjorn3     fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>;
991747ad3c4Slazypassion }
99286d3dc95Sbjorn3 
9938abaa75fSSpartan2909 impl<M: Module + ?Sized> Module for &mut M {
isa(&self) -> &dyn isa::TargetIsa9948abaa75fSSpartan2909     fn isa(&self) -> &dyn isa::TargetIsa {
9958abaa75fSSpartan2909         (**self).isa()
9968abaa75fSSpartan2909     }
9978abaa75fSSpartan2909 
declarations(&self) -> &ModuleDeclarations9988abaa75fSSpartan2909     fn declarations(&self) -> &ModuleDeclarations {
9998abaa75fSSpartan2909         (**self).declarations()
10008abaa75fSSpartan2909     }
10018abaa75fSSpartan2909 
get_name(&self, name: &str) -> Option<FuncOrDataId>10028abaa75fSSpartan2909     fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
10038abaa75fSSpartan2909         (**self).get_name(name)
10048abaa75fSSpartan2909     }
10058abaa75fSSpartan2909 
target_config(&self) -> isa::TargetFrontendConfig10068abaa75fSSpartan2909     fn target_config(&self) -> isa::TargetFrontendConfig {
10078abaa75fSSpartan2909         (**self).target_config()
10088abaa75fSSpartan2909     }
10098abaa75fSSpartan2909 
make_context(&self) -> Context10108abaa75fSSpartan2909     fn make_context(&self) -> Context {
10118abaa75fSSpartan2909         (**self).make_context()
10128abaa75fSSpartan2909     }
10138abaa75fSSpartan2909 
clear_context(&self, ctx: &mut Context)10148abaa75fSSpartan2909     fn clear_context(&self, ctx: &mut Context) {
10158abaa75fSSpartan2909         (**self).clear_context(ctx)
10168abaa75fSSpartan2909     }
10178abaa75fSSpartan2909 
make_signature(&self) -> ir::Signature10188abaa75fSSpartan2909     fn make_signature(&self) -> ir::Signature {
10198abaa75fSSpartan2909         (**self).make_signature()
10208abaa75fSSpartan2909     }
10218abaa75fSSpartan2909 
clear_signature(&self, sig: &mut ir::Signature)10228abaa75fSSpartan2909     fn clear_signature(&self, sig: &mut ir::Signature) {
10238abaa75fSSpartan2909         (**self).clear_signature(sig)
10248abaa75fSSpartan2909     }
10258abaa75fSSpartan2909 
declare_function( &mut self, name: &str, linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult<FuncId>10268abaa75fSSpartan2909     fn declare_function(
10278abaa75fSSpartan2909         &mut self,
10288abaa75fSSpartan2909         name: &str,
10298abaa75fSSpartan2909         linkage: Linkage,
10308abaa75fSSpartan2909         signature: &ir::Signature,
10318abaa75fSSpartan2909     ) -> ModuleResult<FuncId> {
10328abaa75fSSpartan2909         (**self).declare_function(name, linkage, signature)
10338abaa75fSSpartan2909     }
10348abaa75fSSpartan2909 
declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>10358abaa75fSSpartan2909     fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId> {
10368abaa75fSSpartan2909         (**self).declare_anonymous_function(signature)
10378abaa75fSSpartan2909     }
10388abaa75fSSpartan2909 
declare_data( &mut self, name: &str, linkage: Linkage, writable: bool, tls: bool, ) -> ModuleResult<DataId>10398abaa75fSSpartan2909     fn declare_data(
10408abaa75fSSpartan2909         &mut self,
10418abaa75fSSpartan2909         name: &str,
10428abaa75fSSpartan2909         linkage: Linkage,
10438abaa75fSSpartan2909         writable: bool,
10448abaa75fSSpartan2909         tls: bool,
10458abaa75fSSpartan2909     ) -> ModuleResult<DataId> {
10468abaa75fSSpartan2909         (**self).declare_data(name, linkage, writable, tls)
10478abaa75fSSpartan2909     }
10488abaa75fSSpartan2909 
declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>10498abaa75fSSpartan2909     fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> {
10508abaa75fSSpartan2909         (**self).declare_anonymous_data(writable, tls)
10518abaa75fSSpartan2909     }
10528abaa75fSSpartan2909 
declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef10538abaa75fSSpartan2909     fn declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef {
10548abaa75fSSpartan2909         (**self).declare_func_in_func(func, in_func)
10558abaa75fSSpartan2909     }
10568abaa75fSSpartan2909 
declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue10578abaa75fSSpartan2909     fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
10588abaa75fSSpartan2909         (**self).declare_data_in_func(data, func)
10598abaa75fSSpartan2909     }
10608abaa75fSSpartan2909 
declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef10618abaa75fSSpartan2909     fn declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef {
10628abaa75fSSpartan2909         (**self).declare_func_in_data(func_id, data)
10638abaa75fSSpartan2909     }
10648abaa75fSSpartan2909 
declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue10658abaa75fSSpartan2909     fn declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue {
10668abaa75fSSpartan2909         (**self).declare_data_in_data(data_id, data)
10678abaa75fSSpartan2909     }
10688abaa75fSSpartan2909 
define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()>10698abaa75fSSpartan2909     fn define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()> {
10708abaa75fSSpartan2909         (**self).define_function(func, ctx)
10718abaa75fSSpartan2909     }
10728abaa75fSSpartan2909 
define_function_with_control_plane( &mut self, func: FuncId, ctx: &mut Context, ctrl_plane: &mut ControlPlane, ) -> ModuleResult<()>10738abaa75fSSpartan2909     fn define_function_with_control_plane(
10748abaa75fSSpartan2909         &mut self,
10758abaa75fSSpartan2909         func: FuncId,
10768abaa75fSSpartan2909         ctx: &mut Context,
10778abaa75fSSpartan2909         ctrl_plane: &mut ControlPlane,
10788abaa75fSSpartan2909     ) -> ModuleResult<()> {
10798abaa75fSSpartan2909         (**self).define_function_with_control_plane(func, ctx, ctrl_plane)
10808abaa75fSSpartan2909     }
10818abaa75fSSpartan2909 
define_function_bytes( &mut self, func_id: FuncId, alignment: u64, bytes: &[u8], relocs: &[ModuleReloc], ) -> ModuleResult<()>10828abaa75fSSpartan2909     fn define_function_bytes(
10838abaa75fSSpartan2909         &mut self,
10848abaa75fSSpartan2909         func_id: FuncId,
10858abaa75fSSpartan2909         alignment: u64,
10868abaa75fSSpartan2909         bytes: &[u8],
1087716ebceaSbjorn3         relocs: &[ModuleReloc],
10888abaa75fSSpartan2909     ) -> ModuleResult<()> {
1089716ebceaSbjorn3         (**self).define_function_bytes(func_id, alignment, bytes, relocs)
10908abaa75fSSpartan2909     }
10918abaa75fSSpartan2909 
define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>10928abaa75fSSpartan2909     fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> {
10938abaa75fSSpartan2909         (**self).define_data(data_id, data)
10948abaa75fSSpartan2909     }
10958abaa75fSSpartan2909 }
10968abaa75fSSpartan2909 
10978abaa75fSSpartan2909 impl<M: Module + ?Sized> Module for Box<M> {
isa(&self) -> &dyn isa::TargetIsa109886d3dc95Sbjorn3     fn isa(&self) -> &dyn isa::TargetIsa {
109986d3dc95Sbjorn3         (**self).isa()
110086d3dc95Sbjorn3     }
110186d3dc95Sbjorn3 
declarations(&self) -> &ModuleDeclarations110286d3dc95Sbjorn3     fn declarations(&self) -> &ModuleDeclarations {
110386d3dc95Sbjorn3         (**self).declarations()
110486d3dc95Sbjorn3     }
110586d3dc95Sbjorn3 
get_name(&self, name: &str) -> Option<FuncOrDataId>110686d3dc95Sbjorn3     fn get_name(&self, name: &str) -> Option<FuncOrDataId> {
110786d3dc95Sbjorn3         (**self).get_name(name)
110886d3dc95Sbjorn3     }
110986d3dc95Sbjorn3 
target_config(&self) -> isa::TargetFrontendConfig111086d3dc95Sbjorn3     fn target_config(&self) -> isa::TargetFrontendConfig {
111186d3dc95Sbjorn3         (**self).target_config()
111286d3dc95Sbjorn3     }
111386d3dc95Sbjorn3 
make_context(&self) -> Context111486d3dc95Sbjorn3     fn make_context(&self) -> Context {
111586d3dc95Sbjorn3         (**self).make_context()
111686d3dc95Sbjorn3     }
111786d3dc95Sbjorn3 
clear_context(&self, ctx: &mut Context)111886d3dc95Sbjorn3     fn clear_context(&self, ctx: &mut Context) {
111986d3dc95Sbjorn3         (**self).clear_context(ctx)
112086d3dc95Sbjorn3     }
112186d3dc95Sbjorn3 
make_signature(&self) -> ir::Signature112286d3dc95Sbjorn3     fn make_signature(&self) -> ir::Signature {
112386d3dc95Sbjorn3         (**self).make_signature()
112486d3dc95Sbjorn3     }
112586d3dc95Sbjorn3 
clear_signature(&self, sig: &mut ir::Signature)112686d3dc95Sbjorn3     fn clear_signature(&self, sig: &mut ir::Signature) {
112786d3dc95Sbjorn3         (**self).clear_signature(sig)
112886d3dc95Sbjorn3     }
112986d3dc95Sbjorn3 
declare_function( &mut self, name: &str, linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult<FuncId>113086d3dc95Sbjorn3     fn declare_function(
113186d3dc95Sbjorn3         &mut self,
113286d3dc95Sbjorn3         name: &str,
113386d3dc95Sbjorn3         linkage: Linkage,
113486d3dc95Sbjorn3         signature: &ir::Signature,
113586d3dc95Sbjorn3     ) -> ModuleResult<FuncId> {
113686d3dc95Sbjorn3         (**self).declare_function(name, linkage, signature)
113786d3dc95Sbjorn3     }
113886d3dc95Sbjorn3 
declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>1139cc891114Sbjorn3     fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId> {
1140cc891114Sbjorn3         (**self).declare_anonymous_function(signature)
1141cc891114Sbjorn3     }
1142cc891114Sbjorn3 
declare_data( &mut self, name: &str, linkage: Linkage, writable: bool, tls: bool, ) -> ModuleResult<DataId>114386d3dc95Sbjorn3     fn declare_data(
114486d3dc95Sbjorn3         &mut self,
114586d3dc95Sbjorn3         name: &str,
114686d3dc95Sbjorn3         linkage: Linkage,
114786d3dc95Sbjorn3         writable: bool,
114886d3dc95Sbjorn3         tls: bool,
114986d3dc95Sbjorn3     ) -> ModuleResult<DataId> {
115086d3dc95Sbjorn3         (**self).declare_data(name, linkage, writable, tls)
115186d3dc95Sbjorn3     }
115286d3dc95Sbjorn3 
declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>1153cc891114Sbjorn3     fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> {
1154cc891114Sbjorn3         (**self).declare_anonymous_data(writable, tls)
1155cc891114Sbjorn3     }
1156cc891114Sbjorn3 
declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef11578a9b1a90SBenjamin Bouvier     fn declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef {
115886d3dc95Sbjorn3         (**self).declare_func_in_func(func, in_func)
115986d3dc95Sbjorn3     }
116086d3dc95Sbjorn3 
declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue116186d3dc95Sbjorn3     fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue {
116286d3dc95Sbjorn3         (**self).declare_data_in_func(data, func)
116386d3dc95Sbjorn3     }
116486d3dc95Sbjorn3 
declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef116567c85b88Sbjorn3     fn declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef {
116667c85b88Sbjorn3         (**self).declare_func_in_data(func_id, data)
11672ce03cceSBenjamin Bouvier     }
11682ce03cceSBenjamin Bouvier 
declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue116967c85b88Sbjorn3     fn declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue {
117067c85b88Sbjorn3         (**self).declare_data_in_data(data_id, data)
11712ce03cceSBenjamin Bouvier     }
11722ce03cceSBenjamin Bouvier 
define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()>117391d1d246Sbjorn3     fn define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()> {
1174e1812b61Sbjorn3         (**self).define_function(func, ctx)
1175e1812b61Sbjorn3     }
1176e1812b61Sbjorn3 
define_function_with_control_plane( &mut self, func: FuncId, ctx: &mut Context, ctrl_plane: &mut ControlPlane, ) -> ModuleResult<()>1177e1812b61Sbjorn3     fn define_function_with_control_plane(
1178e1812b61Sbjorn3         &mut self,
1179e1812b61Sbjorn3         func: FuncId,
1180e1812b61Sbjorn3         ctx: &mut Context,
11817eb89140SRemo Senekowitsch         ctrl_plane: &mut ControlPlane,
118291d1d246Sbjorn3     ) -> ModuleResult<()> {
1183e1812b61Sbjorn3         (**self).define_function_with_control_plane(func, ctx, ctrl_plane)
118486d3dc95Sbjorn3     }
118586d3dc95Sbjorn3 
define_function_bytes( &mut self, func_id: FuncId, alignment: u64, bytes: &[u8], relocs: &[ModuleReloc], ) -> ModuleResult<()>118686d3dc95Sbjorn3     fn define_function_bytes(
118786d3dc95Sbjorn3         &mut self,
11888a9b1a90SBenjamin Bouvier         func_id: FuncId,
1189dde2c5a3STrevor Elliott         alignment: u64,
119086d3dc95Sbjorn3         bytes: &[u8],
1191716ebceaSbjorn3         relocs: &[ModuleReloc],
119291d1d246Sbjorn3     ) -> ModuleResult<()> {
1193716ebceaSbjorn3         (**self).define_function_bytes(func_id, alignment, bytes, relocs)
119486d3dc95Sbjorn3     }
119586d3dc95Sbjorn3 
define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>119667c85b88Sbjorn3     fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> {
119767c85b88Sbjorn3         (**self).define_data(data_id, data)
119886d3dc95Sbjorn3     }
119986d3dc95Sbjorn3 }
1200