Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/asmjs/asm-types.cc

Issue 2148073002: V8. ASM-2-WASM. Fixes technical debt in asm-types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/asmjs/asm-types.h"
6
7 #include <cinttypes>
8
5 #include "src/v8.h" 9 #include "src/v8.h"
6 10
7 #include "src/asmjs/asm-types.h"
8
9 namespace v8 { 11 namespace v8 {
10 namespace internal { 12 namespace internal {
11 namespace wasm { 13 namespace wasm {
12 14
13 AsmCallableType* AsmType::AsCallableType() { 15 AsmCallableType* AsmType::AsCallableType() {
14 if (AsValueType() != nullptr) { 16 if (AsValueType() != nullptr) {
15 return nullptr; 17 return nullptr;
16 } 18 }
17 19
18 DCHECK(this->AsFunctionType() != nullptr ||
19 this->AsOverloadedFunctionType() != nullptr ||
20 this->AsFFIType() != nullptr ||
21 this->AsFunctionTableType() != nullptr);
22 return reinterpret_cast<AsmCallableType*>(this); 20 return reinterpret_cast<AsmCallableType*>(this);
23 } 21 }
24 22
25 std::string AsmType::Name() { 23 std::string AsmType::Name() {
26 AsmValueType* avt = this->AsValueType(); 24 AsmValueType* avt = this->AsValueType();
27 if (avt != nullptr) { 25 if (avt != nullptr) {
28 switch (avt->Bitset()) { 26 switch (avt->Bitset()) {
29 #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \ 27 #define RETURN_TYPE_NAME(CamelName, string_name, number, parent_types) \
30 case AsmValueType::kAsm##CamelName: \ 28 case AsmValueType::kAsm##CamelName: \
31 return string_name; 29 return string_name;
(...skipping 19 matching lines...) Expand all
51 } 49 }
52 50
53 // TODO(jpp): is it useful to allow non-value types to be tested with 51 // TODO(jpp): is it useful to allow non-value types to be tested with
54 // IsExactly? 52 // IsExactly?
55 return that == this; 53 return that == this;
56 } 54 }
57 55
58 bool AsmType::IsA(AsmType* that) { 56 bool AsmType::IsA(AsmType* that) {
59 // IsA is used for querying inheritance relationships. Therefore it is only 57 // IsA is used for querying inheritance relationships. Therefore it is only
60 // meaningful for basic types. 58 // meaningful for basic types.
61 AsmValueType* tavt = that->AsValueType(); 59 if (auto* avt = this->AsValueType()) {
62 if (tavt != nullptr) { 60 if (auto* tavt = that->AsValueType()) {
63 AsmValueType* avt = this->AsValueType(); 61 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset();
64 if (avt == nullptr) {
65 return false;
66 } 62 }
67 return (avt->Bitset() & tavt->Bitset()) == tavt->Bitset(); 63 return false;
68 } 64 }
69 65
70 // TODO(jpp): is it useful to allow non-value types to be tested with IsA? 66 if (auto* as_callable = this->AsCallableType()) {
67 return as_callable->IsA(that);
68 }
69
70 UNREACHABLE();
71 return that == this; 71 return that == this;
72 } 72 }
73 73
74 int32_t AsmType::ElementSizeInBytes() { 74 int32_t AsmType::ElementSizeInBytes() {
75 auto* value = AsValueType(); 75 auto* value = AsValueType();
76 if (value == nullptr) { 76 if (value == nullptr) {
77 return AsmType::kNotHeapType; 77 return AsmType::kNotHeapType;
78 } 78 }
79 switch (value->Bitset()) { 79 switch (value->Bitset()) {
80 case AsmValueType::kAsmInt8Array: 80 case AsmValueType::kAsmInt8Array:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 return AsmType::Intish(); 131 return AsmType::Intish();
132 case AsmValueType::kAsmFloat32Array: 132 case AsmValueType::kAsmFloat32Array:
133 return AsmType::FloatishDoubleQ(); 133 return AsmType::FloatishDoubleQ();
134 case AsmValueType::kAsmFloat64Array: 134 case AsmValueType::kAsmFloat64Array:
135 return AsmType::FloatQDoubleQ(); 135 return AsmType::FloatQDoubleQ();
136 default: 136 default:
137 return AsmType::None(); 137 return AsmType::None();
138 } 138 }
139 } 139 }
140 140
141 bool AsmCallableType::IsA(AsmType* other) {
142 return other->AsCallableType() == this;
143 }
144
141 std::string AsmFunctionType::Name() { 145 std::string AsmFunctionType::Name() {
142 if (IsFroundType()) {
143 return "fround";
144 }
145
146 std::string ret; 146 std::string ret;
147 ret += "("; 147 ret += "(";
148 for (size_t ii = 0; ii < args_.size(); ++ii) { 148 for (size_t ii = 0; ii < args_.size(); ++ii) {
149 ret += args_[ii]->Name(); 149 ret += args_[ii]->Name();
150 if (ii != args_.size() - 1) { 150 if (ii != args_.size() - 1) {
151 ret += ", "; 151 ret += ", ";
152 } 152 }
153 } 153 }
154 if (IsMinMaxType()) {
155 DCHECK_EQ(args_.size(), 2);
156 ret += "...";
157 }
158 ret += ") -> "; 154 ret += ") -> ";
159 ret += return_type_->Name(); 155 ret += return_type_->Name();
160 return ret; 156 return ret;
161 } 157 }
162 158
163 namespace { 159 namespace {
164 class AsmFroundType final : public AsmFunctionType { 160 class AsmFroundType final : public AsmCallableType {
165 public: 161 public:
166 bool IsFroundType() const override { return true; }
167
168 private:
169 friend AsmType; 162 friend AsmType;
170 163
171 explicit AsmFroundType(Zone* zone) 164 AsmFroundType() : AsmCallableType() {}
172 : AsmFunctionType(zone, AsmType::Float()) {}
173 165
174 AsmType* ValidateCall(AsmType* return_type,
175 const ZoneVector<AsmType*>& args) override;
176 bool CanBeInvokedWith(AsmType* return_type, 166 bool CanBeInvokedWith(AsmType* return_type,
177 const ZoneVector<AsmType*>& args) override; 167 const ZoneVector<AsmType*>& args) override;
168
169 std::string Name() override { return "fround"; }
178 }; 170 };
179 } // namespace 171 } // namespace
180 172
181 AsmType* AsmType::FroundType(Zone* zone) { 173 AsmType* AsmType::FroundType(Zone* zone) {
182 auto* Fround = new (zone) AsmFroundType(zone); 174 auto* Fround = new (zone) AsmFroundType();
183 return reinterpret_cast<AsmType*>(Fround); 175 return reinterpret_cast<AsmType*>(Fround);
184 } 176 }
185 177
186 // TODO(jpp): Remove this method.
187 AsmType* AsmFroundType::ValidateCall(AsmType* return_type,
188 const ZoneVector<AsmType*>& args) {
189 if (args.size() != 1) {
190 return AsmType::None();
191 }
192
193 auto* arg = args[0];
194 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
195 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
196 return AsmType::None();
197 }
198
199 return AsmType::Float();
200 }
201
202 bool AsmFroundType::CanBeInvokedWith(AsmType* return_type, 178 bool AsmFroundType::CanBeInvokedWith(AsmType* return_type,
203 const ZoneVector<AsmType*>& args) { 179 const ZoneVector<AsmType*>& args) {
204 if (args.size() != 1) { 180 if (args.size() != 1) {
205 return false; 181 return false;
206 } 182 }
207 183
208 auto* arg = args[0]; 184 auto* arg = args[0];
209 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) && 185 if (!arg->IsA(AsmType::Floatish()) && !arg->IsA(AsmType::DoubleQ()) &&
210 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) { 186 !arg->IsA(AsmType::Signed()) && !arg->IsA(AsmType::Unsigned())) {
211 return false; 187 return false;
212 } 188 }
213 189
214 return true; 190 return true;
215 } 191 }
216 192
217 namespace { 193 namespace {
218 class AsmMinMaxType final : public AsmFunctionType { 194 class AsmMinMaxType final : public AsmCallableType {
219 public:
220 bool IsMinMaxType() const override { return true; }
221
222 private: 195 private:
223 friend AsmType; 196 friend AsmType;
224 197
225 AsmMinMaxType(Zone* zone, AsmType* dest, AsmType* src) 198 AsmMinMaxType(AsmType* dest, AsmType* src)
226 : AsmFunctionType(zone, dest) { 199 : AsmCallableType(), return_type_(dest), arg_(src) {}
227 AddArgument(src);
228 AddArgument(src);
229 }
230
231 AsmType* ValidateCall(AsmType* return_type,
232 const ZoneVector<AsmType*>& args) override {
233 if (!ReturnType()->IsExactly(return_type)) {
234 return AsmType::None();
235 }
236
237 if (args.size() < 2) {
238 return AsmType::None();
239 }
240
241 for (size_t ii = 0; ii < Arguments().size(); ++ii) {
242 if (!Arguments()[0]->IsExactly(args[ii])) {
243 return AsmType::None();
244 }
245 }
246
247 return ReturnType();
248 }
249 200
250 bool CanBeInvokedWith(AsmType* return_type, 201 bool CanBeInvokedWith(AsmType* return_type,
251 const ZoneVector<AsmType*>& args) override { 202 const ZoneVector<AsmType*>& args) override {
252 if (!ReturnType()->IsExactly(return_type)) { 203 if (!return_type_->IsExactly(return_type)) {
253 return false; 204 return false;
254 } 205 }
255 206
256 if (args.size() < 2) { 207 if (args.size() < 2) {
257 return false; 208 return false;
258 } 209 }
259 210
260 auto* arg_type = Arguments()[0]; 211 for (size_t ii = 0; ii < args.size(); ++ii) {
261 for (size_t ii = 0; ii < Arguments().size(); ++ii) { 212 if (!args[ii]->IsA(arg_)) {
262 if (!args[ii]->IsA(arg_type)) {
263 return false; 213 return false;
264 } 214 }
265 } 215 }
266 216
267 return true; 217 return true;
268 } 218 }
219
220 std::string Name() override {
221 return "(" + arg_->Name() + ", " + arg_->Name() + "...) -> " +
222 return_type_->Name();
223 }
224
225 AsmType* return_type_;
226 AsmType* arg_;
269 }; 227 };
270 } // namespace 228 } // namespace
271 229
272 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) { 230 AsmType* AsmType::MinMaxType(Zone* zone, AsmType* dest, AsmType* src) {
273 DCHECK(dest->AsValueType() != nullptr); 231 DCHECK(dest->AsValueType() != nullptr);
274 DCHECK(src->AsValueType() != nullptr); 232 DCHECK(src->AsValueType() != nullptr);
275 auto* MinMax = new (zone) AsmMinMaxType(zone, dest, src); 233 auto* MinMax = new (zone) AsmMinMaxType(dest, src);
276 return reinterpret_cast<AsmType*>(MinMax); 234 return reinterpret_cast<AsmType*>(MinMax);
277 } 235 }
278 236
279 AsmType* AsmFFIType::ValidateCall(AsmType* return_type,
280 const ZoneVector<AsmType*>& args) {
281 for (size_t ii = 0; ii < args.size(); ++ii) {
282 if (!args[ii]->IsA(AsmType::Extern())) {
283 return AsmType::None();
284 }
285 }
286
287 return return_type;
288 }
289
290 bool AsmFFIType::CanBeInvokedWith(AsmType* return_type, 237 bool AsmFFIType::CanBeInvokedWith(AsmType* return_type,
291 const ZoneVector<AsmType*>& args) { 238 const ZoneVector<AsmType*>& args) {
292 if (return_type->IsExactly(AsmType::Float())) { 239 if (return_type->IsExactly(AsmType::Float())) {
293 return false; 240 return false;
294 } 241 }
295 242
296 for (size_t ii = 0; ii < args.size(); ++ii) { 243 for (size_t ii = 0; ii < args.size(); ++ii) {
297 if (!args[ii]->IsA(AsmType::Extern())) { 244 if (!args[ii]->IsA(AsmType::Extern())) {
298 return false; 245 return false;
299 } 246 }
300 } 247 }
301 248
302 return true; 249 return true;
303 } 250 }
304 251
305 AsmType* AsmFunctionType::ValidateCall(AsmType* return_type, 252 bool AsmFunctionType::IsA(AsmType* other) {
306 const ZoneVector<AsmType*>& args) { 253 auto* that = other->AsFunctionType();
307 if (!return_type_->IsExactly(return_type)) { 254 if (that == nullptr) {
308 return AsmType::None(); 255 return false;
256 }
257 if (!return_type_->IsExactly(that->return_type_)) {
258 return false;
309 } 259 }
310 260
311 if (args_.size() != args.size()) { 261 if (args_.size() != that->args_.size()) {
312 return AsmType::None(); 262 return false;
313 } 263 }
314 264
315 for (size_t ii = 0; ii < args_.size(); ++ii) { 265 for (size_t ii = 0; ii < args_.size(); ++ii) {
316 if (!args_[ii]->IsExactly(args[ii])) { 266 if (!args_[ii]->IsExactly(that->args_[ii])) {
317 return AsmType::None(); 267 return false;
318 } 268 }
319 } 269 }
320 270
321 return return_type_; 271 return true;
322 } 272 }
323 273
324 bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type, 274 bool AsmFunctionType::CanBeInvokedWith(AsmType* return_type,
325 const ZoneVector<AsmType*>& args) { 275 const ZoneVector<AsmType*>& args) {
326 if (!return_type_->IsExactly(return_type)) { 276 if (!return_type_->IsExactly(return_type)) {
327 return false; 277 return false;
328 } 278 }
329 279
330 if (args_.size() != args.size()) { 280 if (args_.size() != args.size()) {
331 return false; 281 return false;
(...skipping 14 matching lines...) Expand all
346 for (size_t ii = 0; ii < overloads_.size(); ++ii) { 296 for (size_t ii = 0; ii < overloads_.size(); ++ii) {
347 if (ii != 0) { 297 if (ii != 0) {
348 ret += " /\\ "; 298 ret += " /\\ ";
349 } 299 }
350 ret += overloads_[ii]->Name(); 300 ret += overloads_[ii]->Name();
351 } 301 }
352 302
353 return ret; 303 return ret;
354 } 304 }
355 305
356 AsmType* AsmOverloadedFunctionType::ValidateCall(
357 AsmType* return_type, const ZoneVector<AsmType*>& args) {
358 for (size_t ii = 0; ii < overloads_.size(); ++ii) {
359 auto* validated_type =
360 overloads_[ii]->AsCallableType()->ValidateCall(return_type, args);
361 if (validated_type != AsmType::None()) {
362 return validated_type;
363 }
364 }
365
366 return AsmType::None();
367 }
368
369 bool AsmOverloadedFunctionType::CanBeInvokedWith( 306 bool AsmOverloadedFunctionType::CanBeInvokedWith(
370 AsmType* return_type, const ZoneVector<AsmType*>& args) { 307 AsmType* return_type, const ZoneVector<AsmType*>& args) {
371 for (size_t ii = 0; ii < overloads_.size(); ++ii) { 308 for (size_t ii = 0; ii < overloads_.size(); ++ii) {
372 if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) { 309 if (overloads_[ii]->AsCallableType()->CanBeInvokedWith(return_type, args)) {
373 return true; 310 return true;
374 } 311 }
375 } 312 }
376 313
377 return false; 314 return false;
378 } 315 }
379 316
380 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) { 317 void AsmOverloadedFunctionType::AddOverload(AsmType* overload) {
381 DCHECK(overload->AsFunctionType() != nullptr); 318 DCHECK(overload->AsCallableType() != nullptr);
382 overloads_.push_back(overload); 319 overloads_.push_back(overload);
383 } 320 }
384 321
385 AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature) 322 AsmFunctionTableType::AsmFunctionTableType(size_t length, AsmType* signature)
386 : length_(length), signature_(signature) { 323 : length_(length), signature_(signature) {
387 DCHECK(signature_ != nullptr); 324 DCHECK(signature_ != nullptr);
388 DCHECK(signature_->AsFunctionType() != nullptr); 325 DCHECK(signature_->AsFunctionType() != nullptr);
389 } 326 }
390 327
328 namespace {
329 // ToString is used for reporting function tables' names. It converts its
330 // argument to uint32_t because asm.js integers are 32-bits, thus effectively
331 // limiting the max function table's length.
332 std::string ToString(size_t s) {
333 auto u32 = static_cast<uint32_t>(s);
334 // 16 bytes is more than enough to represent a 32-bit integer as a base 10
335 // string.
336 char digits[16];
337 int length = base::OS::SNPrintF(digits, arraysize(digits), "%" PRIu32, u32);
338 DCHECK_NE(length, -1);
339 return std::string(digits, length);
340 }
341 } // namespace
342
391 std::string AsmFunctionTableType::Name() { 343 std::string AsmFunctionTableType::Name() {
392 return signature_->Name() + "[" + std::to_string(length_) + "]"; 344 return "(" + signature_->Name() + ")[" + ToString(length_) + "]";
393 }
394
395 AsmType* AsmFunctionTableType::ValidateCall(AsmType* return_type,
396 const ZoneVector<AsmType*>& args) {
397 return signature_->AsCallableType()->ValidateCall(return_type, args);
398 } 345 }
399 346
400 bool AsmFunctionTableType::CanBeInvokedWith(AsmType* return_type, 347 bool AsmFunctionTableType::CanBeInvokedWith(AsmType* return_type,
401 const ZoneVector<AsmType*>& args) { 348 const ZoneVector<AsmType*>& args) {
402 return signature_->AsCallableType()->CanBeInvokedWith(return_type, args); 349 return signature_->AsCallableType()->CanBeInvokedWith(return_type, args);
403 } 350 }
404 351
405 } // namespace wasm 352 } // namespace wasm
406 } // namespace internal 353 } // namespace internal
407 } // namespace v8 354 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698