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); | |
1075 rhs = ToNumber(rhs, t); | |
1076 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. | |
1078 bool maybe_nan = | |
1079 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || | |
1080 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | |
1081 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | |
1082 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | |
1083 } | 1044 } |
1084 | 1045 |
1085 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1046 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
1086 return t->operation_typer()->NumericModulus(ToNumber(lhs, t), | 1047 return t->operation_typer()->NumberModulus(ToNumber(lhs, t), |
1087 ToNumber(rhs, t)); | 1048 ToNumber(rhs, t)); |
1088 } | 1049 } |
1089 | 1050 |
1090 | 1051 |
1091 // JS unary operators. | 1052 // JS unary operators. |
1092 | 1053 |
1093 | 1054 |
1094 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { | 1055 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { |
1095 Factory* const f = t->isolate()->factory(); | 1056 Factory* const f = t->isolate()->factory(); |
1096 if (type->Is(Type::Boolean())) { | 1057 if (type->Is(Type::Boolean())) { |
1097 return Type::Constant(f->boolean_string(), t->zone()); | 1058 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(); | 1609 return Type::Integral32(); |
1649 } | 1610 } |
1650 | 1611 |
1651 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { | 1612 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { |
1652 return Type::Number(); | 1613 return Type::Number(); |
1653 } | 1614 } |
1654 | 1615 |
1655 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } | 1616 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } |
1656 | 1617 |
1657 Type* Typer::Visitor::TypeNumberAbs(Node* node) { | 1618 Type* Typer::Visitor::TypeNumberAbs(Node* node) { |
1658 return TypeUnaryOp(node, NumberAbs); | 1619 return typer_->operation_typer()->NumberAbs(Operand(node, 0)); |
1659 } | 1620 } |
1660 | 1621 |
1661 Type* Typer::Visitor::TypeNumberClz32(Node* node) { | 1622 Type* Typer::Visitor::TypeNumberClz32(Node* node) { |
1662 return typer_->cache_.kZeroToThirtyTwo; | 1623 return typer_->cache_.kZeroToThirtyTwo; |
1663 } | 1624 } |
1664 | 1625 |
1665 Type* Typer::Visitor::TypeNumberCeil(Node* node) { | 1626 Type* Typer::Visitor::TypeNumberCeil(Node* node) { |
1666 return TypeUnaryOp(node, NumberCeil); | 1627 return TypeUnaryOp(node, NumberCeil); |
1667 } | 1628 } |
1668 | 1629 |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 } | 2531 } |
2571 if (Type::IsInteger(*value)) { | 2532 if (Type::IsInteger(*value)) { |
2572 return Type::Range(value->Number(), value->Number(), zone()); | 2533 return Type::Range(value->Number(), value->Number(), zone()); |
2573 } | 2534 } |
2574 return Type::Constant(value, zone()); | 2535 return Type::Constant(value, zone()); |
2575 } | 2536 } |
2576 | 2537 |
2577 } // namespace compiler | 2538 } // namespace compiler |
2578 } // namespace internal | 2539 } // namespace internal |
2579 } // namespace v8 | 2540 } // namespace v8 |
OLD | NEW |