| 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 }; | 224 }; |
| 225 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome; | 225 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome; |
| 226 | 226 |
| 227 static ComparisonOutcome Invert(ComparisonOutcome, Typer*); | 227 static ComparisonOutcome Invert(ComparisonOutcome, Typer*); |
| 228 static Type* Invert(Type*, Typer*); | 228 static Type* Invert(Type*, Typer*); |
| 229 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); | 229 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); |
| 230 static Type* Rangify(Type*, Typer*); | 230 static Type* Rangify(Type*, Typer*); |
| 231 | 231 |
| 232 static Type* ToPrimitive(Type*, Typer*); | 232 static Type* ToPrimitive(Type*, Typer*); |
| 233 static Type* ToBoolean(Type*, Typer*); | 233 static Type* ToBoolean(Type*, Typer*); |
| 234 static Type* ToInteger(Type*, Typer*); |
| 235 static Type* ToLength(Type*, Typer*); |
| 236 static Type* ToName(Type*, Typer*); |
| 234 static Type* ToNumber(Type*, Typer*); | 237 static Type* ToNumber(Type*, Typer*); |
| 238 static Type* ToObject(Type*, Typer*); |
| 235 static Type* ToString(Type*, Typer*); | 239 static Type* ToString(Type*, Typer*); |
| 236 static Type* NumberToInt32(Type*, Typer*); | 240 static Type* NumberToInt32(Type*, Typer*); |
| 237 static Type* NumberToUint32(Type*, Typer*); | 241 static Type* NumberToUint32(Type*, Typer*); |
| 238 | 242 |
| 239 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); | 243 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); |
| 240 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); | 244 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); |
| 241 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); | 245 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); |
| 242 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); | 246 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); |
| 243 static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*); | 247 static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*); |
| 244 | 248 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 if (type->Is(Type::Boolean())) return type; | 399 if (type->Is(Type::Boolean())) return type; |
| 396 if (type->Is(t->falsish_)) return t->singleton_false_; | 400 if (type->Is(t->falsish_)) return t->singleton_false_; |
| 397 if (type->Is(t->truish_)) return t->singleton_true_; | 401 if (type->Is(t->truish_)) return t->singleton_true_; |
| 398 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { | 402 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { |
| 399 return t->singleton_true_; // Ruled out nan, -0 and +0. | 403 return t->singleton_true_; // Ruled out nan, -0 and +0. |
| 400 } | 404 } |
| 401 return Type::Boolean(); | 405 return Type::Boolean(); |
| 402 } | 406 } |
| 403 | 407 |
| 404 | 408 |
| 409 // static |
| 410 Type* Typer::Visitor::ToInteger(Type* type, Typer* t) { |
| 411 // ES6 section 7.1.4 ToInteger ( argument ) |
| 412 type = ToNumber(type, t); |
| 413 if (type->Is(t->cache_.kIntegerish)) return type; |
| 414 return t->cache_.kIntegerish; |
| 415 } |
| 416 |
| 417 |
| 418 // static |
| 419 Type* Typer::Visitor::ToLength(Type* type, Typer* t) { |
| 420 // ES6 section 7.1.15 ToLength ( argument ) |
| 421 type = ToInteger(type, t); |
| 422 double min = type->Min(); |
| 423 double max = type->Max(); |
| 424 if (min <= 0.0) min = 0.0; |
| 425 if (max > kMaxSafeInteger) max = kMaxSafeInteger; |
| 426 if (max <= min) max = min; |
| 427 return Type::Range(min, max, t->zone()); |
| 428 } |
| 429 |
| 430 |
| 431 // static |
| 432 Type* Typer::Visitor::ToName(Type* type, Typer* t) { |
| 433 // ES6 section 7.1.14 ToPropertyKey ( argument ) |
| 434 type = ToPrimitive(type, t); |
| 435 if (type->Is(Type::Name())) return type; |
| 436 if (type->Maybe(Type::Symbol())) return Type::Name(); |
| 437 return ToString(type, t); |
| 438 } |
| 439 |
| 440 |
| 441 // static |
| 405 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { | 442 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
| 406 if (type->Is(Type::Number())) return type; | 443 if (type->Is(Type::Number())) return type; |
| 407 if (type->Is(Type::NullOrUndefined())) { | 444 if (type->Is(Type::NullOrUndefined())) { |
| 408 if (type->Is(Type::Null())) return t->cache_.kSingletonZero; | 445 if (type->Is(Type::Null())) return t->cache_.kSingletonZero; |
| 409 if (type->Is(Type::Undefined())) return Type::NaN(); | 446 if (type->Is(Type::Undefined())) return Type::NaN(); |
| 410 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone()); | 447 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone()); |
| 411 } | 448 } |
| 412 if (type->Is(Type::NumberOrUndefined())) { | 449 if (type->Is(Type::NumberOrUndefined())) { |
| 413 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 450 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
| 414 Type::NaN(), t->zone()); | 451 Type::NaN(), t->zone()); |
| 415 } | 452 } |
| 416 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero; | 453 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero; |
| 417 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne; | 454 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne; |
| 418 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne; | 455 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne; |
| 419 if (type->Is(Type::BooleanOrNumber())) { | 456 if (type->Is(Type::BooleanOrNumber())) { |
| 420 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 457 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
| 421 t->cache_.kZeroOrOne, t->zone()); | 458 t->cache_.kZeroOrOne, t->zone()); |
| 422 } | 459 } |
| 423 return Type::Number(); | 460 return Type::Number(); |
| 424 } | 461 } |
| 425 | 462 |
| 426 | 463 |
| 464 // static |
| 465 Type* Typer::Visitor::ToObject(Type* type, Typer* t) { |
| 466 // ES6 section 7.1.13 ToObject ( argument ) |
| 467 if (type->Is(Type::Receiver())) return type; |
| 468 if (type->Is(Type::Primitive())) return Type::OtherObject(); |
| 469 if (!type->Maybe(Type::Undetectable())) return Type::DetectableReceiver(); |
| 470 return Type::Receiver(); |
| 471 } |
| 472 |
| 473 |
| 474 // static |
| 427 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 475 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
| 476 // ES6 section 7.1.12 ToString ( argument ) |
| 477 type = ToPrimitive(type, t); |
| 428 if (type->Is(Type::String())) return type; | 478 if (type->Is(Type::String())) return type; |
| 429 return Type::String(); | 479 return Type::String(); |
| 430 } | 480 } |
| 431 | 481 |
| 432 | 482 |
| 433 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { | 483 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { |
| 434 // TODO(neis): DCHECK(type->Is(Type::Number())); | 484 // TODO(neis): DCHECK(type->Is(Type::Number())); |
| 435 if (type->Is(Type::Signed32())) return type; | 485 if (type->Is(Type::Signed32())) return type; |
| 436 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; | 486 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; |
| 437 if (type->Is(t->signed32ish_)) { | 487 if (type->Is(t->signed32ish_)) { |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 Type* Typer::Visitor::TypeJSToNumber(Node* node) { | 1185 Type* Typer::Visitor::TypeJSToNumber(Node* node) { |
| 1136 return TypeUnaryOp(node, ToNumber); | 1186 return TypeUnaryOp(node, ToNumber); |
| 1137 } | 1187 } |
| 1138 | 1188 |
| 1139 | 1189 |
| 1140 Type* Typer::Visitor::TypeJSToString(Node* node) { | 1190 Type* Typer::Visitor::TypeJSToString(Node* node) { |
| 1141 return TypeUnaryOp(node, ToString); | 1191 return TypeUnaryOp(node, ToString); |
| 1142 } | 1192 } |
| 1143 | 1193 |
| 1144 | 1194 |
| 1145 Type* Typer::Visitor::TypeJSToName(Node* node) { return Type::Name(); } | 1195 Type* Typer::Visitor::TypeJSToName(Node* node) { |
| 1196 return TypeUnaryOp(node, ToName); |
| 1197 } |
| 1146 | 1198 |
| 1147 | 1199 |
| 1148 Type* Typer::Visitor::TypeJSToObject(Node* node) { return Type::Receiver(); } | 1200 Type* Typer::Visitor::TypeJSToObject(Node* node) { |
| 1201 return TypeUnaryOp(node, ToObject); |
| 1202 } |
| 1149 | 1203 |
| 1150 | 1204 |
| 1151 // JS object operators. | 1205 // JS object operators. |
| 1152 | 1206 |
| 1153 | 1207 |
| 1154 Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); } | 1208 Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); } |
| 1155 | 1209 |
| 1156 | 1210 |
| 1157 Type* Typer::Visitor::TypeJSCreateArguments(Node* node) { | 1211 Type* Typer::Visitor::TypeJSCreateArguments(Node* node) { |
| 1158 return Type::OtherObject(); | 1212 return Type::OtherObject(); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 case Runtime::kInlineMathSqrt: | 1515 case Runtime::kInlineMathSqrt: |
| 1462 case Runtime::kInlineMathAcos: | 1516 case Runtime::kInlineMathAcos: |
| 1463 case Runtime::kInlineMathAsin: | 1517 case Runtime::kInlineMathAsin: |
| 1464 case Runtime::kInlineMathAtan: | 1518 case Runtime::kInlineMathAtan: |
| 1465 case Runtime::kInlineMathAtan2: | 1519 case Runtime::kInlineMathAtan2: |
| 1466 return Type::Number(); | 1520 return Type::Number(); |
| 1467 case Runtime::kInlineMathClz32: | 1521 case Runtime::kInlineMathClz32: |
| 1468 return Type::Range(0, 32, zone()); | 1522 return Type::Range(0, 32, zone()); |
| 1469 case Runtime::kInlineStringGetLength: | 1523 case Runtime::kInlineStringGetLength: |
| 1470 return Type::Range(0, String::kMaxLength, zone()); | 1524 return Type::Range(0, String::kMaxLength, zone()); |
| 1525 case Runtime::kInlineToInteger: |
| 1526 return TypeUnaryOp(node, ToInteger); |
| 1527 case Runtime::kInlineToLength: |
| 1528 return TypeUnaryOp(node, ToLength); |
| 1529 case Runtime::kInlineToName: |
| 1530 return TypeUnaryOp(node, ToName); |
| 1531 case Runtime::kInlineToNumber: |
| 1532 return TypeUnaryOp(node, ToNumber); |
| 1471 case Runtime::kInlineToObject: | 1533 case Runtime::kInlineToObject: |
| 1472 return Type::Receiver(); | 1534 return TypeUnaryOp(node, ToObject); |
| 1535 case Runtime::kInlineToPrimitive: |
| 1536 case Runtime::kInlineToPrimitive_Number: |
| 1537 case Runtime::kInlineToPrimitive_String: |
| 1538 return TypeUnaryOp(node, ToPrimitive); |
| 1539 case Runtime::kInlineToString: |
| 1540 return TypeUnaryOp(node, ToString); |
| 1473 default: | 1541 default: |
| 1474 break; | 1542 break; |
| 1475 } | 1543 } |
| 1476 return Type::Any(); | 1544 return Type::Any(); |
| 1477 } | 1545 } |
| 1478 | 1546 |
| 1479 | 1547 |
| 1480 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) { | 1548 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) { |
| 1481 return Type::Receiver(); | 1549 return Type::Receiver(); |
| 1482 } | 1550 } |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2202 } | 2270 } |
| 2203 if (Type::IsInteger(*value)) { | 2271 if (Type::IsInteger(*value)) { |
| 2204 return Type::Range(value->Number(), value->Number(), zone()); | 2272 return Type::Range(value->Number(), value->Number(), zone()); |
| 2205 } | 2273 } |
| 2206 return Type::Constant(value, zone()); | 2274 return Type::Constant(value, zone()); |
| 2207 } | 2275 } |
| 2208 | 2276 |
| 2209 } // namespace compiler | 2277 } // namespace compiler |
| 2210 } // namespace internal | 2278 } // namespace internal |
| 2211 } // namespace v8 | 2279 } // namespace v8 |
| OLD | NEW |