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