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