• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "src/compiler/typer.h"
6 
7 #include <iomanip>
8 
9 #include "src/base/flags.h"
10 #include "src/bootstrapper.h"
11 #include "src/compiler/common-operator.h"
12 #include "src/compiler/graph-reducer.h"
13 #include "src/compiler/js-operator.h"
14 #include "src/compiler/linkage.h"
15 #include "src/compiler/loop-variable-optimizer.h"
16 #include "src/compiler/node-properties.h"
17 #include "src/compiler/node.h"
18 #include "src/compiler/operation-typer.h"
19 #include "src/compiler/simplified-operator.h"
20 #include "src/compiler/type-cache.h"
21 #include "src/objects-inl.h"
22 
23 namespace v8 {
24 namespace internal {
25 namespace compiler {
26 
27 class Typer::Decorator final : public GraphDecorator {
28  public:
Decorator(Typer * typer)29   explicit Decorator(Typer* typer) : typer_(typer) {}
30   void Decorate(Node* node) final;
31 
32  private:
33   Typer* const typer_;
34 };
35 
Typer(Isolate * isolate,Flags flags,Graph * graph)36 Typer::Typer(Isolate* isolate, Flags flags, Graph* graph)
37     : isolate_(isolate),
38       flags_(flags),
39       graph_(graph),
40       decorator_(nullptr),
41       cache_(TypeCache::Get()),
42       operation_typer_(isolate, zone()) {
43   Zone* zone = this->zone();
44   Factory* const factory = isolate->factory();
45 
46   singleton_empty_string_ = Type::HeapConstant(factory->empty_string(), zone);
47   singleton_false_ = operation_typer_.singleton_false();
48   singleton_true_ = operation_typer_.singleton_true();
49   falsish_ = Type::Union(
50       Type::Undetectable(),
51       Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
52                   Type::Union(singleton_empty_string_, Type::Hole(), zone),
53                   zone),
54       zone);
55   truish_ = Type::Union(
56       singleton_true_,
57       Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
58 
59   decorator_ = new (zone) Decorator(this);
60   graph_->AddDecorator(decorator_);
61 }
62 
63 
~Typer()64 Typer::~Typer() {
65   graph_->RemoveDecorator(decorator_);
66 }
67 
68 
69 class Typer::Visitor : public Reducer {
70  public:
Visitor(Typer * typer,LoopVariableOptimizer * induction_vars)71   explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
72       : typer_(typer),
73         induction_vars_(induction_vars),
74         weakened_nodes_(typer->zone()) {}
75 
Reduce(Node * node)76   Reduction Reduce(Node* node) override {
77     if (node->op()->ValueOutputCount() == 0) return NoChange();
78     switch (node->opcode()) {
79 #define DECLARE_CASE(x) \
80   case IrOpcode::k##x:  \
81     return UpdateType(node, TypeBinaryOp(node, x##Typer));
82       JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
83 #undef DECLARE_CASE
84 
85 #define DECLARE_CASE(x) \
86   case IrOpcode::k##x:  \
87     return UpdateType(node, Type##x(node));
88       DECLARE_CASE(Start)
89       DECLARE_CASE(IfException)
90       // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
91       COMMON_OP_LIST(DECLARE_CASE)
92       SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
93       SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
94       JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
95       JS_OBJECT_OP_LIST(DECLARE_CASE)
96       JS_CONTEXT_OP_LIST(DECLARE_CASE)
97       JS_OTHER_OP_LIST(DECLARE_CASE)
98 #undef DECLARE_CASE
99 
100 #define DECLARE_CASE(x) \
101   case IrOpcode::k##x:  \
102     return UpdateType(node, TypeBinaryOp(node, x));
103       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
104       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
105 #undef DECLARE_CASE
106 
107 #define DECLARE_CASE(x) \
108   case IrOpcode::k##x:  \
109     return UpdateType(node, TypeUnaryOp(node, x));
110       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
111 #undef DECLARE_CASE
112 
113 #define DECLARE_CASE(x) case IrOpcode::k##x:
114       DECLARE_CASE(Loop)
115       DECLARE_CASE(Branch)
116       DECLARE_CASE(IfTrue)
117       DECLARE_CASE(IfFalse)
118       DECLARE_CASE(IfSuccess)
119       DECLARE_CASE(Switch)
120       DECLARE_CASE(IfValue)
121       DECLARE_CASE(IfDefault)
122       DECLARE_CASE(Merge)
123       DECLARE_CASE(Deoptimize)
124       DECLARE_CASE(DeoptimizeIf)
125       DECLARE_CASE(DeoptimizeUnless)
126       DECLARE_CASE(TrapIf)
127       DECLARE_CASE(TrapUnless)
128       DECLARE_CASE(Return)
129       DECLARE_CASE(TailCall)
130       DECLARE_CASE(Terminate)
131       DECLARE_CASE(OsrNormalEntry)
132       DECLARE_CASE(OsrLoopEntry)
133       DECLARE_CASE(Throw)
134       DECLARE_CASE(End)
135       SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
136       SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
137       MACHINE_SIMD_OP_LIST(DECLARE_CASE)
138       MACHINE_OP_LIST(DECLARE_CASE)
139 #undef DECLARE_CASE
140       break;
141     }
142     return NoChange();
143   }
144 
TypeNode(Node * node)145   Type* TypeNode(Node* node) {
146     switch (node->opcode()) {
147 #define DECLARE_CASE(x) \
148       case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
149       JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
150 #undef DECLARE_CASE
151 
152 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
153       DECLARE_CASE(Start)
154       DECLARE_CASE(IfException)
155       // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
156       COMMON_OP_LIST(DECLARE_CASE)
157       SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
158       SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
159       JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
160       JS_OBJECT_OP_LIST(DECLARE_CASE)
161       JS_CONTEXT_OP_LIST(DECLARE_CASE)
162       JS_OTHER_OP_LIST(DECLARE_CASE)
163 #undef DECLARE_CASE
164 
165 #define DECLARE_CASE(x) \
166   case IrOpcode::k##x:  \
167     return TypeBinaryOp(node, x);
168       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
169       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
170 #undef DECLARE_CASE
171 
172 #define DECLARE_CASE(x) \
173   case IrOpcode::k##x:  \
174     return TypeUnaryOp(node, x);
175       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
176 #undef DECLARE_CASE
177 
178 #define DECLARE_CASE(x) case IrOpcode::k##x:
179       DECLARE_CASE(Loop)
180       DECLARE_CASE(Branch)
181       DECLARE_CASE(IfTrue)
182       DECLARE_CASE(IfFalse)
183       DECLARE_CASE(IfSuccess)
184       DECLARE_CASE(Switch)
185       DECLARE_CASE(IfValue)
186       DECLARE_CASE(IfDefault)
187       DECLARE_CASE(Merge)
188       DECLARE_CASE(Deoptimize)
189       DECLARE_CASE(DeoptimizeIf)
190       DECLARE_CASE(DeoptimizeUnless)
191       DECLARE_CASE(TrapIf)
192       DECLARE_CASE(TrapUnless)
193       DECLARE_CASE(Return)
194       DECLARE_CASE(TailCall)
195       DECLARE_CASE(Terminate)
196       DECLARE_CASE(OsrNormalEntry)
197       DECLARE_CASE(OsrLoopEntry)
198       DECLARE_CASE(Throw)
199       DECLARE_CASE(End)
200       SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
201       SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
202       MACHINE_SIMD_OP_LIST(DECLARE_CASE)
203       MACHINE_OP_LIST(DECLARE_CASE)
204 #undef DECLARE_CASE
205       break;
206     }
207     UNREACHABLE();
208     return nullptr;
209   }
210 
211   Type* TypeConstant(Handle<Object> value);
212 
213  private:
214   Typer* typer_;
215   LoopVariableOptimizer* induction_vars_;
216   ZoneSet<NodeId> weakened_nodes_;
217 
218 #define DECLARE_METHOD(x) inline Type* Type##x(Node* node);
219   DECLARE_METHOD(Start)
DECLARE_METHOD(IfException)220   DECLARE_METHOD(IfException)
221   COMMON_OP_LIST(DECLARE_METHOD)
222   SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
223   SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
224   JS_OP_LIST(DECLARE_METHOD)
225 #undef DECLARE_METHOD
226 
227   Type* TypeOrNone(Node* node) {
228     return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
229                                          : Type::None();
230   }
231 
Operand(Node * node,int i)232   Type* Operand(Node* node, int i) {
233     Node* operand_node = NodeProperties::GetValueInput(node, i);
234     return TypeOrNone(operand_node);
235   }
236 
237   Type* Weaken(Node* node, Type* current_type, Type* previous_type);
238 
zone()239   Zone* zone() { return typer_->zone(); }
isolate()240   Isolate* isolate() { return typer_->isolate(); }
graph()241   Graph* graph() { return typer_->graph(); }
242 
SetWeakened(NodeId node_id)243   void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
IsWeakened(NodeId node_id)244   bool IsWeakened(NodeId node_id) {
245     return weakened_nodes_.find(node_id) != weakened_nodes_.end();
246   }
247 
248   typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
249   typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
250 
251   Type* TypeUnaryOp(Node* node, UnaryTyperFun);
252   Type* TypeBinaryOp(Node* node, BinaryTyperFun);
253 
254   enum ComparisonOutcomeFlags {
255     kComparisonTrue = 1,
256     kComparisonFalse = 2,
257     kComparisonUndefined = 4
258   };
259   typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
260 
261   static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
262   static Type* Invert(Type*, Typer*);
263   static Type* FalsifyUndefined(ComparisonOutcome, Typer*);
264 
265   static Type* ToPrimitive(Type*, Typer*);
266   static Type* ToBoolean(Type*, Typer*);
267   static Type* ToInteger(Type*, Typer*);
268   static Type* ToLength(Type*, Typer*);
269   static Type* ToName(Type*, Typer*);
270   static Type* ToNumber(Type*, Typer*);
271   static Type* ToObject(Type*, Typer*);
272   static Type* ToString(Type*, Typer*);
273 #define DECLARE_METHOD(Name)                \
274   static Type* Name(Type* type, Typer* t) { \
275     return t->operation_typer_.Name(type);  \
276   }
277   SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
278 #undef DECLARE_METHOD
279 #define DECLARE_METHOD(Name)                          \
280   static Type* Name(Type* lhs, Type* rhs, Typer* t) { \
281     return t->operation_typer_.Name(lhs, rhs);        \
282   }
283   SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
284   SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
285 #undef DECLARE_METHOD
286 
287   static Type* ObjectIsDetectableCallable(Type*, Typer*);
288   static Type* ObjectIsNonCallable(Type*, Typer*);
289   static Type* ObjectIsNumber(Type*, Typer*);
290   static Type* ObjectIsReceiver(Type*, Typer*);
291   static Type* ObjectIsSmi(Type*, Typer*);
292   static Type* ObjectIsString(Type*, Typer*);
293   static Type* ObjectIsUndetectable(Type*, Typer*);
294 
295   static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
296 
297 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
298   JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
299 #undef DECLARE_METHOD
300 
301   static Type* JSCallTyper(Type*, Typer*);
302 
303   static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
304   static Type* StringFromCharCodeTyper(Type*, Typer*);
305   static Type* StringFromCodePointTyper(Type*, Typer*);
306 
UpdateType(Node * node,Type * current)307   Reduction UpdateType(Node* node, Type* current) {
308     if (NodeProperties::IsTyped(node)) {
309       // Widen the type of a previously typed node.
310       Type* previous = NodeProperties::GetType(node);
311       if (node->opcode() == IrOpcode::kPhi ||
312           node->opcode() == IrOpcode::kInductionVariablePhi) {
313         // Speed up termination in the presence of range types:
314         current = Weaken(node, current, previous);
315       }
316 
317       CHECK(previous->Is(current));
318 
319       NodeProperties::SetType(node, current);
320       if (!current->Is(previous)) {
321         // If something changed, revisit all uses.
322         return Changed(node);
323       }
324       return NoChange();
325     } else {
326       // No previous type, simply update the type.
327       NodeProperties::SetType(node, current);
328       return Changed(node);
329     }
330   }
331 };
332 
Run()333 void Typer::Run() { Run(NodeVector(zone()), nullptr); }
334 
Run(const NodeVector & roots,LoopVariableOptimizer * induction_vars)335 void Typer::Run(const NodeVector& roots,
336                 LoopVariableOptimizer* induction_vars) {
337   if (induction_vars != nullptr) {
338     induction_vars->ChangeToInductionVariablePhis();
339   }
340   Visitor visitor(this, induction_vars);
341   GraphReducer graph_reducer(zone(), graph());
342   graph_reducer.AddReducer(&visitor);
343   for (Node* const root : roots) graph_reducer.ReduceNode(root);
344   graph_reducer.ReduceGraph();
345 
346   if (induction_vars != nullptr) {
347     induction_vars->ChangeToPhisAndInsertGuards();
348   }
349 }
350 
Decorate(Node * node)351 void Typer::Decorator::Decorate(Node* node) {
352   if (node->op()->ValueOutputCount() > 0) {
353     // Only eagerly type-decorate nodes with known input types.
354     // Other cases will generally require a proper fixpoint iteration with Run.
355     bool is_typed = NodeProperties::IsTyped(node);
356     if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
357       Visitor typing(typer_, nullptr);
358       Type* type = typing.TypeNode(node);
359       if (is_typed) {
360         type = Type::Intersect(type, NodeProperties::GetType(node),
361                                typer_->zone());
362       }
363       NodeProperties::SetType(node, type);
364     }
365   }
366 }
367 
368 
369 // -----------------------------------------------------------------------------
370 
371 // Helper functions that lift a function f on types to a function on bounds,
372 // and uses that to type the given node.  Note that f is never called with None
373 // as an argument.
374 
375 
TypeUnaryOp(Node * node,UnaryTyperFun f)376 Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
377   Type* input = Operand(node, 0);
378   return input->IsInhabited() ? f(input, typer_) : Type::None();
379 }
380 
381 
TypeBinaryOp(Node * node,BinaryTyperFun f)382 Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
383   Type* left = Operand(node, 0);
384   Type* right = Operand(node, 1);
385   return left->IsInhabited() && right->IsInhabited() ? f(left, right, typer_)
386                                                      : Type::None();
387 }
388 
389 
Invert(Type * type,Typer * t)390 Type* Typer::Visitor::Invert(Type* type, Typer* t) {
391   DCHECK(type->Is(Type::Boolean()));
392   DCHECK(type->IsInhabited());
393   if (type->Is(t->singleton_false_)) return t->singleton_true_;
394   if (type->Is(t->singleton_true_)) return t->singleton_false_;
395   return type;
396 }
397 
398 
Invert(ComparisonOutcome outcome,Typer * t)399 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
400     ComparisonOutcome outcome, Typer* t) {
401   ComparisonOutcome result(0);
402   if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
403   if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
404   if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
405   return result;
406 }
407 
408 
FalsifyUndefined(ComparisonOutcome outcome,Typer * t)409 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
410   if ((outcome & kComparisonFalse) != 0 ||
411       (outcome & kComparisonUndefined) != 0) {
412     return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
413                                             : t->singleton_false_;
414   }
415   // Type should be non empty, so we know it should be true.
416   DCHECK((outcome & kComparisonTrue) != 0);
417   return t->singleton_true_;
418 }
419 
420 // Type conversion.
421 
ToPrimitive(Type * type,Typer * t)422 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
423   if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
424     return type;
425   }
426   return Type::Primitive();
427 }
428 
429 
ToBoolean(Type * type,Typer * t)430 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
431   if (type->Is(Type::Boolean())) return type;
432   if (type->Is(t->falsish_)) return t->singleton_false_;
433   if (type->Is(t->truish_)) return t->singleton_true_;
434   if (type->Is(Type::Number())) {
435     return t->operation_typer()->NumberToBoolean(type);
436   }
437   return Type::Boolean();
438 }
439 
440 
441 // static
ToInteger(Type * type,Typer * t)442 Type* Typer::Visitor::ToInteger(Type* type, Typer* t) {
443   // ES6 section 7.1.4 ToInteger ( argument )
444   type = ToNumber(type, t);
445   if (type->Is(t->cache_.kIntegerOrMinusZero)) return type;
446   if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
447     return Type::Union(
448         Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()),
449         t->cache_.kSingletonZero, t->zone());
450   }
451   return t->cache_.kIntegerOrMinusZero;
452 }
453 
454 
455 // static
ToLength(Type * type,Typer * t)456 Type* Typer::Visitor::ToLength(Type* type, Typer* t) {
457   // ES6 section 7.1.15 ToLength ( argument )
458   type = ToInteger(type, t);
459   double min = type->Min();
460   double max = type->Max();
461   if (min <= 0.0) min = 0.0;
462   if (max > kMaxSafeInteger) max = kMaxSafeInteger;
463   if (max <= min) max = min;
464   return Type::Range(min, max, t->zone());
465 }
466 
467 
468 // static
ToName(Type * type,Typer * t)469 Type* Typer::Visitor::ToName(Type* type, Typer* t) {
470   // ES6 section 7.1.14 ToPropertyKey ( argument )
471   type = ToPrimitive(type, t);
472   if (type->Is(Type::Name())) return type;
473   if (type->Maybe(Type::Symbol())) return Type::Name();
474   return ToString(type, t);
475 }
476 
477 
478 // static
ToNumber(Type * type,Typer * t)479 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
480   return t->operation_typer_.ToNumber(type);
481 }
482 
483 
484 // static
ToObject(Type * type,Typer * t)485 Type* Typer::Visitor::ToObject(Type* type, Typer* t) {
486   // ES6 section 7.1.13 ToObject ( argument )
487   if (type->Is(Type::Receiver())) return type;
488   if (type->Is(Type::Primitive())) return Type::OtherObject();
489   if (!type->Maybe(Type::OtherUndetectable())) {
490     return Type::DetectableReceiver();
491   }
492   return Type::Receiver();
493 }
494 
495 
496 // static
ToString(Type * type,Typer * t)497 Type* Typer::Visitor::ToString(Type* type, Typer* t) {
498   // ES6 section 7.1.12 ToString ( argument )
499   type = ToPrimitive(type, t);
500   if (type->Is(Type::String())) return type;
501   return Type::String();
502 }
503 
504 // Type checks.
505 
ObjectIsDetectableCallable(Type * type,Typer * t)506 Type* Typer::Visitor::ObjectIsDetectableCallable(Type* type, Typer* t) {
507   if (type->Is(Type::DetectableCallable())) return t->singleton_true_;
508   if (!type->Maybe(Type::DetectableCallable())) return t->singleton_false_;
509   return Type::Boolean();
510 }
511 
ObjectIsNonCallable(Type * type,Typer * t)512 Type* Typer::Visitor::ObjectIsNonCallable(Type* type, Typer* t) {
513   if (type->Is(Type::NonCallable())) return t->singleton_true_;
514   if (!type->Maybe(Type::NonCallable())) return t->singleton_false_;
515   return Type::Boolean();
516 }
517 
ObjectIsNumber(Type * type,Typer * t)518 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) {
519   if (type->Is(Type::Number())) return t->singleton_true_;
520   if (!type->Maybe(Type::Number())) return t->singleton_false_;
521   return Type::Boolean();
522 }
523 
524 
ObjectIsReceiver(Type * type,Typer * t)525 Type* Typer::Visitor::ObjectIsReceiver(Type* type, Typer* t) {
526   if (type->Is(Type::Receiver())) return t->singleton_true_;
527   if (!type->Maybe(Type::Receiver())) return t->singleton_false_;
528   return Type::Boolean();
529 }
530 
531 
ObjectIsSmi(Type * type,Typer * t)532 Type* Typer::Visitor::ObjectIsSmi(Type* type, Typer* t) {
533   if (!type->Maybe(Type::SignedSmall())) return t->singleton_false_;
534   return Type::Boolean();
535 }
536 
ObjectIsString(Type * type,Typer * t)537 Type* Typer::Visitor::ObjectIsString(Type* type, Typer* t) {
538   if (type->Is(Type::String())) return t->singleton_true_;
539   if (!type->Maybe(Type::String())) return t->singleton_false_;
540   return Type::Boolean();
541 }
542 
ObjectIsUndetectable(Type * type,Typer * t)543 Type* Typer::Visitor::ObjectIsUndetectable(Type* type, Typer* t) {
544   if (type->Is(Type::Undetectable())) return t->singleton_true_;
545   if (!type->Maybe(Type::Undetectable())) return t->singleton_false_;
546   return Type::Boolean();
547 }
548 
549 
550 // -----------------------------------------------------------------------------
551 
552 
553 // Control operators.
554 
TypeStart(Node * node)555 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
556 
TypeIfException(Node * node)557 Type* Typer::Visitor::TypeIfException(Node* node) {
558   return Type::NonInternal();
559 }
560 
561 // Common operators.
562 
TypeParameter(Node * node)563 Type* Typer::Visitor::TypeParameter(Node* node) {
564   Node* const start = node->InputAt(0);
565   DCHECK_EQ(IrOpcode::kStart, start->opcode());
566   int const parameter_count = start->op()->ValueOutputCount() - 4;
567   DCHECK_LE(1, parameter_count);
568   int const index = ParameterIndexOf(node->op());
569   if (index == Linkage::kJSCallClosureParamIndex) {
570     return Type::Function();
571   } else if (index == 0) {
572     if (typer_->flags() & Typer::kThisIsReceiver) {
573       return Type::Receiver();
574     } else {
575       // Parameter[this] can be the_hole for derived class constructors.
576       return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
577     }
578   } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
579     if (typer_->flags() & Typer::kNewTargetIsReceiver) {
580       return Type::Receiver();
581     } else {
582       return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
583     }
584   } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
585     return Type::Range(0.0, Code::kMaxArguments, typer_->zone());
586   } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
587     return Type::OtherInternal();
588   }
589   return Type::NonInternal();
590 }
591 
TypeOsrValue(Node * node)592 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
593 
TypeOsrGuard(Node * node)594 Type* Typer::Visitor::TypeOsrGuard(Node* node) {
595   switch (OsrGuardTypeOf(node->op())) {
596     case OsrGuardType::kUninitialized:
597       return Type::None();
598     case OsrGuardType::kSignedSmall:
599       return Type::SignedSmall();
600     case OsrGuardType::kAny:
601       return Type::Any();
602   }
603   UNREACHABLE();
604   return nullptr;
605 }
606 
TypeRetain(Node * node)607 Type* Typer::Visitor::TypeRetain(Node* node) {
608   UNREACHABLE();
609   return nullptr;
610 }
611 
TypeInt32Constant(Node * node)612 Type* Typer::Visitor::TypeInt32Constant(Node* node) {
613   UNREACHABLE();
614   return nullptr;
615 }
616 
TypeInt64Constant(Node * node)617 Type* Typer::Visitor::TypeInt64Constant(Node* node) {
618   UNREACHABLE();
619   return nullptr;
620 }
621 
TypeRelocatableInt32Constant(Node * node)622 Type* Typer::Visitor::TypeRelocatableInt32Constant(Node* node) {
623   UNREACHABLE();
624   return nullptr;
625 }
626 
TypeRelocatableInt64Constant(Node * node)627 Type* Typer::Visitor::TypeRelocatableInt64Constant(Node* node) {
628   UNREACHABLE();
629   return nullptr;
630 }
631 
TypeFloat32Constant(Node * node)632 Type* Typer::Visitor::TypeFloat32Constant(Node* node) {
633   UNREACHABLE();
634   return nullptr;
635 }
636 
TypeFloat64Constant(Node * node)637 Type* Typer::Visitor::TypeFloat64Constant(Node* node) {
638   UNREACHABLE();
639   return nullptr;
640 }
641 
TypeNumberConstant(Node * node)642 Type* Typer::Visitor::TypeNumberConstant(Node* node) {
643   double number = OpParameter<double>(node);
644   return Type::NewConstant(number, zone());
645 }
646 
TypeHeapConstant(Node * node)647 Type* Typer::Visitor::TypeHeapConstant(Node* node) {
648   return TypeConstant(OpParameter<Handle<HeapObject>>(node));
649 }
650 
TypeExternalConstant(Node * node)651 Type* Typer::Visitor::TypeExternalConstant(Node* node) {
652   return Type::ExternalPointer();
653 }
654 
TypePointerConstant(Node * node)655 Type* Typer::Visitor::TypePointerConstant(Node* node) {
656   return Type::ExternalPointer();
657 }
658 
TypeSelect(Node * node)659 Type* Typer::Visitor::TypeSelect(Node* node) {
660   return Type::Union(Operand(node, 1), Operand(node, 2), zone());
661 }
662 
TypePhi(Node * node)663 Type* Typer::Visitor::TypePhi(Node* node) {
664   int arity = node->op()->ValueInputCount();
665   Type* type = Operand(node, 0);
666   for (int i = 1; i < arity; ++i) {
667     type = Type::Union(type, Operand(node, i), zone());
668   }
669   return type;
670 }
671 
TypeInductionVariablePhi(Node * node)672 Type* Typer::Visitor::TypeInductionVariablePhi(Node* node) {
673   int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
674   DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
675   DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());
676 
677   Type* initial_type = Operand(node, 0);
678   Type* increment_type = Operand(node, 2);
679 
680   // We only handle integer induction variables (otherwise ranges
681   // do not apply and we cannot do anything).
682   if (!initial_type->Is(typer_->cache_.kInteger) ||
683       !increment_type->Is(typer_->cache_.kInteger)) {
684     // Fallback to normal phi typing, but ensure monotonicity.
685     // (Unfortunately, without baking in the previous type, monotonicity might
686     // be violated because we might not yet have retyped the incrementing
687     // operation even though the increment's type might been already reflected
688     // in the induction variable phi.)
689     Type* type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
690                                                : Type::None();
691     for (int i = 0; i < arity; ++i) {
692       type = Type::Union(type, Operand(node, i), zone());
693     }
694     return type;
695   }
696   // If we do not have enough type information for the initial value or
697   // the increment, just return the initial value's type.
698   if (!initial_type->IsInhabited() ||
699       increment_type->Is(typer_->cache_.kSingletonZero)) {
700     return initial_type;
701   }
702 
703   // Now process the bounds.
704   auto res = induction_vars_->induction_variables().find(node->id());
705   DCHECK(res != induction_vars_->induction_variables().end());
706   InductionVariable* induction_var = res->second;
707 
708   InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
709 
710   double min = -V8_INFINITY;
711   double max = V8_INFINITY;
712 
713   double increment_min;
714   double increment_max;
715   if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
716     increment_min = increment_type->Min();
717     increment_max = increment_type->Max();
718   } else {
719     DCHECK(arithmetic_type == InductionVariable::ArithmeticType::kSubtraction);
720     increment_min = -increment_type->Max();
721     increment_max = -increment_type->Min();
722   }
723 
724   if (increment_min >= 0) {
725     // increasing sequence
726     min = initial_type->Min();
727     for (auto bound : induction_var->upper_bounds()) {
728       Type* bound_type = TypeOrNone(bound.bound);
729       // If the type is not an integer, just skip the bound.
730       if (!bound_type->Is(typer_->cache_.kInteger)) continue;
731       // If the type is not inhabited, then we can take the initial value.
732       if (!bound_type->IsInhabited()) {
733         max = initial_type->Max();
734         break;
735       }
736       double bound_max = bound_type->Max();
737       if (bound.kind == InductionVariable::kStrict) {
738         bound_max -= 1;
739       }
740       max = std::min(max, bound_max + increment_max);
741     }
742     // The upper bound must be at least the initial value's upper bound.
743     max = std::max(max, initial_type->Max());
744   } else if (increment_max <= 0) {
745     // decreasing sequence
746     max = initial_type->Max();
747     for (auto bound : induction_var->lower_bounds()) {
748       Type* bound_type = TypeOrNone(bound.bound);
749       // If the type is not an integer, just skip the bound.
750       if (!bound_type->Is(typer_->cache_.kInteger)) continue;
751       // If the type is not inhabited, then we can take the initial value.
752       if (!bound_type->IsInhabited()) {
753         min = initial_type->Min();
754         break;
755       }
756       double bound_min = bound_type->Min();
757       if (bound.kind == InductionVariable::kStrict) {
758         bound_min += 1;
759       }
760       min = std::max(min, bound_min + increment_min);
761     }
762     // The lower bound must be at most the initial value's lower bound.
763     min = std::min(min, initial_type->Min());
764   } else {
765     // Shortcut: If the increment can be both positive and negative,
766     // the variable can go arbitrarily far, so just return integer.
767     return typer_->cache_.kInteger;
768   }
769   if (FLAG_trace_turbo_loop) {
770     OFStream os(stdout);
771     os << std::setprecision(10);
772     os << "Loop (" << NodeProperties::GetControlInput(node)->id()
773        << ") variable bounds in "
774        << (arithmetic_type == InductionVariable::ArithmeticType::kAddition
775                ? "addition"
776                : "subtraction")
777        << " for phi " << node->id() << ": (" << min << ", " << max << ")\n";
778   }
779   return Type::Range(min, max, typer_->zone());
780 }
781 
TypeEffectPhi(Node * node)782 Type* Typer::Visitor::TypeEffectPhi(Node* node) {
783   UNREACHABLE();
784   return nullptr;
785 }
786 
TypeLoopExit(Node * node)787 Type* Typer::Visitor::TypeLoopExit(Node* node) {
788   UNREACHABLE();
789   return nullptr;
790 }
791 
TypeLoopExitValue(Node * node)792 Type* Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
793 
TypeLoopExitEffect(Node * node)794 Type* Typer::Visitor::TypeLoopExitEffect(Node* node) {
795   UNREACHABLE();
796   return nullptr;
797 }
798 
TypeEnsureWritableFastElements(Node * node)799 Type* Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
800   return Operand(node, 1);
801 }
802 
TypeMaybeGrowFastElements(Node * node)803 Type* Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
804   return Operand(node, 1);
805 }
806 
TypeTransitionElementsKind(Node * node)807 Type* Typer::Visitor::TypeTransitionElementsKind(Node* node) {
808   UNREACHABLE();
809   return nullptr;
810 }
811 
TypeCheckpoint(Node * node)812 Type* Typer::Visitor::TypeCheckpoint(Node* node) {
813   UNREACHABLE();
814   return nullptr;
815 }
816 
TypeBeginRegion(Node * node)817 Type* Typer::Visitor::TypeBeginRegion(Node* node) {
818   UNREACHABLE();
819   return nullptr;
820 }
821 
822 
TypeFinishRegion(Node * node)823 Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
824 
825 
TypeFrameState(Node * node)826 Type* Typer::Visitor::TypeFrameState(Node* node) {
827   // TODO(rossberg): Ideally FrameState wouldn't have a value output.
828   return Type::Internal();
829 }
830 
TypeStateValues(Node * node)831 Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
832 
TypeTypedStateValues(Node * node)833 Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
834   return Type::Internal();
835 }
836 
TypeArgumentsObjectState(Node * node)837 Type* Typer::Visitor::TypeArgumentsObjectState(Node* node) {
838   return Type::Internal();
839 }
840 
TypeObjectState(Node * node)841 Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
842 
TypeTypedObjectState(Node * node)843 Type* Typer::Visitor::TypeTypedObjectState(Node* node) {
844   return Type::Internal();
845 }
846 
TypeCall(Node * node)847 Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
848 
849 
TypeProjection(Node * node)850 Type* Typer::Visitor::TypeProjection(Node* node) {
851   Type* const type = Operand(node, 0);
852   if (type->Is(Type::None())) return Type::None();
853   int const index = static_cast<int>(ProjectionIndexOf(node->op()));
854   if (type->IsTuple() && index < type->AsTuple()->Arity()) {
855     return type->AsTuple()->Element(index);
856   }
857   return Type::Any();
858 }
859 
TypeTypeGuard(Node * node)860 Type* Typer::Visitor::TypeTypeGuard(Node* node) {
861   Type* const type = Operand(node, 0);
862   return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
863 }
864 
TypeDead(Node * node)865 Type* Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
866 
867 // JS comparison operators.
868 
869 
JSEqualTyper(Type * lhs,Type * rhs,Typer * t)870 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
871   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
872   if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) {
873     return t->singleton_true_;
874   }
875   if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
876       (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
877     return t->singleton_false_;
878   }
879   if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
880     // Types are equal and are inhabited only by a single semantic value,
881     // which is not nan due to the earlier check.
882     return t->singleton_true_;
883   }
884   return Type::Boolean();
885 }
886 
887 
JSNotEqualTyper(Type * lhs,Type * rhs,Typer * t)888 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
889   return Invert(JSEqualTyper(lhs, rhs, t), t);
890 }
891 
892 
JSType(Type * type)893 static Type* JSType(Type* type) {
894   if (type->Is(Type::Boolean())) return Type::Boolean();
895   if (type->Is(Type::String())) return Type::String();
896   if (type->Is(Type::Number())) return Type::Number();
897   if (type->Is(Type::Undefined())) return Type::Undefined();
898   if (type->Is(Type::Null())) return Type::Null();
899   if (type->Is(Type::Symbol())) return Type::Symbol();
900   if (type->Is(Type::Receiver())) return Type::Receiver();  // JS "Object"
901   return Type::Any();
902 }
903 
904 
JSStrictEqualTyper(Type * lhs,Type * rhs,Typer * t)905 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
906   if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_;
907   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
908   if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
909       (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
910     return t->singleton_false_;
911   }
912   if ((lhs->Is(Type::Hole()) || rhs->Is(Type::Hole())) && !lhs->Maybe(rhs)) {
913     return t->singleton_false_;
914   }
915   if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
916     // Types are equal and are inhabited only by a single semantic value,
917     // which is not nan due to the earlier check.
918     return t->singleton_true_;
919   }
920   return Type::Boolean();
921 }
922 
923 
JSStrictNotEqualTyper(Type * lhs,Type * rhs,Typer * t)924 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
925   return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
926 }
927 
928 
929 // The EcmaScript specification defines the four relational comparison operators
930 // (<, <=, >=, >) with the help of a single abstract one.  It behaves like <
931 // but returns undefined when the inputs cannot be compared.
932 // We implement the typing analogously.
JSCompareTyper(Type * lhs,Type * rhs,Typer * t)933 Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs,
934                                                                  Type* rhs,
935                                                                  Typer* t) {
936   lhs = ToPrimitive(lhs, t);
937   rhs = ToPrimitive(rhs, t);
938   if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
939     return ComparisonOutcome(kComparisonTrue) |
940            ComparisonOutcome(kComparisonFalse);
941   }
942   lhs = ToNumber(lhs, t);
943   rhs = ToNumber(rhs, t);
944 
945   // Shortcut for NaNs.
946   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;
947 
948   ComparisonOutcome result;
949   if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
950     // Types are equal and are inhabited only by a single semantic value.
951     result = kComparisonFalse;
952   } else if (lhs->Min() >= rhs->Max()) {
953     result = kComparisonFalse;
954   } else if (lhs->Max() < rhs->Min()) {
955     result = kComparisonTrue;
956   } else {
957     // We cannot figure out the result, return both true and false. (We do not
958     // have to return undefined because that cannot affect the result of
959     // FalsifyUndefined.)
960     return ComparisonOutcome(kComparisonTrue) |
961            ComparisonOutcome(kComparisonFalse);
962   }
963   // Add the undefined if we could see NaN.
964   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
965     result |= kComparisonUndefined;
966   }
967   return result;
968 }
969 
970 
JSLessThanTyper(Type * lhs,Type * rhs,Typer * t)971 Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
972   return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
973 }
974 
975 
JSGreaterThanTyper(Type * lhs,Type * rhs,Typer * t)976 Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
977   return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
978 }
979 
980 
JSLessThanOrEqualTyper(Type * lhs,Type * rhs,Typer * t)981 Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
982   return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
983 }
984 
985 
JSGreaterThanOrEqualTyper(Type * lhs,Type * rhs,Typer * t)986 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
987     Type* lhs, Type* rhs, Typer* t) {
988   return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
989 }
990 
991 // JS bitwise operators.
992 
993 
JSBitwiseOrTyper(Type * lhs,Type * rhs,Typer * t)994 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
995   return NumberBitwiseOr(ToNumber(lhs, t), ToNumber(rhs, t), t);
996 }
997 
998 
JSBitwiseAndTyper(Type * lhs,Type * rhs,Typer * t)999 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
1000   return NumberBitwiseAnd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1001 }
1002 
1003 
JSBitwiseXorTyper(Type * lhs,Type * rhs,Typer * t)1004 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
1005   return NumberBitwiseXor(ToNumber(lhs, t), ToNumber(rhs, t), t);
1006 }
1007 
1008 
JSShiftLeftTyper(Type * lhs,Type * rhs,Typer * t)1009 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
1010   return NumberShiftLeft(ToNumber(lhs, t), ToNumber(rhs, t), t);
1011 }
1012 
1013 
JSShiftRightTyper(Type * lhs,Type * rhs,Typer * t)1014 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
1015   return NumberShiftRight(ToNumber(lhs, t), ToNumber(rhs, t), t);
1016 }
1017 
1018 
JSShiftRightLogicalTyper(Type * lhs,Type * rhs,Typer * t)1019 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
1020   return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1021 }
1022 
1023 
1024 // JS arithmetic operators.
1025 
JSAddTyper(Type * lhs,Type * rhs,Typer * t)1026 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
1027   lhs = ToPrimitive(lhs, t);
1028   rhs = ToPrimitive(rhs, t);
1029   if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
1030     if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
1031       return Type::String();
1032     } else {
1033       return Type::NumberOrString();
1034     }
1035   }
1036   // The addition must be numeric.
1037   return NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1038 }
1039 
JSSubtractTyper(Type * lhs,Type * rhs,Typer * t)1040 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
1041   return NumberSubtract(ToNumber(lhs, t), ToNumber(rhs, t), t);
1042 }
1043 
JSMultiplyTyper(Type * lhs,Type * rhs,Typer * t)1044 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1045   return NumberMultiply(ToNumber(lhs, t), ToNumber(rhs, t), t);
1046 }
1047 
JSDivideTyper(Type * lhs,Type * rhs,Typer * t)1048 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
1049   return NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t), t);
1050 }
1051 
JSModulusTyper(Type * lhs,Type * rhs,Typer * t)1052 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1053   return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t);
1054 }
1055 
1056 
1057 // JS unary operators.
1058 
TypeJSClassOf(Node * node)1059 Type* Typer::Visitor::TypeJSClassOf(Node* node) {
1060   return Type::InternalizedStringOrNull();
1061 }
1062 
TypeJSTypeOf(Node * node)1063 Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
1064   return Type::InternalizedString();
1065 }
1066 
1067 
1068 // JS conversion operators.
1069 
1070 
TypeJSToBoolean(Node * node)1071 Type* Typer::Visitor::TypeJSToBoolean(Node* node) {
1072   return TypeUnaryOp(node, ToBoolean);
1073 }
1074 
TypeJSToInteger(Node * node)1075 Type* Typer::Visitor::TypeJSToInteger(Node* node) {
1076   return TypeUnaryOp(node, ToInteger);
1077 }
1078 
TypeJSToLength(Node * node)1079 Type* Typer::Visitor::TypeJSToLength(Node* node) {
1080   return TypeUnaryOp(node, ToLength);
1081 }
1082 
TypeJSToName(Node * node)1083 Type* Typer::Visitor::TypeJSToName(Node* node) {
1084   return TypeUnaryOp(node, ToName);
1085 }
1086 
TypeJSToNumber(Node * node)1087 Type* Typer::Visitor::TypeJSToNumber(Node* node) {
1088   return TypeUnaryOp(node, ToNumber);
1089 }
1090 
TypeJSToObject(Node * node)1091 Type* Typer::Visitor::TypeJSToObject(Node* node) {
1092   return TypeUnaryOp(node, ToObject);
1093 }
1094 
TypeJSToString(Node * node)1095 Type* Typer::Visitor::TypeJSToString(Node* node) {
1096   return TypeUnaryOp(node, ToString);
1097 }
1098 
1099 // JS object operators.
1100 
1101 
TypeJSCreate(Node * node)1102 Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1103 
1104 
TypeJSCreateArguments(Node * node)1105 Type* Typer::Visitor::TypeJSCreateArguments(Node* node) {
1106   return Type::OtherObject();
1107 }
1108 
1109 
TypeJSCreateArray(Node * node)1110 Type* Typer::Visitor::TypeJSCreateArray(Node* node) {
1111   return Type::OtherObject();
1112 }
1113 
1114 
TypeJSCreateClosure(Node * node)1115 Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
1116   return Type::Function();
1117 }
1118 
1119 
TypeJSCreateIterResultObject(Node * node)1120 Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1121   return Type::OtherObject();
1122 }
1123 
TypeJSCreateKeyValueArray(Node * node)1124 Type* Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1125   return Type::OtherObject();
1126 }
1127 
TypeJSCreateLiteralArray(Node * node)1128 Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1129   return Type::OtherObject();
1130 }
1131 
1132 
TypeJSCreateLiteralObject(Node * node)1133 Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1134   return Type::OtherObject();
1135 }
1136 
1137 
TypeJSCreateLiteralRegExp(Node * node)1138 Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1139   return Type::OtherObject();
1140 }
1141 
1142 
TypeJSLoadProperty(Node * node)1143 Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
1144   return Type::NonInternal();
1145 }
1146 
1147 
TypeJSLoadNamed(Node * node)1148 Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
1149   return Type::NonInternal();
1150 }
1151 
TypeJSLoadGlobal(Node * node)1152 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1153   return Type::NonInternal();
1154 }
1155 
1156 // Returns a somewhat larger range if we previously assigned
1157 // a (smaller) range to this node. This is used  to speed up
1158 // the fixpoint calculation in case there appears to be a loop
1159 // in the graph. In the current implementation, we are
1160 // increasing the limits to the closest power of two.
Weaken(Node * node,Type * current_type,Type * previous_type)1161 Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
1162                              Type* previous_type) {
1163   static const double kWeakenMinLimits[] = {
1164       0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1165       -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1166       -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1167       -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1168       -70368744177664.0, -140737488355328.0, -281474976710656.0,
1169       -562949953421312.0};
1170   static const double kWeakenMaxLimits[] = {
1171       0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1172       17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1173       274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1174       4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1175       70368744177663.0, 140737488355327.0, 281474976710655.0,
1176       562949953421311.0};
1177   STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1178 
1179   // If the types have nothing to do with integers, return the types.
1180   Type* const integer = typer_->cache_.kInteger;
1181   if (!previous_type->Maybe(integer)) {
1182     return current_type;
1183   }
1184   DCHECK(current_type->Maybe(integer));
1185 
1186   Type* current_integer = Type::Intersect(current_type, integer, zone());
1187   Type* previous_integer = Type::Intersect(previous_type, integer, zone());
1188 
1189   // Once we start weakening a node, we should always weaken.
1190   if (!IsWeakened(node->id())) {
1191     // Only weaken if there is range involved; we should converge quickly
1192     // for all other types (the exception is a union of many constants,
1193     // but we currently do not increase the number of constants in unions).
1194     Type* previous = previous_integer->GetRange();
1195     Type* current = current_integer->GetRange();
1196     if (current == nullptr || previous == nullptr) {
1197       return current_type;
1198     }
1199     // Range is involved => we are weakening.
1200     SetWeakened(node->id());
1201   }
1202 
1203   double current_min = current_integer->Min();
1204   double new_min = current_min;
1205   // Find the closest lower entry in the list of allowed
1206   // minima (or negative infinity if there is no such entry).
1207   if (current_min != previous_integer->Min()) {
1208     new_min = -V8_INFINITY;
1209     for (double const min : kWeakenMinLimits) {
1210       if (min <= current_min) {
1211         new_min = min;
1212         break;
1213       }
1214     }
1215   }
1216 
1217   double current_max = current_integer->Max();
1218   double new_max = current_max;
1219   // Find the closest greater entry in the list of allowed
1220   // maxima (or infinity if there is no such entry).
1221   if (current_max != previous_integer->Max()) {
1222     new_max = V8_INFINITY;
1223     for (double const max : kWeakenMaxLimits) {
1224       if (max >= current_max) {
1225         new_max = max;
1226         break;
1227       }
1228     }
1229   }
1230 
1231   return Type::Union(current_type,
1232                      Type::Range(new_min, new_max, typer_->zone()),
1233                      typer_->zone());
1234 }
1235 
1236 
TypeJSStoreProperty(Node * node)1237 Type* Typer::Visitor::TypeJSStoreProperty(Node* node) {
1238   UNREACHABLE();
1239   return nullptr;
1240 }
1241 
1242 
TypeJSStoreNamed(Node * node)1243 Type* Typer::Visitor::TypeJSStoreNamed(Node* node) {
1244   UNREACHABLE();
1245   return nullptr;
1246 }
1247 
1248 
TypeJSStoreGlobal(Node * node)1249 Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
1250   UNREACHABLE();
1251   return nullptr;
1252 }
1253 
TypeJSStoreNamedOwn(Node * node)1254 Type* Typer::Visitor::TypeJSStoreNamedOwn(Node* node) {
1255   UNREACHABLE();
1256   return nullptr;
1257 }
1258 
TypeJSStoreDataPropertyInLiteral(Node * node)1259 Type* Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1260   UNREACHABLE();
1261   return nullptr;
1262 }
1263 
TypeJSDeleteProperty(Node * node)1264 Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1265   return Type::Boolean();
1266 }
1267 
TypeJSHasProperty(Node * node)1268 Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1269 
1270 // JS instanceof operator.
1271 
JSInstanceOfTyper(Type * lhs,Type * rhs,Typer * t)1272 Type* Typer::Visitor::JSInstanceOfTyper(Type* lhs, Type* rhs, Typer* t) {
1273   return Type::Boolean();
1274 }
1275 
JSOrdinaryHasInstanceTyper(Type * lhs,Type * rhs,Typer * t)1276 Type* Typer::Visitor::JSOrdinaryHasInstanceTyper(Type* lhs, Type* rhs,
1277                                                  Typer* t) {
1278   return Type::Boolean();
1279 }
1280 
TypeJSGetSuperConstructor(Node * node)1281 Type* Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1282   return Type::Callable();
1283 }
1284 
1285 // JS context operators.
1286 
1287 
TypeJSLoadContext(Node * node)1288 Type* Typer::Visitor::TypeJSLoadContext(Node* node) {
1289   ContextAccess const& access = ContextAccessOf(node->op());
1290   switch (access.index()) {
1291     case Context::PREVIOUS_INDEX:
1292     case Context::NATIVE_CONTEXT_INDEX:
1293       return Type::OtherInternal();
1294     case Context::CLOSURE_INDEX:
1295       return Type::Function();
1296     default:
1297       return Type::Any();
1298   }
1299 }
1300 
1301 
TypeJSStoreContext(Node * node)1302 Type* Typer::Visitor::TypeJSStoreContext(Node* node) {
1303   UNREACHABLE();
1304   return nullptr;
1305 }
1306 
1307 
TypeJSCreateFunctionContext(Node * node)1308 Type* Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1309   return Type::OtherInternal();
1310 }
1311 
TypeJSCreateCatchContext(Node * node)1312 Type* Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1313   return Type::OtherInternal();
1314 }
1315 
TypeJSCreateWithContext(Node * node)1316 Type* Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1317   return Type::OtherInternal();
1318 }
1319 
TypeJSCreateBlockContext(Node * node)1320 Type* Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1321   return Type::OtherInternal();
1322 }
1323 
TypeJSCreateScriptContext(Node * node)1324 Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
1325   return Type::OtherInternal();
1326 }
1327 
1328 // JS other operators.
1329 
TypeJSConstruct(Node * node)1330 Type* Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1331 
TypeJSConstructWithSpread(Node * node)1332 Type* Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1333   return Type::Receiver();
1334 }
1335 
JSCallTyper(Type * fun,Typer * t)1336 Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) {
1337   if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
1338     Handle<JSFunction> function =
1339         Handle<JSFunction>::cast(fun->AsHeapConstant()->Value());
1340     if (function->shared()->HasBuiltinFunctionId()) {
1341       switch (function->shared()->builtin_function_id()) {
1342         case kMathRandom:
1343           return Type::PlainNumber();
1344         case kMathFloor:
1345         case kMathCeil:
1346         case kMathRound:
1347         case kMathTrunc:
1348           return t->cache_.kIntegerOrMinusZeroOrNaN;
1349         // Unary math functions.
1350         case kMathAbs:
1351         case kMathExp:
1352         case kMathExpm1:
1353           return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1354         case kMathAcos:
1355         case kMathAcosh:
1356         case kMathAsin:
1357         case kMathAsinh:
1358         case kMathAtan:
1359         case kMathAtanh:
1360         case kMathCbrt:
1361         case kMathCos:
1362         case kMathFround:
1363         case kMathLog:
1364         case kMathLog1p:
1365         case kMathLog10:
1366         case kMathLog2:
1367         case kMathSin:
1368         case kMathSqrt:
1369         case kMathTan:
1370           return Type::Number();
1371         case kMathSign:
1372           return t->cache_.kMinusOneToOneOrMinusZeroOrNaN;
1373         // Binary math functions.
1374         case kMathAtan2:
1375         case kMathPow:
1376         case kMathMax:
1377         case kMathMin:
1378           return Type::Number();
1379         case kMathImul:
1380           return Type::Signed32();
1381         case kMathClz32:
1382           return t->cache_.kZeroToThirtyTwo;
1383         // Date functions.
1384         case kDateNow:
1385           return t->cache_.kTimeValueType;
1386         case kDateGetDate:
1387           return t->cache_.kJSDateDayType;
1388         case kDateGetDay:
1389           return t->cache_.kJSDateWeekdayType;
1390         case kDateGetFullYear:
1391           return t->cache_.kJSDateYearType;
1392         case kDateGetHours:
1393           return t->cache_.kJSDateHourType;
1394         case kDateGetMilliseconds:
1395           return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1396                              t->zone());
1397         case kDateGetMinutes:
1398           return t->cache_.kJSDateMinuteType;
1399         case kDateGetMonth:
1400           return t->cache_.kJSDateMonthType;
1401         case kDateGetSeconds:
1402           return t->cache_.kJSDateSecondType;
1403         case kDateGetTime:
1404           return t->cache_.kJSDateValueType;
1405 
1406         // Number functions.
1407         case kNumberIsFinite:
1408         case kNumberIsInteger:
1409         case kNumberIsNaN:
1410         case kNumberIsSafeInteger:
1411           return Type::Boolean();
1412         case kNumberParseFloat:
1413           return Type::Number();
1414         case kNumberParseInt:
1415           return t->cache_.kIntegerOrMinusZeroOrNaN;
1416         case kNumberToString:
1417           return Type::String();
1418 
1419         // String functions.
1420         case kStringCharCodeAt:
1421           return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1422                              t->zone());
1423         case kStringCharAt:
1424           return Type::String();
1425         case kStringCodePointAt:
1426           return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1427                              Type::Undefined(), t->zone());
1428         case kStringConcat:
1429         case kStringFromCharCode:
1430         case kStringFromCodePoint:
1431           return Type::String();
1432         case kStringIndexOf:
1433         case kStringLastIndexOf:
1434           return Type::Range(-1.0, String::kMaxLength, t->zone());
1435         case kStringEndsWith:
1436         case kStringIncludes:
1437           return Type::Boolean();
1438         case kStringRaw:
1439         case kStringRepeat:
1440         case kStringSlice:
1441           return Type::String();
1442         case kStringStartsWith:
1443           return Type::Boolean();
1444         case kStringSubstr:
1445         case kStringSubstring:
1446         case kStringToLowerCase:
1447         case kStringToString:
1448         case kStringToUpperCase:
1449         case kStringTrim:
1450         case kStringTrimLeft:
1451         case kStringTrimRight:
1452         case kStringValueOf:
1453           return Type::String();
1454 
1455         case kStringIterator:
1456         case kStringIteratorNext:
1457           return Type::OtherObject();
1458 
1459         case kArrayEntries:
1460         case kArrayKeys:
1461         case kArrayValues:
1462         case kTypedArrayEntries:
1463         case kTypedArrayKeys:
1464         case kTypedArrayValues:
1465         case kArrayIteratorNext:
1466           return Type::OtherObject();
1467 
1468         // Array functions.
1469         case kArrayIsArray:
1470           return Type::Boolean();
1471         case kArrayConcat:
1472           return Type::Receiver();
1473         case kArrayEvery:
1474           return Type::Boolean();
1475         case kArrayFill:
1476         case kArrayFilter:
1477           return Type::Receiver();
1478         case kArrayFindIndex:
1479           return Type::Range(-1, kMaxSafeInteger, t->zone());
1480         case kArrayForEach:
1481           return Type::Undefined();
1482         case kArrayIncludes:
1483           return Type::Boolean();
1484         case kArrayIndexOf:
1485           return Type::Range(-1, kMaxSafeInteger, t->zone());
1486         case kArrayJoin:
1487           return Type::String();
1488         case kArrayLastIndexOf:
1489           return Type::Range(-1, kMaxSafeInteger, t->zone());
1490         case kArrayMap:
1491           return Type::Receiver();
1492         case kArrayPush:
1493           return t->cache_.kPositiveSafeInteger;
1494         case kArrayReverse:
1495         case kArraySlice:
1496           return Type::Receiver();
1497         case kArraySome:
1498           return Type::Boolean();
1499         case kArraySplice:
1500           return Type::Receiver();
1501         case kArrayUnshift:
1502           return t->cache_.kPositiveSafeInteger;
1503 
1504         // Object functions.
1505         case kObjectAssign:
1506         case kObjectCreate:
1507           return Type::OtherObject();
1508         case kObjectHasOwnProperty:
1509           return Type::Boolean();
1510         case kObjectToString:
1511           return Type::String();
1512 
1513         // RegExp functions.
1514         case kRegExpCompile:
1515           return Type::OtherObject();
1516         case kRegExpExec:
1517           return Type::Union(Type::OtherObject(), Type::Null(), t->zone());
1518         case kRegExpTest:
1519           return Type::Boolean();
1520         case kRegExpToString:
1521           return Type::String();
1522 
1523         // Function functions.
1524         case kFunctionHasInstance:
1525           return Type::Boolean();
1526 
1527         // Global functions.
1528         case kGlobalDecodeURI:
1529         case kGlobalDecodeURIComponent:
1530         case kGlobalEncodeURI:
1531         case kGlobalEncodeURIComponent:
1532         case kGlobalEscape:
1533         case kGlobalUnescape:
1534           return Type::String();
1535         case kGlobalIsFinite:
1536         case kGlobalIsNaN:
1537           return Type::Boolean();
1538 
1539         // Map functions.
1540         case kMapClear:
1541         case kMapForEach:
1542           return Type::Undefined();
1543         case kMapDelete:
1544         case kMapHas:
1545           return Type::Boolean();
1546         case kMapEntries:
1547         case kMapKeys:
1548         case kMapSet:
1549         case kMapValues:
1550           return Type::OtherObject();
1551 
1552         // Set functions.
1553         case kSetAdd:
1554         case kSetEntries:
1555         case kSetKeys:
1556         case kSetValues:
1557           return Type::OtherObject();
1558         case kSetClear:
1559         case kSetForEach:
1560           return Type::Undefined();
1561         case kSetDelete:
1562         case kSetHas:
1563           return Type::Boolean();
1564 
1565         // WeakMap functions.
1566         case kWeakMapDelete:
1567         case kWeakMapHas:
1568           return Type::Boolean();
1569         case kWeakMapSet:
1570           return Type::OtherObject();
1571 
1572         // WeakSet functions.
1573         case kWeakSetAdd:
1574           return Type::OtherObject();
1575         case kWeakSetDelete:
1576         case kWeakSetHas:
1577           return Type::Boolean();
1578         default:
1579           break;
1580       }
1581     }
1582   }
1583   return Type::NonInternal();
1584 }
1585 
TypeJSCallForwardVarargs(Node * node)1586 Type* Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1587   return TypeUnaryOp(node, JSCallTyper);
1588 }
1589 
TypeJSCall(Node * node)1590 Type* Typer::Visitor::TypeJSCall(Node* node) {
1591   // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1592   // argument types for the JSCallTyper above.
1593   return TypeUnaryOp(node, JSCallTyper);
1594 }
1595 
TypeJSCallWithSpread(Node * node)1596 Type* Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1597   return TypeUnaryOp(node, JSCallTyper);
1598 }
1599 
TypeJSCallRuntime(Node * node)1600 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
1601   switch (CallRuntimeParametersOf(node->op()).id()) {
1602     case Runtime::kInlineIsJSReceiver:
1603       return TypeUnaryOp(node, ObjectIsReceiver);
1604     case Runtime::kInlineIsSmi:
1605       return TypeUnaryOp(node, ObjectIsSmi);
1606     case Runtime::kInlineIsArray:
1607     case Runtime::kInlineIsDate:
1608     case Runtime::kInlineIsTypedArray:
1609     case Runtime::kInlineIsRegExp:
1610       return Type::Boolean();
1611     case Runtime::kInlineCreateIterResultObject:
1612       return Type::OtherObject();
1613     case Runtime::kInlineSubString:
1614     case Runtime::kInlineStringCharFromCode:
1615       return Type::String();
1616     case Runtime::kInlineToInteger:
1617       return TypeUnaryOp(node, ToInteger);
1618     case Runtime::kInlineToLength:
1619       return TypeUnaryOp(node, ToLength);
1620     case Runtime::kInlineToNumber:
1621       return TypeUnaryOp(node, ToNumber);
1622     case Runtime::kInlineToObject:
1623       return TypeUnaryOp(node, ToObject);
1624     case Runtime::kInlineToString:
1625       return TypeUnaryOp(node, ToString);
1626     case Runtime::kInlineClassOf:
1627       return Type::InternalizedStringOrNull();
1628     case Runtime::kHasInPrototypeChain:
1629       return Type::Boolean();
1630     default:
1631       break;
1632   }
1633   // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1634   // have a few weird runtime calls that return the hole or even FixedArrays;
1635   // change this once those weird runtime calls have been removed.
1636   return Type::Any();
1637 }
1638 
1639 
TypeJSConvertReceiver(Node * node)1640 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) {
1641   return Type::Receiver();
1642 }
1643 
1644 
TypeJSForInNext(Node * node)1645 Type* Typer::Visitor::TypeJSForInNext(Node* node) {
1646   return Type::Union(Type::String(), Type::Undefined(), zone());
1647 }
1648 
1649 
TypeJSForInPrepare(Node * node)1650 Type* Typer::Visitor::TypeJSForInPrepare(Node* node) {
1651   STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1652   Type* const cache_type =
1653       Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1654   Type* const cache_array = Type::OtherInternal();
1655   Type* const cache_length = typer_->cache_.kFixedArrayLengthType;
1656   return Type::Tuple(cache_type, cache_array, cache_length, zone());
1657 }
1658 
1659 
TypeJSLoadMessage(Node * node)1660 Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1661 
1662 
TypeJSStoreMessage(Node * node)1663 Type* Typer::Visitor::TypeJSStoreMessage(Node* node) {
1664   UNREACHABLE();
1665   return nullptr;
1666 }
1667 
TypeJSLoadModule(Node * node)1668 Type* Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1669 
TypeJSStoreModule(Node * node)1670 Type* Typer::Visitor::TypeJSStoreModule(Node* node) {
1671   UNREACHABLE();
1672   return nullptr;
1673 }
1674 
TypeJSGeneratorStore(Node * node)1675 Type* Typer::Visitor::TypeJSGeneratorStore(Node* node) {
1676   UNREACHABLE();
1677   return nullptr;
1678 }
1679 
TypeJSGeneratorRestoreContinuation(Node * node)1680 Type* Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1681   return Type::SignedSmall();
1682 }
1683 
TypeJSGeneratorRestoreRegister(Node * node)1684 Type* Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1685   return Type::Any();
1686 }
1687 
TypeJSStackCheck(Node * node)1688 Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1689 
TypeJSDebugger(Node * node)1690 Type* Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1691 
1692 // Simplified operators.
1693 
TypeBooleanNot(Node * node)1694 Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1695 
TypeNumberEqual(Node * node)1696 Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); }
1697 
TypeNumberLessThan(Node * node)1698 Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); }
1699 
TypeNumberLessThanOrEqual(Node * node)1700 Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1701   return Type::Boolean();
1702 }
1703 
TypeSpeculativeNumberEqual(Node * node)1704 Type* Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1705   return Type::Boolean();
1706 }
1707 
TypeSpeculativeNumberLessThan(Node * node)1708 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1709   return Type::Boolean();
1710 }
1711 
TypeSpeculativeNumberLessThanOrEqual(Node * node)1712 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1713   return Type::Boolean();
1714 }
1715 
TypePlainPrimitiveToNumber(Node * node)1716 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1717   return TypeUnaryOp(node, ToNumber);
1718 }
1719 
TypePlainPrimitiveToWord32(Node * node)1720 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1721   return Type::Integral32();
1722 }
1723 
TypePlainPrimitiveToFloat64(Node * node)1724 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1725   return Type::Number();
1726 }
1727 
1728 // static
ReferenceEqualTyper(Type * lhs,Type * rhs,Typer * t)1729 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1730   if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
1731     return t->singleton_true_;
1732   }
1733   return Type::Boolean();
1734 }
1735 
1736 
TypeReferenceEqual(Node * node)1737 Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
1738   return TypeBinaryOp(node, ReferenceEqualTyper);
1739 }
1740 
TypeStringEqual(Node * node)1741 Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1742 
TypeStringLessThan(Node * node)1743 Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1744 
TypeStringLessThanOrEqual(Node * node)1745 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1746   return Type::Boolean();
1747 }
1748 
StringFromCharCodeTyper(Type * type,Typer * t)1749 Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) {
1750   return Type::String();
1751 }
1752 
StringFromCodePointTyper(Type * type,Typer * t)1753 Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) {
1754   return Type::String();
1755 }
1756 
TypeStringCharAt(Node * node)1757 Type* Typer::Visitor::TypeStringCharAt(Node* node) { return Type::String(); }
1758 
TypeStringCharCodeAt(Node * node)1759 Type* Typer::Visitor::TypeStringCharCodeAt(Node* node) {
1760   return typer_->cache_.kUint16;
1761 }
1762 
TypeStringFromCharCode(Node * node)1763 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
1764   return TypeUnaryOp(node, StringFromCharCodeTyper);
1765 }
1766 
TypeStringFromCodePoint(Node * node)1767 Type* Typer::Visitor::TypeStringFromCodePoint(Node* node) {
1768   return TypeUnaryOp(node, StringFromCodePointTyper);
1769 }
1770 
TypeStringIndexOf(Node * node)1771 Type* Typer::Visitor::TypeStringIndexOf(Node* node) {
1772   return Type::Range(-1.0, String::kMaxLength - 1.0, zone());
1773 }
1774 
TypeCheckBounds(Node * node)1775 Type* Typer::Visitor::TypeCheckBounds(Node* node) {
1776   Type* index = Operand(node, 0);
1777   Type* length = Operand(node, 1);
1778   index = Type::Intersect(index, Type::Integral32(), zone());
1779   if (!index->IsInhabited() || !length->IsInhabited()) return Type::None();
1780   double min = std::max(index->Min(), 0.0);
1781   double max = std::min(index->Max(), length->Max() - 1);
1782   if (max < min) return Type::None();
1783   return Type::Range(min, max, zone());
1784 }
1785 
TypeCheckHeapObject(Node * node)1786 Type* Typer::Visitor::TypeCheckHeapObject(Node* node) {
1787   Type* type = Operand(node, 0);
1788   return type;
1789 }
1790 
TypeCheckIf(Node * node)1791 Type* Typer::Visitor::TypeCheckIf(Node* node) {
1792   UNREACHABLE();
1793   return nullptr;
1794 }
1795 
TypeCheckInternalizedString(Node * node)1796 Type* Typer::Visitor::TypeCheckInternalizedString(Node* node) {
1797   Type* arg = Operand(node, 0);
1798   return Type::Intersect(arg, Type::InternalizedString(), zone());
1799 }
1800 
TypeCheckMaps(Node * node)1801 Type* Typer::Visitor::TypeCheckMaps(Node* node) {
1802   UNREACHABLE();
1803   return nullptr;
1804 }
1805 
TypeCheckNumber(Node * node)1806 Type* Typer::Visitor::TypeCheckNumber(Node* node) {
1807   Type* arg = Operand(node, 0);
1808   return Type::Intersect(arg, Type::Number(), zone());
1809 }
1810 
TypeCheckReceiver(Node * node)1811 Type* Typer::Visitor::TypeCheckReceiver(Node* node) {
1812   Type* arg = Operand(node, 0);
1813   return Type::Intersect(arg, Type::Receiver(), zone());
1814 }
1815 
TypeCheckSmi(Node * node)1816 Type* Typer::Visitor::TypeCheckSmi(Node* node) {
1817   Type* arg = Operand(node, 0);
1818   return Type::Intersect(arg, Type::SignedSmall(), zone());
1819 }
1820 
TypeCheckString(Node * node)1821 Type* Typer::Visitor::TypeCheckString(Node* node) {
1822   Type* arg = Operand(node, 0);
1823   return Type::Intersect(arg, Type::String(), zone());
1824 }
1825 
TypeCheckFloat64Hole(Node * node)1826 Type* Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
1827   Type* type = Operand(node, 0);
1828   return type;
1829 }
1830 
TypeCheckTaggedHole(Node * node)1831 Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) {
1832   Type* type = Operand(node, 0);
1833   type = Type::Intersect(type, Type::NonInternal(), zone());
1834   return type;
1835 }
1836 
TypeConvertTaggedHoleToUndefined(Node * node)1837 Type* Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
1838   Type* type = Operand(node, 0);
1839   if (type->Maybe(Type::Hole())) {
1840     // Turn "the hole" into undefined.
1841     type = Type::Intersect(type, Type::NonInternal(), zone());
1842     type = Type::Union(type, Type::Undefined(), zone());
1843   }
1844   return type;
1845 }
1846 
TypeAllocate(Node * node)1847 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::Any(); }
1848 
TypeLoadField(Node * node)1849 Type* Typer::Visitor::TypeLoadField(Node* node) {
1850   return FieldAccessOf(node->op()).type;
1851 }
1852 
TypeLoadBuffer(Node * node)1853 Type* Typer::Visitor::TypeLoadBuffer(Node* node) {
1854   switch (BufferAccessOf(node->op()).external_array_type()) {
1855 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \
1856   case kExternal##ElemType##Array:                          \
1857     return Type::Union(typer_->cache_.k##ElemType, Type::Undefined(), zone());
1858     TYPED_ARRAYS(TYPED_ARRAY_CASE)
1859 #undef TYPED_ARRAY_CASE
1860   }
1861   UNREACHABLE();
1862   return nullptr;
1863 }
1864 
1865 
TypeLoadElement(Node * node)1866 Type* Typer::Visitor::TypeLoadElement(Node* node) {
1867   return ElementAccessOf(node->op()).type;
1868 }
1869 
TypeLoadTypedElement(Node * node)1870 Type* Typer::Visitor::TypeLoadTypedElement(Node* node) {
1871   switch (ExternalArrayTypeOf(node->op())) {
1872 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \
1873   case kExternal##ElemType##Array:                          \
1874     return typer_->cache_.k##ElemType;
1875     TYPED_ARRAYS(TYPED_ARRAY_CASE)
1876 #undef TYPED_ARRAY_CASE
1877   }
1878   UNREACHABLE();
1879   return nullptr;
1880 }
1881 
TypeStoreField(Node * node)1882 Type* Typer::Visitor::TypeStoreField(Node* node) {
1883   UNREACHABLE();
1884   return nullptr;
1885 }
1886 
1887 
TypeStoreBuffer(Node * node)1888 Type* Typer::Visitor::TypeStoreBuffer(Node* node) {
1889   UNREACHABLE();
1890   return nullptr;
1891 }
1892 
1893 
TypeStoreElement(Node * node)1894 Type* Typer::Visitor::TypeStoreElement(Node* node) {
1895   UNREACHABLE();
1896   return nullptr;
1897 }
1898 
TypeStoreTypedElement(Node * node)1899 Type* Typer::Visitor::TypeStoreTypedElement(Node* node) {
1900   UNREACHABLE();
1901   return nullptr;
1902 }
1903 
TypeObjectIsDetectableCallable(Node * node)1904 Type* Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
1905   return TypeUnaryOp(node, ObjectIsDetectableCallable);
1906 }
1907 
TypeObjectIsNonCallable(Node * node)1908 Type* Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
1909   return TypeUnaryOp(node, ObjectIsNonCallable);
1910 }
1911 
TypeObjectIsNumber(Node * node)1912 Type* Typer::Visitor::TypeObjectIsNumber(Node* node) {
1913   return TypeUnaryOp(node, ObjectIsNumber);
1914 }
1915 
1916 
TypeObjectIsReceiver(Node * node)1917 Type* Typer::Visitor::TypeObjectIsReceiver(Node* node) {
1918   return TypeUnaryOp(node, ObjectIsReceiver);
1919 }
1920 
1921 
TypeObjectIsSmi(Node * node)1922 Type* Typer::Visitor::TypeObjectIsSmi(Node* node) {
1923   return TypeUnaryOp(node, ObjectIsSmi);
1924 }
1925 
TypeObjectIsString(Node * node)1926 Type* Typer::Visitor::TypeObjectIsString(Node* node) {
1927   return TypeUnaryOp(node, ObjectIsString);
1928 }
1929 
TypeObjectIsUndetectable(Node * node)1930 Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
1931   return TypeUnaryOp(node, ObjectIsUndetectable);
1932 }
1933 
TypeNewUnmappedArgumentsElements(Node * node)1934 Type* Typer::Visitor::TypeNewUnmappedArgumentsElements(Node* node) {
1935   return Type::OtherInternal();
1936 }
1937 
TypeNewRestParameterElements(Node * node)1938 Type* Typer::Visitor::TypeNewRestParameterElements(Node* node) {
1939   return Type::OtherInternal();
1940 }
1941 
TypeArrayBufferWasNeutered(Node * node)1942 Type* Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) {
1943   return Type::Boolean();
1944 }
1945 
1946 // Heap constants.
1947 
TypeConstant(Handle<Object> value)1948 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
1949   if (Type::IsInteger(*value)) {
1950     return Type::Range(value->Number(), value->Number(), zone());
1951   }
1952   return Type::NewConstant(value, zone());
1953 }
1954 
1955 }  // namespace compiler
1956 }  // namespace internal
1957 }  // namespace v8
1958