1 | /* |
2 | * Copyright 2017 WebAssembly Community Group participants |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #ifndef wasm_support_name_h |
18 | #define wasm_support_name_h |
19 | |
20 | #include "support/istring.h" |
21 | |
22 | namespace wasm { |
23 | |
24 | // We use a Name for all of the identifiers. These are IStrings, so they are |
25 | // all interned - comparisons etc are just pointer comparisons, so there is no |
26 | // perf loss. Having names everywhere makes using the AST much nicer (for |
27 | // example, block names are strings and not offsets, which makes composition |
28 | // - adding blocks, removing blocks - easy). One exception is local variables, |
29 | // where we do use indices, as they are a large proportion of the AST, |
30 | // perf matters a lot there, and compositionality is not a problem. |
31 | // TODO: as an optimization, IString values < some threshold could be considered |
32 | // numerical indices directly. |
33 | |
34 | struct Name : public IString { |
35 | Name() : IString() {} |
36 | Name(std::string_view str) : IString(str, false) {} |
37 | Name(const char* str) : IString(str, false) {} |
38 | Name(IString str) : IString(str) {} |
39 | Name(const std::string& str) : IString(str) {} |
40 | |
41 | // String literals do not need to be copied. Note: Not safe to construct from |
42 | // temporary char arrays! Take their address first. |
43 | template<size_t N> Name(const char (&str)[N]) : IString(str) {} |
44 | |
45 | friend std::ostream& operator<<(std::ostream& o, Name name) { |
46 | if (name) { |
47 | return o << name.str; |
48 | } else { |
49 | return o << "(null Name)" ; |
50 | } |
51 | } |
52 | |
53 | static Name fromInt(size_t i) { |
54 | return IString(std::to_string(i).c_str(), false); |
55 | } |
56 | |
57 | bool hasSubstring(IString substring) { |
58 | // TODO: Use C++23 `contains`. |
59 | return str.find(substring.str) != std::string_view::npos; |
60 | } |
61 | }; |
62 | |
63 | } // namespace wasm |
64 | |
65 | namespace std { |
66 | |
67 | template<> struct hash<wasm::Name> : hash<wasm::IString> {}; |
68 | |
69 | } // namespace std |
70 | |
71 | #endif // wasm_support_name_h |
72 | |