1 //! Defines `Module` and related types. 2 3 // TODO: Should `ir::Function` really have a `name`? 4 5 // TODO: Factor out `ir::Function`'s `ext_funcs` and `global_values` into a struct 6 // shared with `DataDescription`? 7 8 use super::HashMap; 9 use crate::data_context::DataDescription; 10 use core::fmt::Display; 11 use cranelift_codegen::binemit::{CodeOffset, Reloc}; 12 use cranelift_codegen::entity::{entity_impl, PrimaryMap}; 13 use cranelift_codegen::ir::function::{Function, VersionMarker}; 14 use cranelift_codegen::settings::SetError; 15 use cranelift_codegen::MachReloc; 16 use cranelift_codegen::{ir, isa, CodegenError, CompileError, Context}; 17 use cranelift_control::ControlPlane; 18 use std::borrow::{Cow, ToOwned}; 19 use std::string::String; 20 21 /// A module relocation. 22 #[derive(Clone)] 23 pub struct ModuleReloc { 24 /// The offset at which the relocation applies, *relative to the 25 /// containing section*. 26 pub offset: CodeOffset, 27 /// The kind of relocation. 28 pub kind: Reloc, 29 /// The external symbol / name to which this relocation refers. 30 pub name: ModuleExtName, 31 /// The addend to add to the symbol value. 32 pub addend: i64, 33 } 34 35 impl ModuleReloc { 36 /// Converts a `MachReloc` produced from a `Function` into a `ModuleReloc`. 37 pub fn from_mach_reloc(mach_reloc: &MachReloc, func: &Function) -> Self { 38 let name = match mach_reloc.name { 39 ir::ExternalName::User(reff) => { 40 let name = &func.params.user_named_funcs()[reff]; 41 ModuleExtName::user(name.namespace, name.index) 42 } 43 ir::ExternalName::TestCase(_) => unimplemented!(), 44 ir::ExternalName::LibCall(libcall) => ModuleExtName::LibCall(libcall), 45 ir::ExternalName::KnownSymbol(ks) => ModuleExtName::KnownSymbol(ks), 46 }; 47 Self { 48 offset: mach_reloc.offset, 49 kind: mach_reloc.kind, 50 name, 51 addend: mach_reloc.addend, 52 } 53 } 54 } 55 56 /// A function identifier for use in the `Module` interface. 57 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 58 #[cfg_attr( 59 feature = "enable-serde", 60 derive(serde_derive::Serialize, serde_derive::Deserialize) 61 )] 62 pub struct FuncId(u32); 63 entity_impl!(FuncId, "funcid"); 64 65 /// Function identifiers are namespace 0 in `ir::ExternalName` 66 impl From<FuncId> for ModuleExtName { 67 fn from(id: FuncId) -> Self { 68 Self::User { 69 namespace: 0, 70 index: id.0, 71 } 72 } 73 } 74 75 impl FuncId { 76 /// Get the `FuncId` for the function named by `name`. 77 pub fn from_name(name: &ModuleExtName) -> FuncId { 78 if let ModuleExtName::User { namespace, index } = name { 79 debug_assert_eq!(*namespace, 0); 80 FuncId::from_u32(*index) 81 } else { 82 panic!("unexpected name in DataId::from_name") 83 } 84 } 85 } 86 87 /// A data object identifier for use in the `Module` interface. 88 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 89 #[cfg_attr( 90 feature = "enable-serde", 91 derive(serde_derive::Serialize, serde_derive::Deserialize) 92 )] 93 pub struct DataId(u32); 94 entity_impl!(DataId, "dataid"); 95 96 /// Data identifiers are namespace 1 in `ir::ExternalName` 97 impl From<DataId> for ModuleExtName { 98 fn from(id: DataId) -> Self { 99 Self::User { 100 namespace: 1, 101 index: id.0, 102 } 103 } 104 } 105 106 impl DataId { 107 /// Get the `DataId` for the data object named by `name`. 108 pub fn from_name(name: &ModuleExtName) -> DataId { 109 if let ModuleExtName::User { namespace, index } = name { 110 debug_assert_eq!(*namespace, 1); 111 DataId::from_u32(*index) 112 } else { 113 panic!("unexpected name in DataId::from_name") 114 } 115 } 116 } 117 118 /// Linkage refers to where an entity is defined and who can see it. 119 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 120 #[cfg_attr( 121 feature = "enable-serde", 122 derive(serde_derive::Serialize, serde_derive::Deserialize) 123 )] 124 pub enum Linkage { 125 /// Defined outside of a module. 126 Import, 127 /// Defined inside the module, but not visible outside it. 128 Local, 129 /// Defined inside the module, visible outside it, and may be preempted. 130 Preemptible, 131 /// Defined inside the module, visible inside the current static linkage unit, but not outside. 132 /// 133 /// A static linkage unit is the combination of all object files passed to a linker to create 134 /// an executable or dynamic library. 135 Hidden, 136 /// Defined inside the module, and visible outside it. 137 Export, 138 } 139 140 impl Linkage { 141 fn merge(a: Self, b: Self) -> Self { 142 match a { 143 Self::Export => Self::Export, 144 Self::Hidden => match b { 145 Self::Export => Self::Export, 146 Self::Preemptible => Self::Preemptible, 147 _ => Self::Hidden, 148 }, 149 Self::Preemptible => match b { 150 Self::Export => Self::Export, 151 _ => Self::Preemptible, 152 }, 153 Self::Local => match b { 154 Self::Export => Self::Export, 155 Self::Hidden => Self::Hidden, 156 Self::Preemptible => Self::Preemptible, 157 Self::Local | Self::Import => Self::Local, 158 }, 159 Self::Import => b, 160 } 161 } 162 163 /// Test whether this linkage can have a definition. 164 pub fn is_definable(self) -> bool { 165 match self { 166 Self::Import => false, 167 Self::Local | Self::Preemptible | Self::Hidden | Self::Export => true, 168 } 169 } 170 171 /// Test whether this linkage will have a definition that cannot be preempted. 172 pub fn is_final(self) -> bool { 173 match self { 174 Self::Import | Self::Preemptible => false, 175 Self::Local | Self::Hidden | Self::Export => true, 176 } 177 } 178 } 179 180 /// A declared name may refer to either a function or data declaration 181 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 182 #[cfg_attr( 183 feature = "enable-serde", 184 derive(serde_derive::Serialize, serde_derive::Deserialize) 185 )] 186 pub enum FuncOrDataId { 187 /// When it's a FuncId 188 Func(FuncId), 189 /// When it's a DataId 190 Data(DataId), 191 } 192 193 /// Mapping to `ModuleExtName` is trivial based on the `FuncId` and `DataId` mapping. 194 impl From<FuncOrDataId> for ModuleExtName { 195 fn from(id: FuncOrDataId) -> Self { 196 match id { 197 FuncOrDataId::Func(funcid) => Self::from(funcid), 198 FuncOrDataId::Data(dataid) => Self::from(dataid), 199 } 200 } 201 } 202 203 /// Information about a function which can be called. 204 #[derive(Debug)] 205 #[cfg_attr( 206 feature = "enable-serde", 207 derive(serde_derive::Serialize, serde_derive::Deserialize) 208 )] 209 pub struct FunctionDeclaration { 210 #[allow(missing_docs)] 211 pub name: Option<String>, 212 #[allow(missing_docs)] 213 pub linkage: Linkage, 214 #[allow(missing_docs)] 215 pub signature: ir::Signature, 216 } 217 218 impl FunctionDeclaration { 219 /// The linkage name of the function. 220 /// 221 /// Synthesized from the given function id if it is an anonymous function. 222 pub fn linkage_name(&self, id: FuncId) -> Cow<'_, str> { 223 match &self.name { 224 Some(name) => Cow::Borrowed(name), 225 // Symbols starting with .L are completely omitted from the symbol table after linking. 226 // Using hexadecimal instead of decimal for slightly smaller symbol names and often 227 // slightly faster linking. 228 None => Cow::Owned(format!(".Lfn{:x}", id.as_u32())), 229 } 230 } 231 232 fn merge( 233 &mut self, 234 id: FuncId, 235 linkage: Linkage, 236 sig: &ir::Signature, 237 ) -> Result<(), ModuleError> { 238 self.linkage = Linkage::merge(self.linkage, linkage); 239 if &self.signature != sig { 240 return Err(ModuleError::IncompatibleSignature( 241 self.linkage_name(id).into_owned(), 242 self.signature.clone(), 243 sig.clone(), 244 )); 245 } 246 Ok(()) 247 } 248 } 249 250 /// Error messages for all `Module` methods 251 #[derive(Debug)] 252 pub enum ModuleError { 253 /// Indicates an identifier was used before it was declared 254 Undeclared(String), 255 256 /// Indicates an identifier was used as data/function first, but then used as the other 257 IncompatibleDeclaration(String), 258 259 /// Indicates a function identifier was declared with a 260 /// different signature than declared previously 261 IncompatibleSignature(String, ir::Signature, ir::Signature), 262 263 /// Indicates an identifier was defined more than once 264 DuplicateDefinition(String), 265 266 /// Indicates an identifier was defined, but was declared as an import 267 InvalidImportDefinition(String), 268 269 /// Wraps a `cranelift-codegen` error 270 Compilation(CodegenError), 271 272 /// Memory allocation failure from a backend 273 Allocation { 274 /// Tell where the allocation came from 275 message: &'static str, 276 /// Io error the allocation failed with 277 err: std::io::Error, 278 }, 279 280 /// Wraps a generic error from a backend 281 Backend(anyhow::Error), 282 283 /// Wraps an error from a flag definition. 284 Flag(SetError), 285 } 286 287 impl<'a> From<CompileError<'a>> for ModuleError { 288 fn from(err: CompileError<'a>) -> Self { 289 Self::Compilation(err.inner) 290 } 291 } 292 293 // This is manually implementing Error and Display instead of using thiserror to reduce the amount 294 // of dependencies used by Cranelift. 295 impl std::error::Error for ModuleError { 296 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 297 match self { 298 Self::Undeclared { .. } 299 | Self::IncompatibleDeclaration { .. } 300 | Self::IncompatibleSignature { .. } 301 | Self::DuplicateDefinition { .. } 302 | Self::InvalidImportDefinition { .. } => None, 303 Self::Compilation(source) => Some(source), 304 Self::Allocation { err: source, .. } => Some(source), 305 Self::Backend(source) => Some(&**source), 306 Self::Flag(source) => Some(source), 307 } 308 } 309 } 310 311 impl std::fmt::Display for ModuleError { 312 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 313 match self { 314 Self::Undeclared(name) => { 315 write!(f, "Undeclared identifier: {}", name) 316 } 317 Self::IncompatibleDeclaration(name) => { 318 write!(f, "Incompatible declaration of identifier: {}", name,) 319 } 320 Self::IncompatibleSignature(name, prev_sig, new_sig) => { 321 write!( 322 f, 323 "Function {} signature {:?} is incompatible with previous declaration {:?}", 324 name, new_sig, prev_sig, 325 ) 326 } 327 Self::DuplicateDefinition(name) => { 328 write!(f, "Duplicate definition of identifier: {}", name) 329 } 330 Self::InvalidImportDefinition(name) => { 331 write!( 332 f, 333 "Invalid to define identifier declared as an import: {}", 334 name, 335 ) 336 } 337 Self::Compilation(err) => { 338 write!(f, "Compilation error: {}", err) 339 } 340 Self::Allocation { message, err } => { 341 write!(f, "Allocation error: {}: {}", message, err) 342 } 343 Self::Backend(err) => write!(f, "Backend error: {}", err), 344 Self::Flag(err) => write!(f, "Flag error: {}", err), 345 } 346 } 347 } 348 349 impl std::convert::From<CodegenError> for ModuleError { 350 fn from(source: CodegenError) -> Self { 351 Self::Compilation { 0: source } 352 } 353 } 354 355 impl std::convert::From<SetError> for ModuleError { 356 fn from(source: SetError) -> Self { 357 Self::Flag { 0: source } 358 } 359 } 360 361 /// A convenient alias for a `Result` that uses `ModuleError` as the error type. 362 pub type ModuleResult<T> = Result<T, ModuleError>; 363 364 /// Information about a data object which can be accessed. 365 #[derive(Debug)] 366 #[cfg_attr( 367 feature = "enable-serde", 368 derive(serde_derive::Serialize, serde_derive::Deserialize) 369 )] 370 pub struct DataDeclaration { 371 #[allow(missing_docs)] 372 pub name: Option<String>, 373 #[allow(missing_docs)] 374 pub linkage: Linkage, 375 #[allow(missing_docs)] 376 pub writable: bool, 377 #[allow(missing_docs)] 378 pub tls: bool, 379 } 380 381 impl DataDeclaration { 382 /// The linkage name of the data object. 383 /// 384 /// Synthesized from the given data id if it is an anonymous function. 385 pub fn linkage_name(&self, id: DataId) -> Cow<'_, str> { 386 match &self.name { 387 Some(name) => Cow::Borrowed(name), 388 // Symbols starting with .L are completely omitted from the symbol table after linking. 389 // Using hexadecimal instead of decimal for slightly smaller symbol names and often 390 // slightly faster linking. 391 None => Cow::Owned(format!(".Ldata{:x}", id.as_u32())), 392 } 393 } 394 395 fn merge(&mut self, linkage: Linkage, writable: bool, tls: bool) { 396 self.linkage = Linkage::merge(self.linkage, linkage); 397 self.writable = self.writable || writable; 398 assert_eq!( 399 self.tls, tls, 400 "Can't change TLS data object to normal or in the opposite way", 401 ); 402 } 403 } 404 405 /// A translated `ExternalName` into something global we can handle. 406 #[derive(Clone, Debug)] 407 #[cfg_attr( 408 feature = "enable-serde", 409 derive(serde_derive::Serialize, serde_derive::Deserialize) 410 )] 411 pub enum ModuleExtName { 412 /// User defined function, converted from `ExternalName::User`. 413 User { 414 /// Arbitrary. 415 namespace: u32, 416 /// Arbitrary. 417 index: u32, 418 }, 419 /// Call into a library function. 420 LibCall(ir::LibCall), 421 /// Symbols known to the linker. 422 KnownSymbol(ir::KnownSymbol), 423 } 424 425 impl ModuleExtName { 426 /// Creates a user-defined external name. 427 pub fn user(namespace: u32, index: u32) -> Self { 428 Self::User { namespace, index } 429 } 430 } 431 432 impl Display for ModuleExtName { 433 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 434 match self { 435 Self::User { namespace, index } => write!(f, "u{}:{}", namespace, index), 436 Self::LibCall(lc) => write!(f, "%{}", lc), 437 Self::KnownSymbol(ks) => write!(f, "{}", ks), 438 } 439 } 440 } 441 442 /// This provides a view to the state of a module which allows `ir::ExternalName`s to be translated 443 /// into `FunctionDeclaration`s and `DataDeclaration`s. 444 #[derive(Debug, Default)] 445 pub struct ModuleDeclarations { 446 /// A version marker used to ensure that serialized clif ir is never deserialized with a 447 /// different version of Cranelift. 448 // Note: This must be the first field to ensure that Serde will deserialize it before 449 // attempting to deserialize other fields that are potentially changed between versions. 450 _version_marker: VersionMarker, 451 452 names: HashMap<String, FuncOrDataId>, 453 functions: PrimaryMap<FuncId, FunctionDeclaration>, 454 data_objects: PrimaryMap<DataId, DataDeclaration>, 455 } 456 457 #[cfg(feature = "enable-serde")] 458 mod serialize { 459 // This is manually implementing Serialize and Deserialize to avoid serializing the names field, 460 // which can be entirely reconstructed from the functions and data_objects fields, saving space. 461 462 use super::*; 463 464 use serde::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Unexpected, Visitor}; 465 use serde::ser::{Serialize, SerializeStruct, Serializer}; 466 use std::fmt; 467 468 fn get_names<E: Error>( 469 functions: &PrimaryMap<FuncId, FunctionDeclaration>, 470 data_objects: &PrimaryMap<DataId, DataDeclaration>, 471 ) -> Result<HashMap<String, FuncOrDataId>, E> { 472 let mut names = HashMap::new(); 473 for (func_id, decl) in functions.iter() { 474 if let Some(name) = &decl.name { 475 let old = names.insert(name.clone(), FuncOrDataId::Func(func_id)); 476 if old.is_some() { 477 return Err(E::invalid_value( 478 Unexpected::Other("duplicate name"), 479 &"FunctionDeclaration's with no duplicate names", 480 )); 481 } 482 } 483 } 484 for (data_id, decl) in data_objects.iter() { 485 if let Some(name) = &decl.name { 486 let old = names.insert(name.clone(), FuncOrDataId::Data(data_id)); 487 if old.is_some() { 488 return Err(E::invalid_value( 489 Unexpected::Other("duplicate name"), 490 &"DataDeclaration's with no duplicate names", 491 )); 492 } 493 } 494 } 495 Ok(names) 496 } 497 498 impl Serialize for ModuleDeclarations { 499 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> { 500 let ModuleDeclarations { 501 _version_marker, 502 functions, 503 data_objects, 504 names: _, 505 } = self; 506 507 let mut state = s.serialize_struct("ModuleDeclarations", 4)?; 508 state.serialize_field("_version_marker", _version_marker)?; 509 state.serialize_field("functions", functions)?; 510 state.serialize_field("data_objects", data_objects)?; 511 state.end() 512 } 513 } 514 515 enum ModuleDeclarationsField { 516 VersionMarker, 517 Functions, 518 DataObjects, 519 Ignore, 520 } 521 522 struct ModuleDeclarationsFieldVisitor; 523 524 impl<'de> serde::de::Visitor<'de> for ModuleDeclarationsFieldVisitor { 525 type Value = ModuleDeclarationsField; 526 527 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 528 f.write_str("field identifier") 529 } 530 531 fn visit_u64<E: Error>(self, val: u64) -> Result<Self::Value, E> { 532 match val { 533 0u64 => Ok(ModuleDeclarationsField::VersionMarker), 534 1u64 => Ok(ModuleDeclarationsField::Functions), 535 2u64 => Ok(ModuleDeclarationsField::DataObjects), 536 _ => Ok(ModuleDeclarationsField::Ignore), 537 } 538 } 539 540 fn visit_str<E: Error>(self, val: &str) -> Result<Self::Value, E> { 541 match val { 542 "_version_marker" => Ok(ModuleDeclarationsField::VersionMarker), 543 "functions" => Ok(ModuleDeclarationsField::Functions), 544 "data_objects" => Ok(ModuleDeclarationsField::DataObjects), 545 _ => Ok(ModuleDeclarationsField::Ignore), 546 } 547 } 548 549 fn visit_bytes<E: Error>(self, val: &[u8]) -> Result<Self::Value, E> { 550 match val { 551 b"_version_marker" => Ok(ModuleDeclarationsField::VersionMarker), 552 b"functions" => Ok(ModuleDeclarationsField::Functions), 553 b"data_objects" => Ok(ModuleDeclarationsField::DataObjects), 554 _ => Ok(ModuleDeclarationsField::Ignore), 555 } 556 } 557 } 558 559 impl<'de> Deserialize<'de> for ModuleDeclarationsField { 560 #[inline] 561 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> { 562 d.deserialize_identifier(ModuleDeclarationsFieldVisitor) 563 } 564 } 565 566 struct ModuleDeclarationsVisitor; 567 568 impl<'de> Visitor<'de> for ModuleDeclarationsVisitor { 569 type Value = ModuleDeclarations; 570 571 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 572 f.write_str("struct ModuleDeclarations") 573 } 574 575 #[inline] 576 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> { 577 let _version_marker = match seq.next_element()? { 578 Some(val) => val, 579 None => { 580 return Err(Error::invalid_length( 581 0usize, 582 &"struct ModuleDeclarations with 4 elements", 583 )); 584 } 585 }; 586 let functions = match seq.next_element()? { 587 Some(val) => val, 588 None => { 589 return Err(Error::invalid_length( 590 2usize, 591 &"struct ModuleDeclarations with 4 elements", 592 )); 593 } 594 }; 595 let data_objects = match seq.next_element()? { 596 Some(val) => val, 597 None => { 598 return Err(Error::invalid_length( 599 3usize, 600 &"struct ModuleDeclarations with 4 elements", 601 )); 602 } 603 }; 604 let names = get_names(&functions, &data_objects)?; 605 Ok(ModuleDeclarations { 606 _version_marker, 607 names, 608 functions, 609 data_objects, 610 }) 611 } 612 613 #[inline] 614 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> { 615 let mut _version_marker: Option<VersionMarker> = None; 616 let mut functions: Option<PrimaryMap<FuncId, FunctionDeclaration>> = None; 617 let mut data_objects: Option<PrimaryMap<DataId, DataDeclaration>> = None; 618 while let Some(key) = map.next_key::<ModuleDeclarationsField>()? { 619 match key { 620 ModuleDeclarationsField::VersionMarker => { 621 if _version_marker.is_some() { 622 return Err(Error::duplicate_field("_version_marker")); 623 } 624 _version_marker = Some(map.next_value()?); 625 } 626 ModuleDeclarationsField::Functions => { 627 if functions.is_some() { 628 return Err(Error::duplicate_field("functions")); 629 } 630 functions = Some(map.next_value()?); 631 } 632 ModuleDeclarationsField::DataObjects => { 633 if data_objects.is_some() { 634 return Err(Error::duplicate_field("data_objects")); 635 } 636 data_objects = Some(map.next_value()?); 637 } 638 _ => { 639 map.next_value::<serde::de::IgnoredAny>()?; 640 } 641 } 642 } 643 let _version_marker = match _version_marker { 644 Some(_version_marker) => _version_marker, 645 None => return Err(Error::missing_field("_version_marker")), 646 }; 647 let functions = match functions { 648 Some(functions) => functions, 649 None => return Err(Error::missing_field("functions")), 650 }; 651 let data_objects = match data_objects { 652 Some(data_objects) => data_objects, 653 None => return Err(Error::missing_field("data_objects")), 654 }; 655 let names = get_names(&functions, &data_objects)?; 656 Ok(ModuleDeclarations { 657 _version_marker, 658 names, 659 functions, 660 data_objects, 661 }) 662 } 663 } 664 665 impl<'de> Deserialize<'de> for ModuleDeclarations { 666 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> { 667 d.deserialize_struct( 668 "ModuleDeclarations", 669 &["_version_marker", "functions", "data_objects"], 670 ModuleDeclarationsVisitor, 671 ) 672 } 673 } 674 } 675 676 impl ModuleDeclarations { 677 /// Get the module identifier for a given name, if that name 678 /// has been declared. 679 pub fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 680 self.names.get(name).copied() 681 } 682 683 /// Get an iterator of all function declarations 684 pub fn get_functions(&self) -> impl Iterator<Item = (FuncId, &FunctionDeclaration)> { 685 self.functions.iter() 686 } 687 688 /// Return whether `name` names a function, rather than a data object. 689 pub fn is_function(name: &ModuleExtName) -> bool { 690 match name { 691 ModuleExtName::User { namespace, .. } => *namespace == 0, 692 ModuleExtName::LibCall(_) | ModuleExtName::KnownSymbol(_) => { 693 panic!("unexpected module ext name") 694 } 695 } 696 } 697 698 /// Get the `FunctionDeclaration` for the function named by `name`. 699 pub fn get_function_decl(&self, func_id: FuncId) -> &FunctionDeclaration { 700 &self.functions[func_id] 701 } 702 703 /// Get an iterator of all data declarations 704 pub fn get_data_objects(&self) -> impl Iterator<Item = (DataId, &DataDeclaration)> { 705 self.data_objects.iter() 706 } 707 708 /// Get the `DataDeclaration` for the data object named by `name`. 709 pub fn get_data_decl(&self, data_id: DataId) -> &DataDeclaration { 710 &self.data_objects[data_id] 711 } 712 713 /// Declare a function in this module. 714 pub fn declare_function( 715 &mut self, 716 name: &str, 717 linkage: Linkage, 718 signature: &ir::Signature, 719 ) -> ModuleResult<(FuncId, Linkage)> { 720 // TODO: Can we avoid allocating names so often? 721 use super::hash_map::Entry::*; 722 match self.names.entry(name.to_owned()) { 723 Occupied(entry) => match *entry.get() { 724 FuncOrDataId::Func(id) => { 725 let existing = &mut self.functions[id]; 726 existing.merge(id, linkage, signature)?; 727 Ok((id, existing.linkage)) 728 } 729 FuncOrDataId::Data(..) => { 730 Err(ModuleError::IncompatibleDeclaration(name.to_owned())) 731 } 732 }, 733 Vacant(entry) => { 734 let id = self.functions.push(FunctionDeclaration { 735 name: Some(name.to_owned()), 736 linkage, 737 signature: signature.clone(), 738 }); 739 entry.insert(FuncOrDataId::Func(id)); 740 Ok((id, self.functions[id].linkage)) 741 } 742 } 743 } 744 745 /// Declare an anonymous function in this module. 746 pub fn declare_anonymous_function( 747 &mut self, 748 signature: &ir::Signature, 749 ) -> ModuleResult<FuncId> { 750 let id = self.functions.push(FunctionDeclaration { 751 name: None, 752 linkage: Linkage::Local, 753 signature: signature.clone(), 754 }); 755 Ok(id) 756 } 757 758 /// Declare a data object in this module. 759 pub fn declare_data( 760 &mut self, 761 name: &str, 762 linkage: Linkage, 763 writable: bool, 764 tls: bool, 765 ) -> ModuleResult<(DataId, Linkage)> { 766 // TODO: Can we avoid allocating names so often? 767 use super::hash_map::Entry::*; 768 match self.names.entry(name.to_owned()) { 769 Occupied(entry) => match *entry.get() { 770 FuncOrDataId::Data(id) => { 771 let existing = &mut self.data_objects[id]; 772 existing.merge(linkage, writable, tls); 773 Ok((id, existing.linkage)) 774 } 775 776 FuncOrDataId::Func(..) => { 777 Err(ModuleError::IncompatibleDeclaration(name.to_owned())) 778 } 779 }, 780 Vacant(entry) => { 781 let id = self.data_objects.push(DataDeclaration { 782 name: Some(name.to_owned()), 783 linkage, 784 writable, 785 tls, 786 }); 787 entry.insert(FuncOrDataId::Data(id)); 788 Ok((id, self.data_objects[id].linkage)) 789 } 790 } 791 } 792 793 /// Declare an anonymous data object in this module. 794 pub fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> { 795 let id = self.data_objects.push(DataDeclaration { 796 name: None, 797 linkage: Linkage::Local, 798 writable, 799 tls, 800 }); 801 Ok(id) 802 } 803 } 804 805 /// A `Module` is a utility for collecting functions and data objects, and linking them together. 806 pub trait Module { 807 /// Return the `TargetIsa` to compile for. 808 fn isa(&self) -> &dyn isa::TargetIsa; 809 810 /// Get all declarations in this module. 811 fn declarations(&self) -> &ModuleDeclarations; 812 813 /// Get the module identifier for a given name, if that name 814 /// has been declared. 815 fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 816 self.declarations().get_name(name) 817 } 818 819 /// Return the target information needed by frontends to produce Cranelift IR 820 /// for the current target. 821 fn target_config(&self) -> isa::TargetFrontendConfig { 822 self.isa().frontend_config() 823 } 824 825 /// Create a new `Context` initialized for use with this `Module`. 826 /// 827 /// This ensures that the `Context` is initialized with the default calling 828 /// convention for the `TargetIsa`. 829 fn make_context(&self) -> Context { 830 let mut ctx = Context::new(); 831 ctx.func.signature.call_conv = self.isa().default_call_conv(); 832 ctx 833 } 834 835 /// Clear the given `Context` and reset it for use with a new function. 836 /// 837 /// This ensures that the `Context` is initialized with the default calling 838 /// convention for the `TargetIsa`. 839 fn clear_context(&self, ctx: &mut Context) { 840 ctx.clear(); 841 ctx.func.signature.call_conv = self.isa().default_call_conv(); 842 } 843 844 /// Create a new empty `Signature` with the default calling convention for 845 /// the `TargetIsa`, to which parameter and return types can be added for 846 /// declaring a function to be called by this `Module`. 847 fn make_signature(&self) -> ir::Signature { 848 ir::Signature::new(self.isa().default_call_conv()) 849 } 850 851 /// Clear the given `Signature` and reset for use with a new function. 852 /// 853 /// This ensures that the `Signature` is initialized with the default 854 /// calling convention for the `TargetIsa`. 855 fn clear_signature(&self, sig: &mut ir::Signature) { 856 sig.clear(self.isa().default_call_conv()); 857 } 858 859 /// Declare a function in this module. 860 fn declare_function( 861 &mut self, 862 name: &str, 863 linkage: Linkage, 864 signature: &ir::Signature, 865 ) -> ModuleResult<FuncId>; 866 867 /// Declare an anonymous function in this module. 868 fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId>; 869 870 /// Declare a data object in this module. 871 fn declare_data( 872 &mut self, 873 name: &str, 874 linkage: Linkage, 875 writable: bool, 876 tls: bool, 877 ) -> ModuleResult<DataId>; 878 879 /// Declare an anonymous data object in this module. 880 fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId>; 881 882 /// Use this when you're building the IR of a function to reference a function. 883 /// 884 /// TODO: Coalesce redundant decls and signatures. 885 /// TODO: Look into ways to reduce the risk of using a FuncRef in the wrong function. 886 fn declare_func_in_func(&mut self, func_id: FuncId, func: &mut ir::Function) -> ir::FuncRef { 887 let decl = &self.declarations().functions[func_id]; 888 let signature = func.import_signature(decl.signature.clone()); 889 let user_name_ref = func.declare_imported_user_function(ir::UserExternalName { 890 namespace: 0, 891 index: func_id.as_u32(), 892 }); 893 let colocated = decl.linkage.is_final(); 894 func.import_function(ir::ExtFuncData { 895 name: ir::ExternalName::user(user_name_ref), 896 signature, 897 colocated, 898 }) 899 } 900 901 /// Use this when you're building the IR of a function to reference a data object. 902 /// 903 /// TODO: Same as above. 904 fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue { 905 let decl = &self.declarations().data_objects[data]; 906 let colocated = decl.linkage.is_final(); 907 let user_name_ref = func.declare_imported_user_function(ir::UserExternalName { 908 namespace: 1, 909 index: data.as_u32(), 910 }); 911 func.create_global_value(ir::GlobalValueData::Symbol { 912 name: ir::ExternalName::user(user_name_ref), 913 offset: ir::immediates::Imm64::new(0), 914 colocated, 915 tls: decl.tls, 916 }) 917 } 918 919 /// TODO: Same as above. 920 fn declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef { 921 data.import_function(ModuleExtName::user(0, func_id.as_u32())) 922 } 923 924 /// TODO: Same as above. 925 fn declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue { 926 data.import_global_value(ModuleExtName::user(1, data_id.as_u32())) 927 } 928 929 /// Define a function, producing the function body from the given `Context`. 930 /// 931 /// Returns the size of the function's code and constant data. 932 /// 933 /// Unlike [`define_function_with_control_plane`] this uses a default [`ControlPlane`] for 934 /// convenience. 935 /// 936 /// Note: After calling this function the given `Context` will contain the compiled function. 937 /// 938 /// [`define_function_with_control_plane`]: Self::define_function_with_control_plane 939 fn define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()> { 940 self.define_function_with_control_plane(func, ctx, &mut ControlPlane::default()) 941 } 942 943 /// Define a function, producing the function body from the given `Context`. 944 /// 945 /// Returns the size of the function's code and constant data. 946 /// 947 /// Note: After calling this function the given `Context` will contain the compiled function. 948 fn define_function_with_control_plane( 949 &mut self, 950 func: FuncId, 951 ctx: &mut Context, 952 ctrl_plane: &mut ControlPlane, 953 ) -> ModuleResult<()>; 954 955 /// Define a function, taking the function body from the given `bytes`. 956 /// 957 /// This function is generally only useful if you need to precisely specify 958 /// the emitted instructions for some reason; otherwise, you should use 959 /// `define_function`. 960 /// 961 /// Returns the size of the function's code. 962 fn define_function_bytes( 963 &mut self, 964 func_id: FuncId, 965 func: &ir::Function, 966 alignment: u64, 967 bytes: &[u8], 968 relocs: &[MachReloc], 969 ) -> ModuleResult<()>; 970 971 /// Define a data object, producing the data contents from the given `DataContext`. 972 fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()>; 973 } 974 975 impl<M: Module> Module for &mut M { 976 fn isa(&self) -> &dyn isa::TargetIsa { 977 (**self).isa() 978 } 979 980 fn declarations(&self) -> &ModuleDeclarations { 981 (**self).declarations() 982 } 983 984 fn get_name(&self, name: &str) -> Option<FuncOrDataId> { 985 (**self).get_name(name) 986 } 987 988 fn target_config(&self) -> isa::TargetFrontendConfig { 989 (**self).target_config() 990 } 991 992 fn make_context(&self) -> Context { 993 (**self).make_context() 994 } 995 996 fn clear_context(&self, ctx: &mut Context) { 997 (**self).clear_context(ctx) 998 } 999 1000 fn make_signature(&self) -> ir::Signature { 1001 (**self).make_signature() 1002 } 1003 1004 fn clear_signature(&self, sig: &mut ir::Signature) { 1005 (**self).clear_signature(sig) 1006 } 1007 1008 fn declare_function( 1009 &mut self, 1010 name: &str, 1011 linkage: Linkage, 1012 signature: &ir::Signature, 1013 ) -> ModuleResult<FuncId> { 1014 (**self).declare_function(name, linkage, signature) 1015 } 1016 1017 fn declare_anonymous_function(&mut self, signature: &ir::Signature) -> ModuleResult<FuncId> { 1018 (**self).declare_anonymous_function(signature) 1019 } 1020 1021 fn declare_data( 1022 &mut self, 1023 name: &str, 1024 linkage: Linkage, 1025 writable: bool, 1026 tls: bool, 1027 ) -> ModuleResult<DataId> { 1028 (**self).declare_data(name, linkage, writable, tls) 1029 } 1030 1031 fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult<DataId> { 1032 (**self).declare_anonymous_data(writable, tls) 1033 } 1034 1035 fn declare_func_in_func(&mut self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef { 1036 (**self).declare_func_in_func(func, in_func) 1037 } 1038 1039 fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue { 1040 (**self).declare_data_in_func(data, func) 1041 } 1042 1043 fn declare_func_in_data(&self, func_id: FuncId, data: &mut DataDescription) -> ir::FuncRef { 1044 (**self).declare_func_in_data(func_id, data) 1045 } 1046 1047 fn declare_data_in_data(&self, data_id: DataId, data: &mut DataDescription) -> ir::GlobalValue { 1048 (**self).declare_data_in_data(data_id, data) 1049 } 1050 1051 fn define_function(&mut self, func: FuncId, ctx: &mut Context) -> ModuleResult<()> { 1052 (**self).define_function(func, ctx) 1053 } 1054 1055 fn define_function_with_control_plane( 1056 &mut self, 1057 func: FuncId, 1058 ctx: &mut Context, 1059 ctrl_plane: &mut ControlPlane, 1060 ) -> ModuleResult<()> { 1061 (**self).define_function_with_control_plane(func, ctx, ctrl_plane) 1062 } 1063 1064 fn define_function_bytes( 1065 &mut self, 1066 func_id: FuncId, 1067 func: &ir::Function, 1068 alignment: u64, 1069 bytes: &[u8], 1070 relocs: &[MachReloc], 1071 ) -> ModuleResult<()> { 1072 (**self).define_function_bytes(func_id, func, alignment, bytes, relocs) 1073 } 1074 1075 fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> { 1076 (**self).define_data(data_id, data) 1077 } 1078 } 1079