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