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