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