Chromium Code Reviews| 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); | 247 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); |
| 248 | 248 |
| 249 static Type* ToPrimitive(Type*, Typer*); | 249 static Type* ToPrimitive(Type*, Typer*); |
| 250 static Type* ToBoolean(Type*, Typer*); | 250 static Type* ToBoolean(Type*, Typer*); |
| 251 static Type* ToInteger(Type*, Typer*); | 251 static Type* ToInteger(Type*, Typer*); |
| 252 static Type* ToLength(Type*, Typer*); | 252 static Type* ToLength(Type*, Typer*); |
| 253 static Type* ToName(Type*, Typer*); | 253 static Type* ToName(Type*, Typer*); |
| 254 static Type* ToNumber(Type*, Typer*); | 254 static Type* ToNumber(Type*, Typer*); |
| 255 static Type* ToObject(Type*, Typer*); | 255 static Type* ToObject(Type*, Typer*); |
| 256 static Type* ToString(Type*, Typer*); | 256 static Type* ToString(Type*, Typer*); |
| 257 static Type* NumberAbs(Type*, Typer*); | |
| 258 static Type* NumberCeil(Type*, Typer*); | 257 static Type* NumberCeil(Type*, Typer*); |
| 259 static Type* NumberFloor(Type*, Typer*); | 258 static Type* NumberFloor(Type*, Typer*); |
| 260 static Type* NumberRound(Type*, Typer*); | 259 static Type* NumberRound(Type*, Typer*); |
| 261 static Type* NumberSign(Type*, Typer*); | 260 static Type* NumberSign(Type*, Typer*); |
| 262 static Type* NumberTrunc(Type*, Typer*); | 261 static Type* NumberTrunc(Type*, Typer*); |
| 263 static Type* NumberToInt32(Type*, Typer*); | 262 static Type* NumberToInt32(Type*, Typer*); |
| 264 static Type* NumberToUint32(Type*, Typer*); | 263 static Type* NumberToUint32(Type*, Typer*); |
| 265 | 264 |
| 266 static Type* ObjectIsCallable(Type*, Typer*); | 265 static Type* ObjectIsCallable(Type*, Typer*); |
| 267 static Type* ObjectIsNumber(Type*, Typer*); | 266 static Type* ObjectIsNumber(Type*, Typer*); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 485 | 484 |
| 486 // static | 485 // static |
| 487 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 486 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
| 488 // ES6 section 7.1.12 ToString ( argument ) | 487 // ES6 section 7.1.12 ToString ( argument ) |
| 489 type = ToPrimitive(type, t); | 488 type = ToPrimitive(type, t); |
| 490 if (type->Is(Type::String())) return type; | 489 if (type->Is(Type::String())) return type; |
| 491 return Type::String(); | 490 return Type::String(); |
| 492 } | 491 } |
| 493 | 492 |
| 494 // static | 493 // static |
| 495 Type* Typer::Visitor::NumberAbs(Type* type, Typer* t) { | |
| 496 DCHECK(type->Is(Type::Number())); | |
| 497 Factory* const f = t->isolate()->factory(); | |
| 498 bool const maybe_nan = type->Maybe(Type::NaN()); | |
| 499 bool const maybe_minuszero = type->Maybe(Type::MinusZero()); | |
| 500 type = Type::Intersect(type, Type::PlainNumber(), t->zone()); | |
| 501 double const max = type->Max(); | |
| 502 double const min = type->Min(); | |
| 503 if (min < 0) { | |
| 504 if (type->Is(t->cache_.kInteger)) { | |
| 505 type = | |
| 506 Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), t->zone()); | |
| 507 } else if (min == max) { | |
| 508 type = Type::Constant(f->NewNumber(std::fabs(min)), t->zone()); | |
| 509 } else { | |
| 510 type = Type::PlainNumber(); | |
| 511 } | |
| 512 } | |
| 513 if (maybe_minuszero) { | |
| 514 type = Type::Union(type, t->cache_.kSingletonZero, t->zone()); | |
| 515 } | |
| 516 if (maybe_nan) { | |
| 517 type = Type::Union(type, Type::NaN(), t->zone()); | |
| 518 } | |
| 519 return type; | |
| 520 } | |
| 521 | |
| 522 // static | |
| 523 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { | 494 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { |
| 524 DCHECK(type->Is(Type::Number())); | 495 DCHECK(type->Is(Type::Number())); |
| 525 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | 496 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; |
| 526 // TODO(bmeurer): We could infer a more precise type here. | 497 // TODO(bmeurer): We could infer a more precise type here. |
| 527 return t->cache_.kIntegerOrMinusZeroOrNaN; | 498 return t->cache_.kIntegerOrMinusZeroOrNaN; |
| 528 } | 499 } |
| 529 | 500 |
| 530 // static | 501 // static |
| 531 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { | 502 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { |
| 532 DCHECK(type->Is(Type::Number())); | 503 DCHECK(type->Is(Type::Number())); |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1048 lhs = ToPrimitive(lhs, t); | 1019 lhs = ToPrimitive(lhs, t); |
| 1049 rhs = ToPrimitive(rhs, t); | 1020 rhs = ToPrimitive(rhs, t); |
| 1050 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { | 1021 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { |
| 1051 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { | 1022 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { |
| 1052 return Type::String(); | 1023 return Type::String(); |
| 1053 } else { | 1024 } else { |
| 1054 return Type::NumberOrString(); | 1025 return Type::NumberOrString(); |
| 1055 } | 1026 } |
| 1056 } | 1027 } |
| 1057 // The addition must be numeric. | 1028 // The addition must be numeric. |
| 1058 return t->operation_typer()->NumericAdd(ToNumber(lhs, t), ToNumber(rhs, t)); | 1029 return t->operation_typer()->NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t)); |
| 1059 } | 1030 } |
| 1060 | 1031 |
| 1061 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { | 1032 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1062 return t->operation_typer()->NumericSubtract(ToNumber(lhs, t), | 1033 return t->operation_typer()->NumberSubtract(ToNumber(lhs, t), |
| 1063 ToNumber(rhs, t)); | 1034 ToNumber(rhs, t)); |
| 1064 } | 1035 } |
| 1065 | 1036 |
| 1066 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 1037 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1067 return t->operation_typer()->NumericMultiply(ToNumber(lhs, t), | 1038 return t->operation_typer()->NumberMultiply(ToNumber(lhs, t), |
| 1068 ToNumber(rhs, t)); | 1039 ToNumber(rhs, t)); |
| 1069 } | 1040 } |
| 1070 | 1041 |
| 1071 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 1042 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1072 return t->operation_typer()->NumericDivide(ToNumber(lhs, t), | 1043 return t->operation_typer()->NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t)); |
| 1073 ToNumber(rhs, t)); | |
| 1074 lhs = ToNumber(lhs, t); | 1044 lhs = ToNumber(lhs, t); |
|
Jarin
2016/07/12 08:51:49
Could you delete this dead code while you are here
Benedikt Meurer
2016/07/12 09:43:49
Done.
| |
| 1075 rhs = ToNumber(rhs, t); | 1045 rhs = ToNumber(rhs, t); |
| 1076 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1046 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
| 1077 // Division is tricky, so all we do is try ruling out nan. | 1047 // Division is tricky, so all we do is try ruling out nan. |
| 1078 bool maybe_nan = | 1048 bool maybe_nan = |
| 1079 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || | 1049 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || |
| 1080 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1050 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
| 1081 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1051 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
| 1082 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1052 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
| 1083 } | 1053 } |
| 1084 | 1054 |
| 1085 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1055 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1086 return t->operation_typer()->NumericModulus(ToNumber(lhs, t), | 1056 return t->operation_typer()->NumberModulus(ToNumber(lhs, t), |
| 1087 ToNumber(rhs, t)); | 1057 ToNumber(rhs, t)); |
| 1088 } | 1058 } |
| 1089 | 1059 |
| 1090 | 1060 |
| 1091 // JS unary operators. | 1061 // JS unary operators. |
| 1092 | 1062 |
| 1093 | 1063 |
| 1094 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { | 1064 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { |
| 1095 Factory* const f = t->isolate()->factory(); | 1065 Factory* const f = t->isolate()->factory(); |
| 1096 if (type->Is(Type::Boolean())) { | 1066 if (type->Is(Type::Boolean())) { |
| 1097 return Type::Constant(f->boolean_string(), t->zone()); | 1067 return Type::Constant(f->boolean_string(), t->zone()); |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 return Type::Integral32(); | 1618 return Type::Integral32(); |
| 1649 } | 1619 } |
| 1650 | 1620 |
| 1651 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { | 1621 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { |
| 1652 return Type::Number(); | 1622 return Type::Number(); |
| 1653 } | 1623 } |
| 1654 | 1624 |
| 1655 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } | 1625 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } |
| 1656 | 1626 |
| 1657 Type* Typer::Visitor::TypeNumberAbs(Node* node) { | 1627 Type* Typer::Visitor::TypeNumberAbs(Node* node) { |
| 1658 return TypeUnaryOp(node, NumberAbs); | 1628 return typer_->operation_typer()->NumberAbs(Operand(node, 0)); |
| 1659 } | 1629 } |
| 1660 | 1630 |
| 1661 Type* Typer::Visitor::TypeNumberClz32(Node* node) { | 1631 Type* Typer::Visitor::TypeNumberClz32(Node* node) { |
| 1662 return typer_->cache_.kZeroToThirtyTwo; | 1632 return typer_->cache_.kZeroToThirtyTwo; |
| 1663 } | 1633 } |
| 1664 | 1634 |
| 1665 Type* Typer::Visitor::TypeNumberCeil(Node* node) { | 1635 Type* Typer::Visitor::TypeNumberCeil(Node* node) { |
| 1666 return TypeUnaryOp(node, NumberCeil); | 1636 return TypeUnaryOp(node, NumberCeil); |
| 1667 } | 1637 } |
| 1668 | 1638 |
| (...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2570 } | 2540 } |
| 2571 if (Type::IsInteger(*value)) { | 2541 if (Type::IsInteger(*value)) { |
| 2572 return Type::Range(value->Number(), value->Number(), zone()); | 2542 return Type::Range(value->Number(), value->Number(), zone()); |
| 2573 } | 2543 } |
| 2574 return Type::Constant(value, zone()); | 2544 return Type::Constant(value, zone()); |
| 2575 } | 2545 } |
| 2576 | 2546 |
| 2577 } // namespace compiler | 2547 } // namespace compiler |
| 2578 } // namespace internal | 2548 } // namespace internal |
| 2579 } // namespace v8 | 2549 } // namespace v8 |
| OLD | NEW |