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