| 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/base/flags.h" | 5 #include "src/base/flags.h" |
| 6 #include "src/bootstrapper.h" | 6 #include "src/bootstrapper.h" |
| 7 #include "src/compiler/graph-reducer.h" | 7 #include "src/compiler/graph-reducer.h" |
| 8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
| 9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| 11 #include "src/compiler/simplified-operator.h" | 11 #include "src/compiler/simplified-operator.h" |
| 12 #include "src/compiler/typer.h" | 12 #include "src/compiler/typer.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace compiler { | 16 namespace compiler { |
| 17 | 17 |
| 18 #define NATIVE_TYPES(V) \ | 18 #define NATIVE_TYPES(V) \ |
| 19 V(Int8) \ | 19 V(Int8) \ |
| 20 V(Uint8) \ | 20 V(Uint8) \ |
| 21 V(Int16) \ | 21 V(Int16) \ |
| 22 V(Uint16) \ | 22 V(Uint16) \ |
| 23 V(Int32) \ | 23 V(Int32) \ |
| 24 V(Uint32) \ | 24 V(Uint32) \ |
| 25 V(Float32) \ | 25 V(Float32) \ |
| 26 V(Float64) | 26 V(Float64) |
| 27 | 27 |
| 28 enum LazyCachedType { | 28 enum LazyCachedType { |
| 29 kInteger, |
| 30 kWeakint, |
| 31 kWeakintFunc1, |
| 32 kRandomFunc0, |
| 29 kAnyFunc0, | 33 kAnyFunc0, |
| 30 kAnyFunc1, | 34 kAnyFunc1, |
| 31 kAnyFunc2, | 35 kAnyFunc2, |
| 32 kAnyFunc3, | 36 kAnyFunc3, |
| 33 kNumberFunc0, | 37 kNumberFunc0, |
| 34 kNumberFunc1, | 38 kNumberFunc1, |
| 35 kNumberFunc2, | 39 kNumberFunc2, |
| 36 kImulFunc, | 40 kImulFunc, |
| 37 kClz32Func, | 41 kClz32Func, |
| 38 kArrayBufferFunc, | 42 kArrayBufferFunc, |
| 39 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 43 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 40 k##Type, k##Type##Array, k##Type##ArrayFunc, | 44 k##Type, k##Type##Array, k##Type##ArrayFunc, |
| 41 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 45 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 42 #undef TYPED_ARRAY_CASE | 46 #undef TYPED_ARRAY_CASE |
| 43 kNumLazyCachedTypes | 47 kNumLazyCachedTypes |
| 44 }; | 48 }; |
| 45 | 49 |
| 46 | 50 |
| 47 // Constructs and caches types lazily. | 51 // Constructs and caches types lazily. |
| 48 // TODO(turbofan): these types could be globally cached or cached per isolate. | 52 // TODO(turbofan): these types could be globally cached or cached per isolate. |
| 49 class LazyTypeCache final : public ZoneObject { | 53 class LazyTypeCache final : public ZoneObject { |
| 50 public: | 54 public: |
| 51 explicit LazyTypeCache(Isolate* isolate, Zone* zone) | 55 explicit LazyTypeCache(Isolate* isolate, Zone* zone) |
| 52 : isolate_(isolate), zone_(zone) { | 56 : isolate_(isolate), zone_(zone) { |
| 53 memset(cache_, 0, sizeof(cache_)); | 57 memset(cache_, 0, sizeof(cache_)); |
| 54 } | 58 } |
| 55 | 59 |
| 56 inline Type* Get(LazyCachedType type) { | 60 V8_INLINE Type* Get(LazyCachedType type) { |
| 57 int index = static_cast<int>(type); | 61 int const index = static_cast<int>(type); |
| 58 DCHECK(index < kNumLazyCachedTypes); | 62 DCHECK_LT(index, kNumLazyCachedTypes); |
| 59 if (cache_[index] == NULL) cache_[index] = Create(type); | 63 if (cache_[index] == NULL) cache_[index] = Create(type); |
| 60 return cache_[index]; | 64 return cache_[index]; |
| 61 } | 65 } |
| 62 | 66 |
| 63 private: | 67 private: |
| 64 Type* Create(LazyCachedType type) { | 68 Type* Create(LazyCachedType type) { |
| 65 switch (type) { | 69 switch (type) { |
| 66 case kInt8: | 70 case kInt8: |
| 67 return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8()); | 71 return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8()); |
| 68 case kUint8: | 72 case kUint8: |
| 69 return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8()); | 73 return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8()); |
| 70 case kInt16: | 74 case kInt16: |
| 71 return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16()); | 75 return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16()); |
| 72 case kUint16: | 76 case kUint16: |
| 73 return CreateNative(CreateRange<uint16_t>(), | 77 return CreateNative(CreateRange<uint16_t>(), |
| 74 Type::UntaggedUnsigned16()); | 78 Type::UntaggedUnsigned16()); |
| 75 case kInt32: | 79 case kInt32: |
| 76 return CreateNative(Type::Signed32(), Type::UntaggedSigned32()); | 80 return CreateNative(Type::Signed32(), Type::UntaggedSigned32()); |
| 77 case kUint32: | 81 case kUint32: |
| 78 return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32()); | 82 return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32()); |
| 79 case kFloat32: | 83 case kFloat32: |
| 80 return CreateNative(Type::Number(), Type::UntaggedFloat32()); | 84 return CreateNative(Type::Number(), Type::UntaggedFloat32()); |
| 81 case kFloat64: | 85 case kFloat64: |
| 82 return CreateNative(Type::Number(), Type::UntaggedFloat64()); | 86 return CreateNative(Type::Number(), Type::UntaggedFloat64()); |
| 83 case kUint8Clamped: | 87 case kUint8Clamped: |
| 84 return Get(kUint8); | 88 return Get(kUint8); |
| 89 case kInteger: |
| 90 return CreateRange(-V8_INFINITY, V8_INFINITY); |
| 91 case kWeakint: |
| 92 return Type::Union(Get(kInteger), Type::MinusZeroOrNaN(), zone()); |
| 93 case kWeakintFunc1: |
| 94 return Type::Function(Get(kWeakint), Type::Number(), zone()); |
| 95 case kRandomFunc0: |
| 96 return Type::Function(Type::OrderedNumber(), zone()); |
| 85 case kAnyFunc0: | 97 case kAnyFunc0: |
| 86 return Type::Function(Type::Any(), zone()); | 98 return Type::Function(Type::Any(), zone()); |
| 87 case kAnyFunc1: | 99 case kAnyFunc1: |
| 88 return Type::Function(Type::Any(), Type::Any(), zone()); | 100 return Type::Function(Type::Any(), Type::Any(), zone()); |
| 89 case kAnyFunc2: | 101 case kAnyFunc2: |
| 90 return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone()); | 102 return Type::Function(Type::Any(), Type::Any(), Type::Any(), zone()); |
| 91 case kAnyFunc3: | 103 case kAnyFunc3: |
| 92 return Type::Function(Type::Any(), Type::Any(), Type::Any(), | 104 return Type::Function(Type::Any(), Type::Any(), Type::Any(), |
| 93 Type::Any(), zone()); | 105 Type::Any(), zone()); |
| 94 case kNumberFunc0: | 106 case kNumberFunc0: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 }; | 176 }; |
| 165 | 177 |
| 166 | 178 |
| 167 Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context) | 179 Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context) |
| 168 : isolate_(isolate), | 180 : isolate_(isolate), |
| 169 graph_(graph), | 181 graph_(graph), |
| 170 context_(context), | 182 context_(context), |
| 171 decorator_(NULL), | 183 decorator_(NULL), |
| 172 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) { | 184 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) { |
| 173 Zone* zone = this->zone(); | 185 Zone* zone = this->zone(); |
| 174 Factory* f = isolate->factory(); | 186 Factory* const factory = isolate->factory(); |
| 175 | 187 |
| 176 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); | 188 Type* infinity = Type::Constant(factory->infinity_value(), zone); |
| 177 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); | 189 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); |
| 190 Type* truncating_to_zero = |
| 191 Type::Union(Type::Union(infinity, minus_infinity, zone), |
| 192 Type::MinusZeroOrNaN(), zone); |
| 178 | 193 |
| 179 Type* number = Type::Number(); | 194 singleton_false_ = Type::Constant(factory->false_value(), zone); |
| 180 Type* signed32 = Type::Signed32(); | 195 singleton_true_ = Type::Constant(factory->true_value(), zone); |
| 181 Type* unsigned32 = Type::Unsigned32(); | 196 singleton_zero_ = Type::Range(0.0, 0.0, zone); |
| 182 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); | 197 singleton_one_ = Type::Range(1.0, 1.0, zone); |
| 183 Type* truncating_to_zero = | 198 zero_or_one_ = Type::Range(0.0, 1.0, zone); |
| 184 Type::Union(Type::Union(Type::Constant(infinity, zone), | 199 zeroish_ = Type::Union(singleton_zero_, Type::MinusZeroOrNaN(), zone); |
| 185 Type::Constant(minusinfinity, zone), zone), | 200 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); |
| 186 nan_or_minuszero, zone); | 201 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); |
| 187 | 202 falsish_ = |
| 188 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone); | 203 Type::Union(Type::Undetectable(), |
| 189 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); | 204 Type::Union(Type::Union(singleton_false_, zeroish_, zone), |
| 190 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone); | 205 Type::NullOrUndefined(), zone), |
| 191 singleton_false = Type::Constant(f->false_value(), zone); | 206 zone); |
| 192 singleton_true = Type::Constant(f->true_value(), zone); | 207 truish_ = Type::Union( |
| 193 singleton_zero = Type::Range(0.0, 0.0, zone); | 208 singleton_true_, |
| 194 singleton_one = Type::Range(1.0, 1.0, zone); | |
| 195 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); | |
| 196 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone); | |
| 197 signed32ish = Type::Union(signed32, truncating_to_zero, zone); | |
| 198 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone); | |
| 199 falsish = Type::Union(Type::Undetectable(), | |
| 200 Type::Union(Type::Union(singleton_false, zeroish, zone), | |
| 201 undefined_or_null, zone), | |
| 202 zone); | |
| 203 truish = Type::Union( | |
| 204 singleton_true, | |
| 205 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); | 209 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); |
| 206 integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone); | |
| 207 weakint = Type::Union(integer, nan_or_minuszero, zone); | |
| 208 | |
| 209 number_fun0_ = Type::Function(number, zone); | |
| 210 number_fun1_ = Type::Function(number, number, zone); | |
| 211 number_fun2_ = Type::Function(number, number, number, zone); | |
| 212 | |
| 213 weakint_fun1_ = Type::Function(weakint, number, zone); | |
| 214 random_fun_ = Type::Function(Type::OrderedNumber(), zone); | |
| 215 | 210 |
| 216 decorator_ = new (zone) Decorator(this); | 211 decorator_ = new (zone) Decorator(this); |
| 217 graph_->AddDecorator(decorator_); | 212 graph_->AddDecorator(decorator_); |
| 218 } | 213 } |
| 219 | 214 |
| 220 | 215 |
| 221 Typer::~Typer() { | 216 Typer::~Typer() { |
| 222 graph_->RemoveDecorator(decorator_); | 217 graph_->RemoveDecorator(decorator_); |
| 223 } | 218 } |
| 224 | 219 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 : f(left.lower, right.lower, typer_)) | 488 : f(left.lower, right.lower, typer_)) |
| 494 : Type::None(); | 489 : Type::None(); |
| 495 // TODO(neis): Figure out what to do with lower bound. | 490 // TODO(neis): Figure out what to do with lower bound. |
| 496 return Bounds(lower, upper); | 491 return Bounds(lower, upper); |
| 497 } | 492 } |
| 498 | 493 |
| 499 | 494 |
| 500 Type* Typer::Visitor::Invert(Type* type, Typer* t) { | 495 Type* Typer::Visitor::Invert(Type* type, Typer* t) { |
| 501 DCHECK(type->Is(Type::Boolean())); | 496 DCHECK(type->Is(Type::Boolean())); |
| 502 DCHECK(type->IsInhabited()); | 497 DCHECK(type->IsInhabited()); |
| 503 if (type->Is(t->singleton_false)) return t->singleton_true; | 498 if (type->Is(t->singleton_false_)) return t->singleton_true_; |
| 504 if (type->Is(t->singleton_true)) return t->singleton_false; | 499 if (type->Is(t->singleton_true_)) return t->singleton_false_; |
| 505 return type; | 500 return type; |
| 506 } | 501 } |
| 507 | 502 |
| 508 | 503 |
| 509 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert( | 504 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert( |
| 510 ComparisonOutcome outcome, Typer* t) { | 505 ComparisonOutcome outcome, Typer* t) { |
| 511 ComparisonOutcome result(0); | 506 ComparisonOutcome result(0); |
| 512 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; | 507 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; |
| 513 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; | 508 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; |
| 514 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; | 509 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; |
| 515 return result; | 510 return result; |
| 516 } | 511 } |
| 517 | 512 |
| 518 | 513 |
| 519 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { | 514 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { |
| 520 if ((outcome & kComparisonFalse) != 0 || | 515 if ((outcome & kComparisonFalse) != 0 || |
| 521 (outcome & kComparisonUndefined) != 0) { | 516 (outcome & kComparisonUndefined) != 0) { |
| 522 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() | 517 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() |
| 523 : t->singleton_false; | 518 : t->singleton_false_; |
| 524 } | 519 } |
| 525 // Type should be non empty, so we know it should be true. | 520 // Type should be non empty, so we know it should be true. |
| 526 DCHECK((outcome & kComparisonTrue) != 0); | 521 DCHECK((outcome & kComparisonTrue) != 0); |
| 527 return t->singleton_true; | 522 return t->singleton_true_; |
| 528 } | 523 } |
| 529 | 524 |
| 530 | 525 |
| 531 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { | 526 Type* Typer::Visitor::Rangify(Type* type, Typer* t) { |
| 532 if (type->IsRange()) return type; // Shortcut. | 527 if (type->IsRange()) return type; // Shortcut. |
| 533 if (!type->Is(t->integer) && !type->Is(Type::Integral32())) { | 528 if (!type->Is(t->cache_->Get(kInteger))) { |
| 534 return type; // Give up on non-integer types. | 529 return type; // Give up on non-integer types. |
| 535 } | 530 } |
| 536 double min = type->Min(); | 531 double min = type->Min(); |
| 537 double max = type->Max(); | 532 double max = type->Max(); |
| 538 // Handle the degenerate case of empty bitset types (such as | 533 // Handle the degenerate case of empty bitset types (such as |
| 539 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). | 534 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). |
| 540 if (std::isnan(min)) { | 535 if (std::isnan(min)) { |
| 541 DCHECK(std::isnan(max)); | 536 DCHECK(std::isnan(max)); |
| 542 return type; | 537 return type; |
| 543 } | 538 } |
| 544 return Type::Range(min, max, t->zone()); | 539 return Type::Range(min, max, t->zone()); |
| 545 } | 540 } |
| 546 | 541 |
| 547 | 542 |
| 548 // Type conversion. | 543 // Type conversion. |
| 549 | 544 |
| 550 | 545 |
| 551 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { | 546 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { |
| 552 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { | 547 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { |
| 553 return type; | 548 return type; |
| 554 } | 549 } |
| 555 return Type::Primitive(); | 550 return Type::Primitive(); |
| 556 } | 551 } |
| 557 | 552 |
| 558 | 553 |
| 559 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { | 554 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { |
| 560 if (type->Is(Type::Boolean())) return type; | 555 if (type->Is(Type::Boolean())) return type; |
| 561 if (type->Is(t->falsish)) return t->singleton_false; | 556 if (type->Is(t->falsish_)) return t->singleton_false_; |
| 562 if (type->Is(t->truish)) return t->singleton_true; | 557 if (type->Is(t->truish_)) return t->singleton_true_; |
| 563 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { | 558 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { |
| 564 return t->singleton_true; // Ruled out nan, -0 and +0. | 559 return t->singleton_true_; // Ruled out nan, -0 and +0. |
| 565 } | 560 } |
| 566 return Type::Boolean(); | 561 return Type::Boolean(); |
| 567 } | 562 } |
| 568 | 563 |
| 569 | 564 |
| 570 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { | 565 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |
| 571 if (type->Is(Type::Number())) return type; | 566 if (type->Is(Type::Number())) return type; |
| 572 if (type->Is(Type::Null())) return t->singleton_zero; | 567 if (type->Is(Type::NullOrUndefined())) { |
| 573 if (type->Is(Type::Undefined())) return Type::NaN(); | 568 if (type->Is(Type::Null())) return t->singleton_zero_; |
| 574 if (type->Is(t->undefined_or_null)) { | 569 if (type->Is(Type::Undefined())) return Type::NaN(); |
| 575 return Type::Union(Type::NaN(), t->singleton_zero, t->zone()); | 570 return Type::Union(Type::NaN(), t->singleton_zero_, t->zone()); |
| 576 } | 571 } |
| 577 if (type->Is(t->undefined_or_number)) { | 572 if (type->Is(Type::NumberOrUndefined())) { |
| 578 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 573 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
| 579 Type::NaN(), t->zone()); | 574 Type::NaN(), t->zone()); |
| 580 } | 575 } |
| 581 if (type->Is(t->singleton_false)) return t->singleton_zero; | 576 if (type->Is(t->singleton_false_)) return t->singleton_zero_; |
| 582 if (type->Is(t->singleton_true)) return t->singleton_one; | 577 if (type->Is(t->singleton_true_)) return t->singleton_one_; |
| 583 if (type->Is(Type::Boolean())) return t->zero_or_one; | 578 if (type->Is(Type::Boolean())) return t->zero_or_one_; |
| 584 if (type->Is(t->boolean_or_number)) { | 579 if (type->Is(Type::BooleanOrNumber())) { |
| 585 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), | 580 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), |
| 586 t->zero_or_one, t->zone()); | 581 t->zero_or_one_, t->zone()); |
| 587 } | 582 } |
| 588 return Type::Number(); | 583 return Type::Number(); |
| 589 } | 584 } |
| 590 | 585 |
| 591 | 586 |
| 592 Type* Typer::Visitor::ToString(Type* type, Typer* t) { | 587 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |
| 593 if (type->Is(Type::String())) return type; | 588 if (type->Is(Type::String())) return type; |
| 594 return Type::String(); | 589 return Type::String(); |
| 595 } | 590 } |
| 596 | 591 |
| 597 | 592 |
| 598 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { | 593 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { |
| 599 // TODO(neis): DCHECK(type->Is(Type::Number())); | 594 // TODO(neis): DCHECK(type->Is(Type::Number())); |
| 600 if (type->Is(Type::Signed32())) return type; | 595 if (type->Is(Type::Signed32())) return type; |
| 601 if (type->Is(t->zeroish)) return t->singleton_zero; | 596 if (type->Is(t->zeroish_)) return t->singleton_zero_; |
| 602 if (type->Is(t->signed32ish)) { | 597 if (type->Is(t->signed32ish_)) { |
| 603 return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()), | 598 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), |
| 604 Type::Signed32(), t->zone()); | 599 Type::Signed32(), t->zone()); |
| 605 } | 600 } |
| 606 return Type::Signed32(); | 601 return Type::Signed32(); |
| 607 } | 602 } |
| 608 | 603 |
| 609 | 604 |
| 610 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { | 605 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { |
| 611 // TODO(neis): DCHECK(type->Is(Type::Number())); | 606 // TODO(neis): DCHECK(type->Is(Type::Number())); |
| 612 if (type->Is(Type::Unsigned32())) return type; | 607 if (type->Is(Type::Unsigned32())) return type; |
| 613 if (type->Is(t->zeroish)) return t->singleton_zero; | 608 if (type->Is(t->zeroish_)) return t->singleton_zero_; |
| 614 if (type->Is(t->unsigned32ish)) { | 609 if (type->Is(t->unsigned32ish_)) { |
| 615 return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()), | 610 return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()), |
| 616 Type::Unsigned32(), t->zone()); | 611 Type::Unsigned32(), t->zone()); |
| 617 } | 612 } |
| 618 return Type::Unsigned32(); | 613 return Type::Unsigned32(); |
| 619 } | 614 } |
| 620 | 615 |
| 621 | 616 |
| 622 // ----------------------------------------------------------------------------- | 617 // ----------------------------------------------------------------------------- |
| 623 | 618 |
| 624 | 619 |
| 625 // Control operators. | 620 // Control operators. |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 | 764 |
| 770 Bounds Typer::Visitor::TypeDead(Node* node) { | 765 Bounds Typer::Visitor::TypeDead(Node* node) { |
| 771 return Bounds::Unbounded(zone()); | 766 return Bounds::Unbounded(zone()); |
| 772 } | 767 } |
| 773 | 768 |
| 774 | 769 |
| 775 // JS comparison operators. | 770 // JS comparison operators. |
| 776 | 771 |
| 777 | 772 |
| 778 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 773 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 779 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; | 774 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; |
| 780 if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) { | 775 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { |
| 781 return t->singleton_true; | 776 return t->singleton_true_; |
| 782 } | 777 } |
| 783 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && | 778 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |
| 784 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { | 779 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |
| 785 return t->singleton_false; | 780 return t->singleton_false_; |
| 786 } | 781 } |
| 787 if (lhs->IsConstant() && rhs->Is(lhs)) { | 782 if (lhs->IsConstant() && rhs->Is(lhs)) { |
| 788 // Types are equal and are inhabited only by a single semantic value, | 783 // Types are equal and are inhabited only by a single semantic value, |
| 789 // which is not nan due to the earlier check. | 784 // which is not nan due to the earlier check. |
| 790 // TODO(neis): Extend this to Range(x,x), MinusZero, ...? | 785 // TODO(neis): Extend this to Range(x,x), MinusZero, ...? |
| 791 return t->singleton_true; | 786 return t->singleton_true_; |
| 792 } | 787 } |
| 793 return Type::Boolean(); | 788 return Type::Boolean(); |
| 794 } | 789 } |
| 795 | 790 |
| 796 | 791 |
| 797 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 792 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 798 return Invert(JSEqualTyper(lhs, rhs, t), t); | 793 return Invert(JSEqualTyper(lhs, rhs, t), t); |
| 799 } | 794 } |
| 800 | 795 |
| 801 | 796 |
| 802 static Type* JSType(Type* type) { | 797 static Type* JSType(Type* type) { |
| 803 if (type->Is(Type::Boolean())) return Type::Boolean(); | 798 if (type->Is(Type::Boolean())) return Type::Boolean(); |
| 804 if (type->Is(Type::String())) return Type::String(); | 799 if (type->Is(Type::String())) return Type::String(); |
| 805 if (type->Is(Type::Number())) return Type::Number(); | 800 if (type->Is(Type::Number())) return Type::Number(); |
| 806 if (type->Is(Type::Undefined())) return Type::Undefined(); | 801 if (type->Is(Type::Undefined())) return Type::Undefined(); |
| 807 if (type->Is(Type::Null())) return Type::Null(); | 802 if (type->Is(Type::Null())) return Type::Null(); |
| 808 if (type->Is(Type::Symbol())) return Type::Symbol(); | 803 if (type->Is(Type::Symbol())) return Type::Symbol(); |
| 809 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object" | 804 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object" |
| 810 return Type::Any(); | 805 return Type::Any(); |
| 811 } | 806 } |
| 812 | 807 |
| 813 | 808 |
| 814 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 809 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 815 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false; | 810 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_; |
| 816 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; | 811 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; |
| 817 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && | 812 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |
| 818 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { | 813 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |
| 819 return t->singleton_false; | 814 return t->singleton_false_; |
| 820 } | 815 } |
| 821 if (lhs->IsConstant() && rhs->Is(lhs)) { | 816 if (lhs->IsConstant() && rhs->Is(lhs)) { |
| 822 // Types are equal and are inhabited only by a single semantic value, | 817 // Types are equal and are inhabited only by a single semantic value, |
| 823 // which is not nan due to the earlier check. | 818 // which is not nan due to the earlier check. |
| 824 return t->singleton_true; | 819 return t->singleton_true_; |
| 825 } | 820 } |
| 826 return Type::Boolean(); | 821 return Type::Boolean(); |
| 827 } | 822 } |
| 828 | 823 |
| 829 | 824 |
| 830 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { | 825 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |
| 831 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); | 826 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); |
| 832 } | 827 } |
| 833 | 828 |
| 834 | 829 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1155 double rmin = rhs->Min(); | 1150 double rmin = rhs->Min(); |
| 1156 double rmax = rhs->Max(); | 1151 double rmax = rhs->Max(); |
| 1157 results[0] = lmin * rmin; | 1152 results[0] = lmin * rmin; |
| 1158 results[1] = lmin * rmax; | 1153 results[1] = lmin * rmax; |
| 1159 results[2] = lmax * rmin; | 1154 results[2] = lmax * rmin; |
| 1160 results[3] = lmax * rmax; | 1155 results[3] = lmax * rmax; |
| 1161 // If the result may be nan, we give up on calculating a precise type, because | 1156 // If the result may be nan, we give up on calculating a precise type, because |
| 1162 // the discontinuity makes it too complicated. Note that even if none of the | 1157 // the discontinuity makes it too complicated. Note that even if none of the |
| 1163 // "results" above is nan, the actual result may still be, so we have to do a | 1158 // "results" above is nan, the actual result may still be, so we have to do a |
| 1164 // different check: | 1159 // different check: |
| 1165 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && | 1160 bool maybe_nan = (lhs->Maybe(t->singleton_zero_) && |
| 1166 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | 1161 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || |
| 1167 (rhs->Maybe(t->singleton_zero) && | 1162 (rhs->Maybe(t->singleton_zero_) && |
| 1168 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | 1163 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); |
| 1169 if (maybe_nan) return t->weakint; // Giving up. | 1164 if (maybe_nan) return t->cache_->Get(kWeakint); // Giving up. |
| 1170 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || | 1165 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero_) && rmin < 0) || |
| 1171 (rhs->Maybe(t->singleton_zero) && lmin < 0); | 1166 (rhs->Maybe(t->singleton_zero_) && lmin < 0); |
| 1172 Type* range = | 1167 Type* range = |
| 1173 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); | 1168 Type::Range(array_min(results, 4), array_max(results, 4), t->zone()); |
| 1174 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) | 1169 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) |
| 1175 : range; | 1170 : range; |
| 1176 } | 1171 } |
| 1177 | 1172 |
| 1178 | 1173 |
| 1179 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 1174 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1180 lhs = Rangify(ToNumber(lhs, t), t); | 1175 lhs = Rangify(ToNumber(lhs, t), t); |
| 1181 rhs = Rangify(ToNumber(rhs, t), t); | 1176 rhs = Rangify(ToNumber(rhs, t), t); |
| 1182 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1177 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
| 1183 if (lhs->IsRange() && rhs->IsRange()) { | 1178 if (lhs->IsRange() && rhs->IsRange()) { |
| 1184 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); | 1179 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); |
| 1185 } | 1180 } |
| 1186 return Type::Number(); | 1181 return Type::Number(); |
| 1187 } | 1182 } |
| 1188 | 1183 |
| 1189 | 1184 |
| 1190 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 1185 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1191 lhs = ToNumber(lhs, t); | 1186 lhs = ToNumber(lhs, t); |
| 1192 rhs = ToNumber(rhs, t); | 1187 rhs = ToNumber(rhs, t); |
| 1193 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1188 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
| 1194 // Division is tricky, so all we do is try ruling out nan. | 1189 // Division is tricky, so all we do is try ruling out nan. |
| 1195 // TODO(neis): try ruling out -0 as well? | 1190 // TODO(neis): try ruling out -0 as well? |
| 1196 bool maybe_nan = | 1191 bool maybe_nan = |
| 1197 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1192 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || |
| 1198 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1193 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
| 1199 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1194 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
| 1200 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1195 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
| 1201 } | 1196 } |
| 1202 | 1197 |
| 1203 | 1198 |
| 1204 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | 1199 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, |
| 1205 Type::RangeType* rhs, Typer* t) { | 1200 Type::RangeType* rhs, Typer* t) { |
| 1206 double lmin = lhs->Min(); | 1201 double lmin = lhs->Min(); |
| 1207 double lmax = lhs->Max(); | 1202 double lmax = lhs->Max(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1232 result = Type::Union(result, Type::MinusZero(), t->zone()); | 1227 result = Type::Union(result, Type::MinusZero(), t->zone()); |
| 1233 return result; | 1228 return result; |
| 1234 } | 1229 } |
| 1235 | 1230 |
| 1236 | 1231 |
| 1237 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1232 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
| 1238 lhs = ToNumber(lhs, t); | 1233 lhs = ToNumber(lhs, t); |
| 1239 rhs = ToNumber(rhs, t); | 1234 rhs = ToNumber(rhs, t); |
| 1240 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1235 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
| 1241 | 1236 |
| 1242 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1237 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) || |
| 1243 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { | 1238 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { |
| 1244 // Result maybe NaN. | 1239 // Result maybe NaN. |
| 1245 return Type::Number(); | 1240 return Type::Number(); |
| 1246 } | 1241 } |
| 1247 | 1242 |
| 1248 lhs = Rangify(lhs, t); | 1243 lhs = Rangify(lhs, t); |
| 1249 rhs = Rangify(rhs, t); | 1244 rhs = Rangify(rhs, t); |
| 1250 if (lhs->IsRange() && rhs->IsRange()) { | 1245 if (lhs->IsRange() && rhs->IsRange()) { |
| 1251 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); | 1246 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); |
| 1252 } | 1247 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 static const double kWeakenMaxLimits[] = { | 1355 static const double kWeakenMaxLimits[] = { |
| 1361 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, | 1356 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, |
| 1362 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, | 1357 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, |
| 1363 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, | 1358 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, |
| 1364 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, | 1359 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, |
| 1365 70368744177663.0, 140737488355327.0, 281474976710655.0, | 1360 70368744177663.0, 140737488355327.0, 281474976710655.0, |
| 1366 562949953421311.0}; | 1361 562949953421311.0}; |
| 1367 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); | 1362 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); |
| 1368 | 1363 |
| 1369 // If the types have nothing to do with integers, return the types. | 1364 // If the types have nothing to do with integers, return the types. |
| 1370 if (!previous_type->Maybe(typer_->integer)) { | 1365 Type* const integer = typer_->cache_->Get(kInteger); |
| 1366 if (!previous_type->Maybe(integer)) { |
| 1371 return current_type; | 1367 return current_type; |
| 1372 } | 1368 } |
| 1373 DCHECK(current_type->Maybe(typer_->integer)); | 1369 DCHECK(current_type->Maybe(integer)); |
| 1374 | 1370 |
| 1375 Type* current_integer = | 1371 Type* current_integer = Type::Intersect(current_type, integer, zone()); |
| 1376 Type::Intersect(current_type, typer_->integer, zone()); | 1372 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); |
| 1377 Type* previous_integer = | |
| 1378 Type::Intersect(previous_type, typer_->integer, zone()); | |
| 1379 | 1373 |
| 1380 // Once we start weakening a node, we should always weaken. | 1374 // Once we start weakening a node, we should always weaken. |
| 1381 if (!IsWeakened(node->id())) { | 1375 if (!IsWeakened(node->id())) { |
| 1382 // Only weaken if there is range involved; we should converge quickly | 1376 // Only weaken if there is range involved; we should converge quickly |
| 1383 // for all other types (the exception is a union of many constants, | 1377 // for all other types (the exception is a union of many constants, |
| 1384 // but we currently do not increase the number of constants in unions). | 1378 // but we currently do not increase the number of constants in unions). |
| 1385 Type::RangeType* previous = previous_integer->GetRange(); | 1379 Type::RangeType* previous = previous_integer->GetRange(); |
| 1386 Type::RangeType* current = current_integer->GetRange(); | 1380 Type::RangeType* current = current_integer->GetRange(); |
| 1387 if (current == nullptr || previous == nullptr) { | 1381 if (current == nullptr || previous == nullptr) { |
| 1388 return current_type; | 1382 return current_type; |
| 1389 } | 1383 } |
| 1390 // Range is involved => we are weakening. | 1384 // Range is involved => we are weakening. |
| 1391 SetWeakened(node->id()); | 1385 SetWeakened(node->id()); |
| 1392 } | 1386 } |
| 1393 | 1387 |
| 1394 double current_min = current_integer->Min(); | 1388 double current_min = current_integer->Min(); |
| 1395 double new_min = current_min; | 1389 double new_min = current_min; |
| 1396 // Find the closest lower entry in the list of allowed | 1390 // Find the closest lower entry in the list of allowed |
| 1397 // minima (or negative infinity if there is no such entry). | 1391 // minima (or negative infinity if there is no such entry). |
| 1398 if (current_min != previous_integer->Min()) { | 1392 if (current_min != previous_integer->Min()) { |
| 1399 new_min = typer_->integer->AsRange()->Min(); | 1393 new_min = -V8_INFINITY; |
| 1400 for (double const min : kWeakenMinLimits) { | 1394 for (double const min : kWeakenMinLimits) { |
| 1401 if (min <= current_min) { | 1395 if (min <= current_min) { |
| 1402 new_min = min; | 1396 new_min = min; |
| 1403 break; | 1397 break; |
| 1404 } | 1398 } |
| 1405 } | 1399 } |
| 1406 } | 1400 } |
| 1407 | 1401 |
| 1408 double current_max = current_integer->Max(); | 1402 double current_max = current_integer->Max(); |
| 1409 double new_max = current_max; | 1403 double new_max = current_max; |
| 1410 // Find the closest greater entry in the list of allowed | 1404 // Find the closest greater entry in the list of allowed |
| 1411 // maxima (or infinity if there is no such entry). | 1405 // maxima (or infinity if there is no such entry). |
| 1412 if (current_max != previous_integer->Max()) { | 1406 if (current_max != previous_integer->Max()) { |
| 1413 new_max = typer_->integer->AsRange()->Max(); | 1407 new_max = V8_INFINITY; |
| 1414 for (double const max : kWeakenMaxLimits) { | 1408 for (double const max : kWeakenMaxLimits) { |
| 1415 if (max >= current_max) { | 1409 if (max >= current_max) { |
| 1416 new_max = max; | 1410 new_max = max; |
| 1417 break; | 1411 break; |
| 1418 } | 1412 } |
| 1419 } | 1413 } |
| 1420 } | 1414 } |
| 1421 | 1415 |
| 1422 return Type::Union(current_type, | 1416 return Type::Union(current_type, |
| 1423 Type::Range(new_min, new_max, typer_->zone()), | 1417 Type::Range(new_min, new_max, typer_->zone()), |
| (...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2329 | 2323 |
| 2330 | 2324 |
| 2331 // Heap constants. | 2325 // Heap constants. |
| 2332 | 2326 |
| 2333 | 2327 |
| 2334 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { | 2328 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { |
| 2335 if (value->IsJSFunction()) { | 2329 if (value->IsJSFunction()) { |
| 2336 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { | 2330 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { |
| 2337 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { | 2331 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { |
| 2338 case kMathRandom: | 2332 case kMathRandom: |
| 2339 return typer_->random_fun_; | 2333 return typer_->cache_->Get(kRandomFunc0); |
| 2340 case kMathFloor: | 2334 case kMathFloor: |
| 2341 return typer_->weakint_fun1_; | |
| 2342 case kMathRound: | 2335 case kMathRound: |
| 2343 return typer_->weakint_fun1_; | |
| 2344 case kMathCeil: | 2336 case kMathCeil: |
| 2345 return typer_->weakint_fun1_; | 2337 return typer_->cache_->Get(kWeakintFunc1); |
| 2346 // Unary math functions. | 2338 // Unary math functions. |
| 2347 case kMathAbs: // TODO(rossberg): can't express overloading | 2339 case kMathAbs: // TODO(rossberg): can't express overloading |
| 2348 case kMathLog: | 2340 case kMathLog: |
| 2349 case kMathExp: | 2341 case kMathExp: |
| 2350 case kMathSqrt: | 2342 case kMathSqrt: |
| 2351 case kMathCos: | 2343 case kMathCos: |
| 2352 case kMathSin: | 2344 case kMathSin: |
| 2353 case kMathTan: | 2345 case kMathTan: |
| 2354 case kMathAcos: | 2346 case kMathAcos: |
| 2355 case kMathAsin: | 2347 case kMathAsin: |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2421 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2413 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 2422 #undef TYPED_ARRAY_CASE | 2414 #undef TYPED_ARRAY_CASE |
| 2423 } | 2415 } |
| 2424 } | 2416 } |
| 2425 return Type::Constant(value, zone()); | 2417 return Type::Constant(value, zone()); |
| 2426 } | 2418 } |
| 2427 | 2419 |
| 2428 } // namespace compiler | 2420 } // namespace compiler |
| 2429 } // namespace internal | 2421 } // namespace internal |
| 2430 } // namespace v8 | 2422 } // namespace v8 |
| OLD | NEW |