| 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/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
| 10 #include "src/compiler/graph-reducer.h" | 10 #include "src/compiler/graph-reducer.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 Typer::Typer(Isolate* isolate, Graph* graph) | 33 Typer::Typer(Isolate* isolate, Graph* graph) |
| 34 : isolate_(isolate), | 34 : isolate_(isolate), |
| 35 graph_(graph), | 35 graph_(graph), |
| 36 decorator_(nullptr), | 36 decorator_(nullptr), |
| 37 cache_(TypeCache::Get()), | 37 cache_(TypeCache::Get()), |
| 38 operation_typer_(isolate, zone()) { | 38 operation_typer_(isolate, zone()) { |
| 39 Zone* zone = this->zone(); | 39 Zone* zone = this->zone(); |
| 40 Factory* const factory = isolate->factory(); | 40 Factory* const factory = isolate->factory(); |
| 41 | 41 |
| 42 Type* infinity = Type::Constant(factory->infinity_value(), zone); | |
| 43 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); | |
| 44 // Unfortunately, the infinities created in other places might be different | |
| 45 // ones (eg the result of NewNumber in TypeNumberConstant). | |
| 46 Type* truncating_to_zero = | |
| 47 Type::Union(Type::Union(infinity, minus_infinity, zone), | |
| 48 Type::MinusZeroOrNaN(), zone); | |
| 49 DCHECK(!truncating_to_zero->Maybe(Type::Integral32())); | |
| 50 | |
| 51 singleton_false_ = Type::Constant(factory->false_value(), zone); | 42 singleton_false_ = Type::Constant(factory->false_value(), zone); |
| 52 singleton_true_ = Type::Constant(factory->true_value(), zone); | 43 singleton_true_ = Type::Constant(factory->true_value(), zone); |
| 53 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); | 44 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); |
| 54 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); | |
| 55 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); | |
| 56 falsish_ = Type::Union( | 45 falsish_ = Type::Union( |
| 57 Type::Undetectable(), | 46 Type::Undetectable(), |
| 58 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), | 47 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), |
| 59 singleton_the_hole_, zone), | 48 singleton_the_hole_, zone), |
| 60 zone); | 49 zone); |
| 61 truish_ = Type::Union( | 50 truish_ = Type::Union( |
| 62 singleton_true_, | 51 singleton_true_, |
| 63 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); | 52 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); |
| 64 | 53 |
| 65 decorator_ = new (zone) Decorator(this); | 54 decorator_ = new (zone) Decorator(this); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) | 87 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) |
| 99 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) | 88 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) |
| 100 MACHINE_OP_LIST(DECLARE_CASE) | 89 MACHINE_OP_LIST(DECLARE_CASE) |
| 101 MACHINE_SIMD_OP_LIST(DECLARE_CASE) | 90 MACHINE_SIMD_OP_LIST(DECLARE_CASE) |
| 102 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) | 91 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) |
| 103 JS_OBJECT_OP_LIST(DECLARE_CASE) | 92 JS_OBJECT_OP_LIST(DECLARE_CASE) |
| 104 JS_CONTEXT_OP_LIST(DECLARE_CASE) | 93 JS_CONTEXT_OP_LIST(DECLARE_CASE) |
| 105 JS_OTHER_OP_LIST(DECLARE_CASE) | 94 JS_OTHER_OP_LIST(DECLARE_CASE) |
| 106 #undef DECLARE_CASE | 95 #undef DECLARE_CASE |
| 107 | 96 |
| 97 #define DECLARE_CASE(x) \ |
| 98 case IrOpcode::k##x: \ |
| 99 return UpdateType(node, TypeBinaryOp(node, x)); |
| 100 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE) |
| 101 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE) |
| 102 #undef DECLARE_CASE |
| 103 |
| 104 #define DECLARE_CASE(x) \ |
| 105 case IrOpcode::k##x: \ |
| 106 return UpdateType(node, TypeUnaryOp(node, x)); |
| 107 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE) |
| 108 #undef DECLARE_CASE |
| 109 |
| 108 #define DECLARE_CASE(x) case IrOpcode::k##x: | 110 #define DECLARE_CASE(x) case IrOpcode::k##x: |
| 109 DECLARE_CASE(Loop) | 111 DECLARE_CASE(Loop) |
| 110 DECLARE_CASE(Branch) | 112 DECLARE_CASE(Branch) |
| 111 DECLARE_CASE(IfTrue) | 113 DECLARE_CASE(IfTrue) |
| 112 DECLARE_CASE(IfFalse) | 114 DECLARE_CASE(IfFalse) |
| 113 DECLARE_CASE(IfSuccess) | 115 DECLARE_CASE(IfSuccess) |
| 114 DECLARE_CASE(Switch) | 116 DECLARE_CASE(Switch) |
| 115 DECLARE_CASE(IfValue) | 117 DECLARE_CASE(IfValue) |
| 116 DECLARE_CASE(IfDefault) | 118 DECLARE_CASE(IfDefault) |
| 117 DECLARE_CASE(Merge) | 119 DECLARE_CASE(Merge) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 148 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) | 150 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) |
| 149 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) | 151 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) |
| 150 MACHINE_OP_LIST(DECLARE_CASE) | 152 MACHINE_OP_LIST(DECLARE_CASE) |
| 151 MACHINE_SIMD_OP_LIST(DECLARE_CASE) | 153 MACHINE_SIMD_OP_LIST(DECLARE_CASE) |
| 152 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) | 154 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) |
| 153 JS_OBJECT_OP_LIST(DECLARE_CASE) | 155 JS_OBJECT_OP_LIST(DECLARE_CASE) |
| 154 JS_CONTEXT_OP_LIST(DECLARE_CASE) | 156 JS_CONTEXT_OP_LIST(DECLARE_CASE) |
| 155 JS_OTHER_OP_LIST(DECLARE_CASE) | 157 JS_OTHER_OP_LIST(DECLARE_CASE) |
| 156 #undef DECLARE_CASE | 158 #undef DECLARE_CASE |
| 157 | 159 |
| 160 #define DECLARE_CASE(x) \ |
| 161 case IrOpcode::k##x: \ |
| 162 return TypeBinaryOp(node, x); |
| 163 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE) |
| 164 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE) |
| 165 #undef DECLARE_CASE |
| 166 |
| 167 #define DECLARE_CASE(x) \ |
| 168 case IrOpcode::k##x: \ |
| 169 return TypeUnaryOp(node, x); |
| 170 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE) |
| 171 #undef DECLARE_CASE |
| 172 |
| 158 #define DECLARE_CASE(x) case IrOpcode::k##x: | 173 #define DECLARE_CASE(x) case IrOpcode::k##x: |
| 159 DECLARE_CASE(Loop) | 174 DECLARE_CASE(Loop) |
| 160 DECLARE_CASE(Branch) | 175 DECLARE_CASE(Branch) |
| 161 DECLARE_CASE(IfTrue) | 176 DECLARE_CASE(IfTrue) |
| 162 DECLARE_CASE(IfFalse) | 177 DECLARE_CASE(IfFalse) |
| 163 DECLARE_CASE(IfSuccess) | 178 DECLARE_CASE(IfSuccess) |
| 164 DECLARE_CASE(Switch) | 179 DECLARE_CASE(Switch) |
| 165 DECLARE_CASE(IfValue) | 180 DECLARE_CASE(IfValue) |
| 166 DECLARE_CASE(IfDefault) | 181 DECLARE_CASE(IfDefault) |
| 167 DECLARE_CASE(Merge) | 182 DECLARE_CASE(Merge) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); | 257 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); |
| 243 | 258 |
| 244 static Type* ToPrimitive(Type*, Typer*); | 259 static Type* ToPrimitive(Type*, Typer*); |
| 245 static Type* ToBoolean(Type*, Typer*); | 260 static Type* ToBoolean(Type*, Typer*); |
| 246 static Type* ToInteger(Type*, Typer*); | 261 static Type* ToInteger(Type*, Typer*); |
| 247 static Type* ToLength(Type*, Typer*); | 262 static Type* ToLength(Type*, Typer*); |
| 248 static Type* ToName(Type*, Typer*); | 263 static Type* ToName(Type*, Typer*); |
| 249 static Type* ToNumber(Type*, Typer*); | 264 static Type* ToNumber(Type*, Typer*); |
| 250 static Type* ToObject(Type*, Typer*); | 265 static Type* ToObject(Type*, Typer*); |
| 251 static Type* ToString(Type*, Typer*); | 266 static Type* ToString(Type*, Typer*); |
| 252 static Type* NumberCeil(Type*, Typer*); | 267 #define DECLARE_METHOD(Name) \ |
| 253 static Type* NumberFloor(Type*, Typer*); | 268 static Type* Name(Type* type, Typer* t) { \ |
| 254 static Type* NumberMax(Type*, Type*, Typer*); | 269 return t->operation_typer_.Name(type); \ |
| 255 static Type* NumberMin(Type*, Type*, Typer*); | 270 } |
| 256 static Type* NumberRound(Type*, Typer*); | 271 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD) |
| 257 static Type* NumberSign(Type*, Typer*); | 272 #undef DECLARE_METHOD |
| 258 static Type* NumberTrunc(Type*, Typer*); | 273 #define DECLARE_METHOD(Name) \ |
| 259 static Type* NumberToInt32(Type*, Typer*); | 274 static Type* Name(Type* lhs, Type* rhs, Typer* t) { \ |
| 260 static Type* NumberToUint32(Type*, Typer*); | 275 return t->operation_typer_.Name(lhs, rhs); \ |
| 276 } |
| 277 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD) |
| 278 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD) |
| 279 #undef DECLARE_METHOD |
| 261 | 280 |
| 262 static Type* ObjectIsCallable(Type*, Typer*); | 281 static Type* ObjectIsCallable(Type*, Typer*); |
| 263 static Type* ObjectIsNumber(Type*, Typer*); | 282 static Type* ObjectIsNumber(Type*, Typer*); |
| 264 static Type* ObjectIsReceiver(Type*, Typer*); | 283 static Type* ObjectIsReceiver(Type*, Typer*); |
| 265 static Type* ObjectIsSmi(Type*, Typer*); | 284 static Type* ObjectIsSmi(Type*, Typer*); |
| 266 static Type* ObjectIsString(Type*, Typer*); | 285 static Type* ObjectIsString(Type*, Typer*); |
| 267 static Type* ObjectIsUndetectable(Type*, Typer*); | 286 static Type* ObjectIsUndetectable(Type*, Typer*); |
| 268 | 287 |
| 269 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); | 288 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); |
| 270 | 289 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // ES6 section 7.1.14 ToPropertyKey ( argument ) | 463 // ES6 section 7.1.14 ToPropertyKey ( argument ) |
| 445 type = ToPrimitive(type, t); | 464 type = ToPrimitive(type, t); |
| 446 if (type->Is(Type::Name())) return type; | 465 if (type->Is(Type::Name())) return type; |
| 447 if (type->Maybe(Type::Symbol())) return Type::Name(); | 466 if (type->Maybe(Type::Symbol())) return Type::Name(); |
| 448 return ToString(type, t); | 467 return ToString(type, t); |
| 449 } | 468 } |
| 450 | 469 |
| 451 | 470 |
| 452 // static | 471 // static |
| 453 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { | 472 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
| 454 if (type->Is(Type::Number())) return type; | 473 return t->operation_typer_.ToNumber(type); |
| 455 if (type->Is(Type::NullOrUndefined())) { | |
| 456 if (type->Is(Type::Null())) return t->cache_.kSingletonZero; | |
| 457 if (type->Is(Type::Undefined())) return Type::NaN(); | |
| 458 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone()); | |
| 459 } | |
| 460 if (type->Is(Type::NumberOrUndefined())) { | |
| 461 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | |
| 462 Type::NaN(), t->zone()); | |
| 463 } | |
| 464 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero; | |
| 465 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne; | |
| 466 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne; | |
| 467 if (type->Is(Type::BooleanOrNumber())) { | |
| 468 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | |
| 469 t->cache_.kZeroOrOne, t->zone()); | |
| 470 } | |
| 471 return Type::Number(); | |
| 472 } | 474 } |
| 473 | 475 |
| 474 | 476 |
| 475 // static | 477 // static |
| 476 Type* Typer::Visitor::ToObject(Type* type, Typer* t) { | 478 Type* Typer::Visitor::ToObject(Type* type, Typer* t) { |
| 477 // ES6 section 7.1.13 ToObject ( argument ) | 479 // ES6 section 7.1.13 ToObject ( argument ) |
| 478 if (type->Is(Type::Receiver())) return type; | 480 if (type->Is(Type::Receiver())) return type; |
| 479 if (type->Is(Type::Primitive())) return Type::OtherObject(); | 481 if (type->Is(Type::Primitive())) return Type::OtherObject(); |
| 480 if (!type->Maybe(Type::OtherUndetectable())) { | 482 if (!type->Maybe(Type::OtherUndetectable())) { |
| 481 return Type::DetectableReceiver(); | 483 return Type::DetectableReceiver(); |
| 482 } | 484 } |
| 483 return Type::Receiver(); | 485 return Type::Receiver(); |
| 484 } | 486 } |
| 485 | 487 |
| 486 | 488 |
| 487 // static | 489 // static |
| 488 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 490 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
| 489 // ES6 section 7.1.12 ToString ( argument ) | 491 // ES6 section 7.1.12 ToString ( argument ) |
| 490 type = ToPrimitive(type, t); | 492 type = ToPrimitive(type, t); |
| 491 if (type->Is(Type::String())) return type; | 493 if (type->Is(Type::String())) return type; |
| 492 return Type::String(); | 494 return Type::String(); |
| 493 } | 495 } |
| 494 | 496 |
| 495 // static | |
| 496 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { | |
| 497 DCHECK(type->Is(Type::Number())); | |
| 498 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | |
| 499 // TODO(bmeurer): We could infer a more precise type here. | |
| 500 return t->cache_.kIntegerOrMinusZeroOrNaN; | |
| 501 } | |
| 502 | |
| 503 // static | |
| 504 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { | |
| 505 DCHECK(type->Is(Type::Number())); | |
| 506 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | |
| 507 // TODO(bmeurer): We could infer a more precise type here. | |
| 508 return t->cache_.kIntegerOrMinusZeroOrNaN; | |
| 509 } | |
| 510 | |
| 511 // static | |
| 512 Type* Typer::Visitor::NumberMax(Type* lhs, Type* rhs, Typer* t) { | |
| 513 DCHECK(lhs->Is(Type::Number())); | |
| 514 DCHECK(rhs->Is(Type::Number())); | |
| 515 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { | |
| 516 return Type::NaN(); | |
| 517 } | |
| 518 Type* type = Type::None(); | |
| 519 // TODO(turbofan): Improve minus zero handling here. | |
| 520 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { | |
| 521 type = Type::Union(type, Type::NaN(), t->zone()); | |
| 522 } | |
| 523 lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone()); | |
| 524 rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone()); | |
| 525 if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) { | |
| 526 double max = std::max(lhs->Max(), rhs->Max()); | |
| 527 double min = std::max(lhs->Min(), rhs->Min()); | |
| 528 type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone()); | |
| 529 } else { | |
| 530 type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone()); | |
| 531 } | |
| 532 return type; | |
| 533 } | |
| 534 | |
| 535 // static | |
| 536 Type* Typer::Visitor::NumberMin(Type* lhs, Type* rhs, Typer* t) { | |
| 537 DCHECK(lhs->Is(Type::Number())); | |
| 538 DCHECK(rhs->Is(Type::Number())); | |
| 539 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { | |
| 540 return Type::NaN(); | |
| 541 } | |
| 542 Type* type = Type::None(); | |
| 543 // TODO(turbofan): Improve minus zero handling here. | |
| 544 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { | |
| 545 type = Type::Union(type, Type::NaN(), t->zone()); | |
| 546 } | |
| 547 lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone()); | |
| 548 rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone()); | |
| 549 if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) { | |
| 550 double max = std::min(lhs->Max(), rhs->Max()); | |
| 551 double min = std::min(lhs->Min(), rhs->Min()); | |
| 552 type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone()); | |
| 553 } else { | |
| 554 type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone()); | |
| 555 } | |
| 556 return type; | |
| 557 } | |
| 558 | |
| 559 // static | |
| 560 Type* Typer::Visitor::NumberRound(Type* type, Typer* t) { | |
| 561 DCHECK(type->Is(Type::Number())); | |
| 562 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | |
| 563 // TODO(bmeurer): We could infer a more precise type here. | |
| 564 return t->cache_.kIntegerOrMinusZeroOrNaN; | |
| 565 } | |
| 566 | |
| 567 // static | |
| 568 Type* Typer::Visitor::NumberSign(Type* type, Typer* t) { | |
| 569 DCHECK(type->Is(Type::Number())); | |
| 570 if (type->Is(t->cache_.kZeroish)) return type; | |
| 571 bool maybe_minuszero = type->Maybe(Type::MinusZero()); | |
| 572 bool maybe_nan = type->Maybe(Type::NaN()); | |
| 573 type = Type::Intersect(type, Type::PlainNumber(), t->zone()); | |
| 574 if (type->Max() < 0.0) { | |
| 575 type = t->cache_.kSingletonMinusOne; | |
| 576 } else if (type->Max() <= 0.0) { | |
| 577 type = t->cache_.kMinusOneOrZero; | |
| 578 } else if (type->Min() > 0.0) { | |
| 579 type = t->cache_.kSingletonOne; | |
| 580 } else if (type->Min() >= 0.0) { | |
| 581 type = t->cache_.kZeroOrOne; | |
| 582 } else { | |
| 583 type = Type::Range(-1.0, 1.0, t->zone()); | |
| 584 } | |
| 585 if (maybe_minuszero) { | |
| 586 type = Type::Union(type, Type::MinusZero(), t->zone()); | |
| 587 } | |
| 588 if (maybe_nan) { | |
| 589 type = Type::Union(type, Type::NaN(), t->zone()); | |
| 590 } | |
| 591 return type; | |
| 592 } | |
| 593 | |
| 594 // static | |
| 595 Type* Typer::Visitor::NumberTrunc(Type* type, Typer* t) { | |
| 596 DCHECK(type->Is(Type::Number())); | |
| 597 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; | |
| 598 // TODO(bmeurer): We could infer a more precise type here. | |
| 599 return t->cache_.kIntegerOrMinusZeroOrNaN; | |
| 600 } | |
| 601 | |
| 602 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { | |
| 603 if (type->Is(Type::Signed32())) return type; | |
| 604 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; | |
| 605 if (type->Is(t->signed32ish_)) { | |
| 606 return Type::Intersect( | |
| 607 Type::Union(type, t->cache_.kSingletonZero, t->zone()), | |
| 608 Type::Signed32(), t->zone()); | |
| 609 } | |
| 610 return Type::Signed32(); | |
| 611 } | |
| 612 | |
| 613 | |
| 614 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { | |
| 615 if (type->Is(Type::Unsigned32())) return type; | |
| 616 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; | |
| 617 if (type->Is(t->unsigned32ish_)) { | |
| 618 return Type::Intersect( | |
| 619 Type::Union(type, t->cache_.kSingletonZero, t->zone()), | |
| 620 Type::Unsigned32(), t->zone()); | |
| 621 } | |
| 622 return Type::Unsigned32(); | |
| 623 } | |
| 624 | |
| 625 // Type checks. | 497 // Type checks. |
| 626 | 498 |
| 627 Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) { | 499 Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) { |
| 628 if (type->Is(Type::Function())) return t->singleton_true_; | 500 if (type->Is(Type::Function())) return t->singleton_true_; |
| 629 if (type->Is(Type::Primitive())) return t->singleton_false_; | 501 if (type->Is(Type::Primitive())) return t->singleton_false_; |
| 630 return Type::Boolean(); | 502 return Type::Boolean(); |
| 631 } | 503 } |
| 632 | 504 |
| 633 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) { | 505 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) { |
| 634 if (type->Is(Type::Number())) return t->singleton_true_; | 506 if (type->Is(Type::Number())) return t->singleton_true_; |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 | 889 |
| 1018 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( | 890 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( |
| 1019 Type* lhs, Type* rhs, Typer* t) { | 891 Type* lhs, Type* rhs, Typer* t) { |
| 1020 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); | 892 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); |
| 1021 } | 893 } |
| 1022 | 894 |
| 1023 // JS bitwise operators. | 895 // JS bitwise operators. |
| 1024 | 896 |
| 1025 | 897 |
| 1026 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 898 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1027 lhs = NumberToInt32(ToNumber(lhs, t), t); | 899 return NumberBitwiseOr(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1028 rhs = NumberToInt32(ToNumber(rhs, t), t); | |
| 1029 double lmin = lhs->Min(); | |
| 1030 double rmin = rhs->Min(); | |
| 1031 double lmax = lhs->Max(); | |
| 1032 double rmax = rhs->Max(); | |
| 1033 // Or-ing any two values results in a value no smaller than their minimum. | |
| 1034 // Even no smaller than their maximum if both values are non-negative. | |
| 1035 double min = | |
| 1036 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); | |
| 1037 double max = Type::Signed32()->Max(); | |
| 1038 | |
| 1039 // Or-ing with 0 is essentially a conversion to int32. | |
| 1040 if (rmin == 0 && rmax == 0) { | |
| 1041 min = lmin; | |
| 1042 max = lmax; | |
| 1043 } | |
| 1044 if (lmin == 0 && lmax == 0) { | |
| 1045 min = rmin; | |
| 1046 max = rmax; | |
| 1047 } | |
| 1048 | |
| 1049 if (lmax < 0 || rmax < 0) { | |
| 1050 // Or-ing two values of which at least one is negative results in a negative | |
| 1051 // value. | |
| 1052 max = std::min(max, -1.0); | |
| 1053 } | |
| 1054 return Type::Range(min, max, t->zone()); | |
| 1055 } | 900 } |
| 1056 | 901 |
| 1057 | 902 |
| 1058 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { | 903 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1059 lhs = NumberToInt32(ToNumber(lhs, t), t); | 904 return NumberBitwiseAnd(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1060 rhs = NumberToInt32(ToNumber(rhs, t), t); | |
| 1061 double lmin = lhs->Min(); | |
| 1062 double rmin = rhs->Min(); | |
| 1063 double lmax = lhs->Max(); | |
| 1064 double rmax = rhs->Max(); | |
| 1065 double min = Type::Signed32()->Min(); | |
| 1066 // And-ing any two values results in a value no larger than their maximum. | |
| 1067 // Even no larger than their minimum if both values are non-negative. | |
| 1068 double max = | |
| 1069 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); | |
| 1070 // And-ing with a non-negative value x causes the result to be between | |
| 1071 // zero and x. | |
| 1072 if (lmin >= 0) { | |
| 1073 min = 0; | |
| 1074 max = std::min(max, lmax); | |
| 1075 } | |
| 1076 if (rmin >= 0) { | |
| 1077 min = 0; | |
| 1078 max = std::min(max, rmax); | |
| 1079 } | |
| 1080 return Type::Range(min, max, t->zone()); | |
| 1081 } | 905 } |
| 1082 | 906 |
| 1083 | 907 |
| 1084 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { | 908 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1085 lhs = NumberToInt32(ToNumber(lhs, t), t); | 909 return NumberBitwiseXor(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1086 rhs = NumberToInt32(ToNumber(rhs, t), t); | |
| 1087 double lmin = lhs->Min(); | |
| 1088 double rmin = rhs->Min(); | |
| 1089 double lmax = lhs->Max(); | |
| 1090 double rmax = rhs->Max(); | |
| 1091 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { | |
| 1092 // Xor-ing negative or non-negative values results in a non-negative value. | |
| 1093 return Type::Unsigned31(); | |
| 1094 } | |
| 1095 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { | |
| 1096 // Xor-ing a negative and a non-negative value results in a negative value. | |
| 1097 // TODO(jarin) Use a range here. | |
| 1098 return Type::Negative32(); | |
| 1099 } | |
| 1100 return Type::Signed32(); | |
| 1101 } | 910 } |
| 1102 | 911 |
| 1103 | 912 |
| 1104 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { | 913 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1105 return Type::Signed32(); | 914 return NumberShiftLeft(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1106 } | 915 } |
| 1107 | 916 |
| 1108 | 917 |
| 1109 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { | 918 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1110 lhs = NumberToInt32(ToNumber(lhs, t), t); | 919 return NumberShiftRight(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1111 rhs = NumberToUint32(ToNumber(rhs, t), t); | |
| 1112 double min = kMinInt; | |
| 1113 double max = kMaxInt; | |
| 1114 if (lhs->Min() >= 0) { | |
| 1115 // Right-shifting a non-negative value cannot make it negative, nor larger. | |
| 1116 min = std::max(min, 0.0); | |
| 1117 max = std::min(max, lhs->Max()); | |
| 1118 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 1119 max = static_cast<int>(max) >> static_cast<int>(rhs->Min()); | |
| 1120 } | |
| 1121 } | |
| 1122 if (lhs->Max() < 0) { | |
| 1123 // Right-shifting a negative value cannot make it non-negative, nor smaller. | |
| 1124 min = std::max(min, lhs->Min()); | |
| 1125 max = std::min(max, -1.0); | |
| 1126 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 1127 min = static_cast<int>(min) >> static_cast<int>(rhs->Min()); | |
| 1128 } | |
| 1129 } | |
| 1130 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 1131 // Right-shifting by a positive value yields a small integer value. | |
| 1132 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); | |
| 1133 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); | |
| 1134 min = std::max(min, shift_min); | |
| 1135 max = std::min(max, shift_max); | |
| 1136 } | |
| 1137 // TODO(jarin) Ideally, the following micro-optimization should be performed | |
| 1138 // by the type constructor. | |
| 1139 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { | |
| 1140 return Type::Range(min, max, t->zone()); | |
| 1141 } | |
| 1142 return Type::Signed32(); | |
| 1143 } | 920 } |
| 1144 | 921 |
| 1145 | 922 |
| 1146 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { | 923 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1147 lhs = NumberToUint32(ToNumber(lhs, t), t); | 924 return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1148 // Logical right-shifting any value cannot make it larger. | |
| 1149 return Type::Range(0.0, lhs->Max(), t->zone()); | |
| 1150 } | 925 } |
| 1151 | 926 |
| 1152 | 927 |
| 1153 // JS arithmetic operators. | 928 // JS arithmetic operators. |
| 1154 | 929 |
| 1155 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { | 930 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1156 lhs = ToPrimitive(lhs, t); | 931 lhs = ToPrimitive(lhs, t); |
| 1157 rhs = ToPrimitive(rhs, t); | 932 rhs = ToPrimitive(rhs, t); |
| 1158 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { | 933 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { |
| 1159 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { | 934 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { |
| 1160 return Type::String(); | 935 return Type::String(); |
| 1161 } else { | 936 } else { |
| 1162 return Type::NumberOrString(); | 937 return Type::NumberOrString(); |
| 1163 } | 938 } |
| 1164 } | 939 } |
| 1165 // The addition must be numeric. | 940 // The addition must be numeric. |
| 1166 return t->operation_typer()->NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t)); | 941 return NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1167 } | 942 } |
| 1168 | 943 |
| 1169 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { | 944 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1170 return t->operation_typer()->NumberSubtract(ToNumber(lhs, t), | 945 return NumberSubtract(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1171 ToNumber(rhs, t)); | |
| 1172 } | 946 } |
| 1173 | 947 |
| 1174 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 948 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1175 return t->operation_typer()->NumberMultiply(ToNumber(lhs, t), | 949 return NumberMultiply(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1176 ToNumber(rhs, t)); | |
| 1177 } | 950 } |
| 1178 | 951 |
| 1179 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 952 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1180 return t->operation_typer()->NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t)); | 953 return NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1181 } | 954 } |
| 1182 | 955 |
| 1183 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 956 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1184 return t->operation_typer()->NumberModulus(ToNumber(lhs, t), | 957 return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t); |
| 1185 ToNumber(rhs, t)); | |
| 1186 } | 958 } |
| 1187 | 959 |
| 1188 | 960 |
| 1189 // JS unary operators. | 961 // JS unary operators. |
| 1190 | 962 |
| 1191 | 963 |
| 1192 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { | 964 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { |
| 1193 Factory* const f = t->isolate()->factory(); | 965 Factory* const f = t->isolate()->factory(); |
| 1194 if (type->Is(Type::Boolean())) { | 966 if (type->Is(Type::Boolean())) { |
| 1195 return Type::Constant(f->boolean_string(), t->zone()); | 967 return Type::Constant(f->boolean_string(), t->zone()); |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1662 } | 1434 } |
| 1663 | 1435 |
| 1664 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) { | 1436 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) { |
| 1665 return Type::Boolean(); | 1437 return Type::Boolean(); |
| 1666 } | 1438 } |
| 1667 | 1439 |
| 1668 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) { | 1440 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) { |
| 1669 return Type::Boolean(); | 1441 return Type::Boolean(); |
| 1670 } | 1442 } |
| 1671 | 1443 |
| 1672 Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); } | |
| 1673 | |
| 1674 Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); } | |
| 1675 | |
| 1676 Type* Typer::Visitor::TypeSpeculativeNumberAdd(Node* node) { | |
| 1677 return Type::Number(); | |
| 1678 } | |
| 1679 | |
| 1680 Type* Typer::Visitor::TypeSpeculativeNumberSubtract(Node* node) { | |
| 1681 return Type::Number(); | |
| 1682 } | |
| 1683 | |
| 1684 Type* Typer::Visitor::TypeSpeculativeNumberMultiply(Node* node) { | |
| 1685 return Type::Number(); | |
| 1686 } | |
| 1687 | |
| 1688 Type* Typer::Visitor::TypeSpeculativeNumberDivide(Node* node) { | |
| 1689 return Type::Number(); | |
| 1690 } | |
| 1691 | |
| 1692 Type* Typer::Visitor::TypeSpeculativeNumberModulus(Node* node) { | |
| 1693 return Type::Number(); | |
| 1694 } | |
| 1695 | |
| 1696 Type* Typer::Visitor::TypeSpeculativeNumberShiftLeft(Node* node) { | |
| 1697 return Type::Signed32(); | |
| 1698 } | |
| 1699 | |
| 1700 Type* Typer::Visitor::TypeSpeculativeNumberShiftRight(Node* node) { | |
| 1701 return Type::Signed32(); | |
| 1702 } | |
| 1703 | |
| 1704 Type* Typer::Visitor::TypeSpeculativeNumberShiftRightLogical(Node* node) { | |
| 1705 return Type::Unsigned32(); | |
| 1706 } | |
| 1707 | |
| 1708 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseOr(Node* node) { | |
| 1709 return Type::Signed32(); | |
| 1710 } | |
| 1711 | |
| 1712 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseXor(Node* node) { | |
| 1713 return Type::Signed32(); | |
| 1714 } | |
| 1715 | |
| 1716 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseAnd(Node* node) { | |
| 1717 return Type::Signed32(); | |
| 1718 } | |
| 1719 | |
| 1720 Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); } | |
| 1721 | |
| 1722 Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); } | |
| 1723 | |
| 1724 Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); } | |
| 1725 | |
| 1726 Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) { | |
| 1727 return Type::Signed32(); | |
| 1728 } | |
| 1729 | |
| 1730 | |
| 1731 Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) { | |
| 1732 return Type::Signed32(); | |
| 1733 } | |
| 1734 | |
| 1735 | |
| 1736 Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) { | |
| 1737 return Type::Signed32(); | |
| 1738 } | |
| 1739 | |
| 1740 | |
| 1741 Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) { | |
| 1742 return Type::Signed32(); | |
| 1743 } | |
| 1744 | |
| 1745 | |
| 1746 Type* Typer::Visitor::TypeNumberShiftRight(Node* node) { | |
| 1747 return Type::Signed32(); | |
| 1748 } | |
| 1749 | |
| 1750 | |
| 1751 Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) { | |
| 1752 return Type::Unsigned32(); | |
| 1753 } | |
| 1754 | |
| 1755 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { | 1444 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { |
| 1756 return TypeUnaryOp(node, ToNumber); | 1445 return TypeUnaryOp(node, ToNumber); |
| 1757 } | 1446 } |
| 1758 | 1447 |
| 1759 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { | 1448 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { |
| 1760 return Type::Integral32(); | 1449 return Type::Integral32(); |
| 1761 } | 1450 } |
| 1762 | 1451 |
| 1763 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { | 1452 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { |
| 1764 return Type::Number(); | 1453 return Type::Number(); |
| 1765 } | 1454 } |
| 1766 | 1455 |
| 1767 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } | |
| 1768 | |
| 1769 Type* Typer::Visitor::TypeNumberAbs(Node* node) { | |
| 1770 return typer_->operation_typer()->NumberAbs(Operand(node, 0)); | |
| 1771 } | |
| 1772 | |
| 1773 Type* Typer::Visitor::TypeNumberClz32(Node* node) { | |
| 1774 return typer_->cache_.kZeroToThirtyTwo; | |
| 1775 } | |
| 1776 | |
| 1777 Type* Typer::Visitor::TypeNumberCeil(Node* node) { | |
| 1778 return TypeUnaryOp(node, NumberCeil); | |
| 1779 } | |
| 1780 | |
| 1781 Type* Typer::Visitor::TypeNumberFloor(Node* node) { | |
| 1782 return TypeUnaryOp(node, NumberFloor); | |
| 1783 } | |
| 1784 | |
| 1785 Type* Typer::Visitor::TypeNumberFround(Node* node) { return Type::Number(); } | |
| 1786 | |
| 1787 Type* Typer::Visitor::TypeNumberSign(Node* node) { | |
| 1788 return TypeUnaryOp(node, NumberSign); | |
| 1789 } | |
| 1790 | |
| 1791 Type* Typer::Visitor::TypeNumberAcos(Node* node) { return Type::Number(); } | |
| 1792 | |
| 1793 Type* Typer::Visitor::TypeNumberAcosh(Node* node) { return Type::Number(); } | |
| 1794 | |
| 1795 Type* Typer::Visitor::TypeNumberAsin(Node* node) { return Type::Number(); } | |
| 1796 | |
| 1797 Type* Typer::Visitor::TypeNumberAsinh(Node* node) { return Type::Number(); } | |
| 1798 | |
| 1799 Type* Typer::Visitor::TypeNumberAtan(Node* node) { return Type::Number(); } | |
| 1800 | |
| 1801 Type* Typer::Visitor::TypeNumberAtanh(Node* node) { return Type::Number(); } | |
| 1802 | |
| 1803 Type* Typer::Visitor::TypeNumberAtan2(Node* node) { return Type::Number(); } | |
| 1804 | |
| 1805 Type* Typer::Visitor::TypeNumberCos(Node* node) { return Type::Number(); } | |
| 1806 | |
| 1807 Type* Typer::Visitor::TypeNumberCosh(Node* node) { return Type::Number(); } | |
| 1808 | |
| 1809 Type* Typer::Visitor::TypeNumberExp(Node* node) { | |
| 1810 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); | |
| 1811 } | |
| 1812 | |
| 1813 // TODO(mvstanton): Is this type sufficient, or should it look like Exp()? | |
| 1814 Type* Typer::Visitor::TypeNumberExpm1(Node* node) { return Type::Number(); } | |
| 1815 | |
| 1816 Type* Typer::Visitor::TypeNumberLog(Node* node) { return Type::Number(); } | |
| 1817 | |
| 1818 Type* Typer::Visitor::TypeNumberLog1p(Node* node) { return Type::Number(); } | |
| 1819 | |
| 1820 Type* Typer::Visitor::TypeNumberLog2(Node* node) { return Type::Number(); } | |
| 1821 | |
| 1822 Type* Typer::Visitor::TypeNumberLog10(Node* node) { return Type::Number(); } | |
| 1823 | |
| 1824 Type* Typer::Visitor::TypeNumberCbrt(Node* node) { return Type::Number(); } | |
| 1825 | |
| 1826 Type* Typer::Visitor::TypeNumberMax(Node* node) { | |
| 1827 return TypeBinaryOp(node, NumberMax); | |
| 1828 } | |
| 1829 | |
| 1830 Type* Typer::Visitor::TypeNumberMin(Node* node) { | |
| 1831 return TypeBinaryOp(node, NumberMin); | |
| 1832 } | |
| 1833 | |
| 1834 Type* Typer::Visitor::TypeNumberPow(Node* node) { return Type::Number(); } | |
| 1835 | |
| 1836 Type* Typer::Visitor::TypeNumberRound(Node* node) { | |
| 1837 return TypeUnaryOp(node, NumberRound); | |
| 1838 } | |
| 1839 | |
| 1840 Type* Typer::Visitor::TypeNumberSin(Node* node) { return Type::Number(); } | |
| 1841 | |
| 1842 Type* Typer::Visitor::TypeNumberSinh(Node* node) { return Type::Number(); } | |
| 1843 | |
| 1844 Type* Typer::Visitor::TypeNumberSqrt(Node* node) { return Type::Number(); } | |
| 1845 | |
| 1846 Type* Typer::Visitor::TypeNumberTan(Node* node) { return Type::Number(); } | |
| 1847 | |
| 1848 Type* Typer::Visitor::TypeNumberTanh(Node* node) { return Type::Number(); } | |
| 1849 | |
| 1850 Type* Typer::Visitor::TypeNumberTrunc(Node* node) { | |
| 1851 return TypeUnaryOp(node, NumberTrunc); | |
| 1852 } | |
| 1853 | |
| 1854 Type* Typer::Visitor::TypeNumberToInt32(Node* node) { | |
| 1855 return TypeUnaryOp(node, NumberToInt32); | |
| 1856 } | |
| 1857 | |
| 1858 | |
| 1859 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { | |
| 1860 return TypeUnaryOp(node, NumberToUint32); | |
| 1861 } | |
| 1862 | |
| 1863 | |
| 1864 // static | 1456 // static |
| 1865 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 1457 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1866 if (lhs->IsConstant() && rhs->Is(lhs)) { | 1458 if (lhs->IsConstant() && rhs->Is(lhs)) { |
| 1867 return t->singleton_true_; | 1459 return t->singleton_true_; |
| 1868 } | 1460 } |
| 1869 return Type::Boolean(); | 1461 return Type::Boolean(); |
| 1870 } | 1462 } |
| 1871 | 1463 |
| 1872 | 1464 |
| 1873 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { | 1465 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2264 | 1856 |
| 2265 Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) { | 1857 Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) { |
| 2266 return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone()); | 1858 return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone()); |
| 2267 } | 1859 } |
| 2268 | 1860 |
| 2269 | 1861 |
| 2270 Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) { | 1862 Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) { |
| 2271 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); | 1863 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); |
| 2272 } | 1864 } |
| 2273 | 1865 |
| 2274 Type* Typer::Visitor::TypeNumberSilenceNaN(Node* node) { | |
| 2275 return Type::Number(); | |
| 2276 } | |
| 2277 | |
| 2278 Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) { | 1866 Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) { |
| 2279 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), | 1867 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), |
| 2280 zone()); | 1868 zone()); |
| 2281 } | 1869 } |
| 2282 | 1870 |
| 2283 Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) { | 1871 Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) { |
| 2284 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), | 1872 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), |
| 2285 zone()); | 1873 zone()); |
| 2286 } | 1874 } |
| 2287 | 1875 |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 } | 2292 } |
| 2705 if (Type::IsInteger(*value)) { | 2293 if (Type::IsInteger(*value)) { |
| 2706 return Type::Range(value->Number(), value->Number(), zone()); | 2294 return Type::Range(value->Number(), value->Number(), zone()); |
| 2707 } | 2295 } |
| 2708 return Type::Constant(value, zone()); | 2296 return Type::Constant(value, zone()); |
| 2709 } | 2297 } |
| 2710 | 2298 |
| 2711 } // namespace compiler | 2299 } // namespace compiler |
| 2712 } // namespace internal | 2300 } // namespace internal |
| 2713 } // namespace v8 | 2301 } // namespace v8 |
| OLD | NEW |