typer.cc 72.7 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#include "src/compiler/typer.h"

7 8
#include <iomanip>

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 18
#include "src/compiler/node.h"
#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 25 26 27

namespace v8 {
namespace internal {
namespace compiler {

28
class Typer::Decorator final : public GraphDecorator {
29 30
 public:
  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 43
      broker_(broker),
      operation_typer_(broker, zone()) {
44 45
  singleton_false_ = operation_typer_.singleton_false();
  singleton_true_ = operation_typer_.singleton_true();
46 47

  decorator_ = new (zone()) Decorator(this);
48 49 50 51 52 53
  graph_->AddDecorator(decorator_);
}


Typer::~Typer() {
  graph_->RemoveDecorator(decorator_);
54 55 56
}


57
class Typer::Visitor : public Reducer {
58
 public:
59 60 61
  explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
      : typer_(typer),
        induction_vars_(induction_vars),
62 63
        weakened_nodes_(typer->zone()),
        remembered_types_(typer->zone()) {}
64

65 66
  const char* reducer_name() const override { return "Typer"; }

67
  Reduction Reduce(Node* node) override {
68 69 70 71
    if (node->op()->ValueOutputCount() == 0) return NoChange();
    switch (node->opcode()) {
#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
72
    return UpdateType(node, TypeBinaryOp(node, x##Typer));
73 74 75 76 77
      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
78
    return UpdateType(node, Type##x(node));
79
      DECLARE_CASE(Start)
80
      DECLARE_CASE(IfException)
81 82
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
83 84
      SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
85 86 87 88 89 90
      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
      JS_OBJECT_OP_LIST(DECLARE_CASE)
      JS_CONTEXT_OP_LIST(DECLARE_CASE)
      JS_OTHER_OP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

91 92 93 94 95 96 97 98 99 100 101
#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return UpdateType(node, TypeBinaryOp(node, x));
      SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return UpdateType(node, TypeUnaryOp(node, x));
      SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
102
      SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
103 104
#undef DECLARE_CASE

105
#define DECLARE_CASE(x) case IrOpcode::k##x:
106 107 108 109 110 111 112 113 114 115
      DECLARE_CASE(Loop)
      DECLARE_CASE(Branch)
      DECLARE_CASE(IfTrue)
      DECLARE_CASE(IfFalse)
      DECLARE_CASE(IfSuccess)
      DECLARE_CASE(Switch)
      DECLARE_CASE(IfValue)
      DECLARE_CASE(IfDefault)
      DECLARE_CASE(Merge)
      DECLARE_CASE(Deoptimize)
116 117
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
118 119
      DECLARE_CASE(TrapIf)
      DECLARE_CASE(TrapUnless)
120
      DECLARE_CASE(Return)
121
      DECLARE_CASE(TailCall)
122
      DECLARE_CASE(Terminate)
123 124 125
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
126
      DECLARE_CASE(End)
127 128
      SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
129
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
130
      MACHINE_OP_LIST(DECLARE_CASE)
131 132 133 134 135 136
#undef DECLARE_CASE
      break;
    }
    return NoChange();
  }

137
  Type TypeNode(Node* node) {
138
    switch (node->opcode()) {
139 140 141 142 143
#define DECLARE_CASE(x) \
      case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

144
#define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
145
      DECLARE_CASE(Start)
146
      DECLARE_CASE(IfException)
147 148
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
149 150
      SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
151 152 153 154
      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
      JS_OBJECT_OP_LIST(DECLARE_CASE)
      JS_CONTEXT_OP_LIST(DECLARE_CASE)
      JS_OTHER_OP_LIST(DECLARE_CASE)
155 156
#undef DECLARE_CASE

157 158 159 160 161 162 163 164 165 166 167
#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return TypeBinaryOp(node, x);
      SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return TypeUnaryOp(node, x);
      SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
168
      SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
169 170
#undef DECLARE_CASE

171
#define DECLARE_CASE(x) case IrOpcode::k##x:
172 173 174 175 176 177 178 179 180 181
      DECLARE_CASE(Loop)
      DECLARE_CASE(Branch)
      DECLARE_CASE(IfTrue)
      DECLARE_CASE(IfFalse)
      DECLARE_CASE(IfSuccess)
      DECLARE_CASE(Switch)
      DECLARE_CASE(IfValue)
      DECLARE_CASE(IfDefault)
      DECLARE_CASE(Merge)
      DECLARE_CASE(Deoptimize)
182 183
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
184 185
      DECLARE_CASE(TrapIf)
      DECLARE_CASE(TrapUnless)
186
      DECLARE_CASE(Return)
187
      DECLARE_CASE(TailCall)
188
      DECLARE_CASE(Terminate)
189 190 191
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
192
      DECLARE_CASE(End)
193 194
      SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
195
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
196
      MACHINE_OP_LIST(DECLARE_CASE)
197 198 199
#undef DECLARE_CASE
      break;
    }
200
    UNREACHABLE();
201 202
  }

203
  Type TypeConstant(Handle<Object> value);
204

205 206
 private:
  Typer* typer_;
207
  LoopVariableOptimizer* induction_vars_;
208
  ZoneSet<NodeId> weakened_nodes_;
209 210
  // TODO(tebbi): remove once chromium:906567 is resolved.
  ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_;
211

212
#define DECLARE_METHOD(x) inline Type Type##x(Node* node);
213
  DECLARE_METHOD(Start)
214
  DECLARE_METHOD(IfException)
215 216 217 218
  COMMON_OP_LIST(DECLARE_METHOD)
  SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
  SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
  JS_OP_LIST(DECLARE_METHOD)
219 220
#undef DECLARE_METHOD

221
  Type TypeOrNone(Node* node) {
222 223
    return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
                                         : Type::None();
224 225
  }

226
  Type Operand(Node* node, int i) {
227
    Node* operand_node = NodeProperties::GetValueInput(node, i);
228
    return TypeOrNone(operand_node);
229 230
  }

231
  Type Weaken(Node* node, Type current_type, Type previous_type);
232

233
  Zone* zone() { return typer_->zone(); }
234
  Graph* graph() { return typer_->graph(); }
235

236 237 238 239 240
  void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
  bool IsWeakened(NodeId node_id) {
    return weakened_nodes_.find(node_id) != weakened_nodes_.end();
  }

241 242
  typedef Type (*UnaryTyperFun)(Type, Typer* t);
  typedef Type (*BinaryTyperFun)(Type, Type, Typer* t);
243

244 245
  Type TypeUnaryOp(Node* node, UnaryTyperFun);
  Type TypeBinaryOp(Node* node, BinaryTyperFun);
246

247 248
  static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
                                  BinaryTyperFun f);
249

250 251 252 253 254 255 256 257
  enum ComparisonOutcomeFlags {
    kComparisonTrue = 1,
    kComparisonFalse = 2,
    kComparisonUndefined = 4
  };
  typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;

  static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
258 259 260 261 262 263 264 265 266 267 268 269 270
  static Type FalsifyUndefined(ComparisonOutcome, Typer*);

  static Type BitwiseNot(Type, Typer*);
  static Type Decrement(Type, Typer*);
  static Type Increment(Type, Typer*);
  static Type Negate(Type, Typer*);

  static Type ToPrimitive(Type, Typer*);
  static Type ToBoolean(Type, Typer*);
  static Type ToInteger(Type, Typer*);
  static Type ToLength(Type, Typer*);
  static Type ToName(Type, Typer*);
  static Type ToNumber(Type, Typer*);
271
  static Type ToNumberConvertBigInt(Type, Typer*);
272 273 274 275 276 277
  static Type ToNumeric(Type, Typer*);
  static Type ToObject(Type, Typer*);
  static Type ToString(Type, Typer*);
#define DECLARE_METHOD(Name)               \
  static Type Name(Type type, Typer* t) {  \
    return t->operation_typer_.Name(type); \
278 279
  }
  SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
280
  SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
281
#undef DECLARE_METHOD
282 283 284
#define DECLARE_METHOD(Name)                       \
  static Type Name(Type lhs, Type rhs, Typer* t) { \
    return t->operation_typer_.Name(lhs, rhs);     \
285 286 287 288
  }
  SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
  SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD
289

290 291 292 293 294 295
  static Type ObjectIsArrayBufferView(Type, Typer*);
  static Type ObjectIsBigInt(Type, Typer*);
  static Type ObjectIsCallable(Type, Typer*);
  static Type ObjectIsConstructor(Type, Typer*);
  static Type ObjectIsDetectableCallable(Type, Typer*);
  static Type ObjectIsMinusZero(Type, Typer*);
296
  static Type NumberIsMinusZero(Type, Typer*);
297 298 299 300 301 302 303 304 305 306 307 308 309 310
  static Type ObjectIsNaN(Type, Typer*);
  static Type NumberIsNaN(Type, Typer*);
  static Type ObjectIsNonCallable(Type, Typer*);
  static Type ObjectIsNumber(Type, Typer*);
  static Type ObjectIsReceiver(Type, Typer*);
  static Type ObjectIsSmi(Type, Typer*);
  static Type ObjectIsString(Type, Typer*);
  static Type ObjectIsSymbol(Type, Typer*);
  static Type ObjectIsUndetectable(Type, Typer*);

  static ComparisonOutcome JSCompareTyper(Type, Type, Typer*);
  static ComparisonOutcome NumberCompareTyper(Type, Type, Typer*);

#define DECLARE_METHOD(x) static Type x##Typer(Type, Type, Typer*);
311 312 313
  JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD

314
  static Type JSCallTyper(Type, Typer*);
315

316 317 318 319 320 321 322
  static Type NumberEqualTyper(Type, Type, Typer*);
  static Type NumberLessThanTyper(Type, Type, Typer*);
  static Type NumberLessThanOrEqualTyper(Type, Type, Typer*);
  static Type ReferenceEqualTyper(Type, Type, Typer*);
  static Type SameValueTyper(Type, Type, Typer*);
  static Type StringFromSingleCharCodeTyper(Type, Typer*);
  static Type StringFromSingleCodePointTyper(Type, Typer*);
323

324
  Reduction UpdateType(Node* node, Type current) {
325
    if (NodeProperties::IsTyped(node)) {
326
      // Widen the type of a previously typed node.
327
      Type previous = NodeProperties::GetType(node);
328 329
      if (node->opcode() == IrOpcode::kPhi ||
          node->opcode() == IrOpcode::kInductionVariablePhi) {
330
        // Speed up termination in the presence of range types:
331
        current = Weaken(node, current, previous);
332
      }
333

334
      if (V8_UNLIKELY(!previous.Is(current))) {
335
        AllowHandleDereference allow;
336
        std::ostringstream ostream;
337
        node->Print(ostream);
338 339 340 341 342 343 344 345 346 347

        if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
          ostream << "Previous UpdateType run (inputs first):";
          for (int i = 0; i < 3; ++i) {
            ostream << "  ";
            if (remembered_types_[{node, i}].IsInvalid()) {
              ostream << "untyped";
            } else {
              remembered_types_[{node, i}].PrintTo(ostream);
            }
348
          }
349 350 351 352 353 354 355 356 357 358 359 360 361

          ostream << "\nCurrent (output) type:  ";
          previous.PrintTo(ostream);

          ostream << "\nThis UpdateType run (inputs first):";
          for (int i = 0; i < 2; ++i) {
            ostream << "  ";
            Node* input = NodeProperties::GetValueInput(node, i);
            if (NodeProperties::IsTyped(input)) {
              NodeProperties::GetType(input).PrintTo(ostream);
            } else {
              ostream << "untyped";
            }
362
          }
363 364
          ostream << "  ";
          current.PrintTo(ostream);
365 366
          ostream << "\n";
        }
367

368 369 370 371 372 373
        FATAL("UpdateType error for node %s", ostream.str().c_str());
      }

      if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
        for (int i = 0; i < 2; ++i) {
          Node* input = NodeProperties::GetValueInput(node, i);
374 375 376
          remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
                                             ? NodeProperties::GetType(input)
                                             : Type::Invalid();
377
        }
378
        remembered_types_[{node, 2}] = current;
379
      }
380

381
      NodeProperties::SetType(node, current);
382
      if (!current.Is(previous)) {
383 384 385 386 387
        // If something changed, revisit all uses.
        return Changed(node);
      }
      return NoChange();
    } else {
388 389 390
      if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
        for (int i = 0; i < 2; ++i) {
          Node* input = NodeProperties::GetValueInput(node, i);
391 392 393
          remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
                                             ? NodeProperties::GetType(input)
                                             : Type::Invalid();
394
        }
395
        remembered_types_[{node, 2}] = current;
396 397
      }

398 399
      // No previous type, simply update the type.
      NodeProperties::SetType(node, current);
400
      return Changed(node);
401 402 403 404
    }
  }
};

405
void Typer::Run() { Run(NodeVector(zone()), nullptr); }
406

407 408 409 410 411 412
void Typer::Run(const NodeVector& roots,
                LoopVariableOptimizer* induction_vars) {
  if (induction_vars != nullptr) {
    induction_vars->ChangeToInductionVariablePhis();
  }
  Visitor visitor(this, induction_vars);
413
  GraphReducer graph_reducer(zone(), graph());
414
  graph_reducer.AddReducer(&visitor);
415
  for (Node* const root : roots) graph_reducer.ReduceNode(root);
416
  graph_reducer.ReduceGraph();
417

418
  if (induction_vars != nullptr) {
419
    induction_vars->ChangeToPhisAndInsertGuards();
420 421
  }
}
422

423
void Typer::Decorator::Decorate(Node* node) {
424
  if (node->op()->ValueOutputCount() > 0) {
425 426 427 428
    // Only eagerly type-decorate nodes with known input types.
    // Other cases will generally require a proper fixpoint iteration with Run.
    bool is_typed = NodeProperties::IsTyped(node);
    if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
429
      Visitor typing(typer_, nullptr);
430
      Type type = typing.TypeNode(node);
431
      if (is_typed) {
432 433
        type = Type::Intersect(type, NodeProperties::GetType(node),
                               typer_->zone());
434
      }
435
      NodeProperties::SetType(node, type);
436
    }
437 438 439 440
  }
}


441 442 443 444 445 446
// -----------------------------------------------------------------------------

// Helper functions that lift a function f on types to a function on bounds,
// and uses that to type the given node.  Note that f is never called with None
// as an argument.

447 448
Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
  Type input = Operand(node, 0);
449
  return input.IsNone() ? Type::None() : f(input, typer_);
450 451
}

452 453 454
Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
  Type left = Operand(node, 0);
  Type right = Operand(node, 1);
455 456
  return left.IsNone() || right.IsNone() ? Type::None()
                                         : f(left, right, typer_);
457 458
}

459 460
Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
                                         BinaryTyperFun f) {
461 462
  lhs = ToNumeric(lhs, t);
  rhs = ToNumeric(rhs, t);
463 464
  bool lhs_is_number = lhs.Is(Type::Number());
  bool rhs_is_number = rhs.Is(Type::Number());
465 466 467
  if (lhs_is_number && rhs_is_number) {
    return f(lhs, rhs, t);
  }
468 469 470
  // In order to maintain monotonicity, the following two conditions are
  // intentionally asymmetric.
  if (lhs_is_number) {
471 472
    return Type::Number();
  }
473
  if (lhs.Is(Type::BigInt())) {
474 475
    return Type::BigInt();
  }
476 477
  return Type::Numeric();
}
478

479 480 481 482 483 484 485 486 487
Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
    ComparisonOutcome outcome, Typer* t) {
  ComparisonOutcome result(0);
  if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
  if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
  if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
  return result;
}

488
Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
489 490 491
  if ((outcome & kComparisonFalse) != 0 ||
      (outcome & kComparisonUndefined) != 0) {
    return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
492
                                            : t->singleton_false_;
493 494
  }
  // Type should be non empty, so we know it should be true.
495
  DCHECK_NE(0, outcome & kComparisonTrue);
496
  return t->singleton_true_;
497 498
}

499
Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
500
  type = ToNumeric(type, t);
501
  if (type.Is(Type::Number())) {
502
    return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
503 504 505 506
  }
  return Type::Numeric();
}

507
Type Typer::Visitor::Decrement(Type type, Typer* t) {
508
  type = ToNumeric(type, t);
509
  if (type.Is(Type::Number())) {
510
    return NumberSubtract(type, t->cache_->kSingletonOne, t);
511 512 513 514
  }
  return Type::Numeric();
}

515
Type Typer::Visitor::Increment(Type type, Typer* t) {
516
  type = ToNumeric(type, t);
517
  if (type.Is(Type::Number())) {
518
    return NumberAdd(type, t->cache_->kSingletonOne, t);
519 520 521 522
  }
  return Type::Numeric();
}

523
Type Typer::Visitor::Negate(Type type, Typer* t) {
524
  type = ToNumeric(type, t);
525
  if (type.Is(Type::Number())) {
526
    return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
527 528 529 530
  }
  return Type::Numeric();
}

531 532
// Type conversion.

533
Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
534
  if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
535 536 537 538 539
    return type;
  }
  return Type::Primitive();
}

540
Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
541
  return t->operation_typer()->ToBoolean(type);
542 543 544
}


545
// static
546
Type Typer::Visitor::ToInteger(Type type, Typer* t) {
547 548
  // ES6 section 7.1.4 ToInteger ( argument )
  type = ToNumber(type, t);
549 550
  if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
  if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
551
    return Type::Union(
552 553
        Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
        t->cache_->kSingletonZero, t->zone());
554
  }
555
  return t->cache_->kIntegerOrMinusZero;
556 557 558 559
}


// static
560
Type Typer::Visitor::ToLength(Type type, Typer* t) {
561
  // ES6 section 7.1.15 ToLength ( argument )
562
  type = ToInteger(type, t);
563 564 565
  if (type.IsNone()) return type;
  double min = type.Min();
  double max = type.Max();
566 567 568 569 570 571
  if (max <= 0.0) {
    return Type::NewConstant(0, t->zone());
  }
  if (min >= kMaxSafeInteger) {
    return Type::NewConstant(kMaxSafeInteger, t->zone());
  }
572
  if (min <= 0.0) min = 0.0;
573
  if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
574 575 576 577 578
  return Type::Range(min, max, t->zone());
}


// static
579
Type Typer::Visitor::ToName(Type type, Typer* t) {
580 581
  // ES6 section 7.1.14 ToPropertyKey ( argument )
  type = ToPrimitive(type, t);
582 583
  if (type.Is(Type::Name())) return type;
  if (type.Maybe(Type::Symbol())) return Type::Name();
584 585 586 587 588
  return ToString(type, t);
}


// static
589
Type Typer::Visitor::ToNumber(Type type, Typer* t) {
590
  return t->operation_typer_.ToNumber(type);
591 592
}

593 594 595 596 597
// static
Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
  return t->operation_typer_.ToNumberConvertBigInt(type);
}

598
// static
599
Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
600 601
  return t->operation_typer_.ToNumeric(type);
}
602

603
// static
604
Type Typer::Visitor::ToObject(Type type, Typer* t) {
605
  // ES6 section 7.1.13 ToObject ( argument )
606 607 608
  if (type.Is(Type::Receiver())) return type;
  if (type.Is(Type::Primitive())) return Type::OtherObject();
  if (!type.Maybe(Type::OtherUndetectable())) {
609 610
    return Type::DetectableReceiver();
  }
611 612 613 614 615
  return Type::Receiver();
}


// static
616
Type Typer::Visitor::ToString(Type type, Typer* t) {
617 618
  // ES6 section 7.1.12 ToString ( argument )
  type = ToPrimitive(type, t);
619
  if (type.Is(Type::String())) return type;
620 621 622
  return Type::String();
}

623 624
// Type checks.

625
Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
626
  // TODO(turbofan): Introduce a Type::ArrayBufferView?
627
  if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
628 629 630
  return Type::Boolean();
}

631
Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
632 633
  if (type.Is(Type::BigInt())) return t->singleton_true_;
  if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
634 635 636
  return Type::Boolean();
}

637
Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
638 639
  if (type.Is(Type::Callable())) return t->singleton_true_;
  if (!type.Maybe(Type::Callable())) return t->singleton_false_;
640 641 642
  return Type::Boolean();
}

643
Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
644
  // TODO(turbofan): Introduce a Type::Constructor?
645
  if (!type.Maybe(Type::Callable())) return t->singleton_false_;
646 647 648
  return Type::Boolean();
}

649
Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
650 651
  if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
  if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_;
652 653 654
  return Type::Boolean();
}

655
Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
656 657
  if (type.Is(Type::MinusZero())) return t->singleton_true_;
  if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
658 659 660
  return Type::Boolean();
}

661 662 663 664 665 666
Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) {
  if (type.Is(Type::MinusZero())) return t->singleton_true_;
  if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
  return Type::Boolean();
}

667
Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
668 669
  if (type.Is(Type::NaN())) return t->singleton_true_;
  if (!type.Maybe(Type::NaN())) return t->singleton_false_;
670 671 672
  return Type::Boolean();
}

673
Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
674 675
  if (type.Is(Type::NaN())) return t->singleton_true_;
  if (!type.Maybe(Type::NaN())) return t->singleton_false_;
676 677 678
  return Type::Boolean();
}

679
Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
680 681
  if (type.Is(Type::NonCallable())) return t->singleton_true_;
  if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
682 683
  return Type::Boolean();
}
684

685
Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
686 687
  if (type.Is(Type::Number())) return t->singleton_true_;
  if (!type.Maybe(Type::Number())) return t->singleton_false_;
688 689 690
  return Type::Boolean();
}

691
Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
692 693
  if (type.Is(Type::Receiver())) return t->singleton_true_;
  if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
694 695 696
  return Type::Boolean();
}

697
Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
698
  if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
699 700 701
  return Type::Boolean();
}

702
Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
703 704
  if (type.Is(Type::String())) return t->singleton_true_;
  if (!type.Maybe(Type::String())) return t->singleton_false_;
705 706
  return Type::Boolean();
}
707

708
Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
709 710
  if (type.Is(Type::Symbol())) return t->singleton_true_;
  if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
711 712 713
  return Type::Boolean();
}

714
Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
715 716
  if (type.Is(Type::Undetectable())) return t->singleton_true_;
  if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
717 718 719 720
  return Type::Boolean();
}


721 722 723 724 725
// -----------------------------------------------------------------------------


// Control operators.

726
Type Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
727

728
Type Typer::Visitor::TypeIfException(Node* node) { return Type::NonInternal(); }
729

730
// Common operators.
731

732
Type Typer::Visitor::TypeParameter(Node* node) {
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
  Node* const start = node->InputAt(0);
  DCHECK_EQ(IrOpcode::kStart, start->opcode());
  int const parameter_count = start->op()->ValueOutputCount() - 4;
  DCHECK_LE(1, parameter_count);
  int const index = ParameterIndexOf(node->op());
  if (index == Linkage::kJSCallClosureParamIndex) {
    return Type::Function();
  } else if (index == 0) {
    if (typer_->flags() & Typer::kThisIsReceiver) {
      return Type::Receiver();
    } else {
      // Parameter[this] can be the_hole for derived class constructors.
      return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
    }
  } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
    if (typer_->flags() & Typer::kNewTargetIsReceiver) {
      return Type::Receiver();
    } else {
      return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
    }
  } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
754
    return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
755 756 757 758 759
  } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
    return Type::OtherInternal();
  }
  return Type::NonInternal();
}
760

761
Type Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
762

763
Type Typer::Visitor::TypeRetain(Node* node) { UNREACHABLE(); }
764

765
Type Typer::Visitor::TypeInt32Constant(Node* node) { UNREACHABLE(); }
766

767
Type Typer::Visitor::TypeInt64Constant(Node* node) { UNREACHABLE(); }
768

769
Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { UNREACHABLE(); }
770

771
Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { UNREACHABLE(); }
772

773
Type Typer::Visitor::TypeFloat32Constant(Node* node) { UNREACHABLE(); }
774

775
Type Typer::Visitor::TypeFloat64Constant(Node* node) { UNREACHABLE(); }
776

777
Type Typer::Visitor::TypeNumberConstant(Node* node) {
778
  double number = OpParameter<double>(node->op());
779
  return Type::NewConstant(number, zone());
780 781
}

782
Type Typer::Visitor::TypeHeapConstant(Node* node) {
783
  return TypeConstant(HeapConstantOf(node->op()));
784 785
}

786
Type Typer::Visitor::TypeExternalConstant(Node* node) {
787
  return Type::ExternalPointer();
788 789
}

790
Type Typer::Visitor::TypePointerConstant(Node* node) {
791 792
  return Type::ExternalPointer();
}
793

794
Type Typer::Visitor::TypeSelect(Node* node) {
795
  return Type::Union(Operand(node, 1), Operand(node, 2), zone());
796 797
}

798
Type Typer::Visitor::TypePhi(Node* node) {
799
  int arity = node->op()->ValueInputCount();
800
  Type type = Operand(node, 0);
801
  for (int i = 1; i < arity; ++i) {
802
    type = Type::Union(type, Operand(node, i), zone());
803
  }
804
  return type;
805 806
}

807
Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
808 809 810 811
  int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
  DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
  DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());

812 813
  Type initial_type = Operand(node, 0);
  Type increment_type = Operand(node, 2);
814 815 816

  // We only handle integer induction variables (otherwise ranges
  // do not apply and we cannot do anything).
817 818
  if (!initial_type.Is(typer_->cache_->kInteger) ||
      !increment_type.Is(typer_->cache_->kInteger)) {
819 820 821 822 823
    // Fallback to normal phi typing, but ensure monotonicity.
    // (Unfortunately, without baking in the previous type, monotonicity might
    // be violated because we might not yet have retyped the incrementing
    // operation even though the increment's type might been already reflected
    // in the induction variable phi.)
824 825
    Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
                                              : Type::None();
826
    for (int i = 0; i < arity; ++i) {
827 828 829 830 831 832
      type = Type::Union(type, Operand(node, i), zone());
    }
    return type;
  }
  // If we do not have enough type information for the initial value or
  // the increment, just return the initial value's type.
833
  if (initial_type.IsNone() ||
834
      increment_type.Is(typer_->cache_->kSingletonZero)) {
835 836 837 838 839 840 841 842
    return initial_type;
  }

  // Now process the bounds.
  auto res = induction_vars_->induction_variables().find(node->id());
  DCHECK(res != induction_vars_->induction_variables().end());
  InductionVariable* induction_var = res->second;

843 844
  InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();

845 846
  double min = -V8_INFINITY;
  double max = V8_INFINITY;
847 848 849 850

  double increment_min;
  double increment_max;
  if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
851 852
    increment_min = increment_type.Min();
    increment_max = increment_type.Max();
853
  } else {
854
    DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
855 856
    increment_min = -increment_type.Max();
    increment_max = -increment_type.Min();
857 858 859 860
  }

  if (increment_min >= 0) {
    // increasing sequence
861
    min = initial_type.Min();
862
    for (auto bound : induction_var->upper_bounds()) {
863
      Type bound_type = TypeOrNone(bound.bound);
864
      // If the type is not an integer, just skip the bound.
865
      if (!bound_type.Is(typer_->cache_->kInteger)) continue;
866
      // If the type is not inhabited, then we can take the initial value.
867 868
      if (bound_type.IsNone()) {
        max = initial_type.Max();
869 870
        break;
      }
871
      double bound_max = bound_type.Max();
872 873 874
      if (bound.kind == InductionVariable::kStrict) {
        bound_max -= 1;
      }
875
      max = std::min(max, bound_max + increment_max);
876 877
    }
    // The upper bound must be at least the initial value's upper bound.
878
    max = std::max(max, initial_type.Max());
879 880
  } else if (increment_max <= 0) {
    // decreasing sequence
881
    max = initial_type.Max();
882
    for (auto bound : induction_var->lower_bounds()) {
883
      Type bound_type = TypeOrNone(bound.bound);
884
      // If the type is not an integer, just skip the bound.
885
      if (!bound_type.Is(typer_->cache_->kInteger)) continue;
886
      // If the type is not inhabited, then we can take the initial value.
887 888
      if (bound_type.IsNone()) {
        min = initial_type.Min();
889 890
        break;
      }
891
      double bound_min = bound_type.Min();
892 893 894
      if (bound.kind == InductionVariable::kStrict) {
        bound_min += 1;
      }
895
      min = std::max(min, bound_min + increment_min);
896 897
    }
    // The lower bound must be at most the initial value's lower bound.
898
    min = std::min(min, initial_type.Min());
899 900 901
  } else {
    // Shortcut: If the increment can be both positive and negative,
    // the variable can go arbitrarily far, so just return integer.
902
    return typer_->cache_->kInteger;
903 904
  }
  if (FLAG_trace_turbo_loop) {
905 906 907 908 909 910 911 912 913
    StdoutStream{} << std::setprecision(10) << "Loop ("
                   << NodeProperties::GetControlInput(node)->id()
                   << ") variable bounds in "
                   << (arithmetic_type ==
                               InductionVariable::ArithmeticType::kAddition
                           ? "addition"
                           : "subtraction")
                   << " for phi " << node->id() << ": (" << min << ", " << max
                   << ")\n";
914 915 916
  }
  return Type::Range(min, max, typer_->zone());
}
917

918
Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); }
919

920
Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }
921

922
Type Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
923

924
Type Typer::Visitor::TypeLoopExitEffect(Node* node) { UNREACHABLE(); }
925

926
Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
927 928 929
  return Operand(node, 1);
}

930
Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
931 932 933
  return Operand(node, 1);
}

934
Type Typer::Visitor::TypeTransitionElementsKind(Node* node) { UNREACHABLE(); }
935

936
Type Typer::Visitor::TypeCheckpoint(Node* node) { UNREACHABLE(); }
937

938
Type Typer::Visitor::TypeBeginRegion(Node* node) { UNREACHABLE(); }
939

940
Type Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
941

942
Type Typer::Visitor::TypeFrameState(Node* node) {
943
  // TODO(rossberg): Ideally FrameState wouldn't have a value output.
944
  return Type::Internal();
945 946
}

947
Type Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
948

949
Type Typer::Visitor::TypeTypedStateValues(Node* node) {
950
  return Type::Internal();
951 952
}

953
Type Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
954

955
Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
956 957 958
  return Type::Internal();
}

959
Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
960 961 962
  return Type::Internal();
}

963
Type Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
964

965
Type Typer::Visitor::TypeTypedObjectState(Node* node) {
966 967
  return Type::Internal();
}
968

969
Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
970

971
Type Typer::Visitor::TypeCallWithCallerSavedRegisters(Node* node) {
972 973
  UNREACHABLE();
}
974

975 976
Type Typer::Visitor::TypeProjection(Node* node) {
  Type const type = Operand(node, 0);
977
  if (type.Is(Type::None())) return Type::None();
978
  int const index = static_cast<int>(ProjectionIndexOf(node->op()));
979 980
  if (type.IsTuple() && index < type.AsTuple()->Arity()) {
    return type.AsTuple()->Element(index);
981
  }
982
  return Type::Any();
983 984
}

985
Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
986

987 988
Type Typer::Visitor::TypeTypeGuard(Node* node) {
  Type const type = Operand(node, 0);
989 990 991
  return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
}

992
Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
993

994
Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
995

996
Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
997

998 999
// JS comparison operators.

1000
Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1001 1002
  if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
  if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1003
    return t->singleton_true_;
1004
  }
1005 1006
  if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
      (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1007
    return t->singleton_false_;
1008
  }
1009
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1010 1011
    // Types are equal and are inhabited only by a single semantic value,
    // which is not nan due to the earlier check.
1012
    return t->singleton_true_;
1013 1014 1015
  }
  return Type::Boolean();
}
1016

1017
Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1018
  return t->operation_typer()->StrictEqual(lhs, rhs);
1019 1020 1021 1022 1023 1024
}

// The EcmaScript specification defines the four relational comparison operators
// (<, <=, >=, >) with the help of a single abstract one.  It behaves like <
// but returns undefined when the inputs cannot be compared.
// We implement the typing analogously.
1025 1026
Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
                                                                 Type rhs,
1027
                                                                 Typer* t) {
1028 1029
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
1030
  if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1031 1032
    return ComparisonOutcome(kComparisonTrue) |
           ComparisonOutcome(kComparisonFalse);
1033
  }
1034 1035
  lhs = ToNumeric(lhs, t);
  rhs = ToNumeric(rhs, t);
1036
  if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1037 1038 1039 1040 1041
    return NumberCompareTyper(lhs, rhs, t);
  }
  return ComparisonOutcome(kComparisonTrue) |
         ComparisonOutcome(kComparisonFalse) |
         ComparisonOutcome(kComparisonUndefined);
1042
}
1043

1044 1045
Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type lhs,
                                                                     Type rhs,
1046
                                                                     Typer* t) {
1047 1048
  DCHECK(lhs.Is(Type::Number()));
  DCHECK(rhs.Is(Type::Number()));
1049

1050
  // Shortcut for NaNs.
1051
  if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1052 1053

  ComparisonOutcome result;
1054
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1055 1056
    // Types are equal and are inhabited only by a single semantic value.
    result = kComparisonFalse;
1057
  } else if (lhs.Min() >= rhs.Max()) {
1058
    result = kComparisonFalse;
1059
  } else if (lhs.Max() < rhs.Min()) {
1060 1061 1062 1063 1064 1065 1066 1067 1068
    result = kComparisonTrue;
  } else {
    // We cannot figure out the result, return both true and false. (We do not
    // have to return undefined because that cannot affect the result of
    // FalsifyUndefined.)
    return ComparisonOutcome(kComparisonTrue) |
           ComparisonOutcome(kComparisonFalse);
  }
  // Add the undefined if we could see NaN.
1069
  if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1070 1071 1072
    result |= kComparisonUndefined;
  }
  return result;
1073 1074
}

1075
Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1076 1077 1078
  return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
}

1079
Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1080 1081 1082
  return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
}

1083
Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1084 1085 1086
  return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
}

1087
Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1088 1089 1090 1091 1092
  return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
}

// JS bitwise operators.

1093
Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1094
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1095 1096
}

1097
Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1098
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1099 1100
}

1101
Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1102
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1103 1104
}

1105
Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1106
  return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1107 1108
}

1109
Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1110
  return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1111 1112
}

1113
Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1114
  return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1115 1116 1117 1118 1119
}


// JS arithmetic operators.

1120
Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1121 1122
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
1123 1124
  if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
    if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1125 1126
      return Type::String();
    } else {
1127
      return Type::NumericOrString();
1128 1129
    }
  }
1130
  // The addition must be numeric.
1131
  return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1132 1133
}

1134
Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1135
  return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1136 1137
}

1138
Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1139
  return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1140 1141
}

1142
Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1143
  return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1144 1145
}

1146
Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1147
  return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1148 1149
}

1150
Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1151
  // TODO(neis): Refine using BinaryNumberOpTyper?
1152
  return Type::Numeric();
1153
}
1154 1155 1156

// JS unary operators.

1157
Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1158 1159 1160
  return TypeUnaryOp(node, BitwiseNot);
}

1161
Type Typer::Visitor::TypeJSDecrement(Node* node) {
1162 1163 1164
  return TypeUnaryOp(node, Decrement);
}

1165
Type Typer::Visitor::TypeJSIncrement(Node* node) {
1166 1167 1168
  return TypeUnaryOp(node, Increment);
}

1169
Type Typer::Visitor::TypeJSNegate(Node* node) {
1170 1171 1172
  return TypeUnaryOp(node, Negate);
}

1173
Type Typer::Visitor::TypeTypeOf(Node* node) {
1174
  return Type::InternalizedString();
1175 1176 1177 1178 1179
}


// JS conversion operators.

1180
Type Typer::Visitor::TypeToBoolean(Node* node) {
1181
  return TypeUnaryOp(node, ToBoolean);
1182 1183
}

1184
Type Typer::Visitor::TypeJSToLength(Node* node) {
1185
  return TypeUnaryOp(node, ToLength);
1186 1187
}

1188
Type Typer::Visitor::TypeJSToName(Node* node) {
1189 1190
  return TypeUnaryOp(node, ToName);
}
1191

1192
Type Typer::Visitor::TypeJSToNumber(Node* node) {
1193 1194
  return TypeUnaryOp(node, ToNumber);
}
1195

1196 1197 1198 1199
Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
  return TypeUnaryOp(node, ToNumberConvertBigInt);
}

1200
Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1201 1202 1203
  return TypeUnaryOp(node, ToNumeric);
}

1204
Type Typer::Visitor::TypeJSToObject(Node* node) {
1205 1206
  return TypeUnaryOp(node, ToObject);
}
1207

1208
Type Typer::Visitor::TypeJSToString(Node* node) {
1209 1210
  return TypeUnaryOp(node, ToString);
}
1211 1212 1213

// JS object operators.

1214
Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1215

1216
Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1217 1218 1219 1220 1221 1222 1223 1224
  switch (CreateArgumentsTypeOf(node->op())) {
    case CreateArgumentsType::kRestParameter:
      return Type::Array();
    case CreateArgumentsType::kMappedArguments:
    case CreateArgumentsType::kUnmappedArguments:
      return Type::OtherObject();
  }
  UNREACHABLE();
1225 1226
}

1227
Type Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1228

1229
Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1230 1231 1232
  return Type::OtherObject();
}

1233 1234 1235 1236
Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) {
  return Type::OtherObject();
}

1237
Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1238 1239 1240
  return Type::OtherObject();
}

1241
Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1242 1243 1244
  return Type::BoundFunction();
}

1245
Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1246 1247 1248
  return Type::OtherObject();
}

1249
Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1250
  return Type::Function();
1251 1252
}

1253
Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1254 1255 1256
  return Type::OtherObject();
}

1257
Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1258 1259 1260
  return Type::OtherObject();
}

1261
Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1262 1263
  return Type::OtherObject();
}
1264

1265
Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1266 1267 1268
  return Type::OtherObject();
}

1269
Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1270 1271 1272
  return Type::OtherObject();
}

1273
Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1274 1275 1276
  return Type::OtherObject();
}

1277
Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1278
  return Type::Array();
1279 1280
}

1281
Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1282 1283
  return Type::Array();
}
1284

1285 1286 1287 1288
Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
  return Type::Array();
}

1289
Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1290
  return Type::OtherObject();
1291 1292
}

1293
Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1294 1295
  return Type::OtherObject();
}
1296

1297 1298 1299 1300
Type Typer::Visitor::TypeJSCloneObject(Node* node) {
  return Type::OtherObject();
}

1301
Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1302 1303 1304
  return Type::OtherObject();
}

1305
Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
1306
  return Type::NonInternal();
1307 1308
}

1309
Type Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::NonInternal(); }
1310

1311
Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1312 1313
  return Type::NonInternal();
}
1314

1315
Type Typer::Visitor::TypeJSParseInt(Node* node) { return Type::Number(); }
1316

1317 1318
Type Typer::Visitor::TypeJSRegExpTest(Node* node) { return Type::Boolean(); }

1319 1320 1321 1322 1323
// Returns a somewhat larger range if we previously assigned
// a (smaller) range to this node. This is used  to speed up
// the fixpoint calculation in case there appears to be a loop
// in the graph. In the current implementation, we are
// increasing the limits to the closest power of two.
1324
Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) {
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
  static const double kWeakenMinLimits[] = {
      0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
      -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
      -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
      -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
      -70368744177664.0, -140737488355328.0, -281474976710656.0,
      -562949953421312.0};
  static const double kWeakenMaxLimits[] = {
      0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
      17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
      274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
      4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
      70368744177663.0, 140737488355327.0, 281474976710655.0,
      562949953421311.0};
  STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));

1341
  // If the types have nothing to do with integers, return the types.
1342
  Type const integer = typer_->cache_->kInteger;
1343
  if (!previous_type.Maybe(integer)) {
1344 1345
    return current_type;
  }
1346
  DCHECK(current_type.Maybe(integer));
1347

1348 1349
  Type current_integer = Type::Intersect(current_type, integer, zone());
  Type previous_integer = Type::Intersect(previous_type, integer, zone());
1350 1351 1352 1353 1354 1355

  // Once we start weakening a node, we should always weaken.
  if (!IsWeakened(node->id())) {
    // Only weaken if there is range involved; we should converge quickly
    // for all other types (the exception is a union of many constants,
    // but we currently do not increase the number of constants in unions).
1356 1357
    Type previous = previous_integer.GetRange();
    Type current = current_integer.GetRange();
1358
    if (current.IsInvalid() || previous.IsInvalid()) {
1359 1360 1361 1362
      return current_type;
    }
    // Range is involved => we are weakening.
    SetWeakened(node->id());
1363 1364
  }

1365
  double current_min = current_integer.Min();
1366
  double new_min = current_min;
1367 1368
  // Find the closest lower entry in the list of allowed
  // minima (or negative infinity if there is no such entry).
1369
  if (current_min != previous_integer.Min()) {
1370
    new_min = -V8_INFINITY;
1371 1372 1373
    for (double const min : kWeakenMinLimits) {
      if (min <= current_min) {
        new_min = min;
1374
        break;
1375 1376
      }
    }
1377
  }
1378

1379
  double current_max = current_integer.Max();
1380
  double new_max = current_max;
1381 1382
  // Find the closest greater entry in the list of allowed
  // maxima (or infinity if there is no such entry).
1383
  if (current_max != previous_integer.Max()) {
1384
    new_max = V8_INFINITY;
1385 1386 1387
    for (double const max : kWeakenMaxLimits) {
      if (max >= current_max) {
        new_max = max;
1388
        break;
1389 1390
      }
    }
1391
  }
1392 1393 1394 1395

  return Type::Union(current_type,
                     Type::Range(new_min, new_max, typer_->zone()),
                     typer_->zone());
1396 1397
}

1398
Type Typer::Visitor::TypeJSStoreProperty(Node* node) { UNREACHABLE(); }
1399

1400
Type Typer::Visitor::TypeJSStoreNamed(Node* node) { UNREACHABLE(); }
1401

1402
Type Typer::Visitor::TypeJSStoreGlobal(Node* node) { UNREACHABLE(); }
1403

1404
Type Typer::Visitor::TypeJSStoreNamedOwn(Node* node) { UNREACHABLE(); }
1405

1406
Type Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1407 1408 1409
  UNREACHABLE();
}

1410
Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
1411

1412
Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1413
  return Type::Boolean();
1414 1415
}

1416
Type Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1417

1418
// JS instanceof operator.
1419

1420
Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1421 1422 1423
  return Type::Boolean();
}

1424
Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1425 1426 1427
  return Type::Boolean();
}

1428
Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1429 1430 1431
  return Type::Boolean();
}

1432
Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1433 1434 1435
  return Type::Callable();
}

1436 1437
// JS context operators.

1438
Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1439
  ContextAccess const& access = ContextAccessOf(node->op());
1440 1441 1442
  switch (access.index()) {
    case Context::PREVIOUS_INDEX:
    case Context::NATIVE_CONTEXT_INDEX:
1443
    case Context::SCOPE_INFO_INDEX:
1444 1445 1446
      return Type::OtherInternal();
    default:
      return Type::Any();
1447
  }
1448 1449
}

1450
Type Typer::Visitor::TypeJSStoreContext(Node* node) { UNREACHABLE(); }
1451

1452
Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1453
  return Type::OtherInternal();
1454 1455
}

1456
Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1457
  return Type::OtherInternal();
1458 1459
}

1460
Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1461
  return Type::OtherInternal();
1462 1463
}

1464
Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1465
  return Type::OtherInternal();
1466 1467 1468 1469
}

// JS other operators.

1470
Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1471 1472 1473
  return Type::Receiver();
}

1474
Type Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1475

1476
Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1477 1478 1479
  return Type::Receiver();
}

1480
Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1481 1482 1483
  return Type::Receiver();
}

1484
Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
1485

1486
Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
1487

1488
Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1489 1490 1491
  if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
    return Type::NonInternal();
  }
1492
  JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1493
  if (!function.shared().HasBuiltinFunctionId()) {
1494 1495
    return Type::NonInternal();
  }
1496
  switch (function.shared().builtin_function_id()) {
1497
    case BuiltinFunctionId::kMathRandom:
1498
      return Type::PlainNumber();
1499 1500 1501 1502
    case BuiltinFunctionId::kMathFloor:
    case BuiltinFunctionId::kMathCeil:
    case BuiltinFunctionId::kMathRound:
    case BuiltinFunctionId::kMathTrunc:
1503
      return t->cache_->kIntegerOrMinusZeroOrNaN;
1504
    // Unary math functions.
1505 1506
    case BuiltinFunctionId::kMathAbs:
    case BuiltinFunctionId::kMathExp:
1507
      return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1508 1509 1510 1511 1512 1513 1514 1515
    case BuiltinFunctionId::kMathAcos:
    case BuiltinFunctionId::kMathAcosh:
    case BuiltinFunctionId::kMathAsin:
    case BuiltinFunctionId::kMathAsinh:
    case BuiltinFunctionId::kMathAtan:
    case BuiltinFunctionId::kMathAtanh:
    case BuiltinFunctionId::kMathCbrt:
    case BuiltinFunctionId::kMathCos:
1516
    case BuiltinFunctionId::kMathExpm1:
1517 1518 1519 1520 1521 1522 1523 1524
    case BuiltinFunctionId::kMathFround:
    case BuiltinFunctionId::kMathLog:
    case BuiltinFunctionId::kMathLog1p:
    case BuiltinFunctionId::kMathLog10:
    case BuiltinFunctionId::kMathLog2:
    case BuiltinFunctionId::kMathSin:
    case BuiltinFunctionId::kMathSqrt:
    case BuiltinFunctionId::kMathTan:
1525
      return Type::Number();
1526
    case BuiltinFunctionId::kMathSign:
1527
      return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1528
    // Binary math functions.
1529 1530 1531 1532
    case BuiltinFunctionId::kMathAtan2:
    case BuiltinFunctionId::kMathPow:
    case BuiltinFunctionId::kMathMax:
    case BuiltinFunctionId::kMathMin:
1533
      return Type::Number();
1534
    case BuiltinFunctionId::kMathImul:
1535
      return Type::Signed32();
1536
    case BuiltinFunctionId::kMathClz32:
1537
      return t->cache_->kZeroToThirtyTwo;
1538
    // Date functions.
1539
    case BuiltinFunctionId::kDateNow:
1540
      return t->cache_->kTimeValueType;
1541
    case BuiltinFunctionId::kDateGetDate:
1542
      return t->cache_->kJSDateDayType;
1543
    case BuiltinFunctionId::kDateGetDay:
1544
      return t->cache_->kJSDateWeekdayType;
1545
    case BuiltinFunctionId::kDateGetFullYear:
1546
      return t->cache_->kJSDateYearType;
1547
    case BuiltinFunctionId::kDateGetHours:
1548
      return t->cache_->kJSDateHourType;
1549
    case BuiltinFunctionId::kDateGetMilliseconds:
1550 1551
      return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
                         t->zone());
1552
    case BuiltinFunctionId::kDateGetMinutes:
1553
      return t->cache_->kJSDateMinuteType;
1554
    case BuiltinFunctionId::kDateGetMonth:
1555
      return t->cache_->kJSDateMonthType;
1556
    case BuiltinFunctionId::kDateGetSeconds:
1557
      return t->cache_->kJSDateSecondType;
1558
    case BuiltinFunctionId::kDateGetTime:
1559
      return t->cache_->kJSDateValueType;
1560 1561

    // Symbol functions.
1562
    case BuiltinFunctionId::kSymbolConstructor:
1563
      return Type::Symbol();
1564 1565 1566 1567
    case BuiltinFunctionId::kSymbolPrototypeToString:
      return Type::String();
    case BuiltinFunctionId::kSymbolPrototypeValueOf:
      return Type::Symbol();
1568 1569

    // BigInt functions.
1570
    case BuiltinFunctionId::kBigIntConstructor:
1571 1572 1573
      return Type::BigInt();

    // Number functions.
1574
    case BuiltinFunctionId::kNumberConstructor:
1575
      return Type::Number();
1576 1577 1578 1579
    case BuiltinFunctionId::kNumberIsFinite:
    case BuiltinFunctionId::kNumberIsInteger:
    case BuiltinFunctionId::kNumberIsNaN:
    case BuiltinFunctionId::kNumberIsSafeInteger:
1580
      return Type::Boolean();
1581
    case BuiltinFunctionId::kNumberParseFloat:
1582
      return Type::Number();
1583
    case BuiltinFunctionId::kNumberParseInt:
1584
      return t->cache_->kIntegerOrMinusZeroOrNaN;
1585
    case BuiltinFunctionId::kNumberToString:
1586 1587 1588
      return Type::String();

    // String functions.
1589
    case BuiltinFunctionId::kStringConstructor:
1590
      return Type::String();
1591
    case BuiltinFunctionId::kStringCharCodeAt:
1592 1593
      return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
                         t->zone());
1594
    case BuiltinFunctionId::kStringCharAt:
1595
      return Type::String();
1596
    case BuiltinFunctionId::kStringCodePointAt:
1597 1598
      return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
                         Type::Undefined(), t->zone());
1599 1600 1601
    case BuiltinFunctionId::kStringConcat:
    case BuiltinFunctionId::kStringFromCharCode:
    case BuiltinFunctionId::kStringFromCodePoint:
1602
      return Type::String();
1603 1604
    case BuiltinFunctionId::kStringIndexOf:
    case BuiltinFunctionId::kStringLastIndexOf:
1605
      return Type::Range(-1.0, String::kMaxLength, t->zone());
1606 1607
    case BuiltinFunctionId::kStringEndsWith:
    case BuiltinFunctionId::kStringIncludes:
1608
      return Type::Boolean();
1609 1610 1611
    case BuiltinFunctionId::kStringRaw:
    case BuiltinFunctionId::kStringRepeat:
    case BuiltinFunctionId::kStringSlice:
1612
      return Type::String();
1613
    case BuiltinFunctionId::kStringStartsWith:
1614
      return Type::Boolean();
1615 1616 1617 1618 1619 1620 1621 1622 1623
    case BuiltinFunctionId::kStringSubstr:
    case BuiltinFunctionId::kStringSubstring:
    case BuiltinFunctionId::kStringToLowerCase:
    case BuiltinFunctionId::kStringToString:
    case BuiltinFunctionId::kStringToUpperCase:
    case BuiltinFunctionId::kStringTrim:
    case BuiltinFunctionId::kStringTrimEnd:
    case BuiltinFunctionId::kStringTrimStart:
    case BuiltinFunctionId::kStringValueOf:
1624 1625
      return Type::String();

1626 1627
    case BuiltinFunctionId::kStringIterator:
    case BuiltinFunctionId::kStringIteratorNext:
1628 1629
      return Type::OtherObject();

1630 1631 1632 1633 1634 1635 1636 1637 1638
    case BuiltinFunctionId::kArrayEntries:
    case BuiltinFunctionId::kArrayKeys:
    case BuiltinFunctionId::kArrayValues:
    case BuiltinFunctionId::kTypedArrayEntries:
    case BuiltinFunctionId::kTypedArrayKeys:
    case BuiltinFunctionId::kTypedArrayValues:
    case BuiltinFunctionId::kArrayIteratorNext:
    case BuiltinFunctionId::kMapIteratorNext:
    case BuiltinFunctionId::kSetIteratorNext:
1639
      return Type::OtherObject();
1640
    case BuiltinFunctionId::kTypedArrayToStringTag:
1641 1642 1643 1644
      return Type::Union(Type::InternalizedString(), Type::Undefined(),
                         t->zone());

    // Array functions.
1645
    case BuiltinFunctionId::kArrayIsArray:
1646
      return Type::Boolean();
1647
    case BuiltinFunctionId::kArrayConcat:
1648
      return Type::Receiver();
1649
    case BuiltinFunctionId::kArrayEvery:
1650
      return Type::Boolean();
1651 1652
    case BuiltinFunctionId::kArrayFill:
    case BuiltinFunctionId::kArrayFilter:
1653
      return Type::Receiver();
1654
    case BuiltinFunctionId::kArrayFindIndex:
1655
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1656
    case BuiltinFunctionId::kArrayForEach:
1657
      return Type::Undefined();
1658
    case BuiltinFunctionId::kArrayIncludes:
1659
      return Type::Boolean();
1660
    case BuiltinFunctionId::kArrayIndexOf:
1661
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1662
    case BuiltinFunctionId::kArrayJoin:
1663
      return Type::String();
1664
    case BuiltinFunctionId::kArrayLastIndexOf:
1665
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1666
    case BuiltinFunctionId::kArrayMap:
1667
      return Type::Receiver();
1668
    case BuiltinFunctionId::kArrayPush:
1669
      return t->cache_->kPositiveSafeInteger;
1670 1671
    case BuiltinFunctionId::kArrayReverse:
    case BuiltinFunctionId::kArraySlice:
1672
      return Type::Receiver();
1673
    case BuiltinFunctionId::kArraySome:
1674
      return Type::Boolean();
1675
    case BuiltinFunctionId::kArraySplice:
1676
      return Type::Receiver();
1677
    case BuiltinFunctionId::kArrayUnshift:
1678
      return t->cache_->kPositiveSafeInteger;
1679 1680

    // ArrayBuffer functions.
1681
    case BuiltinFunctionId::kArrayBufferIsView:
1682 1683 1684
      return Type::Boolean();

    // Object functions.
1685
    case BuiltinFunctionId::kObjectAssign:
1686
      return Type::Receiver();
1687
    case BuiltinFunctionId::kObjectCreate:
1688
      return Type::OtherObject();
1689 1690 1691
    case BuiltinFunctionId::kObjectIs:
    case BuiltinFunctionId::kObjectHasOwnProperty:
    case BuiltinFunctionId::kObjectIsPrototypeOf:
1692
      return Type::Boolean();
1693
    case BuiltinFunctionId::kObjectToString:
1694 1695
      return Type::String();

1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706
    case BuiltinFunctionId::kPromiseAll:
      return Type::Receiver();
    case BuiltinFunctionId::kPromisePrototypeThen:
      return Type::Receiver();
    case BuiltinFunctionId::kPromiseRace:
      return Type::Receiver();
    case BuiltinFunctionId::kPromiseReject:
      return Type::Receiver();
    case BuiltinFunctionId::kPromiseResolve:
      return Type::Receiver();

1707
    // RegExp functions.
1708
    case BuiltinFunctionId::kRegExpCompile:
1709
      return Type::OtherObject();
1710
    case BuiltinFunctionId::kRegExpExec:
1711
      return Type::Union(Type::Array(), Type::Null(), t->zone());
1712
    case BuiltinFunctionId::kRegExpTest:
1713
      return Type::Boolean();
1714
    case BuiltinFunctionId::kRegExpToString:
1715 1716 1717
      return Type::String();

    // Function functions.
1718
    case BuiltinFunctionId::kFunctionBind:
1719
      return Type::BoundFunction();
1720
    case BuiltinFunctionId::kFunctionHasInstance:
1721 1722 1723
      return Type::Boolean();

    // Global functions.
1724 1725 1726 1727 1728 1729
    case BuiltinFunctionId::kGlobalDecodeURI:
    case BuiltinFunctionId::kGlobalDecodeURIComponent:
    case BuiltinFunctionId::kGlobalEncodeURI:
    case BuiltinFunctionId::kGlobalEncodeURIComponent:
    case BuiltinFunctionId::kGlobalEscape:
    case BuiltinFunctionId::kGlobalUnescape:
1730
      return Type::String();
1731 1732
    case BuiltinFunctionId::kGlobalIsFinite:
    case BuiltinFunctionId::kGlobalIsNaN:
1733 1734 1735
      return Type::Boolean();

    // Map functions.
1736 1737
    case BuiltinFunctionId::kMapClear:
    case BuiltinFunctionId::kMapForEach:
1738
      return Type::Undefined();
1739 1740
    case BuiltinFunctionId::kMapDelete:
    case BuiltinFunctionId::kMapHas:
1741
      return Type::Boolean();
1742 1743 1744 1745
    case BuiltinFunctionId::kMapEntries:
    case BuiltinFunctionId::kMapKeys:
    case BuiltinFunctionId::kMapSet:
    case BuiltinFunctionId::kMapValues:
1746 1747 1748
      return Type::OtherObject();

    // Set functions.
1749 1750 1751
    case BuiltinFunctionId::kSetAdd:
    case BuiltinFunctionId::kSetEntries:
    case BuiltinFunctionId::kSetValues:
1752
      return Type::OtherObject();
1753 1754
    case BuiltinFunctionId::kSetClear:
    case BuiltinFunctionId::kSetForEach:
1755
      return Type::Undefined();
1756 1757
    case BuiltinFunctionId::kSetDelete:
    case BuiltinFunctionId::kSetHas:
1758 1759 1760
      return Type::Boolean();

    // WeakMap functions.
1761 1762
    case BuiltinFunctionId::kWeakMapDelete:
    case BuiltinFunctionId::kWeakMapHas:
1763
      return Type::Boolean();
1764
    case BuiltinFunctionId::kWeakMapSet:
1765 1766 1767
      return Type::OtherObject();

    // WeakSet functions.
1768
    case BuiltinFunctionId::kWeakSetAdd:
1769
      return Type::OtherObject();
1770 1771
    case BuiltinFunctionId::kWeakSetDelete:
    case BuiltinFunctionId::kWeakSetHas:
1772 1773 1774
      return Type::Boolean();
    default:
      return Type::NonInternal();
1775
  }
1776 1777
}

1778
Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1779
  return TypeUnaryOp(node, JSCallTyper);
1780
}
1781

1782
Type Typer::Visitor::TypeJSCall(Node* node) {
1783
  // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1784 1785
  // argument types for the JSCallTyper above.
  return TypeUnaryOp(node, JSCallTyper);
1786 1787
}

1788
Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1789 1790 1791
  return TypeUnaryOp(node, JSCallTyper);
}

1792
Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1793
  return TypeUnaryOp(node, JSCallTyper);
1794
}
1795

1796
Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1797
  switch (CallRuntimeParametersOf(node->op()).id()) {
1798 1799
    case Runtime::kInlineIsJSReceiver:
      return TypeUnaryOp(node, ObjectIsReceiver);
1800
    case Runtime::kInlineIsSmi:
1801
      return TypeUnaryOp(node, ObjectIsSmi);
1802
    case Runtime::kInlineIsArray:
1803
    case Runtime::kInlineIsTypedArray:
1804
    case Runtime::kInlineIsRegExp:
1805
      return Type::Boolean();
1806
    case Runtime::kInlineCreateIterResultObject:
1807
      return Type::OtherObject();
1808 1809 1810 1811
    case Runtime::kInlineToLength:
      return TypeUnaryOp(node, ToLength);
    case Runtime::kInlineToNumber:
      return TypeUnaryOp(node, ToNumber);
1812
    case Runtime::kInlineToObject:
1813 1814 1815
      return TypeUnaryOp(node, ToObject);
    case Runtime::kInlineToString:
      return TypeUnaryOp(node, ToString);
1816 1817
    case Runtime::kHasInPrototypeChain:
      return Type::Boolean();
1818 1819 1820
    default:
      break;
  }
1821 1822 1823
  // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
  // have a few weird runtime calls that return the hole or even FixedArrays;
  // change this once those weird runtime calls have been removed.
1824
  return Type::Any();
1825 1826
}

1827
Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1828 1829
  return Type::OtherInternal();
}
1830

1831
Type Typer::Visitor::TypeJSForInNext(Node* node) {
1832
  return Type::Union(Type::String(), Type::Undefined(), zone());
1833 1834
}

1835
Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1836
  STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1837
  Type const cache_type =
1838
      Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1839
  Type const cache_array = Type::OtherInternal();
1840
  Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1841
  return Type::Tuple(cache_type, cache_array, cache_length, zone());
1842 1843
}

1844
Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1845

1846
Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1847

1848
Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1849

1850
Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1851

1852
Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1853

1854
Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1855
  return Type::SignedSmall();
1856 1857
}

1858
Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1859 1860 1861
  return Type::Any();
}

1862
Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1863 1864
  return Type::Any();
}
1865

1866
Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1867 1868 1869
  return Type::Any();
}

1870
Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1871

1872
Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1873

1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885
Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
  return Type::OtherObject();
}

Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
  return Type::OtherObject();
}

Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
  return Type::OtherObject();
}

1886
Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1887 1888 1889
  return Type::Undefined();
}

1890
Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1891 1892 1893
  return Type::Receiver();
}

1894
Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1895
  return Type::Receiver();
1896 1897
}

1898
Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1899 1900 1901
  return Type::Undefined();
}

1902
Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1903 1904 1905
  return Type::Undefined();
}

1906 1907
// Simplified operators.

1908
Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1909

1910
// static
1911
Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1912 1913
  return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
}
1914

1915
// static
1916
Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1917 1918 1919 1920 1921
  return FalsifyUndefined(
      NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
}

// static
1922
Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1923 1924 1925 1926
  return FalsifyUndefined(
      Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
}

1927
Type Typer::Visitor::TypeNumberEqual(Node* node) {
1928 1929 1930
  return TypeBinaryOp(node, NumberEqualTyper);
}

1931
Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1932 1933
  return TypeBinaryOp(node, NumberLessThanTyper);
}
1934

1935
Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1936
  return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1937 1938
}

1939
Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1940
  return TypeBinaryOp(node, NumberEqualTyper);
1941 1942
}

1943
Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1944
  return TypeBinaryOp(node, NumberLessThanTyper);
1945 1946
}

1947
Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1948
  return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1949 1950
}

1951 1952
Type Typer::Visitor::TypeStringConcat(Node* node) { return Type::String(); }

1953
Type Typer::Visitor::TypeStringToNumber(Node* node) {
1954 1955 1956
  return TypeUnaryOp(node, ToNumber);
}

1957
Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1958 1959 1960
  return TypeUnaryOp(node, ToNumber);
}

1961
Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1962 1963 1964
  return Type::Integral32();
}

1965
Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1966 1967 1968
  return Type::Number();
}

1969
// static
1970
Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1971
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1972 1973 1974 1975 1976
    return t->singleton_true_;
  }
  return Type::Boolean();
}

1977
Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1978
  return TypeBinaryOp(node, ReferenceEqualTyper);
1979 1980
}

1981
// static
1982
Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1983 1984 1985
  return t->operation_typer()->SameValue(lhs, rhs);
}

1986
Type Typer::Visitor::TypeSameValue(Node* node) {
1987 1988 1989
  return TypeBinaryOp(node, SameValueTyper);
}

1990
Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1991

1992
Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1993

1994
Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1995
  return Type::Boolean();
1996 1997
}

1998
Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
1999 2000 2001
  return Type::String();
}

2002
Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2003 2004 2005
  return Type::String();
}

2006
Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2007 2008
  return Type::String();
}
2009

2010
Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2011 2012
  return Type::String();
}
2013

2014
Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2015
  return typer_->cache_->kUint16;
2016 2017
}

2018
Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2019 2020 2021
  return Type::Range(0.0, String::kMaxCodePoint, zone());
}

2022
Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2023
  return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2024 2025
}

2026
Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2027
  return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2028 2029
}

2030
Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2031 2032
  return Type::Range(-1.0, String::kMaxLength, zone());
}
2033

2034
Type Typer::Visitor::TypeStringLength(Node* node) {
2035
  return typer_->cache_->kStringLengthType;
2036 2037
}

2038
Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2039

2040
Type Typer::Visitor::TypePoisonIndex(Node* node) {
2041
  return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2042 2043
}

2044
Type Typer::Visitor::TypeCheckBounds(Node* node) {
2045 2046
  return typer_->operation_typer_.CheckBounds(Operand(node, 0),
                                              Operand(node, 1));
2047 2048
}

2049 2050
Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
  Type type = Operand(node, 0);
2051 2052 2053
  return type;
}

2054
Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2055

2056 2057
Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
  Type arg = Operand(node, 0);
2058 2059 2060
  return Type::Intersect(arg, Type::InternalizedString(), zone());
}

2061
Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2062

2063
Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2064

2065
Type Typer::Visitor::TypeCheckNumber(Node* node) {
2066
  return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2067 2068
}

2069 2070
Type Typer::Visitor::TypeCheckReceiver(Node* node) {
  Type arg = Operand(node, 0);
2071 2072 2073
  return Type::Intersect(arg, Type::Receiver(), zone());
}

2074
Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2075
  Type arg = Operand(node, 0);
2076
  return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2077 2078
}

2079 2080
Type Typer::Visitor::TypeCheckSmi(Node* node) {
  Type arg = Operand(node, 0);
2081
  return Type::Intersect(arg, Type::SignedSmall(), zone());
2082 2083
}

2084 2085
Type Typer::Visitor::TypeCheckString(Node* node) {
  Type arg = Operand(node, 0);
2086
  return Type::Intersect(arg, Type::String(), zone());
2087 2088
}

2089 2090
Type Typer::Visitor::TypeCheckSymbol(Node* node) {
  Type arg = Operand(node, 0);
2091 2092 2093
  return Type::Intersect(arg, Type::Symbol(), zone());
}

2094
Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2095
  return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2096 2097
}

2098 2099
Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
  Type type = Operand(node, 0);
2100 2101 2102 2103
  type = Type::Intersect(type, Type::NonInternal(), zone());
  return type;
}

2104 2105
Type Typer::Visitor::TypeConvertReceiver(Node* node) {
  Type arg = Operand(node, 0);
2106 2107 2108
  return typer_->operation_typer_.ConvertReceiver(arg);
}

2109 2110
Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
  Type type = Operand(node, 0);
2111
  return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2112 2113
}

2114
Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2115 2116 2117
  UNREACHABLE();
}

2118
Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2119

2120
Type Typer::Visitor::TypeAllocate(Node* node) {
2121 2122
  return AllocateTypeOf(node->op());
}
2123

2124
Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2125

2126
Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2127 2128 2129
  return Type::NonInternal();
}

2130
Type Typer::Visitor::TypeLoadField(Node* node) {
2131
  return FieldAccessOf(node->op()).type;
2132 2133
}

2134 2135
Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }

2136
Type Typer::Visitor::TypeLoadElement(Node* node) {
2137
  return ElementAccessOf(node->op()).type;
2138 2139
}

2140
Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2141
  switch (ExternalArrayTypeOf(node->op())) {
2142 2143
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
  case kExternal##ElemType##Array:                    \
2144
    return typer_->cache_->k##ElemType;
2145 2146 2147 2148 2149 2150 2151 2152
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  }
  UNREACHABLE();
}

Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
  switch (ExternalArrayTypeOf(node->op())) {
2153 2154
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
  case kExternal##ElemType##Array:                    \
2155
    return typer_->cache_->k##ElemType;
2156 2157 2158 2159 2160
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  }
  UNREACHABLE();
}
2161

2162
Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2163
Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2164

2165
Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2166

2167
Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2168 2169 2170
  UNREACHABLE();
}

2171
Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2172 2173 2174
  UNREACHABLE();
}

2175
Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2176 2177 2178
  UNREACHABLE();
}

2179
Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2180

2181
Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2182

2183 2184
Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }

2185
Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2186 2187 2188
  return TypeUnaryOp(node, ObjectIsArrayBufferView);
}

2189
Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2190 2191 2192
  return TypeUnaryOp(node, ObjectIsBigInt);
}

2193
Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2194 2195 2196
  return TypeUnaryOp(node, ObjectIsCallable);
}

2197
Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2198 2199 2200
  return TypeUnaryOp(node, ObjectIsConstructor);
}

2201
Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2202
  return TypeUnaryOp(node, ObjectIsDetectableCallable);
2203
}
2204

2205
Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2206 2207 2208
  return TypeUnaryOp(node, ObjectIsMinusZero);
}

2209 2210 2211 2212
Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
  return TypeUnaryOp(node, NumberIsMinusZero);
}

2213
Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2214 2215 2216
  return Type::Boolean();
}

2217
Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2218

2219
Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2220 2221 2222
  return Type::Boolean();
}

2223
Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2224

2225
Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2226 2227 2228
  return Type::Boolean();
}

2229
Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2230

2231
Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2232

2233
Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2234 2235 2236
  return TypeUnaryOp(node, ObjectIsNaN);
}

2237
Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2238 2239 2240
  return TypeUnaryOp(node, NumberIsNaN);
}

2241
Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2242 2243 2244
  return TypeUnaryOp(node, ObjectIsNonCallable);
}

2245
Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2246 2247 2248
  return TypeUnaryOp(node, ObjectIsNumber);
}

2249
Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2250
  return TypeUnaryOp(node, ObjectIsReceiver);
2251 2252
}

2253
Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2254
  return TypeUnaryOp(node, ObjectIsSmi);
2255
}
2256

2257
Type Typer::Visitor::TypeObjectIsString(Node* node) {
2258 2259
  return TypeUnaryOp(node, ObjectIsString);
}
2260

2261
Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2262 2263 2264
  return TypeUnaryOp(node, ObjectIsSymbol);
}

2265
Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2266 2267 2268
  return TypeUnaryOp(node, ObjectIsUndetectable);
}

2269
Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2270
  return TypeCache::Get()->kArgumentsLengthType;
2271 2272
}

2273
Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2274
  return Type::ExternalPointer();
2275 2276
}

2277
Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2278 2279 2280
  return Type::OtherInternal();
}

2281
Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2282 2283 2284
  return Type::OtherInternal();
}

2285
Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2286 2287 2288
  return Type::OtherInternal();
}

2289
Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2290

2291 2292 2293 2294
Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
  return Type::String();
}

2295
Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2296
  return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2297 2298
}

2299
Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2300
  return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2301 2302
}

2303
Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2304

2305
// Heap constants.
2306

2307
Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2308
  return Type::NewConstant(typer_->broker(), value, zone());
2309 2310
}

2311 2312 2313
}  // namespace compiler
}  // namespace internal
}  // namespace v8