27
27
template <> class std ::hash<std::vector<wasm::Type>> {
28
28
public:
29
29
size_t operator ()(const std::vector<wasm::Type>& types) const {
30
- uint32_t res = wasm::rehash (0 , uint32_t (types.size ()));
30
+ uint64_t res = wasm::rehash (0 , uint32_t (types.size ()));
31
31
for (auto t : types) {
32
32
res = wasm::rehash (res, t.getID ());
33
33
}
@@ -36,13 +36,13 @@ template<> class std::hash<std::vector<wasm::Type>> {
36
36
};
37
37
38
38
size_t std::hash<wasm::Type>::operator ()(const wasm::Type& type) const {
39
- return std::hash<uint32_t >{}(type.getID ());
39
+ return std::hash<uint64_t >{}(type.getID ());
40
40
}
41
41
42
42
size_t std::hash<wasm::Signature>::
43
43
operator ()(const wasm::Signature& sig) const {
44
- return std::hash<uint64_t >{}(uint64_t ( sig.params .getID ()) << 32 |
45
- uint64_t (sig.results .getID ()));
44
+ return wasm::rehash ( std::hash<uint64_t >{}(sig.params .getID ()),
45
+ std::hash< uint64_t >{} (sig.results .getID ()));
46
46
}
47
47
48
48
namespace wasm {
@@ -52,28 +52,20 @@ namespace {
52
52
// TODO: switch to std::shared_mutex in C++17
53
53
std::shared_timed_mutex mutex;
54
54
55
- std::vector<std::unique_ptr<std::vector<Type>>> typeLists = [] {
56
- std::vector<std::unique_ptr<std::vector<Type>>> lists;
57
-
58
- auto add = [&](std::initializer_list<Type> types) {
59
- return lists.push_back (std::make_unique<std::vector<Type>>(types));
60
- };
61
-
62
- add ({});
63
- add ({Type::unreachable});
64
- add ({Type::i32});
65
- add ({Type::i64});
66
- add ({Type::f32});
67
- add ({Type::f64});
68
- add ({Type::v128});
69
- add ({Type::funcref});
70
- add ({Type::anyref});
71
- add ({Type::nullref});
72
- add ({Type::exnref});
73
- return lists;
74
- }();
75
-
76
- std::unordered_map<std::vector<Type>, uint32_t > indices = {
55
+ std::array<std::vector<Type>, Type::_last_value_type + 1 > typeLists = {
56
+ std::vector<Type>{},
57
+ {Type::unreachable},
58
+ {Type::i32},
59
+ {Type::i64},
60
+ {Type::f32},
61
+ {Type::f64},
62
+ {Type::v128},
63
+ {Type::funcref},
64
+ {Type::anyref},
65
+ {Type::nullref},
66
+ {Type::exnref}};
67
+
68
+ std::unordered_map<std::vector<Type>, uintptr_t > indices = {
77
69
{{}, Type::none},
78
70
{{Type::unreachable}, Type::unreachable},
79
71
{{Type::i32}, Type::i32},
@@ -96,10 +88,14 @@ void Type::init(const std::vector<Type>& types) {
96
88
}
97
89
#endif
98
90
99
- if (types.size () >= (1 << SIZE_BITS)) {
100
- WASM_UNREACHABLE (" Type too large" );
91
+ if (types.size () == 0 ) {
92
+ id = none;
93
+ return ;
94
+ }
95
+ if (types.size () == 1 ) {
96
+ *this = types[0 ];
97
+ return ;
101
98
}
102
- _size = types.size ();
103
99
104
100
auto lookup = [&]() {
105
101
auto indexIt = indices.find (types);
@@ -124,11 +120,9 @@ void Type::init(const std::vector<Type>& types) {
124
120
if (lookup ()) {
125
121
return ;
126
122
}
127
- if (typeLists.size () >= (1 << ID_BITS)) {
128
- WASM_UNREACHABLE (" Too many types!" );
129
- }
130
- id = typeLists.size ();
131
- typeLists.push_back (std::make_unique<std::vector<Type>>(types));
123
+ auto * vec = new std::vector<Type>(types);
124
+ id = uintptr_t (vec);
125
+ assert (id > _last_value_type);
132
126
indices[types] = id;
133
127
}
134
128
}
@@ -137,23 +131,14 @@ Type::Type(std::initializer_list<Type> types) { init(types); }
137
131
138
132
Type::Type (const std::vector<Type>& types) { init (types); }
139
133
140
- Type::Type (uint32_t _id) {
141
- if (_id <= last_value_type) {
142
- *this = Type (static_cast <ValueType>(_id));
143
- } else {
144
- id = _id;
145
- // Unknown complex type; look up the size
146
- std::shared_lock<std::shared_timed_mutex> lock (mutex);
147
- _size = typeLists[id]->size ();
148
- }
149
- }
150
-
151
- size_t Type::size () const { return _size; }
134
+ size_t Type::size () const { return expand ().size (); }
152
135
153
136
const std::vector<Type>& Type::expand () const {
154
- std::shared_lock<std::shared_timed_mutex> lock (mutex);
155
- assert (id < typeLists.size ());
156
- return *typeLists[id].get ();
137
+ if (id <= _last_value_type) {
138
+ return typeLists[id];
139
+ } else {
140
+ return *(std::vector<Type>*)id;
141
+ }
157
142
}
158
143
159
144
bool Type::operator <(const Type& other) const {
0 commit comments