1 use crate::ast::*;
2 use crate::Error;
3 
4 mod expand;
5 mod names;
6 mod tyexpand;
7 
resolve<'a>(module: &mut Module<'a>) -> Result<Names<'a>, Error>8 pub fn resolve<'a>(module: &mut Module<'a>) -> Result<Names<'a>, Error> {
9     let fields = match &mut module.kind {
10         ModuleKind::Text(fields) => fields,
11         _ => return Ok(Default::default()),
12     };
13 
14     // First up, let's de-inline import/export annotations since this'll
15     // restructure the module and affect how we count indices in future passes
16     // since function definitions turn into imports.
17     //
18     // The first pass switches all inline imports to explicit `Import` items.
19     // This pass also counts all `Import` items per-type to start building up
20     // the index space so we know the corresponding index for each item.
21     //
22     // In a second pass we then remove all inline `export` annotations, again
23     // counting indices as we go along to ensure we always know the index for
24     // what we're exporting.
25     //
26     // The final step is then taking all of the injected `export` fields and
27     // actually pushing them onto our list of fields.
28     let mut expander = expand::Expander::default();
29     expander.process(fields, expand::Expander::deinline_import);
30     expander.process(fields, expand::Expander::deinline_export);
31 
32     for i in 1..fields.len() {
33         let span = match &fields[i] {
34             ModuleField::Import(i) => i.span,
35             _ => continue,
36         };
37         let name = match &fields[i - 1] {
38             ModuleField::Memory(_) => "memory",
39             ModuleField::Func(_) => "function",
40             ModuleField::Table(_) => "table",
41             ModuleField::Global(_) => "global",
42             _ => continue,
43         };
44         return Err(Error::new(span, format!("import after {}", name)));
45     }
46 
47     // For the second pass we resolve all inline type annotations. This will, in
48     // the order that we see them, append to the list of types. Note that types
49     // are indexed so we're careful to always insert new types just before the
50     // field that we're looking at.
51     //
52     // It's not strictly required that we `move_types_first` here but it gets
53     // our indexing to exactly match wabt's which our test suite is asserting.
54     let mut cur = 0;
55     let mut expander = tyexpand::Expander::default();
56     move_types_first(fields);
57     while cur < fields.len() {
58         expander.expand(&mut fields[cur]);
59         for new in expander.to_prepend.drain(..) {
60             fields.insert(cur, new);
61             cur += 1;
62         }
63         cur += 1;
64     }
65 
66     // Perform name resolution over all `Index` items to resolve them all to
67     // indices instead of symbolic names.
68     //
69     // For this operation we do need to make sure that imports are sorted first
70     // because otherwise we'll be calculating indices in the wrong order.
71     move_imports_first(fields);
72     let mut resolver = names::Resolver::default();
73     for field in fields.iter_mut() {
74         resolver.register(field)?;
75     }
76     for field in fields.iter_mut() {
77         resolver.resolve(field)?;
78     }
79     Ok(Names { resolver })
80 }
81 
move_imports_first(fields: &mut [ModuleField<'_>])82 fn move_imports_first(fields: &mut [ModuleField<'_>]) {
83     fields.sort_by_key(|f| match f {
84         ModuleField::Import(_) => false,
85         _ => true,
86     });
87 }
88 
move_types_first(fields: &mut [ModuleField<'_>])89 fn move_types_first(fields: &mut [ModuleField<'_>]) {
90     fields.sort_by_key(|f| match f {
91         ModuleField::Type(_) => false,
92         _ => true,
93     });
94 }
95 
96 /// Representation of the results of name resolution for a module.
97 ///
98 /// This structure is returned from the
99 /// [`Module::resolve`](crate::Module::resolve) function and can be used to
100 /// resolve your own name arguments if you have any.
101 #[derive(Default)]
102 pub struct Names<'a> {
103     resolver: names::Resolver<'a>,
104 }
105 
106 impl<'a> Names<'a> {
107     /// Resolves `idx` within the function namespace.
108     ///
109     /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be
110     /// looked up in the function namespace and converted to a `Num`. If the
111     /// `Id` is not defined then an error will be returned.
resolve_func(&self, idx: &mut Index<'a>) -> Result<(), Error>112     pub fn resolve_func(&self, idx: &mut Index<'a>) -> Result<(), Error> {
113         self.resolver.resolve_idx(idx, names::Ns::Func)
114     }
115 
116     /// Resolves `idx` within the memory namespace.
117     ///
118     /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be
119     /// looked up in the memory namespace and converted to a `Num`. If the
120     /// `Id` is not defined then an error will be returned.
resolve_memory(&self, idx: &mut Index<'a>) -> Result<(), Error>121     pub fn resolve_memory(&self, idx: &mut Index<'a>) -> Result<(), Error> {
122         self.resolver.resolve_idx(idx, names::Ns::Memory)
123     }
124 
125     /// Resolves `idx` within the table namespace.
126     ///
127     /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be
128     /// looked up in the table namespace and converted to a `Num`. If the
129     /// `Id` is not defined then an error will be returned.
resolve_table(&self, idx: &mut Index<'a>) -> Result<(), Error>130     pub fn resolve_table(&self, idx: &mut Index<'a>) -> Result<(), Error> {
131         self.resolver.resolve_idx(idx, names::Ns::Table)
132     }
133 
134     /// Resolves `idx` within the global namespace.
135     ///
136     /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be
137     /// looked up in the global namespace and converted to a `Num`. If the
138     /// `Id` is not defined then an error will be returned.
resolve_global(&self, idx: &mut Index<'a>) -> Result<(), Error>139     pub fn resolve_global(&self, idx: &mut Index<'a>) -> Result<(), Error> {
140         self.resolver.resolve_idx(idx, names::Ns::Global)
141     }
142 }
143