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 |