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