| 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/graph-inl.h" |     5 #include "src/compiler/graph-inl.h" | 
|     6 #include "src/compiler/js-operator.h" |     6 #include "src/compiler/js-operator.h" | 
|     7 #include "src/compiler/node.h" |     7 #include "src/compiler/node.h" | 
|     8 #include "src/compiler/node-properties-inl.h" |     8 #include "src/compiler/node-properties-inl.h" | 
|     9 #include "src/compiler/node-properties.h" |     9 #include "src/compiler/node-properties.h" | 
|    10 #include "src/compiler/simplified-operator.h" |    10 #include "src/compiler/simplified-operator.h" | 
|    11 #include "src/compiler/typer.h" |    11 #include "src/compiler/typer.h" | 
|    12  |    12  | 
|    13 namespace v8 { |    13 namespace v8 { | 
|    14 namespace internal { |    14 namespace internal { | 
|    15 namespace compiler { |    15 namespace compiler { | 
|    16  |    16  | 
|    17 Typer::Typer(Zone* zone) : zone_(zone) { |    17 Typer::Typer(Zone* zone) : zone_(zone) { | 
|    18   Factory* f = zone->isolate()->factory(); |    18   Factory* f = zone->isolate()->factory(); | 
|    19  |    19  | 
|    20   Handle<Object> zero = f->NewNumber(0); |  | 
|    21   Handle<Object> one = f->NewNumber(1); |  | 
|    22   Handle<Object> positive_infinity = f->NewNumber(+V8_INFINITY); |  | 
|    23   Handle<Object> negative_infinity = f->NewNumber(-V8_INFINITY); |  | 
|    24  |  | 
|    25   negative_signed32 = Type::Union( |  | 
|    26       Type::SignedSmall(), Type::OtherSigned32(), zone); |  | 
|    27   non_negative_signed32 = Type::Union( |  | 
|    28       Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); |  | 
|    29   undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); |  | 
|    30   singleton_false = Type::Constant(f->false_value(), zone); |  | 
|    31   singleton_true = Type::Constant(f->true_value(), zone); |  | 
|    32   singleton_zero = Type::Range(zero, zero, zone); |  | 
|    33   singleton_one = Type::Range(one, one, zone); |  | 
|    34   zero_or_one = Type::Union(singleton_zero, singleton_one, zone); |  | 
|    35   zeroish = Type::Union( |  | 
|    36       singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); |  | 
|    37   falsish = Type::Union(Type::Undetectable(), |  | 
|    38       Type::Union(zeroish, undefined_or_null, zone), zone); |  | 
|    39   integer = Type::Range(negative_infinity, positive_infinity, zone); |  | 
|    40  |  | 
|    41   Type* number = Type::Number(); |    20   Type* number = Type::Number(); | 
|    42   Type* signed32 = Type::Signed32(); |    21   Type* signed32 = Type::Signed32(); | 
|    43   Type* unsigned32 = Type::Unsigned32(); |    22   Type* unsigned32 = Type::Unsigned32(); | 
|    44   Type* integral32 = Type::Integral32(); |    23   Type* integral32 = Type::Integral32(); | 
|    45   Type* object = Type::Object(); |    24   Type* object = Type::Object(); | 
|    46   Type* undefined = Type::Undefined(); |    25   Type* undefined = Type::Undefined(); | 
|    47   Type* weakint = Type::Union( |    26   Type* weakint = Type::Union( | 
|    48       integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); |    27       Type::Range(f->NewNumber(-V8_INFINITY), f->NewNumber(+V8_INFINITY), zone), | 
 |    28       Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); | 
|    49  |    29  | 
|    50   number_fun0_ = Type::Function(number, zone); |    30   number_fun0_ = Type::Function(number, zone); | 
|    51   number_fun1_ = Type::Function(number, number, zone); |    31   number_fun1_ = Type::Function(number, number, zone); | 
|    52   number_fun2_ = Type::Function(number, number, number, zone); |    32   number_fun2_ = Type::Function(number, number, number, zone); | 
|    53   weakint_fun1_ = Type::Function(weakint, number, zone); |    33   weakint_fun1_ = Type::Function(weakint, number, zone); | 
|    54   imul_fun_ = Type::Function(signed32, integral32, integral32, zone); |    34   imul_fun_ = Type::Function(signed32, integral32, integral32, zone); | 
|    55   random_fun_ = Type::Function(Type::Union( |    35   random_fun_ = Type::Function(Type::Union( | 
|    56       Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); |    36       Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); | 
|    57  |    37  | 
|    58   Type* int8 = Type::Intersect( |  | 
|    59       Type::Range(f->NewNumber(-0x7F), f->NewNumber(0x7F-1), zone), |  | 
|    60       Type::UntaggedInt8(), zone); |  | 
|    61   Type* int16 = Type::Intersect( |  | 
|    62       Type::Range(f->NewNumber(-0x7FFF), f->NewNumber(0x7FFF-1), zone), |  | 
|    63       Type::UntaggedInt16(), zone); |  | 
|    64   Type* uint8 = Type::Intersect( |  | 
|    65       Type::Range(zero, f->NewNumber(0xFF-1), zone), |  | 
|    66       Type::UntaggedInt8(), zone); |  | 
|    67   Type* uint16 = Type::Intersect( |  | 
|    68       Type::Range(zero, f->NewNumber(0xFFFF-1), zone), |  | 
|    69       Type::UntaggedInt16(), zone); |  | 
|    70  |    38  | 
|    71 #define NATIVE_TYPE(sem, rep) \ |    39 #define NATIVE_TYPE(sem, rep) \ | 
|    72     Type::Intersect(Type::sem(), Type::rep(), zone) |    40   Type::Intersect(Type::sem(zone), Type::rep(zone), zone) | 
 |    41   // TODO(rossberg): Use range types for more precision, once we have them. | 
 |    42   Type* int8 = NATIVE_TYPE(SignedSmall, UntaggedInt8); | 
 |    43   Type* int16 = NATIVE_TYPE(SignedSmall, UntaggedInt16); | 
|    73   Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32); |    44   Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32); | 
 |    45   Type* uint8 = NATIVE_TYPE(UnsignedSmall, UntaggedInt8); | 
 |    46   Type* uint16 = NATIVE_TYPE(UnsignedSmall, UntaggedInt16); | 
|    74   Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32); |    47   Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32); | 
|    75   Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32); |    48   Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32); | 
|    76   Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64); |    49   Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64); | 
|    77 #undef NATIVE_TYPE |    50 #undef NATIVE_TYPE | 
|    78  |  | 
|    79   Type* buffer = Type::Buffer(zone); |    51   Type* buffer = Type::Buffer(zone); | 
|    80   Type* int8_array = Type::Array(int8, zone); |    52   Type* int8_array = Type::Array(int8, zone); | 
|    81   Type* int16_array = Type::Array(int16, zone); |    53   Type* int16_array = Type::Array(int16, zone); | 
|    82   Type* int32_array = Type::Array(int32, zone); |    54   Type* int32_array = Type::Array(int32, zone); | 
|    83   Type* uint8_array = Type::Array(uint8, zone); |    55   Type* uint8_array = Type::Array(uint8, zone); | 
|    84   Type* uint16_array = Type::Array(uint16, zone); |    56   Type* uint16_array = Type::Array(uint16, zone); | 
|    85   Type* uint32_array = Type::Array(uint32, zone); |    57   Type* uint32_array = Type::Array(uint32, zone); | 
|    86   Type* float32_array = Type::Array(float32, zone); |    58   Type* float32_array = Type::Array(float32, zone); | 
|    87   Type* float64_array = Type::Array(float64, zone); |    59   Type* float64_array = Type::Array(float64, zone); | 
|    88   Type* arg1 = Type::Union(unsigned32, object, zone); |    60   Type* arg1 = Type::Union(unsigned32, object, zone); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   100 } |    72 } | 
|   101  |    73  | 
|   102  |    74  | 
|   103 class Typer::Visitor : public NullNodeVisitor { |    75 class Typer::Visitor : public NullNodeVisitor { | 
|   104  public: |    76  public: | 
|   105   Visitor(Typer* typer, MaybeHandle<Context> context) |    77   Visitor(Typer* typer, MaybeHandle<Context> context) | 
|   106       : typer_(typer), context_(context) {} |    78       : typer_(typer), context_(context) {} | 
|   107  |    79  | 
|   108   Bounds TypeNode(Node* node) { |    80   Bounds TypeNode(Node* node) { | 
|   109     switch (node->opcode()) { |    81     switch (node->opcode()) { | 
|   110 #define DECLARE_CASE(x) \ |  | 
|   111       case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer); |  | 
|   112       JS_SIMPLE_BINOP_LIST(DECLARE_CASE) |  | 
|   113 #undef DECLARE_CASE |  | 
|   114  |  | 
|   115 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); |    82 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); | 
|   116       DECLARE_CASE(Start) |    83       DECLARE_CASE(Start) | 
|   117       // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: |    84       VALUE_OP_LIST(DECLARE_CASE) | 
|   118       COMMON_OP_LIST(DECLARE_CASE) |  | 
|   119       SIMPLIFIED_OP_LIST(DECLARE_CASE) |  | 
|   120       MACHINE_OP_LIST(DECLARE_CASE) |  | 
|   121       JS_SIMPLE_UNOP_LIST(DECLARE_CASE) |  | 
|   122       JS_OBJECT_OP_LIST(DECLARE_CASE) |  | 
|   123       JS_CONTEXT_OP_LIST(DECLARE_CASE) |  | 
|   124       JS_OTHER_OP_LIST(DECLARE_CASE) |  | 
|   125 #undef DECLARE_CASE |    85 #undef DECLARE_CASE | 
|   126  |    86  | 
|   127 #define DECLARE_CASE(x) case IrOpcode::k##x: |    87 #define DECLARE_CASE(x) case IrOpcode::k##x: | 
|   128       DECLARE_CASE(End) |    88       DECLARE_CASE(End) | 
|   129       INNER_CONTROL_OP_LIST(DECLARE_CASE) |    89       INNER_CONTROL_OP_LIST(DECLARE_CASE) | 
|   130 #undef DECLARE_CASE |    90 #undef DECLARE_CASE | 
|   131       break; |    91       break; | 
|   132     } |    92     } | 
|   133     UNREACHABLE(); |    93     UNREACHABLE(); | 
|   134     return Bounds(); |    94     return Bounds(); | 
|   135   } |    95   } | 
|   136  |    96  | 
|   137   Type* TypeConstant(Handle<Object> value); |    97   Type* TypeConstant(Handle<Object> value); | 
|   138  |    98  | 
|   139  protected: |    99  protected: | 
|   140 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); |   100 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); | 
|   141   DECLARE_METHOD(Start) |   101   DECLARE_METHOD(Start) | 
|   142   VALUE_OP_LIST(DECLARE_METHOD) |   102   VALUE_OP_LIST(DECLARE_METHOD) | 
|   143 #undef DECLARE_METHOD |   103 #undef DECLARE_METHOD | 
|   144  |   104  | 
|   145   static Bounds OperandType(Node* node, int i) { |   105   Bounds OperandType(Node* node, int i) { | 
|   146     return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i)); |   106     return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i)); | 
|   147   } |   107   } | 
|   148  |   108  | 
|   149   static Type* ContextType(Node* node) { |   109   Type* ContextType(Node* node) { | 
|   150     Bounds result = |   110     Bounds result = | 
|   151         NodeProperties::GetBounds(NodeProperties::GetContextInput(node)); |   111         NodeProperties::GetBounds(NodeProperties::GetContextInput(node)); | 
|   152     DCHECK(result.upper->Maybe(Type::Internal())); |   112     DCHECK(result.upper->Maybe(Type::Internal())); | 
|   153     // TODO(rossberg): More precisely, instead of the above assertion, we should |   113     // TODO(rossberg): More precisely, instead of the above assertion, we should | 
|   154     // back-propagate the constraint that it has to be a subtype of Internal. |   114     // back-propagate the constraint that it has to be a subtype of Internal. | 
|   155     return result.upper; |   115     return result.upper; | 
|   156   } |   116   } | 
|   157  |   117  | 
|   158   Zone* zone() { return typer_->zone(); } |   118   Zone* zone() { return typer_->zone(); } | 
|   159   Isolate* isolate() { return typer_->isolate(); } |   119   Isolate* isolate() { return typer_->isolate(); } | 
|   160   MaybeHandle<Context> context() { return context_; } |   120   MaybeHandle<Context> context() { return context_; } | 
|   161  |   121  | 
|   162  private: |   122  private: | 
|   163   Typer* typer_; |   123   Typer* typer_; | 
|   164   MaybeHandle<Context> context_; |   124   MaybeHandle<Context> context_; | 
|   165  |  | 
|   166   typedef Type* (*UnaryTyperFun)(Type*, Typer* t); |  | 
|   167   typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); |  | 
|   168  |  | 
|   169   Bounds TypeUnaryOp(Node* node, UnaryTyperFun); |  | 
|   170   Bounds TypeBinaryOp(Node* node, BinaryTyperFun); |  | 
|   171  |  | 
|   172   static Type* Invert(Type*, Typer*); |  | 
|   173   static Type* FalsifyUndefined(Type*, Typer*); |  | 
|   174  |  | 
|   175   static Type* ToPrimitive(Type*, Typer*); |  | 
|   176   static Type* ToBoolean(Type*, Typer*); |  | 
|   177   static Type* ToNumber(Type*, Typer*); |  | 
|   178   static Type* ToString(Type*, Typer*); |  | 
|   179   static Type* NumberToInt32(Type*, Typer*); |  | 
|   180   static Type* NumberToUint32(Type*, Typer*); |  | 
|   181  |  | 
|   182   static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); |  | 
|   183   static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); |  | 
|   184   static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); |  | 
|   185   static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); |  | 
|   186  |  | 
|   187   static Type* JSCompareTyper(Type*, Type*, Typer*); |  | 
|   188  |  | 
|   189 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |  | 
|   190   JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |  | 
|   191 #undef DECLARE_METHOD |  | 
|   192  |  | 
|   193   static Type* JSUnaryNotTyper(Type*, Typer*); |  | 
|   194   static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |  | 
|   195   static Type* JSCallFunctionTyper(Type*, Typer*); |  | 
|   196 }; |   125 }; | 
|   197  |   126  | 
|   198  |   127  | 
|   199 class Typer::RunVisitor : public Typer::Visitor { |   128 class Typer::RunVisitor : public Typer::Visitor { | 
|   200  public: |   129  public: | 
|   201   RunVisitor(Typer* typer, MaybeHandle<Context> context) |   130   RunVisitor(Typer* typer, MaybeHandle<Context> context) | 
|   202       : Visitor(typer, context), |   131       : Visitor(typer, context), | 
|   203         redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} |   132         redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} | 
|   204  |   133  | 
|   205   GenericGraphVisit::Control Post(Node* node) { |   134   GenericGraphVisit::Control Post(Node* node) { | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   302     Visitor typing(this, MaybeHandle<Context>()); |   231     Visitor typing(this, MaybeHandle<Context>()); | 
|   303     Bounds bounds = typing.TypeNode(node); |   232     Bounds bounds = typing.TypeNode(node); | 
|   304     NodeProperties::SetBounds(node, bounds); |   233     NodeProperties::SetBounds(node, bounds); | 
|   305   } |   234   } | 
|   306 } |   235 } | 
|   307  |   236  | 
|   308  |   237  | 
|   309 // ----------------------------------------------------------------------------- |   238 // ----------------------------------------------------------------------------- | 
|   310  |   239  | 
|   311  |   240  | 
|   312 Bounds Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) { |  | 
|   313   Bounds input = OperandType(node, 0); |  | 
|   314   Type* upper = input.upper->Is(Type::None()) |  | 
|   315       ? Type::None() |  | 
|   316       : f(input.upper, typer_); |  | 
|   317   Type* lower = input.lower->Is(Type::None()) |  | 
|   318       ? Type::None() |  | 
|   319       : (input.lower == input.upper || upper->IsConstant()) |  | 
|   320       ? upper  // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...? |  | 
|   321       : f(input.lower, typer_); |  | 
|   322   // TODO(neis): Figure out what to do with lower bound. |  | 
|   323   return Bounds(lower, upper); |  | 
|   324 } |  | 
|   325  |  | 
|   326  |  | 
|   327 Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) { |  | 
|   328   Bounds left = OperandType(node, 0); |  | 
|   329   Bounds right = OperandType(node, 1); |  | 
|   330   Type* upper = left.upper->Is(Type::None()) || right.upper->Is(Type::None()) |  | 
|   331       ? Type::None() |  | 
|   332       : f(left.upper, right.upper, typer_); |  | 
|   333   Type* lower = left.lower->Is(Type::None()) || right.lower->Is(Type::None()) |  | 
|   334       ? Type::None() |  | 
|   335       : ((left.lower == left.upper && right.lower == right.upper) || |  | 
|   336          upper->IsConstant()) |  | 
|   337       ? upper |  | 
|   338       : f(left.lower, right.lower, typer_); |  | 
|   339   // TODO(neis): Figure out what to do with lower bound. |  | 
|   340   return Bounds(lower, upper); |  | 
|   341 } |  | 
|   342  |  | 
|   343  |  | 
|   344 Type* Typer::Visitor::Invert(Type* type, Typer* t) { |  | 
|   345   if (type->Is(t->singleton_false)) return t->singleton_true; |  | 
|   346   if (type->Is(t->singleton_true)) return t->singleton_false; |  | 
|   347   return type; |  | 
|   348 } |  | 
|   349  |  | 
|   350  |  | 
|   351 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) { |  | 
|   352   if (type->Is(Type::Undefined())) return t->singleton_false; |  | 
|   353   return type; |  | 
|   354 } |  | 
|   355  |  | 
|   356  |  | 
|   357 // Type conversion. |  | 
|   358  |  | 
|   359  |  | 
|   360 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { |  | 
|   361   if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { |  | 
|   362     return type; |  | 
|   363   } |  | 
|   364   return Type::Primitive(); |  | 
|   365 } |  | 
|   366  |  | 
|   367  |  | 
|   368 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { |  | 
|   369   if (type->Is(Type::Boolean())) return type; |  | 
|   370   if (type->Is(t->falsish)) return t->singleton_false; |  | 
|   371   if (type->Is(Type::DetectableReceiver())) return t->singleton_true; |  | 
|   372   if (type->Is(Type::OrderedNumber()) && (type->Max() < 0 || 0 < type->Min())) { |  | 
|   373     return t->singleton_true;  // Ruled out nan, -0 and +0. |  | 
|   374   } |  | 
|   375   return Type::Boolean(); |  | 
|   376 } |  | 
|   377  |  | 
|   378  |  | 
|   379 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { |  | 
|   380   if (type->Is(Type::Number())) return type; |  | 
|   381   if (type->Is(Type::Undefined())) return Type::NaN(); |  | 
|   382   if (type->Is(t->singleton_false)) return t->singleton_zero; |  | 
|   383   if (type->Is(t->singleton_true)) return t->singleton_one; |  | 
|   384   if (type->Is(Type::Boolean())) return t->zero_or_one; |  | 
|   385   return Type::Number(); |  | 
|   386 } |  | 
|   387  |  | 
|   388  |  | 
|   389 Type* Typer::Visitor::ToString(Type* type, Typer* t) { |  | 
|   390   if (type->Is(Type::String())) return type; |  | 
|   391   return Type::String(); |  | 
|   392 } |  | 
|   393  |  | 
|   394  |  | 
|   395 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { |  | 
|   396   DCHECK(type->Is(Type::Number())); |  | 
|   397   if (type->Is(Type::Signed32())) return type; |  | 
|   398   if (type->Is(t->zeroish)) return t->singleton_zero; |  | 
|   399   return Type::Signed32(); |  | 
|   400 } |  | 
|   401  |  | 
|   402  |  | 
|   403 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { |  | 
|   404   DCHECK(type->Is(Type::Number())); |  | 
|   405   if (type->Is(Type::Unsigned32())) return type; |  | 
|   406   if (type->Is(t->zeroish)) return t->singleton_zero; |  | 
|   407   return Type::Unsigned32(); |  | 
|   408 } |  | 
|   409  |  | 
|   410  |  | 
|   411 // ----------------------------------------------------------------------------- |  | 
|   412  |  | 
|   413  |  | 
|   414 // Control operators. |   241 // Control operators. | 
|   415  |   242  | 
|   416  |  | 
|   417 Bounds Typer::Visitor::TypeStart(Node* node) { |   243 Bounds Typer::Visitor::TypeStart(Node* node) { | 
|   418   return Bounds(Type::Internal()); |   244   return Bounds(Type::Internal(zone())); | 
|   419 } |   245 } | 
|   420  |   246  | 
|   421  |   247  | 
|   422 // Common operators. |   248 // Common operators. | 
|   423  |   249  | 
|   424  |  | 
|   425 Bounds Typer::Visitor::TypeParameter(Node* node) { |   250 Bounds Typer::Visitor::TypeParameter(Node* node) { | 
|   426   return Bounds::Unbounded(zone()); |   251   return Bounds::Unbounded(zone()); | 
|   427 } |   252 } | 
|   428  |   253  | 
|   429  |   254  | 
|   430 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { |   255 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { | 
|   431   Factory* f = zone()->isolate()->factory(); |   256   // TODO(titzer): only call Type::Of() if the type is not already known. | 
|   432   Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); |   257   return Bounds(Type::Of(OpParameter<int32_t>(node), zone())); | 
|   433   return Bounds(Type::Intersect( |  | 
|   434       Type::Range(number, number, zone()), Type::UntaggedInt32(), zone())); |  | 
|   435 } |   258 } | 
|   436  |   259  | 
|   437  |   260  | 
|   438 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { |   261 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { | 
|   439   return Bounds(Type::Internal());  // TODO(rossberg): Add int64 bitset type? |   262   // TODO(titzer): only call Type::Of() if the type is not already known. | 
 |   263   return Bounds( | 
 |   264       Type::Of(static_cast<double>(OpParameter<int64_t>(node)), zone())); | 
|   440 } |   265 } | 
|   441  |   266  | 
|   442  |   267  | 
|   443 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { |   268 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { | 
|   444   return Bounds(Type::Intersect( |   269   // TODO(titzer): only call Type::Of() if the type is not already known. | 
|   445       Type::Of(OpParameter<float>(node), zone()), |   270   return Bounds(Type::Of(OpParameter<float>(node), zone())); | 
|   446       Type::UntaggedFloat32(), zone())); |  | 
|   447 } |   271 } | 
|   448  |   272  | 
|   449  |   273  | 
|   450 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { |   274 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { | 
|   451   return Bounds(Type::Intersect( |   275   // TODO(titzer): only call Type::Of() if the type is not already known. | 
|   452       Type::Of(OpParameter<double>(node), zone()), |   276   return Bounds(Type::Of(OpParameter<double>(node), zone())); | 
|   453       Type::UntaggedFloat64(), zone())); |  | 
|   454 } |   277 } | 
|   455  |   278  | 
|   456  |   279  | 
|   457 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { |   280 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { | 
|   458   Factory* f = zone()->isolate()->factory(); |   281   // TODO(titzer): only call Type::Of() if the type is not already known. | 
|   459   return Bounds(Type::Constant( |   282   return Bounds(Type::Of(OpParameter<double>(node), zone())); | 
|   460       f->NewNumber(OpParameter<double>(node)), zone())); |  | 
|   461 } |   283 } | 
|   462  |   284  | 
|   463  |   285  | 
|   464 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { |   286 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { | 
|   465   return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); |   287   return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); | 
|   466 } |   288 } | 
|   467  |   289  | 
|   468  |   290  | 
|   469 Bounds Typer::Visitor::TypeExternalConstant(Node* node) { |   291 Bounds Typer::Visitor::TypeExternalConstant(Node* node) { | 
|   470   return Bounds(Type::Internal()); |   292   return Bounds(Type::Internal(zone())); | 
|   471 } |   293 } | 
|   472  |   294  | 
|   473  |   295  | 
|   474 Bounds Typer::Visitor::TypePhi(Node* node) { |   296 Bounds Typer::Visitor::TypePhi(Node* node) { | 
|   475   int arity = OperatorProperties::GetValueInputCount(node->op()); |   297   int arity = OperatorProperties::GetValueInputCount(node->op()); | 
|   476   Bounds bounds = OperandType(node, 0); |   298   Bounds bounds = OperandType(node, 0); | 
|   477   for (int i = 1; i < arity; ++i) { |   299   for (int i = 1; i < arity; ++i) { | 
|   478     bounds = Bounds::Either(bounds, OperandType(node, i), zone()); |   300     bounds = Bounds::Either(bounds, OperandType(node, i), zone()); | 
|   479   } |   301   } | 
|   480   return bounds; |   302   return bounds; | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|   493 } |   315 } | 
|   494  |   316  | 
|   495  |   317  | 
|   496 Bounds Typer::Visitor::TypeFinish(Node* node) { |   318 Bounds Typer::Visitor::TypeFinish(Node* node) { | 
|   497   return OperandType(node, 0); |   319   return OperandType(node, 0); | 
|   498 } |   320 } | 
|   499  |   321  | 
|   500  |   322  | 
|   501 Bounds Typer::Visitor::TypeFrameState(Node* node) { |   323 Bounds Typer::Visitor::TypeFrameState(Node* node) { | 
|   502   // TODO(rossberg): Ideally FrameState wouldn't have a value output. |   324   // TODO(rossberg): Ideally FrameState wouldn't have a value output. | 
|   503   return Bounds(Type::Internal()); |   325   return Bounds(Type::Internal(zone())); | 
|   504 } |   326 } | 
|   505  |   327  | 
|   506  |   328  | 
|   507 Bounds Typer::Visitor::TypeStateValues(Node* node) { |   329 Bounds Typer::Visitor::TypeStateValues(Node* node) { | 
|   508   return Bounds(Type::Internal()); |   330   return Bounds(Type::Internal(zone())); | 
|   509 } |   331 } | 
|   510  |   332  | 
|   511  |   333  | 
|   512 Bounds Typer::Visitor::TypeCall(Node* node) { |   334 Bounds Typer::Visitor::TypeCall(Node* node) { | 
|   513   return Bounds::Unbounded(zone()); |   335   return Bounds::Unbounded(zone()); | 
|   514 } |   336 } | 
|   515  |   337  | 
|   516  |   338  | 
|   517 Bounds Typer::Visitor::TypeProjection(Node* node) { |   339 Bounds Typer::Visitor::TypeProjection(Node* node) { | 
|   518   // TODO(titzer): use the output type of the input to determine the bounds. |   340   // TODO(titzer): use the output type of the input to determine the bounds. | 
|   519   return Bounds::Unbounded(zone()); |   341   return Bounds::Unbounded(zone()); | 
|   520 } |   342 } | 
|   521  |   343  | 
|   522  |   344  | 
|   523 // JS comparison operators. |   345 // JS comparison operators. | 
|   524  |   346  | 
|   525  |   347 #define DEFINE_METHOD(x)                       \ | 
|   526 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { |   348   Bounds Typer::Visitor::Type##x(Node* node) { \ | 
|   527   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; |   349     return Bounds(Type::Boolean(zone()));      \ | 
|   528   if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) { |  | 
|   529     return t->singleton_true; |  | 
|   530   } |   350   } | 
|   531   if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |   351 JS_COMPARE_BINOP_LIST(DEFINE_METHOD) | 
|   532       (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |   352 #undef DEFINE_METHOD | 
|   533       return t->singleton_false; |  | 
|   534   } |  | 
|   535   if (lhs->IsConstant() && rhs->Is(lhs)) { |  | 
|   536     // Types are equal and are inhabited only by a single semantic value, |  | 
|   537     // which is not nan due to the earlier check. |  | 
|   538     // TODO(neis): Extend this to Range(x,x), MinusZero, ...? |  | 
|   539     return t->singleton_true; |  | 
|   540   } |  | 
|   541   return Type::Boolean(); |  | 
|   542 } |  | 
|   543  |  | 
|   544  |  | 
|   545 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   546   return Invert(JSEqualTyper(lhs, rhs, t), t); |  | 
|   547 } |  | 
|   548  |  | 
|   549  |  | 
|   550 static Type* JSType(Type* type) { |  | 
|   551   if (type->Is(Type::Boolean())) return Type::Boolean(); |  | 
|   552   if (type->Is(Type::String())) return Type::String(); |  | 
|   553   if (type->Is(Type::Number())) return Type::Number(); |  | 
|   554   if (type->Is(Type::Undefined())) return Type::Undefined(); |  | 
|   555   if (type->Is(Type::Null())) return Type::Null(); |  | 
|   556   if (type->Is(Type::Symbol())) return Type::Symbol(); |  | 
|   557   if (type->Is(Type::Receiver())) return Type::Receiver();  // JS "Object" |  | 
|   558   return Type::Any(); |  | 
|   559 } |  | 
|   560  |  | 
|   561  |  | 
|   562 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   563   if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false; |  | 
|   564   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false; |  | 
|   565   if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && |  | 
|   566       (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { |  | 
|   567       return t->singleton_false; |  | 
|   568   } |  | 
|   569   if (lhs->IsConstant() && rhs->Is(lhs)) { |  | 
|   570     // Types are equal and are inhabited only by a single semantic value, |  | 
|   571     // which is not nan due to the earlier check. |  | 
|   572     return t->singleton_true; |  | 
|   573   } |  | 
|   574   return Type::Boolean(); |  | 
|   575 } |  | 
|   576  |  | 
|   577  |  | 
|   578 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   579   return Invert(JSStrictEqualTyper(lhs, rhs, t), t); |  | 
|   580 } |  | 
|   581  |  | 
|   582  |  | 
|   583 // The EcmaScript specification defines the four relational comparison operators |  | 
|   584 // (<, <=, >=, >) with the help of a single abstract one.  It behaves like < |  | 
|   585 // but returns undefined when the inputs cannot be compared. |  | 
|   586 // We implement the typing analogously. |  | 
|   587 Type* Typer::Visitor::JSCompareTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   588   lhs = ToPrimitive(lhs, t); |  | 
|   589   rhs = ToPrimitive(rhs, t); |  | 
|   590   if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) { |  | 
|   591     return Type::Boolean(); |  | 
|   592   } |  | 
|   593   lhs = ToNumber(lhs, t); |  | 
|   594   rhs = ToNumber(rhs, t); |  | 
|   595   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::Undefined(); |  | 
|   596   if (lhs->IsConstant() && rhs->Is(lhs)) { |  | 
|   597     // Types are equal and are inhabited only by a single semantic value, |  | 
|   598     // which is not NaN due to the previous check. |  | 
|   599     return t->singleton_false; |  | 
|   600   } |  | 
|   601   if (lhs->Min() >= rhs->Max()) return t->singleton_false; |  | 
|   602   if (lhs->Max() < rhs->Min() && |  | 
|   603       !lhs->Maybe(Type::NaN()) && !rhs->Maybe(Type::NaN())) { |  | 
|   604     return t->singleton_true; |  | 
|   605   } |  | 
|   606   return Type::Boolean(); |  | 
|   607 } |  | 
|   608  |  | 
|   609  |  | 
|   610 Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   611   return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t); |  | 
|   612 } |  | 
|   613  |  | 
|   614  |  | 
|   615 Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   616   return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t); |  | 
|   617 } |  | 
|   618  |  | 
|   619  |  | 
|   620 Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) { |  | 
|   621   return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t); |  | 
|   622 } |  | 
|   623  |  | 
|   624  |  | 
|   625 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( |  | 
|   626     Type* lhs, Type* rhs, Typer* t) { |  | 
|   627   return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); |  | 
|   628 } |  | 
|   629  |   353  | 
|   630  |   354  | 
|   631 // JS bitwise operators. |   355 // JS bitwise operators. | 
|   632  |   356  | 
|   633  |   357 Bounds Typer::Visitor::TypeJSBitwiseOr(Node* node) { | 
|   634 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |   358   Bounds left = OperandType(node, 0); | 
|   635   Factory* f = t->zone()->isolate()->factory(); |   359   Bounds right = OperandType(node, 1); | 
|   636   lhs = NumberToInt32(ToNumber(lhs, t), t); |   360   Type* upper = Type::Union(left.upper, right.upper, zone()); | 
|   637   rhs = NumberToInt32(ToNumber(rhs, t), t); |   361   if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone()); | 
|   638   double lmin = lhs->Min(); |   362   Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone()); | 
|   639   double rmin = rhs->Min(); |   363   return Bounds(lower, upper); | 
|   640   double lmax = lhs->Max(); |  | 
|   641   double rmax = rhs->Max(); |  | 
|   642   // Or-ing any two values results in a value no smaller than their minimum. |  | 
|   643   // Even no smaller than their maximum if both values are non-negative. |  | 
|   644   Handle<Object> min = f->NewNumber( |  | 
|   645       lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); |  | 
|   646   if (lmax < 0 || rmax < 0) { |  | 
|   647     // Or-ing two values of which at least one is negative results in a negative |  | 
|   648     // value. |  | 
|   649     Handle<Object> max = f->NewNumber(-1); |  | 
|   650     return Type::Range(min, max, t->zone()); |  | 
|   651   } |  | 
|   652   Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); |  | 
|   653   return Type::Range(min, max, t->zone()); |  | 
|   654   // TODO(neis): Be precise for singleton inputs, here and elsewhere. |  | 
|   655 } |   364 } | 
|   656  |   365  | 
|   657  |   366  | 
|   658 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |   367 Bounds Typer::Visitor::TypeJSBitwiseAnd(Node* node) { | 
|   659   Factory* f = t->zone()->isolate()->factory(); |   368   Bounds left = OperandType(node, 0); | 
|   660   lhs = NumberToInt32(ToNumber(lhs, t), t); |   369   Bounds right = OperandType(node, 1); | 
|   661   rhs = NumberToInt32(ToNumber(rhs, t), t); |   370   Type* upper = Type::Union(left.upper, right.upper, zone()); | 
|   662   double lmin = lhs->Min(); |   371   if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone()); | 
|   663   double rmin = rhs->Min(); |   372   Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone()); | 
|   664   double lmax = lhs->Max(); |   373   return Bounds(lower, upper); | 
|   665   double rmax = rhs->Max(); |  | 
|   666   // And-ing any two values results in a value no larger than their maximum. |  | 
|   667   // Even no larger than their minimum if both values are non-negative. |  | 
|   668   Handle<Object> max = f->NewNumber( |  | 
|   669       lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); |  | 
|   670   if (lmin >= 0 || rmin >= 0) { |  | 
|   671     // And-ing two values of which at least one is non-negative results in a |  | 
|   672     // non-negative value. |  | 
|   673     Handle<Object> min = f->NewNumber(0); |  | 
|   674     return Type::Range(min, max, t->zone()); |  | 
|   675   } |  | 
|   676   Handle<Object> min = f->NewNumber(Type::Signed32()->Min()); |  | 
|   677   return Type::Range(min, max, t->zone()); |  | 
|   678 } |   374 } | 
|   679  |   375  | 
|   680  |   376  | 
|   681 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { |   377 Bounds Typer::Visitor::TypeJSBitwiseXor(Node* node) { | 
|   682   lhs = NumberToInt32(ToNumber(lhs, t), t); |   378   return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); | 
|   683   rhs = NumberToInt32(ToNumber(rhs, t), t); |  | 
|   684   double lmin = lhs->Min(); |  | 
|   685   double rmin = rhs->Min(); |  | 
|   686   double lmax = lhs->Max(); |  | 
|   687   double rmax = rhs->Max(); |  | 
|   688   if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { |  | 
|   689     // Xor-ing negative or non-negative values results in a non-negative value. |  | 
|   690     return t->non_negative_signed32; |  | 
|   691   } |  | 
|   692   if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { |  | 
|   693     // Xor-ing a negative and a non-negative value results in a negative value. |  | 
|   694     return t->negative_signed32; |  | 
|   695   } |  | 
|   696   return Type::Signed32(); |  | 
|   697 } |   379 } | 
|   698  |   380  | 
|   699  |   381  | 
|   700 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { |   382 Bounds Typer::Visitor::TypeJSShiftLeft(Node* node) { | 
|   701   return Type::Signed32(); |   383   return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); | 
|   702 } |   384 } | 
|   703  |   385  | 
|   704  |   386  | 
|   705 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { |   387 Bounds Typer::Visitor::TypeJSShiftRight(Node* node) { | 
|   706   lhs = NumberToInt32(ToNumber(lhs, t), t); |   388   return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); | 
|   707   Factory* f = t->zone()->isolate()->factory(); |  | 
|   708   if (lhs->Min() >= 0) { |  | 
|   709     // Right-shifting a non-negative value cannot make it negative, nor larger. |  | 
|   710     Handle<Object> min = f->NewNumber(0); |  | 
|   711     Handle<Object> max = f->NewNumber(lhs->Max()); |  | 
|   712     return Type::Range(min, max, t->zone()); |  | 
|   713   } |  | 
|   714   if (lhs->Max() < 0) { |  | 
|   715     // Right-shifting a negative value cannot make it non-negative, nor smaller. |  | 
|   716     Handle<Object> min = f->NewNumber(lhs->Min()); |  | 
|   717     Handle<Object> max = f->NewNumber(-1); |  | 
|   718     return Type::Range(min, max, t->zone()); |  | 
|   719   } |  | 
|   720   return Type::Signed32(); |  | 
|   721 } |   389 } | 
|   722  |   390  | 
|   723  |   391  | 
|   724 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { |   392 Bounds Typer::Visitor::TypeJSShiftRightLogical(Node* node) { | 
|   725   lhs = NumberToUint32(ToNumber(lhs, t), t); |   393   return Bounds(Type::UnsignedSmall(zone()), Type::Unsigned32(zone())); | 
|   726   Factory* f = t->zone()->isolate()->factory(); |  | 
|   727   // Logical right-shifting any value cannot make it larger. |  | 
|   728   Handle<Object> min = f->NewNumber(0); |  | 
|   729   Handle<Object> max = f->NewNumber(lhs->Max()); |  | 
|   730   return Type::Range(min, max, t->zone()); |  | 
|   731 } |   394 } | 
|   732  |   395  | 
|   733  |   396  | 
|   734 // JS arithmetic operators. |   397 // JS arithmetic operators. | 
|   735  |   398  | 
|   736  |   399 Bounds Typer::Visitor::TypeJSAdd(Node* node) { | 
|   737 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { |   400   Bounds left = OperandType(node, 0); | 
|   738   lhs = ToPrimitive(lhs, t); |   401   Bounds right = OperandType(node, 1); | 
|   739   rhs = ToPrimitive(rhs, t); |   402   Type* lower = | 
|   740   if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { |   403       left.lower->Is(Type::None()) || right.lower->Is(Type::None()) ? | 
|   741     if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { |   404           Type::None(zone()) : | 
|   742       return Type::String(); |   405       left.lower->Is(Type::Number()) && right.lower->Is(Type::Number()) ? | 
|   743     } else { |   406           Type::SignedSmall(zone()) : | 
|   744       return Type::NumberOrString(); |   407       left.lower->Is(Type::String()) || right.lower->Is(Type::String()) ? | 
|   745     } |   408           Type::String(zone()) : Type::None(zone()); | 
|   746   } |   409   Type* upper = | 
|   747   lhs = ToNumber(lhs, t); |   410       left.upper->Is(Type::None()) && right.upper->Is(Type::None()) ? | 
|   748   rhs = ToNumber(rhs, t); |   411           Type::None(zone()) : | 
|   749   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |   412       left.upper->Is(Type::Number()) && right.upper->Is(Type::Number()) ? | 
|   750   // TODO(neis): Do some analysis. |   413           Type::Number(zone()) : | 
|   751   // TODO(neis): Deal with numeric bitsets here and elsewhere. |   414       left.upper->Is(Type::String()) || right.upper->Is(Type::String()) ? | 
|   752   return Type::Number(); |   415           Type::String(zone()) : Type::NumberOrString(zone()); | 
 |   416   return Bounds(lower, upper); | 
|   753 } |   417 } | 
|   754  |   418  | 
|   755  |   419  | 
|   756 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { |   420 Bounds Typer::Visitor::TypeJSSubtract(Node* node) { | 
|   757   lhs = ToNumber(lhs, t); |   421   return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); | 
|   758   rhs = ToNumber(rhs, t); |  | 
|   759   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |  | 
|   760   // TODO(neis): Do some analysis. |  | 
|   761   return Type::Number(); |  | 
|   762 } |   422 } | 
|   763  |   423  | 
|   764  |   424  | 
|   765 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { |   425 Bounds Typer::Visitor::TypeJSMultiply(Node* node) { | 
|   766   lhs = ToNumber(lhs, t); |   426   return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); | 
|   767   rhs = ToNumber(rhs, t); |  | 
|   768   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |  | 
|   769   // TODO(neis): Do some analysis. |  | 
|   770   return Type::Number(); |  | 
|   771 } |   427 } | 
|   772  |   428  | 
|   773  |   429  | 
|   774 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { |   430 Bounds Typer::Visitor::TypeJSDivide(Node* node) { | 
|   775   lhs = ToNumber(lhs, t); |   431   return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); | 
|   776   rhs = ToNumber(rhs, t); |  | 
|   777   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |  | 
|   778   // TODO(neis): Do some analysis. |  | 
|   779   return Type::Number(); |  | 
|   780 } |   432 } | 
|   781  |   433  | 
|   782  |   434  | 
|   783 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |   435 Bounds Typer::Visitor::TypeJSModulus(Node* node) { | 
|   784   lhs = ToNumber(lhs, t); |   436   return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); | 
|   785   rhs = ToNumber(rhs, t); |  | 
|   786   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |  | 
|   787   // TODO(neis): Do some analysis. |  | 
|   788   return Type::Number(); |  | 
|   789 } |   437 } | 
|   790  |   438  | 
|   791  |   439  | 
|   792 // JS unary operators. |   440 // JS unary operators. | 
|   793  |   441  | 
|   794  |  | 
|   795 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { |  | 
|   796   return Invert(ToBoolean(type, t), t); |  | 
|   797 } |  | 
|   798  |  | 
|   799  |  | 
|   800 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) { |   442 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) { | 
|   801   return TypeUnaryOp(node, JSUnaryNotTyper); |   443   return Bounds(Type::Boolean(zone())); | 
|   802 } |   444 } | 
|   803  |   445  | 
|   804  |   446  | 
|   805 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) { |   447 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) { | 
|   806   return Bounds(Type::InternalizedString()); |   448   return Bounds(Type::InternalizedString(zone())); | 
|   807 } |   449 } | 
|   808  |   450  | 
|   809  |   451  | 
|   810 // JS conversion operators. |   452 // JS conversion operators. | 
|   811  |   453  | 
|   812  |  | 
|   813 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) { |   454 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) { | 
|   814   return TypeUnaryOp(node, ToBoolean); |   455   return Bounds(Type::Boolean(zone())); | 
|   815 } |   456 } | 
|   816  |   457  | 
|   817  |   458  | 
|   818 Bounds Typer::Visitor::TypeJSToNumber(Node* node) { |   459 Bounds Typer::Visitor::TypeJSToNumber(Node* node) { | 
|   819   return TypeUnaryOp(node, ToNumber); |   460   return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); | 
|   820 } |   461 } | 
|   821  |   462  | 
|   822  |   463  | 
|   823 Bounds Typer::Visitor::TypeJSToString(Node* node) { |   464 Bounds Typer::Visitor::TypeJSToString(Node* node) { | 
|   824   return TypeUnaryOp(node, ToString); |   465   return Bounds(Type::None(zone()), Type::String(zone())); | 
|   825 } |   466 } | 
|   826  |   467  | 
|   827  |   468  | 
|   828 Bounds Typer::Visitor::TypeJSToName(Node* node) { |   469 Bounds Typer::Visitor::TypeJSToName(Node* node) { | 
|   829   return Bounds(Type::None(), Type::Name()); |   470   return Bounds(Type::None(zone()), Type::Name(zone())); | 
|   830 } |   471 } | 
|   831  |   472  | 
|   832  |   473  | 
|   833 Bounds Typer::Visitor::TypeJSToObject(Node* node) { |   474 Bounds Typer::Visitor::TypeJSToObject(Node* node) { | 
|   834   return Bounds(Type::None(), Type::Receiver()); |   475   return Bounds(Type::None(zone()), Type::Receiver(zone())); | 
|   835 } |   476 } | 
|   836  |   477  | 
|   837  |   478  | 
|   838 // JS object operators. |   479 // JS object operators. | 
|   839  |   480  | 
|   840  |  | 
|   841 Bounds Typer::Visitor::TypeJSCreate(Node* node) { |   481 Bounds Typer::Visitor::TypeJSCreate(Node* node) { | 
|   842   return Bounds(Type::None(), Type::Object()); |   482   return Bounds(Type::None(zone()), Type::Object(zone())); | 
|   843 } |  | 
|   844  |  | 
|   845  |  | 
|   846 Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) { |  | 
|   847   // TODO(rossberg): Use range types and sized array types to filter undefined. |  | 
|   848   if (object->IsArray() && name->Is(Type::Integral32())) { |  | 
|   849     return Type::Union( |  | 
|   850         object->AsArray()->Element(), Type::Undefined(), t->zone()); |  | 
|   851   } |  | 
|   852   return Type::Any(); |  | 
|   853 } |   483 } | 
|   854  |   484  | 
|   855  |   485  | 
|   856 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { |   486 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { | 
|   857   return TypeBinaryOp(node, JSLoadPropertyTyper); |   487   Bounds object = OperandType(node, 0); | 
 |   488   Bounds name = OperandType(node, 1); | 
 |   489   Bounds result = Bounds::Unbounded(zone()); | 
 |   490   // TODO(rossberg): Use range types and sized array types to filter undefined. | 
 |   491   if (object.lower->IsArray() && name.lower->Is(Type::Integral32())) { | 
 |   492     result.lower = Type::Union( | 
 |   493         object.lower->AsArray()->Element(), Type::Undefined(zone()), zone()); | 
 |   494   } | 
 |   495   if (object.upper->IsArray() && name.upper->Is(Type::Integral32())) { | 
 |   496     result.upper = Type::Union( | 
 |   497         object.upper->AsArray()->Element(),  Type::Undefined(zone()), zone()); | 
 |   498   } | 
 |   499   return result; | 
|   858 } |   500 } | 
|   859  |   501  | 
|   860  |   502  | 
|   861 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { |   503 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { | 
|   862   return Bounds::Unbounded(zone()); |   504   return Bounds::Unbounded(zone()); | 
|   863 } |   505 } | 
|   864  |   506  | 
|   865  |   507  | 
|   866 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { |   508 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { | 
|   867   UNREACHABLE(); |   509   UNREACHABLE(); | 
|   868   return Bounds(); |   510   return Bounds(); | 
|   869 } |   511 } | 
|   870  |   512  | 
|   871  |   513  | 
|   872 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { |   514 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { | 
|   873   UNREACHABLE(); |   515   UNREACHABLE(); | 
|   874   return Bounds(); |   516   return Bounds(); | 
|   875 } |   517 } | 
|   876  |   518  | 
|   877  |   519  | 
|   878 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) { |   520 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) { | 
|   879   return Bounds(Type::Boolean()); |   521   return Bounds(Type::Boolean(zone())); | 
|   880 } |   522 } | 
|   881  |   523  | 
|   882  |   524  | 
|   883 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) { |   525 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) { | 
|   884   return Bounds(Type::Boolean()); |   526   return Bounds(Type::Boolean(zone())); | 
|   885 } |   527 } | 
|   886  |   528  | 
|   887  |   529  | 
|   888 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) { |   530 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) { | 
|   889   return Bounds(Type::Boolean()); |   531   return Bounds(Type::Boolean(zone())); | 
|   890 } |   532 } | 
|   891  |   533  | 
|   892  |   534  | 
|   893 // JS context operators. |   535 // JS context operators. | 
|   894  |   536  | 
|   895  |  | 
|   896 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { |   537 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { | 
|   897   Bounds outer = OperandType(node, 0); |   538   Bounds outer = OperandType(node, 0); | 
|   898   DCHECK(outer.upper->Maybe(Type::Internal())); |   539   DCHECK(outer.upper->Maybe(Type::Internal())); | 
|   899   // TODO(rossberg): More precisely, instead of the above assertion, we should |   540   // TODO(rossberg): More precisely, instead of the above assertion, we should | 
|   900   // back-propagate the constraint that it has to be a subtype of Internal. |   541   // back-propagate the constraint that it has to be a subtype of Internal. | 
|   901  |   542  | 
|   902   ContextAccess access = OpParameter<ContextAccess>(node); |   543   ContextAccess access = OpParameter<ContextAccess>(node); | 
|   903   Type* context_type = outer.upper; |   544   Type* context_type = outer.upper; | 
|   904   MaybeHandle<Context> context; |   545   MaybeHandle<Context> context; | 
|   905   if (context_type->IsConstant()) { |   546   if (context_type->IsConstant()) { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|   920       context = handle(context.ToHandleChecked()->previous(), isolate()); |   561       context = handle(context.ToHandleChecked()->previous(), isolate()); | 
|   921     } |   562     } | 
|   922   } |   563   } | 
|   923   if (context.is_null()) { |   564   if (context.is_null()) { | 
|   924     return Bounds::Unbounded(zone()); |   565     return Bounds::Unbounded(zone()); | 
|   925   } else { |   566   } else { | 
|   926     Handle<Object> value = |   567     Handle<Object> value = | 
|   927         handle(context.ToHandleChecked()->get(static_cast<int>(access.index())), |   568         handle(context.ToHandleChecked()->get(static_cast<int>(access.index())), | 
|   928                isolate()); |   569                isolate()); | 
|   929     Type* lower = TypeConstant(value); |   570     Type* lower = TypeConstant(value); | 
|   930     return Bounds(lower, Type::Any()); |   571     return Bounds(lower, Type::Any(zone())); | 
|   931   } |   572   } | 
|   932 } |   573 } | 
|   933  |   574  | 
|   934  |   575  | 
|   935 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { |   576 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { | 
|   936   UNREACHABLE(); |   577   UNREACHABLE(); | 
|   937   return Bounds(); |   578   return Bounds(); | 
|   938 } |   579 } | 
|   939  |   580  | 
|   940  |   581  | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|   970  |   611  | 
|   971  |   612  | 
|   972 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) { |   613 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) { | 
|   973   Type* outer = ContextType(node); |   614   Type* outer = ContextType(node); | 
|   974   return Bounds(Type::Context(outer, zone())); |   615   return Bounds(Type::Context(outer, zone())); | 
|   975 } |   616 } | 
|   976  |   617  | 
|   977  |   618  | 
|   978 // JS other operators. |   619 // JS other operators. | 
|   979  |   620  | 
|   980  |  | 
|   981 Bounds Typer::Visitor::TypeJSYield(Node* node) { |   621 Bounds Typer::Visitor::TypeJSYield(Node* node) { | 
|   982   return Bounds::Unbounded(zone()); |   622   return Bounds::Unbounded(zone()); | 
|   983 } |   623 } | 
|   984  |   624  | 
|   985  |   625  | 
|   986 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) { |   626 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) { | 
|   987   return Bounds(Type::None(), Type::Receiver()); |   627   return Bounds(Type::None(zone()), Type::Receiver(zone())); | 
|   988 } |  | 
|   989  |  | 
|   990  |  | 
|   991 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { |  | 
|   992   return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any(); |  | 
|   993 } |   628 } | 
|   994  |   629  | 
|   995  |   630  | 
|   996 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) { |   631 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) { | 
|   997   return TypeUnaryOp(node, JSCallFunctionTyper);  // We ignore argument types. |   632   Bounds fun = OperandType(node, 0); | 
 |   633   Type* lower = fun.lower->IsFunction() | 
 |   634       ? fun.lower->AsFunction()->Result() : Type::None(zone()); | 
 |   635   Type* upper = fun.upper->IsFunction() | 
 |   636       ? fun.upper->AsFunction()->Result() : Type::Any(zone()); | 
 |   637   return Bounds(lower, upper); | 
|   998 } |   638 } | 
|   999  |   639  | 
|  1000  |   640  | 
|  1001 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) { |   641 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) { | 
|  1002   return Bounds::Unbounded(zone()); |   642   return Bounds::Unbounded(zone()); | 
|  1003 } |   643 } | 
|  1004  |   644  | 
|  1005  |   645  | 
|  1006 Bounds Typer::Visitor::TypeJSDebugger(Node* node) { |   646 Bounds Typer::Visitor::TypeJSDebugger(Node* node) { | 
|  1007   return Bounds::Unbounded(zone()); |   647   return Bounds::Unbounded(zone()); | 
|  1008 } |   648 } | 
|  1009  |   649  | 
|  1010  |   650  | 
|  1011 // Simplified operators. |   651 // Simplified operators. | 
|  1012  |   652  | 
 |   653 Bounds Typer::Visitor::TypeBooleanNot(Node* node) { | 
 |   654   return Bounds(Type::Boolean(zone())); | 
 |   655 } | 
|  1013  |   656  | 
|  1014 Bounds Typer::Visitor::TypeBooleanNot(Node* node) { |   657  | 
 |   658 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) { | 
 |   659   return Bounds(Type::Number(zone())); | 
 |   660 } | 
 |   661  | 
 |   662  | 
 |   663 Bounds Typer::Visitor::TypeNumberEqual(Node* node) { | 
 |   664   return Bounds(Type::Boolean(zone())); | 
 |   665 } | 
 |   666  | 
 |   667  | 
 |   668 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) { | 
 |   669   return Bounds(Type::Boolean(zone())); | 
 |   670 } | 
 |   671  | 
 |   672  | 
 |   673 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { | 
 |   674   return Bounds(Type::Boolean(zone())); | 
 |   675 } | 
 |   676  | 
 |   677  | 
 |   678 Bounds Typer::Visitor::TypeNumberAdd(Node* node) { | 
 |   679   return Bounds(Type::Number(zone())); | 
 |   680 } | 
 |   681  | 
 |   682  | 
 |   683 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) { | 
 |   684   return Bounds(Type::Number(zone())); | 
 |   685 } | 
 |   686  | 
 |   687  | 
 |   688 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) { | 
 |   689   return Bounds(Type::Number(zone())); | 
 |   690 } | 
 |   691  | 
 |   692  | 
 |   693 Bounds Typer::Visitor::TypeNumberDivide(Node* node) { | 
 |   694   return Bounds(Type::Number(zone())); | 
 |   695 } | 
 |   696  | 
 |   697  | 
 |   698 Bounds Typer::Visitor::TypeNumberModulus(Node* node) { | 
 |   699   return Bounds(Type::Number(zone())); | 
 |   700 } | 
 |   701  | 
 |   702  | 
 |   703 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) { | 
 |   704   Bounds arg = OperandType(node, 0); | 
 |   705   Type* s32 = Type::Signed32(zone()); | 
 |   706   Type* lower = arg.lower->Is(s32) ? arg.lower : s32; | 
 |   707   Type* upper = arg.upper->Is(s32) ? arg.upper : s32; | 
 |   708   return Bounds(lower, upper); | 
 |   709 } | 
 |   710  | 
 |   711  | 
 |   712 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) { | 
 |   713   Bounds arg = OperandType(node, 0); | 
 |   714   Type* u32 = Type::Unsigned32(zone()); | 
 |   715   Type* lower = arg.lower->Is(u32) ? arg.lower : u32; | 
 |   716   Type* upper = arg.upper->Is(u32) ? arg.upper : u32; | 
 |   717   return Bounds(lower, upper); | 
 |   718 } | 
 |   719  | 
 |   720  | 
 |   721 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) { | 
 |   722   return Bounds(Type::Boolean(zone())); | 
 |   723 } | 
 |   724  | 
 |   725  | 
 |   726 Bounds Typer::Visitor::TypeStringEqual(Node* node) { | 
 |   727   return Bounds(Type::Boolean(zone())); | 
 |   728 } | 
 |   729  | 
 |   730  | 
 |   731 Bounds Typer::Visitor::TypeStringLessThan(Node* node) { | 
 |   732   return Bounds(Type::Boolean(zone())); | 
 |   733 } | 
 |   734  | 
 |   735  | 
 |   736 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { | 
 |   737   return Bounds(Type::Boolean(zone())); | 
 |   738 } | 
 |   739  | 
 |   740  | 
 |   741 Bounds Typer::Visitor::TypeStringAdd(Node* node) { | 
 |   742   return Bounds(Type::String(zone())); | 
 |   743 } | 
 |   744  | 
 |   745  | 
 |   746 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) { | 
 |   747   // TODO(titzer): type is type of input, representation is Word32. | 
 |   748   return Bounds(Type::Integral32()); | 
 |   749 } | 
 |   750  | 
 |   751  | 
 |   752 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) { | 
 |   753   return Bounds(Type::Integral32());  // TODO(titzer): add appropriate rep | 
 |   754 } | 
 |   755  | 
 |   756  | 
 |   757 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { | 
 |   758   // TODO(titzer): type is type of input, representation is Float64. | 
 |   759   return Bounds(Type::Number()); | 
 |   760 } | 
 |   761  | 
 |   762  | 
 |   763 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { | 
 |   764   // TODO(titzer): type is type of input, representation is Tagged. | 
 |   765   return Bounds(Type::Integral32()); | 
 |   766 } | 
 |   767  | 
 |   768  | 
 |   769 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) { | 
 |   770   // TODO(titzer): type is type of input, representation is Tagged. | 
 |   771   return Bounds(Type::Unsigned32()); | 
 |   772 } | 
 |   773  | 
 |   774  | 
 |   775 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) { | 
 |   776   // TODO(titzer): type is type of input, representation is Tagged. | 
 |   777   return Bounds(Type::Number()); | 
 |   778 } | 
 |   779  | 
 |   780  | 
 |   781 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) { | 
 |   782   // TODO(titzer): type is type of input, representation is Bit. | 
|  1015   return Bounds(Type::Boolean()); |   783   return Bounds(Type::Boolean()); | 
|  1016 } |   784 } | 
|  1017  |   785  | 
|  1018  |   786  | 
|  1019 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) { |   787 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) { | 
|  1020   return Bounds(Type::Number()); |   788   // TODO(titzer): type is type of input, representation is Tagged. | 
|  1021 } |  | 
|  1022  |  | 
|  1023  |  | 
|  1024 Bounds Typer::Visitor::TypeNumberEqual(Node* node) { |  | 
|  1025   return Bounds(Type::Boolean()); |   789   return Bounds(Type::Boolean()); | 
|  1026 } |   790 } | 
|  1027  |   791  | 
|  1028  |   792  | 
|  1029 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) { |  | 
|  1030   return Bounds(Type::Boolean()); |  | 
|  1031 } |  | 
|  1032  |  | 
|  1033  |  | 
|  1034 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { |  | 
|  1035   return Bounds(Type::Boolean()); |  | 
|  1036 } |  | 
|  1037  |  | 
|  1038  |  | 
|  1039 Bounds Typer::Visitor::TypeNumberAdd(Node* node) { |  | 
|  1040   return Bounds(Type::Number()); |  | 
|  1041 } |  | 
|  1042  |  | 
|  1043  |  | 
|  1044 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) { |  | 
|  1045   return Bounds(Type::Number()); |  | 
|  1046 } |  | 
|  1047  |  | 
|  1048  |  | 
|  1049 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) { |  | 
|  1050   return Bounds(Type::Number()); |  | 
|  1051 } |  | 
|  1052  |  | 
|  1053  |  | 
|  1054 Bounds Typer::Visitor::TypeNumberDivide(Node* node) { |  | 
|  1055   return Bounds(Type::Number()); |  | 
|  1056 } |  | 
|  1057  |  | 
|  1058  |  | 
|  1059 Bounds Typer::Visitor::TypeNumberModulus(Node* node) { |  | 
|  1060   return Bounds(Type::Number()); |  | 
|  1061 } |  | 
|  1062  |  | 
|  1063  |  | 
|  1064 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) { |  | 
|  1065   return TypeUnaryOp(node, NumberToInt32); |  | 
|  1066 } |  | 
|  1067  |  | 
|  1068  |  | 
|  1069 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) { |  | 
|  1070   return TypeUnaryOp(node, NumberToUint32); |  | 
|  1071 } |  | 
|  1072  |  | 
|  1073  |  | 
|  1074 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) { |  | 
|  1075   return Bounds(Type::Boolean()); |  | 
|  1076 } |  | 
|  1077  |  | 
|  1078  |  | 
|  1079 Bounds Typer::Visitor::TypeStringEqual(Node* node) { |  | 
|  1080   return Bounds(Type::Boolean()); |  | 
|  1081 } |  | 
|  1082  |  | 
|  1083  |  | 
|  1084 Bounds Typer::Visitor::TypeStringLessThan(Node* node) { |  | 
|  1085   return Bounds(Type::Boolean()); |  | 
|  1086 } |  | 
|  1087  |  | 
|  1088  |  | 
|  1089 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { |  | 
|  1090   return Bounds(Type::Boolean()); |  | 
|  1091 } |  | 
|  1092  |  | 
|  1093  |  | 
|  1094 Bounds Typer::Visitor::TypeStringAdd(Node* node) { |  | 
|  1095   return Bounds(Type::String()); |  | 
|  1096 } |  | 
|  1097  |  | 
|  1098  |  | 
|  1099 static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) { |  | 
|  1100   // TODO(neis): Enable when expressible. |  | 
|  1101   /* |  | 
|  1102   return Type::Union( |  | 
|  1103       Type::Intersect(type, Type::Semantic(), zone), |  | 
|  1104       Type::Intersect(rep, Type::Representation(), zone), zone); |  | 
|  1105   */ |  | 
|  1106   return type; |  | 
|  1107 } |  | 
|  1108  |  | 
|  1109  |  | 
|  1110 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) { |  | 
|  1111   Bounds arg = OperandType(node, 0); |  | 
|  1112   DCHECK(arg.upper->Is(Type::Signed32())); |  | 
|  1113   return Bounds( |  | 
|  1114       ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()), |  | 
|  1115       ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone())); |  | 
|  1116 } |  | 
|  1117  |  | 
|  1118  |  | 
|  1119 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) { |  | 
|  1120   Bounds arg = OperandType(node, 0); |  | 
|  1121   DCHECK(arg.upper->Is(Type::Unsigned32())); |  | 
|  1122   return Bounds( |  | 
|  1123       ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()), |  | 
|  1124       ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone())); |  | 
|  1125 } |  | 
|  1126  |  | 
|  1127  |  | 
|  1128 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { |  | 
|  1129   Bounds arg = OperandType(node, 0); |  | 
|  1130   DCHECK(arg.upper->Is(Type::Number())); |  | 
|  1131   return Bounds( |  | 
|  1132       ChangeRepresentation(arg.lower, Type::UntaggedFloat64(), zone()), |  | 
|  1133       ChangeRepresentation(arg.upper, Type::UntaggedFloat64(), zone())); |  | 
|  1134 } |  | 
|  1135  |  | 
|  1136  |  | 
|  1137 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { |  | 
|  1138   Bounds arg = OperandType(node, 0); |  | 
|  1139   DCHECK(arg.upper->Is(Type::Signed32())); |  | 
|  1140   return Bounds( |  | 
|  1141       ChangeRepresentation(arg.lower, Type::Tagged(), zone()), |  | 
|  1142       ChangeRepresentation(arg.upper, Type::Tagged(), zone())); |  | 
|  1143 } |  | 
|  1144  |  | 
|  1145  |  | 
|  1146 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) { |  | 
|  1147   Bounds arg = OperandType(node, 0); |  | 
|  1148   DCHECK(arg.upper->Is(Type::Unsigned32())); |  | 
|  1149   return Bounds( |  | 
|  1150       ChangeRepresentation(arg.lower, Type::Tagged(), zone()), |  | 
|  1151       ChangeRepresentation(arg.upper, Type::Tagged(), zone())); |  | 
|  1152 } |  | 
|  1153  |  | 
|  1154  |  | 
|  1155 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) { |  | 
|  1156   Bounds arg = OperandType(node, 0); |  | 
|  1157   // CHECK(arg.upper->Is(Type::Number())); |  | 
|  1158   // TODO(neis): This check currently fails due to inconsistent typing. |  | 
|  1159   return Bounds( |  | 
|  1160       ChangeRepresentation(arg.lower, Type::Tagged(), zone()), |  | 
|  1161       ChangeRepresentation(arg.upper, Type::Tagged(), zone())); |  | 
|  1162 } |  | 
|  1163  |  | 
|  1164  |  | 
|  1165 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) { |  | 
|  1166   Bounds arg = OperandType(node, 0); |  | 
|  1167   DCHECK(arg.upper->Is(Type::Boolean())); |  | 
|  1168   return Bounds( |  | 
|  1169       ChangeRepresentation(arg.lower, Type::UntaggedInt1(), zone()), |  | 
|  1170       ChangeRepresentation(arg.upper, Type::UntaggedInt1(), zone())); |  | 
|  1171 } |  | 
|  1172  |  | 
|  1173  |  | 
|  1174 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) { |  | 
|  1175   Bounds arg = OperandType(node, 0); |  | 
|  1176   DCHECK(arg.upper->Is(Type::Boolean())); |  | 
|  1177   return Bounds( |  | 
|  1178       ChangeRepresentation(arg.lower, Type::TaggedPtr(), zone()), |  | 
|  1179       ChangeRepresentation(arg.upper, Type::TaggedPtr(), zone())); |  | 
|  1180 } |  | 
|  1181  |  | 
|  1182  |  | 
|  1183 Bounds Typer::Visitor::TypeLoadField(Node* node) { |   793 Bounds Typer::Visitor::TypeLoadField(Node* node) { | 
|  1184   return Bounds(FieldAccessOf(node->op()).type); |   794   return Bounds(FieldAccessOf(node->op()).type); | 
|  1185 } |   795 } | 
|  1186  |   796  | 
|  1187  |   797  | 
|  1188 Bounds Typer::Visitor::TypeLoadElement(Node* node) { |   798 Bounds Typer::Visitor::TypeLoadElement(Node* node) { | 
|  1189   return Bounds(ElementAccessOf(node->op()).type); |   799   return Bounds(ElementAccessOf(node->op()).type); | 
|  1190 } |   800 } | 
|  1191  |   801  | 
|  1192  |   802  | 
|  1193 Bounds Typer::Visitor::TypeStoreField(Node* node) { |   803 Bounds Typer::Visitor::TypeStoreField(Node* node) { | 
|  1194   UNREACHABLE(); |   804   UNREACHABLE(); | 
|  1195   return Bounds(); |   805   return Bounds(); | 
|  1196 } |   806 } | 
|  1197  |   807  | 
|  1198  |   808  | 
|  1199 Bounds Typer::Visitor::TypeStoreElement(Node* node) { |   809 Bounds Typer::Visitor::TypeStoreElement(Node* node) { | 
|  1200   UNREACHABLE(); |   810   UNREACHABLE(); | 
|  1201   return Bounds(); |   811   return Bounds(); | 
|  1202 } |   812 } | 
|  1203  |   813  | 
|  1204  |   814  | 
|  1205 // Machine operators. |   815 // Machine operators. | 
|  1206  |   816  | 
|  1207  |  | 
|  1208 // TODO(rossberg): implement |   817 // TODO(rossberg): implement | 
|  1209 #define DEFINE_METHOD(x) \ |   818 #define DEFINE_METHOD(x) \ | 
|  1210   Bounds Typer::Visitor::Type##x(Node* node) { \ |   819     Bounds Typer::Visitor::Type##x(Node* node) { return Bounds(Type::None()); } | 
|  1211     return Bounds::Unbounded(zone()); \ |  | 
|  1212   } |  | 
|  1213 MACHINE_OP_LIST(DEFINE_METHOD) |   820 MACHINE_OP_LIST(DEFINE_METHOD) | 
|  1214 #undef DEFINE_METHOD |   821 #undef DEFINE_METHOD | 
|  1215  |   822  | 
|  1216  |   823  | 
|  1217 // Heap constants. |   824 // Heap constants. | 
|  1218  |   825  | 
|  1219 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { |   826 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { | 
|  1220   if (value->IsJSFunction()) { |   827   if (value->IsJSFunction()) { | 
|  1221     if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { |   828     if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { | 
|  1222       switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { |   829       switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1300 } |   907 } | 
|  1301  |   908  | 
|  1302  |   909  | 
|  1303 void Typer::DecorateGraph(Graph* graph) { |   910 void Typer::DecorateGraph(Graph* graph) { | 
|  1304   graph->AddDecorator(new (zone()) TyperDecorator(this)); |   911   graph->AddDecorator(new (zone()) TyperDecorator(this)); | 
|  1305 } |   912 } | 
|  1306  |   913  | 
|  1307 } |   914 } | 
|  1308 } |   915 } | 
|  1309 }  // namespace v8::internal::compiler |   916 }  // namespace v8::internal::compiler | 
| OLD | NEW |