typer.cc 73.8 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/codegen/tick-counter.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/init/bootstrapper.h"
22
#include "src/objects/objects-inl.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 38
Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph,
             TickCounter* tick_counter)
39
    : flags_(flags),
40
      graph_(graph),
41
      decorator_(nullptr),
42
      cache_(TypeCache::Get()),
43
      broker_(broker),
44 45
      operation_typer_(broker, zone()),
      tick_counter_(tick_counter) {
46 47
  singleton_false_ = operation_typer_.singleton_false();
  singleton_true_ = operation_typer_.singleton_true();
48 49

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

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


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

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

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

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
79
    return UpdateType(node, Type##x(node));
80
      DECLARE_CASE(Start)
81
      DECLARE_CASE(IfException)
82 83
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
84 85
      SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
86 87 88 89 90 91
      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

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

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return UpdateType(node, TypeUnaryOp(node, x));
      SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
105
      SIMPLIFIED_BIGINT_UNOP_LIST(DECLARE_CASE)
106
      SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
107
      SIMPLIFIED_SPECULATIVE_BIGINT_UNOP_LIST(DECLARE_CASE)
108 109
#undef DECLARE_CASE

110
#define DECLARE_CASE(x) case IrOpcode::k##x:
111 112 113 114 115 116 117 118 119 120
      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)
121 122
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
123 124
      DECLARE_CASE(TrapIf)
      DECLARE_CASE(TrapUnless)
125
      DECLARE_CASE(Return)
126
      DECLARE_CASE(TailCall)
127
      DECLARE_CASE(Terminate)
128 129 130
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
131
      DECLARE_CASE(End)
132 133
      SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
134
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
135
      MACHINE_OP_LIST(DECLARE_CASE)
136 137 138 139 140 141
#undef DECLARE_CASE
      break;
    }
    return NoChange();
  }

142
  Type TypeNode(Node* node) {
143
    switch (node->opcode()) {
144 145 146 147 148
#define DECLARE_CASE(x) \
      case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
#undef DECLARE_CASE

149
#define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
150
      DECLARE_CASE(Start)
151
      DECLARE_CASE(IfException)
152 153
      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
      COMMON_OP_LIST(DECLARE_CASE)
154 155
      SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
      SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
156 157 158 159
      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
      JS_OBJECT_OP_LIST(DECLARE_CASE)
      JS_CONTEXT_OP_LIST(DECLARE_CASE)
      JS_OTHER_OP_LIST(DECLARE_CASE)
160 161
#undef DECLARE_CASE

162 163 164 165
#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return TypeBinaryOp(node, x);
      SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
166
      SIMPLIFIED_BIGINT_BINOP_LIST(DECLARE_CASE)
167
      SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
168
      SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_CASE)
169 170 171 172 173 174
#undef DECLARE_CASE

#define DECLARE_CASE(x) \
  case IrOpcode::k##x:  \
    return TypeUnaryOp(node, x);
      SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
175
      SIMPLIFIED_BIGINT_UNOP_LIST(DECLARE_CASE)
176
      SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
177
      SIMPLIFIED_SPECULATIVE_BIGINT_UNOP_LIST(DECLARE_CASE)
178 179
#undef DECLARE_CASE

180
#define DECLARE_CASE(x) case IrOpcode::k##x:
181 182 183 184 185 186 187 188 189 190
      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)
191 192
      DECLARE_CASE(DeoptimizeIf)
      DECLARE_CASE(DeoptimizeUnless)
193 194
      DECLARE_CASE(TrapIf)
      DECLARE_CASE(TrapUnless)
195
      DECLARE_CASE(Return)
196
      DECLARE_CASE(TailCall)
197
      DECLARE_CASE(Terminate)
198 199 200
      DECLARE_CASE(OsrNormalEntry)
      DECLARE_CASE(OsrLoopEntry)
      DECLARE_CASE(Throw)
201
      DECLARE_CASE(End)
202 203
      SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
      SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
204
      MACHINE_SIMD_OP_LIST(DECLARE_CASE)
205
      MACHINE_OP_LIST(DECLARE_CASE)
206 207 208
#undef DECLARE_CASE
      break;
    }
209
    UNREACHABLE();
210 211
  }

212
  Type TypeConstant(Handle<Object> value);
213

214 215
 private:
  Typer* typer_;
216
  LoopVariableOptimizer* induction_vars_;
217
  ZoneSet<NodeId> weakened_nodes_;
218 219
  // TODO(tebbi): remove once chromium:906567 is resolved.
  ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_;
220

221
#define DECLARE_METHOD(x) inline Type Type##x(Node* node);
222
  DECLARE_METHOD(Start)
223
  DECLARE_METHOD(IfException)
224 225 226 227
  COMMON_OP_LIST(DECLARE_METHOD)
  SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
  SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
  JS_OP_LIST(DECLARE_METHOD)
228 229
#undef DECLARE_METHOD

230
  Type TypeOrNone(Node* node) {
231 232
    return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
                                         : Type::None();
233 234
  }

235
  Type Operand(Node* node, int i) {
236
    Node* operand_node = NodeProperties::GetValueInput(node, i);
237
    return TypeOrNone(operand_node);
238 239
  }

240
  Type Weaken(Node* node, Type current_type, Type previous_type);
241

242
  Zone* zone() { return typer_->zone(); }
243
  Graph* graph() { return typer_->graph(); }
244

245 246 247 248 249
  void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
  bool IsWeakened(NodeId node_id) {
    return weakened_nodes_.find(node_id) != weakened_nodes_.end();
  }

250 251
  using UnaryTyperFun = Type (*)(Type, Typer* t);
  using BinaryTyperFun = Type (*)(Type, Type, Typer* t);
252

253 254
  Type TypeUnaryOp(Node* node, UnaryTyperFun);
  Type TypeBinaryOp(Node* node, BinaryTyperFun);
255

256 257
  static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
                                  BinaryTyperFun f);
258

259 260 261 262 263
  enum ComparisonOutcomeFlags {
    kComparisonTrue = 1,
    kComparisonFalse = 2,
    kComparisonUndefined = 4
  };
264
  using ComparisonOutcome = base::Flags<ComparisonOutcomeFlags>;
265 266

  static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
267 268 269 270 271 272 273 274 275 276 277 278 279
  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*);
280
  static Type ToNumberConvertBigInt(Type, Typer*);
281 282 283 284 285 286
  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); \
287 288
  }
  SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
289
  SIMPLIFIED_BIGINT_UNOP_LIST(DECLARE_METHOD)
290
  SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
291
  SIMPLIFIED_SPECULATIVE_BIGINT_UNOP_LIST(DECLARE_METHOD)
292
#undef DECLARE_METHOD
293 294 295
#define DECLARE_METHOD(Name)                       \
  static Type Name(Type lhs, Type rhs, Typer* t) { \
    return t->operation_typer_.Name(lhs, rhs);     \
296 297
  }
  SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
298
  SIMPLIFIED_BIGINT_BINOP_LIST(DECLARE_METHOD)
299
  SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
300
  SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(DECLARE_METHOD)
301
#undef DECLARE_METHOD
302

303 304 305 306 307 308
  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*);
309
  static Type NumberIsMinusZero(Type, Typer*);
310 311 312 313 314 315 316 317 318 319 320 321 322 323
  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*);
324 325 326
  JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
#undef DECLARE_METHOD

327
  static Type JSCallTyper(Type, Typer*);
328

329 330 331 332 333
  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*);
334
  static Type SameValueNumbersOnlyTyper(Type, Type, Typer*);
335 336
  static Type StringFromSingleCharCodeTyper(Type, Typer*);
  static Type StringFromSingleCodePointTyper(Type, Typer*);
337

338
  Reduction UpdateType(Node* node, Type current) {
339
    if (NodeProperties::IsTyped(node)) {
340
      // Widen the type of a previously typed node.
341
      Type previous = NodeProperties::GetType(node);
342 343
      if (node->opcode() == IrOpcode::kPhi ||
          node->opcode() == IrOpcode::kInductionVariablePhi) {
344
        // Speed up termination in the presence of range types:
345
        current = Weaken(node, current, previous);
346
      }
347

348
      if (V8_UNLIKELY(!previous.Is(current))) {
349
        AllowHandleDereference allow;
350
        std::ostringstream ostream;
351
        node->Print(ostream);
352 353 354 355 356 357 358 359 360 361

        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);
            }
362
          }
363 364 365 366 367 368 369 370 371 372 373 374 375

          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";
            }
376
          }
377 378
          ostream << "  ";
          current.PrintTo(ostream);
379 380
          ostream << "\n";
        }
381

382 383 384 385 386 387
        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);
388 389 390
          remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
                                             ? NodeProperties::GetType(input)
                                             : Type::Invalid();
391
        }
392
        remembered_types_[{node, 2}] = current;
393
      }
394

395
      NodeProperties::SetType(node, current);
396
      if (!current.Is(previous)) {
397 398 399 400 401
        // If something changed, revisit all uses.
        return Changed(node);
      }
      return NoChange();
    } else {
402 403 404
      if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
        for (int i = 0; i < 2; ++i) {
          Node* input = NodeProperties::GetValueInput(node, i);
405 406 407
          remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
                                             ? NodeProperties::GetType(input)
                                             : Type::Invalid();
408
        }
409
        remembered_types_[{node, 2}] = current;
410 411
      }

412 413
      // No previous type, simply update the type.
      NodeProperties::SetType(node, current);
414
      return Changed(node);
415 416 417 418
    }
  }
};

419
void Typer::Run() { Run(NodeVector(zone()), nullptr); }
420

421 422 423 424 425 426
void Typer::Run(const NodeVector& roots,
                LoopVariableOptimizer* induction_vars) {
  if (induction_vars != nullptr) {
    induction_vars->ChangeToInductionVariablePhis();
  }
  Visitor visitor(this, induction_vars);
427
  GraphReducer graph_reducer(zone(), graph(), tick_counter_);
428
  graph_reducer.AddReducer(&visitor);
429
  for (Node* const root : roots) graph_reducer.ReduceNode(root);
430
  graph_reducer.ReduceGraph();
431

432
  if (induction_vars != nullptr) {
433
    induction_vars->ChangeToPhisAndInsertGuards();
434 435
  }
}
436

437
void Typer::Decorator::Decorate(Node* node) {
438
  if (node->op()->ValueOutputCount() > 0) {
439 440 441 442
    // 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)) {
443
      Visitor typing(typer_, nullptr);
444
      Type type = typing.TypeNode(node);
445
      if (is_typed) {
446 447
        type = Type::Intersect(type, NodeProperties::GetType(node),
                               typer_->zone());
448
      }
449
      NodeProperties::SetType(node, type);
450
    }
451 452 453 454
  }
}


455 456 457 458 459 460
// -----------------------------------------------------------------------------

// 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.

461 462
Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
  Type input = Operand(node, 0);
463
  return input.IsNone() ? Type::None() : f(input, typer_);
464 465
}

466 467 468
Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
  Type left = Operand(node, 0);
  Type right = Operand(node, 1);
469 470
  return left.IsNone() || right.IsNone() ? Type::None()
                                         : f(left, right, typer_);
471 472
}

473 474
Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
                                         BinaryTyperFun f) {
475 476
  lhs = ToNumeric(lhs, t);
  rhs = ToNumeric(rhs, t);
477 478
  bool lhs_is_number = lhs.Is(Type::Number());
  bool rhs_is_number = rhs.Is(Type::Number());
479 480 481
  if (lhs_is_number && rhs_is_number) {
    return f(lhs, rhs, t);
  }
482 483 484
  // In order to maintain monotonicity, the following two conditions are
  // intentionally asymmetric.
  if (lhs_is_number) {
485 486
    return Type::Number();
  }
487
  if (lhs.Is(Type::BigInt())) {
488 489
    return Type::BigInt();
  }
490 491
  return Type::Numeric();
}
492

493 494 495 496 497 498 499 500 501
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;
}

502
Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
503
  if (outcome == 0) return Type::None();
504 505 506
  if ((outcome & kComparisonFalse) != 0 ||
      (outcome & kComparisonUndefined) != 0) {
    return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
507
                                            : t->singleton_false_;
508
  }
509
  DCHECK_NE(0, outcome & kComparisonTrue);
510
  return t->singleton_true_;
511 512
}

513
Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
514
  type = ToNumeric(type, t);
515
  if (type.Is(Type::Number())) {
516
    return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
517 518 519 520
  }
  return Type::Numeric();
}

521
Type Typer::Visitor::Decrement(Type type, Typer* t) {
522
  type = ToNumeric(type, t);
523
  if (type.Is(Type::Number())) {
524
    return NumberSubtract(type, t->cache_->kSingletonOne, t);
525 526 527 528
  }
  return Type::Numeric();
}

529
Type Typer::Visitor::Increment(Type type, Typer* t) {
530
  type = ToNumeric(type, t);
531
  if (type.Is(Type::Number())) {
532
    return NumberAdd(type, t->cache_->kSingletonOne, t);
533 534 535 536
  }
  return Type::Numeric();
}

537
Type Typer::Visitor::Negate(Type type, Typer* t) {
538
  type = ToNumeric(type, t);
539
  if (type.Is(Type::Number())) {
540
    return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
541 542 543 544
  }
  return Type::Numeric();
}

545 546
// Type conversion.

547
Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
548
  if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
549 550 551 552 553
    return type;
  }
  return Type::Primitive();
}

554
Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
555
  return t->operation_typer()->ToBoolean(type);
556 557 558
}


559
// static
560
Type Typer::Visitor::ToInteger(Type type, Typer* t) {
561 562
  // ES6 section 7.1.4 ToInteger ( argument )
  type = ToNumber(type, t);
563 564
  if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
  if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
565
    return Type::Union(
566 567
        Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
        t->cache_->kSingletonZero, t->zone());
568
  }
569
  return t->cache_->kIntegerOrMinusZero;
570 571 572 573
}


// static
574
Type Typer::Visitor::ToLength(Type type, Typer* t) {
575
  // ES6 section 7.1.15 ToLength ( argument )
576
  type = ToInteger(type, t);
577 578 579
  if (type.IsNone()) return type;
  double min = type.Min();
  double max = type.Max();
580 581 582 583 584 585
  if (max <= 0.0) {
    return Type::NewConstant(0, t->zone());
  }
  if (min >= kMaxSafeInteger) {
    return Type::NewConstant(kMaxSafeInteger, t->zone());
  }
586
  if (min <= 0.0) min = 0.0;
587
  if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
588 589 590 591 592
  return Type::Range(min, max, t->zone());
}


// static
593
Type Typer::Visitor::ToName(Type type, Typer* t) {
594 595
  // ES6 section 7.1.14 ToPropertyKey ( argument )
  type = ToPrimitive(type, t);
596 597
  if (type.Is(Type::Name())) return type;
  if (type.Maybe(Type::Symbol())) return Type::Name();
598 599 600 601 602
  return ToString(type, t);
}


// static
603
Type Typer::Visitor::ToNumber(Type type, Typer* t) {
604
  return t->operation_typer_.ToNumber(type);
605 606
}

607 608 609 610 611
// static
Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
  return t->operation_typer_.ToNumberConvertBigInt(type);
}

612
// static
613
Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
614 615
  return t->operation_typer_.ToNumeric(type);
}
616

617
// static
618
Type Typer::Visitor::ToObject(Type type, Typer* t) {
619
  // ES6 section 7.1.13 ToObject ( argument )
620 621 622
  if (type.Is(Type::Receiver())) return type;
  if (type.Is(Type::Primitive())) return Type::OtherObject();
  if (!type.Maybe(Type::OtherUndetectable())) {
623 624
    return Type::DetectableReceiver();
  }
625 626 627 628 629
  return Type::Receiver();
}


// static
630
Type Typer::Visitor::ToString(Type type, Typer* t) {
631 632
  // ES6 section 7.1.12 ToString ( argument )
  type = ToPrimitive(type, t);
633
  if (type.Is(Type::String())) return type;
634 635 636
  return Type::String();
}

637 638
// Type checks.

639
Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
640
  // TODO(turbofan): Introduce a Type::ArrayBufferView?
641
  CHECK(!type.IsNone());
642
  if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
643 644 645
  return Type::Boolean();
}

646
Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
647
  CHECK(!type.IsNone());
648 649
  if (type.Is(Type::BigInt())) return t->singleton_true_;
  if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
650 651 652
  return Type::Boolean();
}

653
Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
654
  CHECK(!type.IsNone());
655 656
  if (type.Is(Type::Callable())) return t->singleton_true_;
  if (!type.Maybe(Type::Callable())) return t->singleton_false_;
657 658 659
  return Type::Boolean();
}

660
Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
661
  // TODO(turbofan): Introduce a Type::Constructor?
662
  CHECK(!type.IsNone());
663
  if (!type.Maybe(Type::Callable())) return t->singleton_false_;
664 665 666
  return Type::Boolean();
}

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

674
Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
675
  CHECK(!type.IsNone());
676 677
  if (type.Is(Type::MinusZero())) return t->singleton_true_;
  if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
678 679 680
  return Type::Boolean();
}

681
Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) {
682
  CHECK(!type.IsNone());
683 684 685 686 687
  if (type.Is(Type::MinusZero())) return t->singleton_true_;
  if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
  return Type::Boolean();
}

688
Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
689
  CHECK(!type.IsNone());
690 691
  if (type.Is(Type::NaN())) return t->singleton_true_;
  if (!type.Maybe(Type::NaN())) return t->singleton_false_;
692 693 694
  return Type::Boolean();
}

695
Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
696
  CHECK(!type.IsNone());
697 698
  if (type.Is(Type::NaN())) return t->singleton_true_;
  if (!type.Maybe(Type::NaN())) return t->singleton_false_;
699 700 701
  return Type::Boolean();
}

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

709
Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
710
  CHECK(!type.IsNone());
711 712
  if (type.Is(Type::Number())) return t->singleton_true_;
  if (!type.Maybe(Type::Number())) return t->singleton_false_;
713 714 715
  return Type::Boolean();
}

716
Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
717
  CHECK(!type.IsNone());
718 719
  if (type.Is(Type::Receiver())) return t->singleton_true_;
  if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
720 721 722
  return Type::Boolean();
}

723
Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
724
  if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
725 726 727
  return Type::Boolean();
}

728
Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
729
  CHECK(!type.IsNone());
730 731
  if (type.Is(Type::String())) return t->singleton_true_;
  if (!type.Maybe(Type::String())) return t->singleton_false_;
732 733
  return Type::Boolean();
}
734

735
Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
736
  CHECK(!type.IsNone());
737 738
  if (type.Is(Type::Symbol())) return t->singleton_true_;
  if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
739 740 741
  return Type::Boolean();
}

742
Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
743
  CHECK(!type.IsNone());
744 745
  if (type.Is(Type::Undetectable())) return t->singleton_true_;
  if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
746 747 748 749
  return Type::Boolean();
}


750 751 752 753 754
// -----------------------------------------------------------------------------


// Control operators.

755
Type Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
756

757
Type Typer::Visitor::TypeIfException(Node* node) { return Type::NonInternal(); }
758

759
// Common operators.
760

761
Type Typer::Visitor::TypeParameter(Node* node) {
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
  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)) {
783
    return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
784 785 786 787 788
  } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
    return Type::OtherInternal();
  }
  return Type::NonInternal();
}
789

790
Type Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
791

792
Type Typer::Visitor::TypeRetain(Node* node) { UNREACHABLE(); }
793

794
Type Typer::Visitor::TypeInt32Constant(Node* node) { UNREACHABLE(); }
795

796
Type Typer::Visitor::TypeInt64Constant(Node* node) { UNREACHABLE(); }
797

798
Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { UNREACHABLE(); }
799

800
Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { UNREACHABLE(); }
801

802
Type Typer::Visitor::TypeFloat32Constant(Node* node) { UNREACHABLE(); }
803

804
Type Typer::Visitor::TypeFloat64Constant(Node* node) { UNREACHABLE(); }
805

806
Type Typer::Visitor::TypeNumberConstant(Node* node) {
807
  double number = OpParameter<double>(node->op());
808
  return Type::NewConstant(number, zone());
809 810
}

811
Type Typer::Visitor::TypeHeapConstant(Node* node) {
812
  return TypeConstant(HeapConstantOf(node->op()));
813 814
}

815 816
Type Typer::Visitor::TypeCompressedHeapConstant(Node* node) { UNREACHABLE(); }

817
Type Typer::Visitor::TypeExternalConstant(Node* node) {
818
  return Type::ExternalPointer();
819 820
}

821
Type Typer::Visitor::TypePointerConstant(Node* node) {
822 823
  return Type::ExternalPointer();
}
824

825
Type Typer::Visitor::TypeSelect(Node* node) {
826
  return Type::Union(Operand(node, 1), Operand(node, 2), zone());
827 828
}

829
Type Typer::Visitor::TypePhi(Node* node) {
830
  int arity = node->op()->ValueInputCount();
831
  Type type = Operand(node, 0);
832
  for (int i = 1; i < arity; ++i) {
833
    type = Type::Union(type, Operand(node, i), zone());
834
  }
835
  return type;
836 837
}

838
Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
839 840 841 842
  int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
  DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
  DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());

843 844
  Type initial_type = Operand(node, 0);
  Type increment_type = Operand(node, 2);
845 846 847

  // We only handle integer induction variables (otherwise ranges
  // do not apply and we cannot do anything).
848 849
  if (!initial_type.Is(typer_->cache_->kInteger) ||
      !increment_type.Is(typer_->cache_->kInteger)) {
850 851 852 853 854
    // 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.)
855 856
    Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
                                              : Type::None();
857
    for (int i = 0; i < arity; ++i) {
858 859 860 861 862 863
      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.
864
  if (initial_type.IsNone() ||
865
      increment_type.Is(typer_->cache_->kSingletonZero)) {
866 867 868 869 870 871 872 873
    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;

874 875
  InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();

876 877
  double min = -V8_INFINITY;
  double max = V8_INFINITY;
878 879 880 881

  double increment_min;
  double increment_max;
  if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
882 883
    increment_min = increment_type.Min();
    increment_max = increment_type.Max();
884
  } else {
885
    DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
886 887
    increment_min = -increment_type.Max();
    increment_max = -increment_type.Min();
888 889 890 891
  }

  if (increment_min >= 0) {
    // increasing sequence
892
    min = initial_type.Min();
893
    for (auto bound : induction_var->upper_bounds()) {
894
      Type bound_type = TypeOrNone(bound.bound);
895
      // If the type is not an integer, just skip the bound.
896
      if (!bound_type.Is(typer_->cache_->kInteger)) continue;
897
      // If the type is not inhabited, then we can take the initial value.
898 899
      if (bound_type.IsNone()) {
        max = initial_type.Max();
900 901
        break;
      }
902
      double bound_max = bound_type.Max();
903 904 905
      if (bound.kind == InductionVariable::kStrict) {
        bound_max -= 1;
      }
906
      max = std::min(max, bound_max + increment_max);
907 908
    }
    // The upper bound must be at least the initial value's upper bound.
909
    max = std::max(max, initial_type.Max());
910 911
  } else if (increment_max <= 0) {
    // decreasing sequence
912
    max = initial_type.Max();
913
    for (auto bound : induction_var->lower_bounds()) {
914
      Type bound_type = TypeOrNone(bound.bound);
915
      // If the type is not an integer, just skip the bound.
916
      if (!bound_type.Is(typer_->cache_->kInteger)) continue;
917
      // If the type is not inhabited, then we can take the initial value.
918 919
      if (bound_type.IsNone()) {
        min = initial_type.Min();
920 921
        break;
      }
922
      double bound_min = bound_type.Min();
923 924 925
      if (bound.kind == InductionVariable::kStrict) {
        bound_min += 1;
      }
926
      min = std::max(min, bound_min + increment_min);
927 928
    }
    // The lower bound must be at most the initial value's lower bound.
929
    min = std::min(min, initial_type.Min());
930 931 932
  } else {
    // Shortcut: If the increment can be both positive and negative,
    // the variable can go arbitrarily far, so just return integer.
933
    return typer_->cache_->kInteger;
934 935
  }
  if (FLAG_trace_turbo_loop) {
936 937 938 939 940 941 942 943 944
    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";
945 946 947
  }
  return Type::Range(min, max, typer_->zone());
}
948

949
Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); }
950

951
Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }
952

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

955
Type Typer::Visitor::TypeLoopExitEffect(Node* node) { UNREACHABLE(); }
956

957
Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
958 959 960
  return Operand(node, 1);
}

961
Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
962 963 964
  return Operand(node, 1);
}

965
Type Typer::Visitor::TypeTransitionElementsKind(Node* node) { UNREACHABLE(); }
966

967
Type Typer::Visitor::TypeCheckpoint(Node* node) { UNREACHABLE(); }
968

969
Type Typer::Visitor::TypeBeginRegion(Node* node) { UNREACHABLE(); }
970

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

973
Type Typer::Visitor::TypeFrameState(Node* node) {
974
  // TODO(rossberg): Ideally FrameState wouldn't have a value output.
975
  return Type::Internal();
976 977
}

978
Type Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
979

980
Type Typer::Visitor::TypeTypedStateValues(Node* node) {
981
  return Type::Internal();
982 983
}

984
Type Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
985

986
Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
987 988 989
  return Type::Internal();
}

990
Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
991 992 993
  return Type::Internal();
}

994
Type Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
995

996
Type Typer::Visitor::TypeTypedObjectState(Node* node) {
997 998
  return Type::Internal();
}
999

1000
Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
1001

1002 1003
Type Typer::Visitor::TypeProjection(Node* node) {
  Type const type = Operand(node, 0);
1004
  if (type.Is(Type::None())) return Type::None();
1005
  int const index = static_cast<int>(ProjectionIndexOf(node->op()));
1006 1007
  if (type.IsTuple() && index < type.AsTuple()->Arity()) {
    return type.AsTuple()->Element(index);
1008
  }
1009
  return Type::Any();
1010 1011
}

1012
Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
1013

1014 1015
Type Typer::Visitor::TypeTypeGuard(Node* node) {
  Type const type = Operand(node, 0);
1016 1017 1018
  return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
}

1019
Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
1020

1021
Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
1022

1023
Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
1024

1025 1026
Type Typer::Visitor::TypeStaticAssert(Node* node) { UNREACHABLE(); }

1027 1028
// JS comparison operators.

1029
Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1030
  if (lhs.IsNone() || rhs.IsNone()) return Type::None();
1031 1032
  if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
  if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1033
    return t->singleton_true_;
1034
  }
1035 1036
  if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
      (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1037
    return t->singleton_false_;
1038
  }
1039
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1040 1041
    // Types are equal and are inhabited only by a single semantic value,
    // which is not nan due to the earlier check.
1042
    return t->singleton_true_;
1043 1044 1045
  }
  return Type::Boolean();
}
1046

1047
Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1048
  return t->operation_typer()->StrictEqual(lhs, rhs);
1049 1050 1051 1052 1053 1054
}

// 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.
1055 1056
Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
                                                                 Type rhs,
1057
                                                                 Typer* t) {
1058 1059
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
1060
  if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1061 1062
    return ComparisonOutcome(kComparisonTrue) |
           ComparisonOutcome(kComparisonFalse);
1063
  }
1064 1065
  lhs = ToNumeric(lhs, t);
  rhs = ToNumeric(rhs, t);
1066
  if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1067 1068 1069 1070 1071
    return NumberCompareTyper(lhs, rhs, t);
  }
  return ComparisonOutcome(kComparisonTrue) |
         ComparisonOutcome(kComparisonFalse) |
         ComparisonOutcome(kComparisonUndefined);
1072
}
1073

1074 1075
Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type lhs,
                                                                     Type rhs,
1076
                                                                     Typer* t) {
1077 1078
  DCHECK(lhs.Is(Type::Number()));
  DCHECK(rhs.Is(Type::Number()));
1079

1080 1081
  if (lhs.IsNone() || rhs.IsNone()) return {};

1082
  // Shortcut for NaNs.
1083
  if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1084 1085

  ComparisonOutcome result;
1086
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1087 1088
    // Types are equal and are inhabited only by a single semantic value.
    result = kComparisonFalse;
1089
  } else if (lhs.Min() >= rhs.Max()) {
1090
    result = kComparisonFalse;
1091
  } else if (lhs.Max() < rhs.Min()) {
1092 1093 1094
    result = kComparisonTrue;
  } else {
    return ComparisonOutcome(kComparisonTrue) |
1095 1096
           ComparisonOutcome(kComparisonFalse) |
           ComparisonOutcome(kComparisonUndefined);
1097 1098
  }
  // Add the undefined if we could see NaN.
1099
  if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1100 1101 1102
    result |= kComparisonUndefined;
  }
  return result;
1103 1104
}

1105
Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1106 1107 1108
  return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
}

1109
Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1110 1111 1112
  return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
}

1113
Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1114 1115 1116
  return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
}

1117
Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1118 1119 1120 1121 1122
  return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
}

// JS bitwise operators.

1123
Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1124
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1125 1126
}

1127
Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1128
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1129 1130
}

1131
Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1132
  return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1133 1134
}

1135
Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1136
  return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1137 1138
}

1139
Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1140
  return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1141 1142
}

1143
Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1144
  return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1145 1146 1147 1148 1149
}


// JS arithmetic operators.

1150
Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1151 1152
  lhs = ToPrimitive(lhs, t);
  rhs = ToPrimitive(rhs, t);
1153 1154
  if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
    if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1155 1156
      return Type::String();
    } else {
1157
      return Type::NumericOrString();
1158 1159
    }
  }
1160
  // The addition must be numeric.
1161
  return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1162 1163
}

1164
Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1165
  return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1166 1167
}

1168
Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1169
  return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1170 1171
}

1172
Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1173
  return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1174 1175
}

1176
Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1177
  return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1178 1179
}

1180
Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1181
  // TODO(neis): Refine using BinaryNumberOpTyper?
1182
  return Type::Numeric();
1183
}
1184 1185 1186

// JS unary operators.

1187
Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1188 1189 1190
  return TypeUnaryOp(node, BitwiseNot);
}

1191
Type Typer::Visitor::TypeJSDecrement(Node* node) {
1192 1193 1194
  return TypeUnaryOp(node, Decrement);
}

1195
Type Typer::Visitor::TypeJSIncrement(Node* node) {
1196 1197 1198
  return TypeUnaryOp(node, Increment);
}

1199
Type Typer::Visitor::TypeJSNegate(Node* node) {
1200 1201 1202
  return TypeUnaryOp(node, Negate);
}

1203
Type Typer::Visitor::TypeTypeOf(Node* node) {
1204
  return Type::InternalizedString();
1205 1206 1207 1208 1209
}


// JS conversion operators.

1210
Type Typer::Visitor::TypeToBoolean(Node* node) {
1211
  return TypeUnaryOp(node, ToBoolean);
1212 1213
}

1214
Type Typer::Visitor::TypeJSToLength(Node* node) {
1215
  return TypeUnaryOp(node, ToLength);
1216 1217
}

1218
Type Typer::Visitor::TypeJSToName(Node* node) {
1219 1220
  return TypeUnaryOp(node, ToName);
}
1221

1222
Type Typer::Visitor::TypeJSToNumber(Node* node) {
1223 1224
  return TypeUnaryOp(node, ToNumber);
}
1225

1226 1227 1228 1229
Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
  return TypeUnaryOp(node, ToNumberConvertBigInt);
}

1230
Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1231 1232 1233
  return TypeUnaryOp(node, ToNumeric);
}

1234
Type Typer::Visitor::TypeJSToObject(Node* node) {
1235 1236
  return TypeUnaryOp(node, ToObject);
}
1237

1238
Type Typer::Visitor::TypeJSToString(Node* node) {
1239 1240
  return TypeUnaryOp(node, ToString);
}
1241 1242 1243

// JS object operators.

1244
Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1245

1246
Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1247 1248 1249 1250 1251 1252 1253 1254
  switch (CreateArgumentsTypeOf(node->op())) {
    case CreateArgumentsType::kRestParameter:
      return Type::Array();
    case CreateArgumentsType::kMappedArguments:
    case CreateArgumentsType::kUnmappedArguments:
      return Type::OtherObject();
  }
  UNREACHABLE();
1255 1256
}

1257
Type Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1258

1259
Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1260 1261 1262
  return Type::OtherObject();
}

1263 1264 1265 1266
Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) {
  return Type::OtherObject();
}

1267
Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1268 1269 1270
  return Type::OtherObject();
}

1271
Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1272 1273 1274
  return Type::BoundFunction();
}

1275
Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1276 1277 1278
  return Type::OtherObject();
}

1279
Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1280
  return Type::Function();
1281 1282
}

1283
Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1284 1285 1286
  return Type::OtherObject();
}

1287
Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1288 1289 1290
  return Type::OtherObject();
}

1291
Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1292 1293
  return Type::OtherObject();
}
1294

1295
Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1296 1297 1298
  return Type::OtherObject();
}

1299
Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1300 1301 1302
  return Type::OtherObject();
}

1303
Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1304 1305 1306
  return Type::OtherObject();
}

1307
Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1308
  return Type::Array();
1309 1310
}

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

1315 1316 1317 1318
Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
  return Type::Array();
}

1319
Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1320
  return Type::OtherObject();
1321 1322
}

1323
Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1324 1325
  return Type::OtherObject();
}
1326

1327 1328 1329 1330
Type Typer::Visitor::TypeJSCloneObject(Node* node) {
  return Type::OtherObject();
}

1331
Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1332 1333 1334
  return Type::OtherObject();
}

1335
Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
1336
  return Type::NonInternal();
1337 1338
}

1339
Type Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::NonInternal(); }
1340

1341
Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1342 1343
  return Type::NonInternal();
}
1344

1345
Type Typer::Visitor::TypeJSParseInt(Node* node) { return Type::Number(); }
1346

1347 1348
Type Typer::Visitor::TypeJSRegExpTest(Node* node) { return Type::Boolean(); }

1349 1350 1351 1352 1353
// 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.
1354
Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) {
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
  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));

1371
  // If the types have nothing to do with integers, return the types.
1372
  Type const integer = typer_->cache_->kInteger;
1373
  if (!previous_type.Maybe(integer)) {
1374 1375
    return current_type;
  }
1376
  DCHECK(current_type.Maybe(integer));
1377

1378 1379
  Type current_integer = Type::Intersect(current_type, integer, zone());
  Type previous_integer = Type::Intersect(previous_type, integer, zone());
1380 1381 1382 1383 1384 1385

  // 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).
1386 1387
    Type previous = previous_integer.GetRange();
    Type current = current_integer.GetRange();
1388
    if (current.IsInvalid() || previous.IsInvalid()) {
1389 1390 1391 1392
      return current_type;
    }
    // Range is involved => we are weakening.
    SetWeakened(node->id());
1393 1394
  }

1395
  double current_min = current_integer.Min();
1396
  double new_min = current_min;
1397 1398
  // Find the closest lower entry in the list of allowed
  // minima (or negative infinity if there is no such entry).
1399
  if (current_min != previous_integer.Min()) {
1400
    new_min = -V8_INFINITY;
1401 1402 1403
    for (double const min : kWeakenMinLimits) {
      if (min <= current_min) {
        new_min = min;
1404
        break;
1405 1406
      }
    }
1407
  }
1408

1409
  double current_max = current_integer.Max();
1410
  double new_max = current_max;
1411 1412
  // Find the closest greater entry in the list of allowed
  // maxima (or infinity if there is no such entry).
1413
  if (current_max != previous_integer.Max()) {
1414
    new_max = V8_INFINITY;
1415 1416 1417
    for (double const max : kWeakenMaxLimits) {
      if (max >= current_max) {
        new_max = max;
1418
        break;
1419 1420
      }
    }
1421
  }
1422 1423 1424 1425

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

1428
Type Typer::Visitor::TypeJSStoreProperty(Node* node) { UNREACHABLE(); }
1429

1430
Type Typer::Visitor::TypeJSStoreNamed(Node* node) { UNREACHABLE(); }
1431

1432
Type Typer::Visitor::TypeJSStoreGlobal(Node* node) { UNREACHABLE(); }
1433

1434
Type Typer::Visitor::TypeJSStoreNamedOwn(Node* node) { UNREACHABLE(); }
1435

1436
Type Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1437 1438 1439
  UNREACHABLE();
}

1440
Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
1441

1442
Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1443
  return Type::Boolean();
1444 1445
}

1446
Type Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1447

1448
// JS instanceof operator.
1449

1450
Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1451 1452 1453
  return Type::Boolean();
}

1454
Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1455 1456 1457
  return Type::Boolean();
}

1458
Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1459 1460 1461
  return Type::Boolean();
}

1462
Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1463 1464 1465
  return Type::Callable();
}

1466 1467
// JS context operators.

1468
Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1469
  ContextAccess const& access = ContextAccessOf(node->op());
1470 1471 1472
  switch (access.index()) {
    case Context::PREVIOUS_INDEX:
    case Context::NATIVE_CONTEXT_INDEX:
1473
    case Context::SCOPE_INFO_INDEX:
1474 1475 1476
      return Type::OtherInternal();
    default:
      return Type::Any();
1477
  }
1478 1479
}

1480
Type Typer::Visitor::TypeJSStoreContext(Node* node) { UNREACHABLE(); }
1481

1482
Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1483
  return Type::OtherInternal();
1484 1485
}

1486
Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1487
  return Type::OtherInternal();
1488 1489
}

1490
Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1491
  return Type::OtherInternal();
1492 1493
}

1494
Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1495
  return Type::OtherInternal();
1496 1497 1498 1499
}

// JS other operators.

1500
Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1501 1502 1503
  return Type::Receiver();
}

1504
Type Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1505

1506
Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1507 1508 1509
  return Type::Receiver();
}

1510
Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1511 1512 1513
  return Type::Receiver();
}

1514
Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
1515

1516
Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
1517

1518
Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1519 1520 1521
  if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
    return Type::NonInternal();
  }
1522
  JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1523
  if (!function.shared().HasBuiltinId()) {
1524 1525
    return Type::NonInternal();
  }
1526 1527
  switch (function.shared().builtin_id()) {
    case Builtins::kMathRandom:
1528
      return Type::PlainNumber();
1529 1530 1531 1532
    case Builtins::kMathFloor:
    case Builtins::kMathCeil:
    case Builtins::kMathRound:
    case Builtins::kMathTrunc:
1533
      return t->cache_->kIntegerOrMinusZeroOrNaN;
1534
    // Unary math functions.
1535 1536
    case Builtins::kMathAbs:
    case Builtins::kMathExp:
1537
      return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
    case Builtins::kMathAcos:
    case Builtins::kMathAcosh:
    case Builtins::kMathAsin:
    case Builtins::kMathAsinh:
    case Builtins::kMathAtan:
    case Builtins::kMathAtanh:
    case Builtins::kMathCbrt:
    case Builtins::kMathCos:
    case Builtins::kMathExpm1:
    case Builtins::kMathFround:
    case Builtins::kMathLog:
    case Builtins::kMathLog1p:
    case Builtins::kMathLog10:
    case Builtins::kMathLog2:
    case Builtins::kMathSin:
    case Builtins::kMathSqrt:
    case Builtins::kMathTan:
1555
      return Type::Number();
1556
    case Builtins::kMathSign:
1557
      return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1558
    // Binary math functions.
1559 1560 1561 1562
    case Builtins::kMathAtan2:
    case Builtins::kMathPow:
    case Builtins::kMathMax:
    case Builtins::kMathMin:
1563
    case Builtins::kMathHypot:
1564
      return Type::Number();
1565
    case Builtins::kMathImul:
1566
      return Type::Signed32();
1567
    case Builtins::kMathClz32:
1568
      return t->cache_->kZeroToThirtyTwo;
1569
    // Date functions.
1570
    case Builtins::kDateNow:
1571
      return t->cache_->kTimeValueType;
1572
    case Builtins::kDatePrototypeGetDate:
1573
      return t->cache_->kJSDateDayType;
1574
    case Builtins::kDatePrototypeGetDay:
1575
      return t->cache_->kJSDateWeekdayType;
1576
    case Builtins::kDatePrototypeGetFullYear:
1577
      return t->cache_->kJSDateYearType;
1578
    case Builtins::kDatePrototypeGetHours:
1579
      return t->cache_->kJSDateHourType;
1580
    case Builtins::kDatePrototypeGetMilliseconds:
1581 1582
      return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
                         t->zone());
1583
    case Builtins::kDatePrototypeGetMinutes:
1584
      return t->cache_->kJSDateMinuteType;
1585
    case Builtins::kDatePrototypeGetMonth:
1586
      return t->cache_->kJSDateMonthType;
1587
    case Builtins::kDatePrototypeGetSeconds:
1588
      return t->cache_->kJSDateSecondType;
1589
    case Builtins::kDatePrototypeGetTime:
1590
      return t->cache_->kJSDateValueType;
1591 1592

    // Symbol functions.
1593
    case Builtins::kSymbolConstructor:
1594
      return Type::Symbol();
1595
    case Builtins::kSymbolPrototypeToString:
1596
      return Type::String();
1597
    case Builtins::kSymbolPrototypeValueOf:
1598
      return Type::Symbol();
1599 1600

    // BigInt functions.
1601
    case Builtins::kBigIntConstructor:
1602 1603 1604
      return Type::BigInt();

    // Number functions.
1605
    case Builtins::kNumberConstructor:
1606
      return Type::Number();
1607 1608 1609 1610
    case Builtins::kNumberIsFinite:
    case Builtins::kNumberIsInteger:
    case Builtins::kNumberIsNaN:
    case Builtins::kNumberIsSafeInteger:
1611
      return Type::Boolean();
1612
    case Builtins::kNumberParseFloat:
1613
      return Type::Number();
1614
    case Builtins::kNumberParseInt:
1615
      return t->cache_->kIntegerOrMinusZeroOrNaN;
1616
    case Builtins::kNumberToString:
1617
      return Type::String();
1618 1619

    // String functions.
1620
    case Builtins::kStringConstructor:
1621
      return Type::String();
1622
    case Builtins::kStringPrototypeCharCodeAt:
1623 1624
      return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
                         t->zone());
1625
    case Builtins::kStringCharAt:
1626
      return Type::String();
1627
    case Builtins::kStringPrototypeCodePointAt:
1628 1629
      return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
                         Type::Undefined(), t->zone());
1630 1631 1632
    case Builtins::kStringPrototypeConcat:
    case Builtins::kStringFromCharCode:
    case Builtins::kStringFromCodePoint:
1633
      return Type::String();
1634 1635
    case Builtins::kStringPrototypeIndexOf:
    case Builtins::kStringPrototypeLastIndexOf:
1636
      return Type::Range(-1.0, String::kMaxLength, t->zone());
1637 1638
    case Builtins::kStringPrototypeEndsWith:
    case Builtins::kStringPrototypeIncludes:
1639
      return Type::Boolean();
1640 1641 1642
    case Builtins::kStringRaw:
    case Builtins::kStringRepeat:
    case Builtins::kStringPrototypeSlice:
1643
      return Type::String();
1644
    case Builtins::kStringPrototypeStartsWith:
1645
      return Type::Boolean();
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
    case Builtins::kStringPrototypeSubstr:
    case Builtins::kStringSubstring:
    case Builtins::kStringPrototypeToString:
#ifdef V8_INTL_SUPPORT
    case Builtins::kStringPrototypeToLowerCaseIntl:
    case Builtins::kStringPrototypeToUpperCaseIntl:
#else
    case Builtins::kStringPrototypeToLowerCase:
    case Builtins::kStringPrototypeToUpperCase:
#endif
    case Builtins::kStringPrototypeTrim:
    case Builtins::kStringPrototypeTrimEnd:
    case Builtins::kStringPrototypeTrimStart:
    case Builtins::kStringPrototypeValueOf:
1660 1661
      return Type::String();

1662 1663
    case Builtins::kStringPrototypeIterator:
    case Builtins::kStringIteratorPrototypeNext:
1664 1665
      return Type::OtherObject();

1666 1667 1668 1669 1670 1671 1672 1673 1674
    case Builtins::kArrayPrototypeEntries:
    case Builtins::kArrayPrototypeKeys:
    case Builtins::kArrayPrototypeValues:
    case Builtins::kTypedArrayPrototypeEntries:
    case Builtins::kTypedArrayPrototypeKeys:
    case Builtins::kTypedArrayPrototypeValues:
    case Builtins::kArrayIteratorPrototypeNext:
    case Builtins::kMapIteratorPrototypeNext:
    case Builtins::kSetIteratorPrototypeNext:
1675
      return Type::OtherObject();
1676
    case Builtins::kTypedArrayPrototypeToStringTag:
1677
      return Type::Union(Type::InternalizedString(), Type::Undefined(),
1678 1679 1680
                         t->zone());

    // Array functions.
1681
    case Builtins::kArrayIsArray:
1682
      return Type::Boolean();
1683
    case Builtins::kArrayConcat:
1684
      return Type::Receiver();
1685
    case Builtins::kArrayEvery:
1686
      return Type::Boolean();
1687 1688
    case Builtins::kArrayPrototypeFill:
    case Builtins::kArrayFilter:
1689
      return Type::Receiver();
1690
    case Builtins::kArrayPrototypeFindIndex:
1691
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1692
    case Builtins::kArrayForEach:
1693
      return Type::Undefined();
1694
    case Builtins::kArrayIncludes:
1695
      return Type::Boolean();
1696
    case Builtins::kArrayIndexOf:
1697
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1698
    case Builtins::kArrayPrototypeJoin:
1699
      return Type::String();
1700
    case Builtins::kArrayPrototypeLastIndexOf:
1701
      return Type::Range(-1, kMaxSafeInteger, t->zone());
1702
    case Builtins::kArrayMap:
1703
      return Type::Receiver();
1704
    case Builtins::kArrayPush:
1705
      return t->cache_->kPositiveSafeInteger;
1706 1707
    case Builtins::kArrayPrototypeReverse:
    case Builtins::kArrayPrototypeSlice:
1708
      return Type::Receiver();
1709
    case Builtins::kArraySome:
1710
      return Type::Boolean();
1711
    case Builtins::kArrayPrototypeSplice:
1712
      return Type::Receiver();
1713
    case Builtins::kArrayUnshift:
1714
      return t->cache_->kPositiveSafeInteger;
1715 1716

    // ArrayBuffer functions.
1717
    case Builtins::kArrayBufferIsView:
1718 1719 1720
      return Type::Boolean();

    // Object functions.
1721
    case Builtins::kObjectAssign:
1722
      return Type::Receiver();
1723
    case Builtins::kObjectCreate:
1724
      return Type::OtherObject();
1725 1726 1727
    case Builtins::kObjectIs:
    case Builtins::kObjectPrototypeHasOwnProperty:
    case Builtins::kObjectPrototypeIsPrototypeOf:
1728
      return Type::Boolean();
1729
    case Builtins::kObjectToString:
1730 1731
      return Type::String();

1732
    case Builtins::kPromiseAll:
1733
      return Type::Receiver();
1734
    case Builtins::kPromisePrototypeThen:
1735
      return Type::Receiver();
1736
    case Builtins::kPromiseRace:
1737
      return Type::Receiver();
1738
    case Builtins::kPromiseReject:
1739
      return Type::Receiver();
1740
    case Builtins::kPromiseResolveTrampoline:
1741 1742
      return Type::Receiver();

1743
    // RegExp functions.
1744
    case Builtins::kRegExpPrototypeCompile:
1745
      return Type::OtherObject();
1746
    case Builtins::kRegExpPrototypeExec:
1747
      return Type::Union(Type::Array(), Type::Null(), t->zone());
1748
    case Builtins::kRegExpPrototypeTest:
1749
      return Type::Boolean();
1750
    case Builtins::kRegExpPrototypeToString:
1751 1752 1753
      return Type::String();

    // Function functions.
1754
    case Builtins::kFunctionPrototypeBind:
1755
      return Type::BoundFunction();
1756
    case Builtins::kFunctionPrototypeHasInstance:
1757 1758 1759
      return Type::Boolean();

    // Global functions.
1760 1761 1762 1763 1764 1765
    case Builtins::kGlobalDecodeURI:
    case Builtins::kGlobalDecodeURIComponent:
    case Builtins::kGlobalEncodeURI:
    case Builtins::kGlobalEncodeURIComponent:
    case Builtins::kGlobalEscape:
    case Builtins::kGlobalUnescape:
1766
      return Type::String();
1767 1768
    case Builtins::kGlobalIsFinite:
    case Builtins::kGlobalIsNaN:
1769 1770 1771
      return Type::Boolean();

    // Map functions.
1772 1773
    case Builtins::kMapPrototypeClear:
    case Builtins::kMapPrototypeForEach:
1774
      return Type::Undefined();
1775 1776
    case Builtins::kMapPrototypeDelete:
    case Builtins::kMapPrototypeHas:
1777
      return Type::Boolean();
1778 1779 1780 1781
    case Builtins::kMapPrototypeEntries:
    case Builtins::kMapPrototypeKeys:
    case Builtins::kMapPrototypeSet:
    case Builtins::kMapPrototypeValues:
1782 1783 1784
      return Type::OtherObject();

    // Set functions.
1785 1786 1787
    case Builtins::kSetPrototypeAdd:
    case Builtins::kSetPrototypeEntries:
    case Builtins::kSetPrototypeValues:
1788
      return Type::OtherObject();
1789 1790
    case Builtins::kSetPrototypeClear:
    case Builtins::kSetPrototypeForEach:
1791
      return Type::Undefined();
1792 1793
    case Builtins::kSetPrototypeDelete:
    case Builtins::kSetPrototypeHas:
1794 1795 1796
      return Type::Boolean();

    // WeakMap functions.
1797 1798
    case Builtins::kWeakMapPrototypeDelete:
    case Builtins::kWeakMapPrototypeHas:
1799
      return Type::Boolean();
1800
    case Builtins::kWeakMapPrototypeSet:
1801 1802 1803
      return Type::OtherObject();

    // WeakSet functions.
1804
    case Builtins::kWeakSetPrototypeAdd:
1805
      return Type::OtherObject();
1806 1807
    case Builtins::kWeakSetPrototypeDelete:
    case Builtins::kWeakSetPrototypeHas:
1808 1809 1810
      return Type::Boolean();
    default:
      return Type::NonInternal();
1811
  }
1812 1813
}

1814
Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1815
  return TypeUnaryOp(node, JSCallTyper);
1816
}
1817

1818
Type Typer::Visitor::TypeJSCall(Node* node) {
1819
  // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1820 1821
  // argument types for the JSCallTyper above.
  return TypeUnaryOp(node, JSCallTyper);
1822 1823
}

1824
Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1825 1826 1827
  return TypeUnaryOp(node, JSCallTyper);
}

1828
Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1829
  return TypeUnaryOp(node, JSCallTyper);
1830
}
1831

1832
Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1833
  switch (CallRuntimeParametersOf(node->op()).id()) {
1834 1835
    case Runtime::kInlineIsJSReceiver:
      return TypeUnaryOp(node, ObjectIsReceiver);
1836
    case Runtime::kInlineIsSmi:
1837
      return TypeUnaryOp(node, ObjectIsSmi);
1838 1839
    case Runtime::kInlineIsArray:
    case Runtime::kInlineIsRegExp:
1840
      return Type::Boolean();
1841
    case Runtime::kInlineCreateIterResultObject:
1842
      return Type::OtherObject();
1843 1844 1845 1846
    case Runtime::kInlineToLength:
      return TypeUnaryOp(node, ToLength);
    case Runtime::kInlineToNumber:
      return TypeUnaryOp(node, ToNumber);
1847
    case Runtime::kInlineToObject:
1848
      return TypeUnaryOp(node, ToObject);
Shiyu Zhang's avatar
Shiyu Zhang committed
1849
    case Runtime::kInlineToStringRT:
1850
      return TypeUnaryOp(node, ToString);
1851 1852
    case Runtime::kHasInPrototypeChain:
      return Type::Boolean();
1853 1854 1855
    default:
      break;
  }
1856 1857 1858
  // 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.
1859
  return Type::Any();
1860 1861
}

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

1866
Type Typer::Visitor::TypeJSForInNext(Node* node) {
1867
  return Type::Union(Type::String(), Type::Undefined(), zone());
1868 1869
}

1870
Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1871
  STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1872
  Type const cache_type =
1873
      Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1874
  Type const cache_array = Type::OtherInternal();
1875
  Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1876
  return Type::Tuple(cache_type, cache_array, cache_length, zone());
1877 1878
}

1879
Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1880

1881
Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1882

1883
Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1884

1885
Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1886

1887
Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1888

1889
Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1890
  return Type::SignedSmall();
1891 1892
}

1893
Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1894 1895 1896
  return Type::Any();
}

1897
Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1898 1899
  return Type::Any();
}
1900

1901
Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1902 1903 1904
  return Type::Any();
}

1905
Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1906

1907
Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1908

1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
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();
}

1921
Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1922 1923 1924
  return Type::Undefined();
}

1925
Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1926 1927 1928
  return Type::Receiver();
}

1929
Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1930
  return Type::Receiver();
1931 1932
}

1933
Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1934 1935 1936
  return Type::Undefined();
}

1937
Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1938 1939 1940
  return Type::Undefined();
}

1941 1942
// Simplified operators.

1943
Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1944

1945
// static
1946
Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1947 1948
  return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
}
1949

1950
// static
1951
Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1952 1953 1954 1955 1956
  return FalsifyUndefined(
      NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
}

// static
1957
Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1958 1959 1960 1961
  return FalsifyUndefined(
      Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
}

1962
Type Typer::Visitor::TypeNumberEqual(Node* node) {
1963 1964 1965
  return TypeBinaryOp(node, NumberEqualTyper);
}

1966
Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1967 1968
  return TypeBinaryOp(node, NumberLessThanTyper);
}
1969

1970
Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1971
  return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1972 1973
}

1974
Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1975
  return TypeBinaryOp(node, NumberEqualTyper);
1976 1977
}

1978
Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1979
  return TypeBinaryOp(node, NumberLessThanTyper);
1980 1981
}

1982
Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1983
  return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1984 1985
}

1986
Type Typer::Visitor::TypeStringConcat(Node* node) { return Type::String(); }
1987

1988
Type Typer::Visitor::TypeStringToNumber(Node* node) {
1989 1990 1991
  return TypeUnaryOp(node, ToNumber);
}

1992
Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1993 1994 1995
  return TypeUnaryOp(node, ToNumber);
}

1996
Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1997 1998 1999
  return Type::Integral32();
}

2000
Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
2001 2002 2003
  return Type::Number();
}

2004
// static
2005
Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
2006
  if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
2007 2008 2009 2010 2011
    return t->singleton_true_;
  }
  return Type::Boolean();
}

2012
Type Typer::Visitor::TypeReferenceEqual(Node* node) {
2013
  return TypeBinaryOp(node, ReferenceEqualTyper);
2014 2015
}

2016
// static
2017
Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
2018 2019 2020
  return t->operation_typer()->SameValue(lhs, rhs);
}

2021 2022 2023 2024 2025
// static
Type Typer::Visitor::SameValueNumbersOnlyTyper(Type lhs, Type rhs, Typer* t) {
  return t->operation_typer()->SameValueNumbersOnly(lhs, rhs);
}

2026
Type Typer::Visitor::TypeSameValue(Node* node) {
2027 2028 2029
  return TypeBinaryOp(node, SameValueTyper);
}

2030 2031 2032 2033
Type Typer::Visitor::TypeSameValueNumbersOnly(Node* node) {
  return TypeBinaryOp(node, SameValueNumbersOnlyTyper);
}

2034 2035
Type Typer::Visitor::TypeNumberSameValue(Node* node) { UNREACHABLE(); }

2036
Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
2037

2038
Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
2039

2040
Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2041
  return Type::Boolean();
2042 2043
}

2044
Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
2045
  return Type::String();
2046 2047
}

2048
Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2049
  return Type::String();
2050 2051
}

2052
Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2053 2054
  return Type::String();
}
2055

2056
Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2057 2058
  return Type::String();
}
2059

2060
Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2061
  return typer_->cache_->kUint16;
2062 2063
}

2064
Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2065 2066 2067
  return Type::Range(0.0, String::kMaxCodePoint, zone());
}

2068
Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2069
  return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2070 2071
}

2072
Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2073
  return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2074 2075
}

2076 2077 2078 2079
Type Typer::Visitor::TypeStringFromCodePointAt(Node* node) {
  return Type::String();
}

2080
Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2081 2082
  return Type::Range(-1.0, String::kMaxLength, zone());
}
2083

2084
Type Typer::Visitor::TypeStringLength(Node* node) {
2085
  return typer_->cache_->kStringLengthType;
2086 2087
}

2088
Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2089

2090
Type Typer::Visitor::TypePoisonIndex(Node* node) {
2091
  return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2092 2093
}

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

2099 2100
Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
  Type type = Operand(node, 0);
2101 2102 2103
  return type;
}

2104
Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2105

2106
Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2107 2108
  Type arg = Operand(node, 0);
  return Type::Intersect(arg, Type::InternalizedString(), zone());
2109 2110
}

2111
Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2112

2113
Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2114

2115
Type Typer::Visitor::TypeCheckNumber(Node* node) {
2116
  return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2117 2118
}

2119 2120
Type Typer::Visitor::TypeCheckReceiver(Node* node) {
  Type arg = Operand(node, 0);
2121 2122 2123
  return Type::Intersect(arg, Type::Receiver(), zone());
}

2124
Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2125
  Type arg = Operand(node, 0);
2126
  return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2127 2128
}

2129 2130
Type Typer::Visitor::TypeCheckSmi(Node* node) {
  Type arg = Operand(node, 0);
2131
  return Type::Intersect(arg, Type::SignedSmall(), zone());
2132 2133
}

2134
Type Typer::Visitor::TypeCheckString(Node* node) {
2135 2136
  Type arg = Operand(node, 0);
  return Type::Intersect(arg, Type::String(), zone());
2137 2138
}

2139 2140
Type Typer::Visitor::TypeCheckSymbol(Node* node) {
  Type arg = Operand(node, 0);
2141 2142 2143
  return Type::Intersect(arg, Type::Symbol(), zone());
}

2144
Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2145
  return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2146 2147
}

2148 2149
Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
  Type type = Operand(node, 0);
2150 2151 2152 2153
  type = Type::Intersect(type, Type::NonInternal(), zone());
  return type;
}

2154 2155
Type Typer::Visitor::TypeConvertReceiver(Node* node) {
  Type arg = Operand(node, 0);
2156 2157 2158
  return typer_->operation_typer_.ConvertReceiver(arg);
}

2159 2160
Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
  Type type = Operand(node, 0);
2161
  return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2162 2163
}

2164
Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2165 2166 2167
  UNREACHABLE();
}

2168
Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2169

2170
Type Typer::Visitor::TypeAllocate(Node* node) {
2171 2172
  return AllocateTypeOf(node->op());
}
2173

2174
Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2175

2176
Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2177 2178 2179
  return Type::NonInternal();
}

2180
Type Typer::Visitor::TypeLoadField(Node* node) {
2181
  return FieldAccessOf(node->op()).type;
2182 2183
}

2184
Type Typer::Visitor::TypeLoadElement(Node* node) {
2185
  return ElementAccessOf(node->op()).type;
2186 2187
}

2188 2189
Type Typer::Visitor::TypeLoadFromObject(Node* node) { UNREACHABLE(); }

2190
Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2191
  switch (ExternalArrayTypeOf(node->op())) {
2192 2193
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
  case kExternal##ElemType##Array:                    \
2194
    return typer_->cache_->k##ElemType;
2195 2196 2197 2198 2199 2200 2201 2202
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  }
  UNREACHABLE();
}

Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
  switch (ExternalArrayTypeOf(node->op())) {
2203 2204
#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
  case kExternal##ElemType##Array:                    \
2205
    return typer_->cache_->k##ElemType;
2206 2207 2208 2209 2210
    TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
  }
  UNREACHABLE();
}
2211

2212
Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2213

2214
Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2215

2216 2217
Type Typer::Visitor::TypeStoreToObject(Node* node) { UNREACHABLE(); }

2218
Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2219 2220 2221
  UNREACHABLE();
}

2222
Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2223 2224 2225
  UNREACHABLE();
}

2226
Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2227 2228 2229
  UNREACHABLE();
}

2230
Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2231

2232
Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2233

2234 2235
Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }

2236
Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2237 2238 2239
  return TypeUnaryOp(node, ObjectIsArrayBufferView);
}

2240
Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2241 2242 2243
  return TypeUnaryOp(node, ObjectIsBigInt);
}

2244
Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2245 2246 2247
  return TypeUnaryOp(node, ObjectIsCallable);
}

2248
Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2249 2250 2251
  return TypeUnaryOp(node, ObjectIsConstructor);
}

2252
Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2253
  return TypeUnaryOp(node, ObjectIsDetectableCallable);
2254
}
2255

2256
Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2257 2258 2259
  return TypeUnaryOp(node, ObjectIsMinusZero);
}

2260 2261 2262 2263
Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
  return TypeUnaryOp(node, NumberIsMinusZero);
}

2264
Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2265 2266 2267
  return Type::Boolean();
}

2268
Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2269

2270
Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2271 2272 2273
  return Type::Boolean();
}

2274
Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2275

2276
Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2277 2278 2279
  return Type::Boolean();
}

2280
Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2281

2282
Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2283

2284
Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2285 2286 2287
  return TypeUnaryOp(node, ObjectIsNaN);
}

2288
Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2289 2290 2291
  return TypeUnaryOp(node, NumberIsNaN);
}

2292
Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2293 2294 2295
  return TypeUnaryOp(node, ObjectIsNonCallable);
}

2296
Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2297 2298 2299
  return TypeUnaryOp(node, ObjectIsNumber);
}

2300
Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2301
  return TypeUnaryOp(node, ObjectIsReceiver);
2302 2303
}

2304
Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2305
  return TypeUnaryOp(node, ObjectIsSmi);
2306
}
2307

2308
Type Typer::Visitor::TypeObjectIsString(Node* node) {
2309 2310
  return TypeUnaryOp(node, ObjectIsString);
}
2311

2312
Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2313 2314 2315
  return TypeUnaryOp(node, ObjectIsSymbol);
}

2316
Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2317 2318 2319
  return TypeUnaryOp(node, ObjectIsUndetectable);
}

2320
Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2321
  return TypeCache::Get()->kArgumentsLengthType;
2322 2323
}

2324
Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2325
  return Type::ExternalPointer();
2326 2327
}

2328
Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2329 2330 2331
  return Type::OtherInternal();
}

2332
Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2333 2334 2335
  return Type::OtherInternal();
}

2336
Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2337 2338 2339
  return Type::OtherInternal();
}

2340
Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2341

2342 2343 2344 2345
Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
  return Type::String();
}

2346
Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2347
  return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2348 2349
}

2350
Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2351
  return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2352 2353
}

2354
Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2355

2356 2357
Type Typer::Visitor::TypeAssertType(Node* node) { UNREACHABLE(); }

2358
// Heap constants.
2359

2360
Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2361
  return Type::NewConstant(typer_->broker(), value, zone());
2362 2363
}

2364 2365 2366
}  // namespace compiler
}  // namespace internal
}  // namespace v8