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