sway_ir/
context.rs

1//! The main handle to an IR instance.
2//!
3//! [`Context`] contains several
4//! [slotmap](https://github.com/orlp/slotmap) collections to maintain the
5//! IR ECS.
6//!
7//! It is passed around as a mutable reference to many of the Sway-IR APIs.
8
9use rustc_hash::FxHashMap;
10use slotmap::{DefaultKey, SlotMap};
11use sway_features::ExperimentalFeatures;
12use sway_types::SourceEngine;
13
14use crate::{
15    block::BlockContent,
16    function::FunctionContent,
17    metadata::Metadatum,
18    module::{Kind, ModuleContent, ModuleIterator},
19    value::ValueContent,
20    variable::LocalVarContent,
21    Constant, ConstantContent, GlobalVarContent, Type, TypeContent,
22};
23
24/// The main IR context handle.
25///
26/// Every module, function, block and value is stored here.  Some aggregate metadata is also
27/// managed by the context.
28pub struct Context<'eng> {
29    pub source_engine: &'eng SourceEngine,
30
31    pub(crate) modules: SlotMap<DefaultKey, ModuleContent>,
32    pub(crate) functions: SlotMap<DefaultKey, FunctionContent>,
33    pub(crate) blocks: SlotMap<DefaultKey, BlockContent>,
34    pub(crate) values: SlotMap<DefaultKey, ValueContent>,
35    pub(crate) local_vars: SlotMap<DefaultKey, LocalVarContent>,
36    pub(crate) global_vars: SlotMap<DefaultKey, GlobalVarContent>,
37    pub(crate) types: SlotMap<DefaultKey, TypeContent>,
38    pub(crate) type_map: FxHashMap<TypeContent, Type>,
39    pub(crate) constants: SlotMap<DefaultKey, ConstantContent>,
40    // Maps the hash of a ConstantContent to the list of constants with that hash.
41    pub(crate) constants_map: FxHashMap<u64, Vec<Constant>>,
42
43    pub(crate) metadata: SlotMap<DefaultKey, Metadatum>,
44
45    pub program_kind: Kind,
46
47    next_unique_sym_tag: u64,
48
49    pub experimental: ExperimentalFeatures,
50}
51
52impl<'eng> Context<'eng> {
53    pub fn new(source_engine: &'eng SourceEngine, experimental: ExperimentalFeatures) -> Self {
54        let mut def = Self {
55            source_engine,
56            modules: Default::default(),
57            functions: Default::default(),
58            blocks: Default::default(),
59            values: Default::default(),
60            local_vars: Default::default(),
61            global_vars: Default::default(),
62            types: Default::default(),
63            type_map: Default::default(),
64            constants: Default::default(),
65            constants_map: Default::default(),
66            metadata: Default::default(),
67            next_unique_sym_tag: Default::default(),
68            program_kind: Kind::Contract,
69            experimental,
70        };
71        Type::create_basic_types(&mut def);
72        def
73    }
74
75    pub fn source_engine(&self) -> &'eng SourceEngine {
76        self.source_engine
77    }
78
79    /// Return an iterator for every module in this context.
80    pub fn module_iter(&self) -> ModuleIterator {
81        ModuleIterator::new(self)
82    }
83
84    /// Get a globally unique symbol.
85    ///
86    /// The name will be in the form `"anon_N"`, where `N` is an incrementing decimal.
87    pub fn get_unique_name(&mut self) -> String {
88        format!("anon_{}", self.get_unique_id())
89    }
90
91    /// Get a globally unique symbol id.
92    pub fn get_unique_id(&mut self) -> u64 {
93        let sym = self.next_unique_sym_tag;
94        self.next_unique_sym_tag += 1;
95        sym
96    }
97}
98
99use std::fmt::{Display, Error, Formatter};
100
101impl Display for Context<'_> {
102    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
103        write!(f, "{}", crate::printer::to_string(self))
104    }
105}
106
107impl From<Context<'_>> for String {
108    fn from(context: Context) -> Self {
109        crate::printer::to_string(&context)
110    }
111}