OLD | NEW |
| (Empty) |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef SRC_WASM_ASM_TYPES_H_ | |
6 #define SRC_WASM_ASM_TYPES_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "src/base/macros.h" | |
11 #include "src/zone-containers.h" | |
12 #include "src/zone.h" | |
13 | |
14 namespace v8 { | |
15 namespace internal { | |
16 namespace wasm { | |
17 | |
18 class AsmType; | |
19 class AsmFFIType; | |
20 class AsmFunctionType; | |
21 class AsmOverloadedFunctionType; | |
22 class AsmFunctionTableType; | |
23 | |
24 // List of V(CamelName, string_name, number, parent_types) | |
25 #define FOR_EACH_ASM_VALUE_TYPE_LIST(V) \ | |
26 /* These tags are not types that are expressable in the asm source. They */ \ | |
27 /* are used to express semantic information about the types they tag. */ \ | |
28 V(Heap, "[]", 1, 0) \ | |
29 /*The following are actual types that appear in the asm source. */ \ | |
30 V(Void, "void", 2, 0) \ | |
31 V(Extern, "extern", 3, 0) \ | |
32 V(DoubleQ, "double?", 4, 0) \ | |
33 V(Double, "double", 5, kAsmDoubleQ | kAsmExtern) \ | |
34 V(Intish, "intish", 6, 0) \ | |
35 V(Int, "int", 7, kAsmIntish) \ | |
36 V(Signed, "signed", 8, kAsmInt | kAsmExtern) \ | |
37 V(Unsigned, "unsigned", 9, kAsmInt) \ | |
38 V(FixNum, "fixnum", 10, kAsmSigned | kAsmUnsigned) \ | |
39 V(Floatish, "floatish", 11, 0) \ | |
40 V(FloatQ, "float?", 12, kAsmFloatish) \ | |
41 V(Float, "float", 13, kAsmFloatQ) \ | |
42 /* Types used for expressing the Heap accesses. */ \ | |
43 V(Uint8Array, "Uint8Array", 14, kAsmHeap) \ | |
44 V(Int8Array, "Int8Array", 15, kAsmHeap) \ | |
45 V(Uint16Array, "Uint16Array", 16, kAsmHeap) \ | |
46 V(Int16Array, "Int16Array", 17, kAsmHeap) \ | |
47 V(Uint32Array, "Uint32Array", 18, kAsmHeap) \ | |
48 V(Int32Array, "Int32Array", 19, kAsmHeap) \ | |
49 V(Float32Array, "Float32Array", 20, kAsmHeap) \ | |
50 V(Float64Array, "Float64Array", 21, kAsmHeap) \ | |
51 /* Pseudo-types used in representing heap access for fp types.*/ \ | |
52 V(FloatishDoubleQ, "floatish|double?", 22, kAsmFloatish | kAsmDoubleQ) \ | |
53 V(FloatQDoubleQ, "float?|double?", 23, kAsmFloatQ | kAsmDoubleQ) \ | |
54 /* None is used to represent errors in the type checker. */ \ | |
55 V(None, "<none>", 31, 0) | |
56 | |
57 // List of V(CamelName) | |
58 #define FOR_EACH_ASM_CALLABLE_TYPE_LIST(V) \ | |
59 V(FunctionType) \ | |
60 V(FFIType) \ | |
61 V(OverloadedFunctionType) \ | |
62 V(FunctionTableType) | |
63 | |
64 class AsmValueType { | |
65 public: | |
66 typedef uint32_t bitset_t; | |
67 | |
68 enum : uint32_t { | |
69 #define DEFINE_TAG(CamelName, string_name, number, parent_types) \ | |
70 kAsm##CamelName = ((1u << (number)) | (parent_types)), | |
71 FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_TAG) | |
72 #undef DEFINE_TAG | |
73 kAsmUnknown = 0, | |
74 kAsmValueTypeTag = 1u | |
75 }; | |
76 | |
77 private: | |
78 friend class AsmType; | |
79 | |
80 static AsmValueType* AsValueType(AsmType* type) { | |
81 if ((reinterpret_cast<uintptr_t>(type) & kAsmValueTypeTag) == | |
82 kAsmValueTypeTag) { | |
83 return reinterpret_cast<AsmValueType*>(type); | |
84 } | |
85 return nullptr; | |
86 } | |
87 | |
88 bitset_t Bitset() const { | |
89 DCHECK((reinterpret_cast<uintptr_t>(this) & kAsmValueTypeTag) == | |
90 kAsmValueTypeTag); | |
91 return static_cast<bitset_t>(reinterpret_cast<uintptr_t>(this) & | |
92 ~kAsmValueTypeTag); | |
93 } | |
94 | |
95 static AsmType* New(bitset_t bits) { | |
96 DCHECK_EQ((bits & kAsmValueTypeTag), 0); | |
97 return reinterpret_cast<AsmType*>( | |
98 static_cast<uintptr_t>(bits | kAsmValueTypeTag)); | |
99 } | |
100 | |
101 // AsmValueTypes can't be created except through AsmValueType::New. | |
102 DISALLOW_IMPLICIT_CONSTRUCTORS(AsmValueType); | |
103 }; | |
104 | |
105 class AsmCallableType : public ZoneObject { | |
106 public: | |
107 virtual std::string Name() = 0; | |
108 virtual AsmType* ValidateCall(AsmType* return_type, | |
109 const ZoneVector<AsmType*>& args) = 0; | |
110 | |
111 #define DECLARE_CAST(CamelName) \ | |
112 virtual Asm##CamelName* As##CamelName() { return nullptr; } | |
113 FOR_EACH_ASM_CALLABLE_TYPE_LIST(DECLARE_CAST) | |
114 #undef DECLARE_CAST | |
115 | |
116 protected: | |
117 AsmCallableType() = default; | |
118 virtual ~AsmCallableType() = default; | |
119 | |
120 private: | |
121 DISALLOW_COPY_AND_ASSIGN(AsmCallableType); | |
122 }; | |
123 | |
124 class AsmFunctionType : public AsmCallableType { | |
125 public: | |
126 AsmFunctionType* AsFunctionType() final { return this; } | |
127 | |
128 void AddArgument(AsmType* type) { args_.push_back(type); } | |
129 const ZoneVector<AsmType*> Arguments() const { return args_; } | |
130 AsmType* ReturnType() const { return return_type_; } | |
131 | |
132 virtual bool IsMinMaxType() const { return false; } | |
133 virtual bool IsFroundType() const { return false; } | |
134 | |
135 protected: | |
136 AsmFunctionType(Zone* zone, AsmType* return_type) | |
137 : return_type_(return_type), args_(zone) {} | |
138 | |
139 private: | |
140 friend AsmType; | |
141 | |
142 std::string Name() override; | |
143 AsmType* ValidateCall(AsmType* return_type, | |
144 const ZoneVector<AsmType*>& args) override; | |
145 | |
146 AsmType* return_type_; | |
147 ZoneVector<AsmType*> args_; | |
148 | |
149 DISALLOW_COPY_AND_ASSIGN(AsmFunctionType); | |
150 }; | |
151 | |
152 class AsmOverloadedFunctionType final : public AsmCallableType { | |
153 public: | |
154 AsmOverloadedFunctionType* AsOverloadedFunctionType() override { | |
155 return this; | |
156 } | |
157 | |
158 void AddOverload(AsmType* overload); | |
159 | |
160 private: | |
161 friend AsmType; | |
162 | |
163 explicit AsmOverloadedFunctionType(Zone* zone) : overloads_(zone) {} | |
164 | |
165 std::string Name() override; | |
166 AsmType* ValidateCall(AsmType* return_type, | |
167 const ZoneVector<AsmType*>& args) override; | |
168 | |
169 ZoneVector<AsmType*> overloads_; | |
170 | |
171 DISALLOW_IMPLICIT_CONSTRUCTORS(AsmOverloadedFunctionType); | |
172 }; | |
173 | |
174 class AsmFFIType final : public AsmCallableType { | |
175 public: | |
176 AsmFFIType* AsFFIType() override { return this; } | |
177 | |
178 std::string Name() override { return "Function"; } | |
179 AsmType* ValidateCall(AsmType* return_type, | |
180 const ZoneVector<AsmType*>& args) override; | |
181 | |
182 private: | |
183 friend AsmType; | |
184 | |
185 AsmFFIType() = default; | |
186 | |
187 DISALLOW_COPY_AND_ASSIGN(AsmFFIType); | |
188 }; | |
189 | |
190 class AsmFunctionTableType : public AsmCallableType { | |
191 public: | |
192 AsmFunctionTableType* AsFunctionTableType() override { return this; } | |
193 | |
194 std::string Name() override; | |
195 | |
196 AsmType* ValidateCall(AsmType* return_type, | |
197 const ZoneVector<AsmType*>& args) override; | |
198 | |
199 size_t length() const { return length_; } | |
200 | |
201 private: | |
202 friend class AsmType; | |
203 | |
204 AsmFunctionTableType(size_t length, AsmType* signature); | |
205 | |
206 size_t length_; | |
207 AsmType* signature_; | |
208 | |
209 DISALLOW_IMPLICIT_CONSTRUCTORS(AsmFunctionTableType); | |
210 }; | |
211 | |
212 class AsmType { | |
213 public: | |
214 #define DEFINE_CONSTRUCTOR(CamelName, string_name, number, parent_types) \ | |
215 static AsmType* CamelName() { \ | |
216 return AsmValueType::New(AsmValueType::kAsm##CamelName); \ | |
217 } | |
218 FOR_EACH_ASM_VALUE_TYPE_LIST(DEFINE_CONSTRUCTOR) | |
219 #undef DEFINE_CONSTRUCTOR | |
220 | |
221 #define DEFINE_CAST(CamelCase) \ | |
222 Asm##CamelCase* As##CamelCase() { \ | |
223 if (AsValueType() != nullptr) { \ | |
224 return nullptr; \ | |
225 } \ | |
226 return reinterpret_cast<AsmCallableType*>(this)->As##CamelCase(); \ | |
227 } | |
228 FOR_EACH_ASM_CALLABLE_TYPE_LIST(DEFINE_CAST) | |
229 #undef DEFINE_CAST | |
230 AsmValueType* AsValueType() { return AsmValueType::AsValueType(this); } | |
231 AsmCallableType* AsCallableType(); | |
232 | |
233 // A function returning ret. Callers still need to invoke AddArgument with the | |
234 // returned type to fully create this type. | |
235 static AsmType* Function(Zone* zone, AsmType* ret) { | |
236 AsmFunctionType* f = new (zone) AsmFunctionType(zone, ret); | |
237 return reinterpret_cast<AsmType*>(f); | |
238 } | |
239 | |
240 // Overloaded function types. Not creatable by asm source, but useful to | |
241 // represent the overloaded stdlib functions. | |
242 static AsmType* OverloadedFunction(Zone* zone) { | |
243 auto* f = new (zone) AsmOverloadedFunctionType(zone); | |
244 return reinterpret_cast<AsmType*>(f); | |
245 } | |
246 | |
247 // The type for fround(src). | |
248 static AsmType* FroundType(Zone* zone); | |
249 | |
250 // The (variadic) type for min and max. | |
251 static AsmType* MinMaxType(Zone* zone, AsmType* dest, AsmType* src); | |
252 | |
253 // The type for foreign functions. | |
254 static AsmType* FFIType(Zone* zone) { | |
255 auto* f = new (zone) AsmFFIType(); | |
256 return reinterpret_cast<AsmType*>(f); | |
257 } | |
258 | |
259 // The type for function tables. | |
260 static AsmType* FunctionTableType(Zone* zone, size_t length, | |
261 AsmType* signature) { | |
262 auto* f = new (zone) AsmFunctionTableType(length, signature); | |
263 return reinterpret_cast<AsmType*>(f); | |
264 } | |
265 | |
266 std::string Name(); | |
267 // IsExactly returns true if this is the exact same type as that. For | |
268 // non-value types (e.g., callables), this returns this == that. | |
269 bool IsExactly(AsmType* that); | |
270 // IsA is used to query whether this is an instance of that (i.e., if this is | |
271 // a type derived from that.) For non-value types (e.g., callables), this | |
272 // returns this == that. | |
273 bool IsA(AsmType* that); | |
274 | |
275 // Types allowed in return statements. void is the type for returns without | |
276 // an expression. | |
277 bool IsReturnType() { | |
278 return this == AsmType::Void() || this == AsmType::Double() || | |
279 this == AsmType::Signed() || this == AsmType::Float(); | |
280 } | |
281 | |
282 // Converts this to the corresponding valid argument type. | |
283 AsmType* ToReturnType() { | |
284 if (this->IsA(AsmType::Signed())) { | |
285 return AsmType::Signed(); | |
286 } | |
287 if (this->IsA(AsmType::Double())) { | |
288 return AsmType::Double(); | |
289 } | |
290 if (this->IsA(AsmType::Float())) { | |
291 return AsmType::Float(); | |
292 } | |
293 if (this->IsA(AsmType::Void())) { | |
294 return AsmType::Void(); | |
295 } | |
296 return AsmType::None(); | |
297 } | |
298 | |
299 // Types allowed to be parameters in asm functions. | |
300 bool IsParameterType() { | |
301 return this == AsmType::Double() || this == AsmType::Int() || | |
302 this == AsmType::Float(); | |
303 } | |
304 | |
305 // Converts this to the corresponding valid argument type. | |
306 AsmType* ToParameterType() { | |
307 if (this->IsA(AsmType::Int())) { | |
308 return AsmType::Int(); | |
309 } | |
310 if (this->IsA(AsmType::Double())) { | |
311 return AsmType::Double(); | |
312 } | |
313 if (this->IsA(AsmType::Float())) { | |
314 return AsmType::Float(); | |
315 } | |
316 return AsmType::None(); | |
317 } | |
318 | |
319 // Types allowed to be compared using the comparison operators. | |
320 bool IsComparableType() { | |
321 return this == AsmType::Double() || this == AsmType::Signed() || | |
322 this == AsmType::Unsigned() || this == AsmType::Float(); | |
323 } | |
324 | |
325 // The following methods are meant to be used for inspecting the traits of | |
326 // element types for the heap view types. | |
327 enum : int32_t { kNotHeapType = -1 }; | |
328 | |
329 // Returns the element size if this is a heap type. Otherwise returns | |
330 // kNotHeapType. | |
331 int32_t ElementSizeInBytes(); | |
332 // Returns the load type if this is a heap type. AsmType::None is returned if | |
333 // this is not a heap type. | |
334 AsmType* LoadType(); | |
335 // Returns the store type if this is a heap type. AsmType::None is returned if | |
336 // this is not a heap type. | |
337 AsmType* StoreType(); | |
338 }; | |
339 | |
340 } // namespace wasm | |
341 } // namespace internal | |
342 } // namespace v8 | |
343 | |
344 #endif // SRC_WASM_ASM_TYPES_H_ | |
OLD | NEW |