/src/wasm-tools/crates/wast/src/names.rs
Line | Count | Source |
1 | | use crate::Error; |
2 | | use crate::token::{Id, Index}; |
3 | | use std::collections::HashMap; |
4 | | |
5 | | #[derive(Default)] |
6 | | pub struct Namespace<'a> { |
7 | | names: HashMap<Id<'a>, u32>, |
8 | | count: u32, |
9 | | } |
10 | | |
11 | | impl<'a> Namespace<'a> { |
12 | 3.18M | pub fn register(&mut self, name: Option<Id<'a>>, desc: &str) -> Result<u32, Error> { |
13 | 3.18M | let index = self.alloc(); |
14 | 3.18M | if let Some(name) = name { |
15 | 59.8k | if let Some(_prev) = self.names.insert(name, index) { |
16 | 0 | return Err(Error::new( |
17 | 0 | name.span(), |
18 | 0 | format!("duplicate {desc} identifier"), |
19 | 0 | )); |
20 | 59.8k | } |
21 | 3.12M | } |
22 | 3.18M | Ok(index) |
23 | 3.18M | } |
24 | | |
25 | 3.18M | pub fn alloc(&mut self) -> u32 { |
26 | 3.18M | let index = self.count; |
27 | 3.18M | self.count += 1; |
28 | 3.18M | index |
29 | 3.18M | } |
30 | | |
31 | 0 | pub fn register_specific(&mut self, name: Id<'a>, index: u32, desc: &str) -> Result<(), Error> { |
32 | 0 | if let Some(_prev) = self.names.insert(name, index) { |
33 | 0 | return Err(Error::new( |
34 | 0 | name.span(), |
35 | 0 | format!( |
36 | 0 | "duplicate identifier: duplicate {desc} named `{}`", |
37 | 0 | name.name() |
38 | 0 | ), |
39 | 0 | )); |
40 | 0 | } |
41 | 0 | Ok(()) |
42 | 0 | } |
43 | | |
44 | 3.73M | pub fn resolve(&self, idx: &mut Index<'a>, desc: &str) -> Result<u32, Error> { |
45 | 3.73M | let id = match idx { |
46 | 3.70M | Index::Num(n, _) => return Ok(*n), |
47 | 34.8k | Index::Id(id) => id, |
48 | | }; |
49 | 34.8k | if let Some(&n) = self.names.get(id) { |
50 | 34.8k | *idx = Index::Num(n, id.span()); |
51 | 34.8k | return Ok(n); |
52 | 0 | } |
53 | 0 | Err(resolve_error(*id, desc)) |
54 | 3.73M | } |
55 | | } |
56 | | |
57 | 0 | pub fn resolve_error(id: Id<'_>, ns: &str) -> Error { |
58 | 0 | assert!( |
59 | 0 | !id.is_gensym(), |
60 | | "symbol generated by `wast` itself cannot be resolved {id:?}" |
61 | | ); |
62 | 0 | Error::new( |
63 | 0 | id.span(), |
64 | 0 | format!("unknown {ns}: failed to find name `${}`", id.name()), |
65 | | ) |
66 | 0 | } |