| 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 |