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