OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/typer.h" | 5 #include "src/compiler/typer.h" |
6 | 6 |
7 #include "src/base/flags.h" | 7 #include "src/base/flags.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); | 236 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); |
237 | 237 |
238 static Type* ToPrimitive(Type*, Typer*); | 238 static Type* ToPrimitive(Type*, Typer*); |
239 static Type* ToBoolean(Type*, Typer*); | 239 static Type* ToBoolean(Type*, Typer*); |
240 static Type* ToInteger(Type*, Typer*); | 240 static Type* ToInteger(Type*, Typer*); |
241 static Type* ToLength(Type*, Typer*); | 241 static Type* ToLength(Type*, Typer*); |
242 static Type* ToName(Type*, Typer*); | 242 static Type* ToName(Type*, Typer*); |
243 static Type* ToNumber(Type*, Typer*); | 243 static Type* ToNumber(Type*, Typer*); |
244 static Type* ToObject(Type*, Typer*); | 244 static Type* ToObject(Type*, Typer*); |
245 static Type* ToString(Type*, Typer*); | 245 static Type* ToString(Type*, Typer*); |
| 246 static Type* NumberAbs(Type*, Typer*); |
246 static Type* NumberCeil(Type*, Typer*); | 247 static Type* NumberCeil(Type*, Typer*); |
247 static Type* NumberFloor(Type*, Typer*); | 248 static Type* NumberFloor(Type*, Typer*); |
248 static Type* NumberRound(Type*, Typer*); | 249 static Type* NumberRound(Type*, Typer*); |
249 static Type* NumberTrunc(Type*, Typer*); | 250 static Type* NumberTrunc(Type*, Typer*); |
250 static Type* NumberToInt32(Type*, Typer*); | 251 static Type* NumberToInt32(Type*, Typer*); |
251 static Type* NumberToUint32(Type*, Typer*); | 252 static Type* NumberToUint32(Type*, Typer*); |
252 | 253 |
253 static Type* ObjectIsCallable(Type*, Typer*); | 254 static Type* ObjectIsCallable(Type*, Typer*); |
254 static Type* ObjectIsNumber(Type*, Typer*); | 255 static Type* ObjectIsNumber(Type*, Typer*); |
255 static Type* ObjectIsReceiver(Type*, Typer*); | 256 static Type* ObjectIsReceiver(Type*, Typer*); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 | 473 |
473 // static | 474 // static |
474 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 475 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
475 // ES6 section 7.1.12 ToString ( argument ) | 476 // ES6 section 7.1.12 ToString ( argument ) |
476 type = ToPrimitive(type, t); | 477 type = ToPrimitive(type, t); |
477 if (type->Is(Type::String())) return type; | 478 if (type->Is(Type::String())) return type; |
478 return Type::String(); | 479 return Type::String(); |
479 } | 480 } |
480 | 481 |
481 // static | 482 // static |
| 483 Type* Typer::Visitor::NumberAbs(Type* type, Typer* t) { |
| 484 DCHECK(type->Is(Type::Number())); |
| 485 Factory* const f = t->isolate()->factory(); |
| 486 bool const maybe_nan = type->Maybe(Type::NaN()); |
| 487 bool const maybe_minuszero = type->Maybe(Type::MinusZero()); |
| 488 type = Type::Intersect(type, Type::PlainNumber(), t->zone()); |
| 489 double const max = type->Max(); |
| 490 double const min = type->Min(); |
| 491 if (min < 0) { |
| 492 if (type->Is(t->cache_.kInteger)) { |
| 493 type = |
| 494 Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), t->zone()); |
| 495 } else if (min == max) { |
| 496 type = Type::Constant(f->NewNumber(std::fabs(min)), t->zone()); |
| 497 } else { |
| 498 type = Type::PlainNumber(); |
| 499 } |
| 500 } |
| 501 if (maybe_minuszero) { |
| 502 type = Type::Union(type, t->cache_.kSingletonZero, t->zone()); |
| 503 } |
| 504 if (maybe_nan) { |
| 505 type = Type::Union(type, Type::NaN(), t->zone()); |
| 506 } |
| 507 return type; |
| 508 } |
| 509 |
| 510 // static |
482 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { | 511 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { |
483 DCHECK(type->Is(Type::Number())); | 512 DCHECK(type->Is(Type::Number())); |
484 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | 513 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; |
485 // TODO(bmeurer): We could infer a more precise type here. | 514 // TODO(bmeurer): We could infer a more precise type here. |
486 return t->cache_.kIntegerOrMinusZeroOrNaN; | 515 return t->cache_.kIntegerOrMinusZeroOrNaN; |
487 } | 516 } |
488 | 517 |
489 // static | 518 // static |
490 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { | 519 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { |
491 DCHECK(type->Is(Type::Number())); | 520 DCHECK(type->Is(Type::Number())); |
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { | 1619 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { |
1591 return Type::Integral32(); | 1620 return Type::Integral32(); |
1592 } | 1621 } |
1593 | 1622 |
1594 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { | 1623 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { |
1595 return Type::Number(); | 1624 return Type::Number(); |
1596 } | 1625 } |
1597 | 1626 |
1598 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } | 1627 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } |
1599 | 1628 |
| 1629 Type* Typer::Visitor::TypeNumberAbs(Node* node) { |
| 1630 return TypeUnaryOp(node, NumberAbs); |
| 1631 } |
| 1632 |
1600 Type* Typer::Visitor::TypeNumberClz32(Node* node) { | 1633 Type* Typer::Visitor::TypeNumberClz32(Node* node) { |
1601 return typer_->cache_.kZeroToThirtyTwo; | 1634 return typer_->cache_.kZeroToThirtyTwo; |
1602 } | 1635 } |
1603 | 1636 |
1604 Type* Typer::Visitor::TypeNumberCeil(Node* node) { | 1637 Type* Typer::Visitor::TypeNumberCeil(Node* node) { |
1605 return TypeUnaryOp(node, NumberCeil); | 1638 return TypeUnaryOp(node, NumberCeil); |
1606 } | 1639 } |
1607 | 1640 |
1608 Type* Typer::Visitor::TypeNumberFloor(Node* node) { | 1641 Type* Typer::Visitor::TypeNumberFloor(Node* node) { |
1609 return TypeUnaryOp(node, NumberFloor); | 1642 return TypeUnaryOp(node, NumberFloor); |
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2588 } | 2621 } |
2589 if (Type::IsInteger(*value)) { | 2622 if (Type::IsInteger(*value)) { |
2590 return Type::Range(value->Number(), value->Number(), zone()); | 2623 return Type::Range(value->Number(), value->Number(), zone()); |
2591 } | 2624 } |
2592 return Type::Constant(value, zone()); | 2625 return Type::Constant(value, zone()); |
2593 } | 2626 } |
2594 | 2627 |
2595 } // namespace compiler | 2628 } // namespace compiler |
2596 } // namespace internal | 2629 } // namespace internal |
2597 } // namespace v8 | 2630 } // namespace v8 |
OLD | NEW |