1 | use crate::core::*; |
2 | use crate::token::Index; |
3 | use crate::{gensym, Error}; |
4 | |
5 | mod deinline_import_export; |
6 | mod names; |
7 | pub(crate) mod types; |
8 | |
9 | #[cfg (feature = "component-model" )] |
10 | pub(crate) use names::ResolveCoreType; |
11 | |
12 | #[derive (PartialEq, Eq, Hash, Copy, Clone, Debug)] |
13 | pub enum Ns { |
14 | Func, |
15 | Table, |
16 | Global, |
17 | Memory, |
18 | Tag, |
19 | Type, |
20 | } |
21 | |
22 | pub fn resolve<'a>(fields: &mut Vec<ModuleField<'a>>) -> Result<Names<'a>, Error> { |
23 | // Ensure that each resolution of a module is deterministic in the names |
24 | // that it generates by resetting our thread-local symbol generator. |
25 | gensym::reset(); |
26 | |
27 | // First up, de-inline import/export annotations. |
28 | // |
29 | // This ensures we only have to deal with inline definitions and to |
30 | // calculate exports we only have to look for a particular kind of module |
31 | // field. |
32 | deinline_import_export::run(fields); |
33 | |
34 | // With a canonical form of imports make sure that imports are all listed |
35 | // first. |
36 | let mut last = None; |
37 | for field in fields.iter() { |
38 | match field { |
39 | ModuleField::Import(i) => { |
40 | if let Some(name) = last { |
41 | return Err(Error::new(i.span, format!("import after {}" , name))); |
42 | } |
43 | } |
44 | ModuleField::Memory(_) => last = Some("memory" ), |
45 | ModuleField::Func(_) => last = Some("function" ), |
46 | ModuleField::Table(_) => last = Some("table" ), |
47 | ModuleField::Global(_) => last = Some("global" ), |
48 | _ => continue, |
49 | } |
50 | } |
51 | |
52 | // Expand all `TypeUse` annotations so all necessary `type` nodes are |
53 | // present in the AST. |
54 | types::expand(fields); |
55 | |
56 | // Perform name resolution over all `Index` items to resolve them all to |
57 | // indices instead of symbolic names. |
58 | let resolver = names::resolve(fields)?; |
59 | Ok(Names { resolver }) |
60 | } |
61 | |
62 | /// Representation of the results of name resolution for a module. |
63 | /// |
64 | /// This structure is returned from the |
65 | /// [`Module::resolve`](crate::core::Module::resolve) function and can be used |
66 | /// to resolve your own name arguments if you have any. |
67 | #[derive (Default)] |
68 | pub struct Names<'a> { |
69 | resolver: names::Resolver<'a>, |
70 | } |
71 | |
72 | impl<'a> Names<'a> { |
73 | /// Resolves `idx` within the function namespace. |
74 | /// |
75 | /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be |
76 | /// looked up in the function namespace and converted to a `Num`. If the |
77 | /// `Id` is not defined then an error will be returned. |
78 | pub fn resolve_func(&self, idx: &mut Index<'a>) -> Result<(), Error> { |
79 | self.resolver.resolve(idx, Ns::Func)?; |
80 | Ok(()) |
81 | } |
82 | |
83 | /// Resolves `idx` within the memory namespace. |
84 | /// |
85 | /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be |
86 | /// looked up in the memory namespace and converted to a `Num`. If the |
87 | /// `Id` is not defined then an error will be returned. |
88 | pub fn resolve_memory(&self, idx: &mut Index<'a>) -> Result<(), Error> { |
89 | self.resolver.resolve(idx, Ns::Memory)?; |
90 | Ok(()) |
91 | } |
92 | |
93 | /// Resolves `idx` within the table namespace. |
94 | /// |
95 | /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be |
96 | /// looked up in the table namespace and converted to a `Num`. If the |
97 | /// `Id` is not defined then an error will be returned. |
98 | pub fn resolve_table(&self, idx: &mut Index<'a>) -> Result<(), Error> { |
99 | self.resolver.resolve(idx, Ns::Table)?; |
100 | Ok(()) |
101 | } |
102 | |
103 | /// Resolves `idx` within the global namespace. |
104 | /// |
105 | /// If `idx` is a `Num`, it is ignored, but if it's an `Id` then it will be |
106 | /// looked up in the global namespace and converted to a `Num`. If the |
107 | /// `Id` is not defined then an error will be returned. |
108 | pub fn resolve_global(&self, idx: &mut Index<'a>) -> Result<(), Error> { |
109 | self.resolver.resolve(idx, Ns::Global)?; |
110 | Ok(()) |
111 | } |
112 | } |
113 | |