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