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 "src/base/flags.h" 8 #include "src/bootstrapper.h" 9 #include "src/compilation-dependencies.h" 10 #include "src/compiler/common-operator.h" 11 #include "src/compiler/graph-reducer.h" 12 #include "src/compiler/js-operator.h" 13 #include "src/compiler/node-properties.h" 14 #include "src/compiler/node.h" 15 #include "src/compiler/operation-typer.h" 16 #include "src/compiler/simplified-operator.h" 17 #include "src/objects-inl.h" 18 #include "src/type-cache.h" 19 20 namespace v8 { 21 namespace internal { 22 namespace compiler { 23 24 class Typer::Decorator final : public GraphDecorator { 25 public: 26 explicit Decorator(Typer* typer) : typer_(typer) {} 27 void Decorate(Node* node) final; 28 29 private: 30 Typer* const typer_; 31 }; 32 33 Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, 34 CompilationDependencies* dependencies, FunctionType* function_type) 35 : isolate_(isolate), 36 graph_(graph), 37 flags_(flags), 38 dependencies_(dependencies), 39 function_type_(function_type), 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 Type* infinity = Type::Constant(factory->infinity_value(), zone); 47 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone); 48 // Unfortunately, the infinities created in other places might be different 49 // ones (eg the result of NewNumber in TypeNumberConstant). 50 Type* truncating_to_zero = 51 Type::Union(Type::Union(infinity, minus_infinity, zone), 52 Type::MinusZeroOrNaN(), zone); 53 DCHECK(!truncating_to_zero->Maybe(Type::Integral32())); 54 55 singleton_false_ = Type::Constant(factory->false_value(), zone); 56 singleton_true_ = Type::Constant(factory->true_value(), zone); 57 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); 58 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); 59 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); 60 falsish_ = Type::Union( 61 Type::Undetectable(), 62 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), 63 singleton_the_hole_, zone), 64 zone); 65 truish_ = Type::Union( 66 singleton_true_, 67 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); 68 69 decorator_ = new (zone) Decorator(this); 70 graph_->AddDecorator(decorator_); 71 } 72 73 74 Typer::~Typer() { 75 graph_->RemoveDecorator(decorator_); 76 } 77 78 79 class Typer::Visitor : public Reducer { 80 public: 81 explicit Visitor(Typer* typer) 82 : typer_(typer), weakened_nodes_(typer->zone()) {} 83 84 Reduction Reduce(Node* node) override { 85 if (node->op()->ValueOutputCount() == 0) return NoChange(); 86 switch (node->opcode()) { 87 #define DECLARE_CASE(x) \ 88 case IrOpcode::k##x: \ 89 return UpdateType(node, TypeBinaryOp(node, x##Typer)); 90 JS_SIMPLE_BINOP_LIST(DECLARE_CASE) 91 #undef DECLARE_CASE 92 93 #define DECLARE_CASE(x) \ 94 case IrOpcode::k##x: \ 95 return UpdateType(node, Type##x(node)); 96 DECLARE_CASE(Start) 97 DECLARE_CASE(IfException) 98 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: 99 COMMON_OP_LIST(DECLARE_CASE) 100 SIMPLIFIED_OP_LIST(DECLARE_CASE) 101 MACHINE_OP_LIST(DECLARE_CASE) 102 MACHINE_SIMD_OP_LIST(DECLARE_CASE) 103 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) 104 JS_OBJECT_OP_LIST(DECLARE_CASE) 105 JS_CONTEXT_OP_LIST(DECLARE_CASE) 106 JS_OTHER_OP_LIST(DECLARE_CASE) 107 #undef DECLARE_CASE 108 109 #define DECLARE_CASE(x) case IrOpcode::k##x: 110 DECLARE_CASE(Loop) 111 DECLARE_CASE(Branch) 112 DECLARE_CASE(IfTrue) 113 DECLARE_CASE(IfFalse) 114 DECLARE_CASE(IfSuccess) 115 DECLARE_CASE(Switch) 116 DECLARE_CASE(IfValue) 117 DECLARE_CASE(IfDefault) 118 DECLARE_CASE(Merge) 119 DECLARE_CASE(Deoptimize) 120 DECLARE_CASE(DeoptimizeIf) 121 DECLARE_CASE(DeoptimizeUnless) 122 DECLARE_CASE(Return) 123 DECLARE_CASE(TailCall) 124 DECLARE_CASE(Terminate) 125 DECLARE_CASE(OsrNormalEntry) 126 DECLARE_CASE(OsrLoopEntry) 127 DECLARE_CASE(Throw) 128 DECLARE_CASE(End) 129 #undef DECLARE_CASE 130 break; 131 } 132 return NoChange(); 133 } 134 135 Type* TypeNode(Node* node) { 136 switch (node->opcode()) { 137 #define DECLARE_CASE(x) \ 138 case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer); 139 JS_SIMPLE_BINOP_LIST(DECLARE_CASE) 140 #undef DECLARE_CASE 141 142 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); 143 DECLARE_CASE(Start) 144 DECLARE_CASE(IfException) 145 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST: 146 COMMON_OP_LIST(DECLARE_CASE) 147 SIMPLIFIED_OP_LIST(DECLARE_CASE) 148 MACHINE_OP_LIST(DECLARE_CASE) 149 MACHINE_SIMD_OP_LIST(DECLARE_CASE) 150 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) 151 JS_OBJECT_OP_LIST(DECLARE_CASE) 152 JS_CONTEXT_OP_LIST(DECLARE_CASE) 153 JS_OTHER_OP_LIST(DECLARE_CASE) 154 #undef DECLARE_CASE 155 156 #define DECLARE_CASE(x) case IrOpcode::k##x: 157 DECLARE_CASE(Loop) 158 DECLARE_CASE(Branch) 159 DECLARE_CASE(IfTrue) 160 DECLARE_CASE(IfFalse) 161 DECLARE_CASE(IfSuccess) 162 DECLARE_CASE(Switch) 163 DECLARE_CASE(IfValue) 164 DECLARE_CASE(IfDefault) 165 DECLARE_CASE(Merge) 166 DECLARE_CASE(Deoptimize) 167 DECLARE_CASE(DeoptimizeIf) 168 DECLARE_CASE(DeoptimizeUnless) 169 DECLARE_CASE(Return) 170 DECLARE_CASE(TailCall) 171 DECLARE_CASE(Terminate) 172 DECLARE_CASE(OsrNormalEntry) 173 DECLARE_CASE(OsrLoopEntry) 174 DECLARE_CASE(Throw) 175 DECLARE_CASE(End) 176 #undef DECLARE_CASE 177 break; 178 } 179 UNREACHABLE(); 180 return nullptr; 181 } 182 183 Type* TypeConstant(Handle<Object> value); 184 185 private: 186 Typer* typer_; 187 ZoneSet<NodeId> weakened_nodes_; 188 189 #define DECLARE_METHOD(x) inline Type* Type##x(Node* node); 190 DECLARE_METHOD(Start) 191 DECLARE_METHOD(IfException) 192 VALUE_OP_LIST(DECLARE_METHOD) 193 #undef DECLARE_METHOD 194 195 Type* TypeOrNone(Node* node) { 196 return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node) 197 : Type::None(); 198 } 199 200 Type* Operand(Node* node, int i) { 201 Node* operand_node = NodeProperties::GetValueInput(node, i); 202 return TypeOrNone(operand_node); 203 } 204 205 Type* WrapContextTypeForInput(Node* node); 206 Type* Weaken(Node* node, Type* current_type, Type* previous_type); 207 208 Zone* zone() { return typer_->zone(); } 209 Isolate* isolate() { return typer_->isolate(); } 210 Graph* graph() { return typer_->graph(); } 211 Typer::Flags flags() const { return typer_->flags(); } 212 CompilationDependencies* dependencies() const { 213 return typer_->dependencies(); 214 } 215 216 void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); } 217 bool IsWeakened(NodeId node_id) { 218 return weakened_nodes_.find(node_id) != weakened_nodes_.end(); 219 } 220 221 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); 222 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); 223 224 Type* TypeUnaryOp(Node* node, UnaryTyperFun); 225 Type* TypeBinaryOp(Node* node, BinaryTyperFun); 226 227 enum ComparisonOutcomeFlags { 228 kComparisonTrue = 1, 229 kComparisonFalse = 2, 230 kComparisonUndefined = 4 231 }; 232 typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome; 233 234 static ComparisonOutcome Invert(ComparisonOutcome, Typer*); 235 static Type* Invert(Type*, Typer*); 236 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); 237 238 static Type* ToPrimitive(Type*, Typer*); 239 static Type* ToBoolean(Type*, Typer*); 240 static Type* ToInteger(Type*, Typer*); 241 static Type* ToLength(Type*, Typer*); 242 static Type* ToName(Type*, Typer*); 243 static Type* ToNumber(Type*, Typer*); 244 static Type* ToObject(Type*, Typer*); 245 static Type* ToString(Type*, Typer*); 246 static Type* NumberAbs(Type*, Typer*); 247 static Type* NumberCeil(Type*, Typer*); 248 static Type* NumberFloor(Type*, Typer*); 249 static Type* NumberRound(Type*, Typer*); 250 static Type* NumberTrunc(Type*, Typer*); 251 static Type* NumberToInt32(Type*, Typer*); 252 static Type* NumberToUint32(Type*, Typer*); 253 254 static Type* ObjectIsCallable(Type*, Typer*); 255 static Type* ObjectIsNumber(Type*, Typer*); 256 static Type* ObjectIsReceiver(Type*, Typer*); 257 static Type* ObjectIsSmi(Type*, Typer*); 258 static Type* ObjectIsString(Type*, Typer*); 259 static Type* ObjectIsUndetectable(Type*, Typer*); 260 261 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); 262 263 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); 264 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) 265 #undef DECLARE_METHOD 266 267 static Type* JSTypeOfTyper(Type*, Typer*); 268 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); 269 static Type* JSCallFunctionTyper(Type*, Typer*); 270 271 static Type* ReferenceEqualTyper(Type*, Type*, Typer*); 272 static Type* StringFromCharCodeTyper(Type*, Typer*); 273 274 Reduction UpdateType(Node* node, Type* current) { 275 if (NodeProperties::IsTyped(node)) { 276 // Widen the type of a previously typed node. 277 Type* previous = NodeProperties::GetType(node); 278 if (node->opcode() == IrOpcode::kPhi) { 279 // Speed up termination in the presence of range types: 280 current = Weaken(node, current, previous); 281 } 282 283 CHECK(previous->Is(current)); 284 285 NodeProperties::SetType(node, current); 286 if (!current->Is(previous)) { 287 // If something changed, revisit all uses. 288 return Changed(node); 289 } 290 return NoChange(); 291 } else { 292 // No previous type, simply update the type. 293 NodeProperties::SetType(node, current); 294 return Changed(node); 295 } 296 } 297 }; 298 299 300 void Typer::Run() { Run(NodeVector(zone())); } 301 302 303 void Typer::Run(const NodeVector& roots) { 304 Visitor visitor(this); 305 GraphReducer graph_reducer(zone(), graph()); 306 graph_reducer.AddReducer(&visitor); 307 for (Node* const root : roots) graph_reducer.ReduceNode(root); 308 graph_reducer.ReduceGraph(); 309 } 310 311 312 void Typer::Decorator::Decorate(Node* node) { 313 if (node->op()->ValueOutputCount() > 0) { 314 // Only eagerly type-decorate nodes with known input types. 315 // Other cases will generally require a proper fixpoint iteration with Run. 316 bool is_typed = NodeProperties::IsTyped(node); 317 if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) { 318 Visitor typing(typer_); 319 Type* type = typing.TypeNode(node); 320 if (is_typed) { 321 type = Type::Intersect(type, NodeProperties::GetType(node), 322 typer_->zone()); 323 } 324 NodeProperties::SetType(node, type); 325 } 326 } 327 } 328 329 330 // ----------------------------------------------------------------------------- 331 332 // Helper functions that lift a function f on types to a function on bounds, 333 // and uses that to type the given node. Note that f is never called with None 334 // as an argument. 335 336 337 Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) { 338 Type* input = Operand(node, 0); 339 return input->IsInhabited() ? f(input, typer_) : Type::None(); 340 } 341 342 343 Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) { 344 Type* left = Operand(node, 0); 345 Type* right = Operand(node, 1); 346 return left->IsInhabited() && right->IsInhabited() ? f(left, right, typer_) 347 : Type::None(); 348 } 349 350 351 Type* Typer::Visitor::Invert(Type* type, Typer* t) { 352 DCHECK(type->Is(Type::Boolean())); 353 DCHECK(type->IsInhabited()); 354 if (type->Is(t->singleton_false_)) return t->singleton_true_; 355 if (type->Is(t->singleton_true_)) return t->singleton_false_; 356 return type; 357 } 358 359 360 Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert( 361 ComparisonOutcome outcome, Typer* t) { 362 ComparisonOutcome result(0); 363 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; 364 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; 365 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; 366 return result; 367 } 368 369 370 Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) { 371 if ((outcome & kComparisonFalse) != 0 || 372 (outcome & kComparisonUndefined) != 0) { 373 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() 374 : t->singleton_false_; 375 } 376 // Type should be non empty, so we know it should be true. 377 DCHECK((outcome & kComparisonTrue) != 0); 378 return t->singleton_true_; 379 } 380 381 // Type conversion. 382 383 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { 384 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 385 return type; 386 } 387 return Type::Primitive(); 388 } 389 390 391 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) { 392 if (type->Is(Type::Boolean())) return type; 393 if (type->Is(t->falsish_)) return t->singleton_false_; 394 if (type->Is(t->truish_)) return t->singleton_true_; 395 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { 396 return t->singleton_true_; // Ruled out nan, -0 and +0. 397 } 398 return Type::Boolean(); 399 } 400 401 402 // static 403 Type* Typer::Visitor::ToInteger(Type* type, Typer* t) { 404 // ES6 section 7.1.4 ToInteger ( argument ) 405 type = ToNumber(type, t); 406 if (type->Is(t->cache_.kIntegerOrMinusZero)) return type; 407 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) { 408 return Type::Union( 409 Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()), 410 t->cache_.kSingletonZero, t->zone()); 411 } 412 return t->cache_.kIntegerOrMinusZero; 413 } 414 415 416 // static 417 Type* Typer::Visitor::ToLength(Type* type, Typer* t) { 418 // ES6 section 7.1.15 ToLength ( argument ) 419 type = ToInteger(type, t); 420 double min = type->Min(); 421 double max = type->Max(); 422 if (min <= 0.0) min = 0.0; 423 if (max > kMaxSafeInteger) max = kMaxSafeInteger; 424 if (max <= min) max = min; 425 return Type::Range(min, max, t->zone()); 426 } 427 428 429 // static 430 Type* Typer::Visitor::ToName(Type* type, Typer* t) { 431 // ES6 section 7.1.14 ToPropertyKey ( argument ) 432 type = ToPrimitive(type, t); 433 if (type->Is(Type::Name())) return type; 434 if (type->Maybe(Type::Symbol())) return Type::Name(); 435 return ToString(type, t); 436 } 437 438 439 // static 440 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { 441 if (type->Is(Type::Number())) return type; 442 if (type->Is(Type::NullOrUndefined())) { 443 if (type->Is(Type::Null())) return t->cache_.kSingletonZero; 444 if (type->Is(Type::Undefined())) return Type::NaN(); 445 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone()); 446 } 447 if (type->Is(Type::NumberOrUndefined())) { 448 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), 449 Type::NaN(), t->zone()); 450 } 451 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero; 452 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne; 453 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne; 454 if (type->Is(Type::BooleanOrNumber())) { 455 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()), 456 t->cache_.kZeroOrOne, t->zone()); 457 } 458 return Type::Number(); 459 } 460 461 462 // static 463 Type* Typer::Visitor::ToObject(Type* type, Typer* t) { 464 // ES6 section 7.1.13 ToObject ( argument ) 465 if (type->Is(Type::Receiver())) return type; 466 if (type->Is(Type::Primitive())) return Type::OtherObject(); 467 if (!type->Maybe(Type::OtherUndetectable())) { 468 return Type::DetectableReceiver(); 469 } 470 return Type::Receiver(); 471 } 472 473 474 // static 475 Type* Typer::Visitor::ToString(Type* type, Typer* t) { 476 // ES6 section 7.1.12 ToString ( argument ) 477 type = ToPrimitive(type, t); 478 if (type->Is(Type::String())) return type; 479 return Type::String(); 480 } 481 482 // static 483 Type* Typer::Visitor::NumberAbs(Type* type, Typer* t) { 484 DCHECK(type->Is(Type::Number())); 485 Factory* const f = t->isolate()->factory(); 486 bool const maybe_nan = type->Maybe(Type::NaN()); 487 bool const maybe_minuszero = type->Maybe(Type::MinusZero()); 488 type = Type::Intersect(type, Type::PlainNumber(), t->zone()); 489 double const max = type->Max(); 490 double const min = type->Min(); 491 if (min < 0) { 492 if (type->Is(t->cache_.kInteger)) { 493 type = 494 Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), t->zone()); 495 } else if (min == max) { 496 type = Type::Constant(f->NewNumber(std::fabs(min)), t->zone()); 497 } else { 498 type = Type::PlainNumber(); 499 } 500 } 501 if (maybe_minuszero) { 502 type = Type::Union(type, t->cache_.kSingletonZero, t->zone()); 503 } 504 if (maybe_nan) { 505 type = Type::Union(type, Type::NaN(), t->zone()); 506 } 507 return type; 508 } 509 510 // static 511 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) { 512 DCHECK(type->Is(Type::Number())); 513 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; 514 // TODO(bmeurer): We could infer a more precise type here. 515 return t->cache_.kIntegerOrMinusZeroOrNaN; 516 } 517 518 // static 519 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { 520 DCHECK(type->Is(Type::Number())); 521 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; 522 // TODO(bmeurer): We could infer a more precise type here. 523 return t->cache_.kIntegerOrMinusZeroOrNaN; 524 } 525 526 // static 527 Type* Typer::Visitor::NumberRound(Type* type, Typer* t) { 528 DCHECK(type->Is(Type::Number())); 529 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; 530 // TODO(bmeurer): We could infer a more precise type here. 531 return t->cache_.kIntegerOrMinusZeroOrNaN; 532 } 533 534 // static 535 Type* Typer::Visitor::NumberTrunc(Type* type, Typer* t) { 536 DCHECK(type->Is(Type::Number())); 537 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; 538 // TODO(bmeurer): We could infer a more precise type here. 539 return t->cache_.kIntegerOrMinusZeroOrNaN; 540 } 541 542 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) { 543 if (type->Is(Type::Signed32())) return type; 544 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; 545 if (type->Is(t->signed32ish_)) { 546 return Type::Intersect( 547 Type::Union(type, t->cache_.kSingletonZero, t->zone()), 548 Type::Signed32(), t->zone()); 549 } 550 return Type::Signed32(); 551 } 552 553 554 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { 555 if (type->Is(Type::Unsigned32())) return type; 556 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero; 557 if (type->Is(t->unsigned32ish_)) { 558 return Type::Intersect( 559 Type::Union(type, t->cache_.kSingletonZero, t->zone()), 560 Type::Unsigned32(), t->zone()); 561 } 562 return Type::Unsigned32(); 563 } 564 565 // Type checks. 566 567 Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) { 568 if (type->Is(Type::Function())) return t->singleton_true_; 569 if (type->Is(Type::Primitive())) return t->singleton_false_; 570 return Type::Boolean(); 571 } 572 573 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) { 574 if (type->Is(Type::Number())) return t->singleton_true_; 575 if (!type->Maybe(Type::Number())) return t->singleton_false_; 576 return Type::Boolean(); 577 } 578 579 580 Type* Typer::Visitor::ObjectIsReceiver(Type* type, Typer* t) { 581 if (type->Is(Type::Receiver())) return t->singleton_true_; 582 if (!type->Maybe(Type::Receiver())) return t->singleton_false_; 583 return Type::Boolean(); 584 } 585 586 587 Type* Typer::Visitor::ObjectIsSmi(Type* type, Typer* t) { 588 if (type->Is(Type::TaggedSigned())) return t->singleton_true_; 589 if (type->Is(Type::TaggedPointer())) return t->singleton_false_; 590 return Type::Boolean(); 591 } 592 593 Type* Typer::Visitor::ObjectIsString(Type* type, Typer* t) { 594 if (type->Is(Type::String())) return t->singleton_true_; 595 if (!type->Maybe(Type::String())) return t->singleton_false_; 596 return Type::Boolean(); 597 } 598 599 Type* Typer::Visitor::ObjectIsUndetectable(Type* type, Typer* t) { 600 if (type->Is(Type::Undetectable())) return t->singleton_true_; 601 if (!type->Maybe(Type::Undetectable())) return t->singleton_false_; 602 return Type::Boolean(); 603 } 604 605 606 // ----------------------------------------------------------------------------- 607 608 609 // Control operators. 610 611 Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); } 612 613 Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } 614 615 616 // Common operators. 617 618 619 Type* Typer::Visitor::TypeParameter(Node* node) { 620 if (FunctionType* function_type = typer_->function_type()) { 621 int const index = ParameterIndexOf(node->op()); 622 if (index >= 0 && index < function_type->Arity()) { 623 return function_type->Parameter(index); 624 } 625 } 626 return Type::Any(); 627 } 628 629 630 Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); } 631 632 633 Type* Typer::Visitor::TypeInt32Constant(Node* node) { 634 double number = OpParameter<int32_t>(node); 635 return Type::Intersect(Type::Range(number, number, zone()), 636 Type::UntaggedIntegral32(), zone()); 637 } 638 639 640 Type* Typer::Visitor::TypeInt64Constant(Node* node) { 641 // TODO(rossberg): This actually seems to be a PointerConstant so far... 642 return Type::Internal(); // TODO(rossberg): Add int64 bitset type? 643 } 644 645 // TODO(gdeepti) : Fix this to do something meaningful. 646 Type* Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { 647 return Type::Internal(); 648 } 649 650 Type* Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { 651 return Type::Internal(); 652 } 653 654 Type* Typer::Visitor::TypeFloat32Constant(Node* node) { 655 return Type::Intersect(Type::Of(OpParameter<float>(node), zone()), 656 Type::UntaggedFloat32(), zone()); 657 } 658 659 660 Type* Typer::Visitor::TypeFloat64Constant(Node* node) { 661 return Type::Intersect(Type::Of(OpParameter<double>(node), zone()), 662 Type::UntaggedFloat64(), zone()); 663 } 664 665 666 Type* Typer::Visitor::TypeNumberConstant(Node* node) { 667 Factory* f = isolate()->factory(); 668 double number = OpParameter<double>(node); 669 if (Type::IsInteger(number)) { 670 return Type::Range(number, number, zone()); 671 } 672 return Type::Constant(f->NewNumber(number), zone()); 673 } 674 675 676 Type* Typer::Visitor::TypeHeapConstant(Node* node) { 677 return TypeConstant(OpParameter<Handle<HeapObject>>(node)); 678 } 679 680 681 Type* Typer::Visitor::TypeExternalConstant(Node* node) { 682 return Type::Internal(); 683 } 684 685 686 Type* Typer::Visitor::TypeSelect(Node* node) { 687 return Type::Union(Operand(node, 1), Operand(node, 2), zone()); 688 } 689 690 691 Type* Typer::Visitor::TypePhi(Node* node) { 692 int arity = node->op()->ValueInputCount(); 693 Type* type = Operand(node, 0); 694 for (int i = 1; i < arity; ++i) { 695 type = Type::Union(type, Operand(node, i), zone()); 696 } 697 return type; 698 } 699 700 701 Type* Typer::Visitor::TypeEffectPhi(Node* node) { 702 UNREACHABLE(); 703 return nullptr; 704 } 705 706 Type* Typer::Visitor::TypeTypeGuard(Node* node) { 707 Type* input_type = Operand(node, 0); 708 Type* guard_type = TypeOf(node->op()); 709 return Type::Intersect(input_type, guard_type, zone()); 710 } 711 712 Type* Typer::Visitor::TypeCheckpoint(Node* node) { 713 UNREACHABLE(); 714 return nullptr; 715 } 716 717 Type* Typer::Visitor::TypeBeginRegion(Node* node) { 718 UNREACHABLE(); 719 return nullptr; 720 } 721 722 723 Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); } 724 725 726 Type* Typer::Visitor::TypeFrameState(Node* node) { 727 // TODO(rossberg): Ideally FrameState wouldn't have a value output. 728 return Type::Internal(); 729 } 730 731 Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); } 732 733 Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); } 734 735 Type* Typer::Visitor::TypeTypedStateValues(Node* node) { 736 return Type::Internal(); 737 } 738 739 740 Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); } 741 742 743 Type* Typer::Visitor::TypeProjection(Node* node) { 744 Type* const type = Operand(node, 0); 745 if (type->Is(Type::None())) return Type::None(); 746 int const index = static_cast<int>(ProjectionIndexOf(node->op())); 747 if (type->IsTuple() && index < type->AsTuple()->Arity()) { 748 return type->AsTuple()->Element(index); 749 } 750 return Type::Any(); 751 } 752 753 754 Type* Typer::Visitor::TypeDead(Node* node) { return Type::Any(); } 755 756 757 // JS comparison operators. 758 759 760 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) { 761 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; 762 if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) { 763 return t->singleton_true_; 764 } 765 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && 766 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { 767 return t->singleton_false_; 768 } 769 if (lhs->IsConstant() && rhs->Is(lhs)) { 770 // Types are equal and are inhabited only by a single semantic value, 771 // which is not nan due to the earlier check. 772 return t->singleton_true_; 773 } 774 return Type::Boolean(); 775 } 776 777 778 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { 779 return Invert(JSEqualTyper(lhs, rhs, t), t); 780 } 781 782 783 static Type* JSType(Type* type) { 784 if (type->Is(Type::Boolean())) return Type::Boolean(); 785 if (type->Is(Type::String())) return Type::String(); 786 if (type->Is(Type::Number())) return Type::Number(); 787 if (type->Is(Type::Undefined())) return Type::Undefined(); 788 if (type->Is(Type::Null())) return Type::Null(); 789 if (type->Is(Type::Symbol())) return Type::Symbol(); 790 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object" 791 return Type::Any(); 792 } 793 794 795 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) { 796 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_; 797 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_; 798 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) && 799 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) { 800 return t->singleton_false_; 801 } 802 if ((lhs->Is(t->singleton_the_hole_) || rhs->Is(t->singleton_the_hole_)) && 803 !lhs->Maybe(rhs)) { 804 return t->singleton_false_; 805 } 806 if (lhs->IsConstant() && rhs->Is(lhs)) { 807 // Types are equal and are inhabited only by a single semantic value, 808 // which is not nan due to the earlier check. 809 return t->singleton_true_; 810 } 811 return Type::Boolean(); 812 } 813 814 815 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) { 816 return Invert(JSStrictEqualTyper(lhs, rhs, t), t); 817 } 818 819 820 // The EcmaScript specification defines the four relational comparison operators 821 // (<, <=, >=, >) with the help of a single abstract one. It behaves like < 822 // but returns undefined when the inputs cannot be compared. 823 // We implement the typing analogously. 824 Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs, 825 Type* rhs, 826 Typer* t) { 827 lhs = ToPrimitive(lhs, t); 828 rhs = ToPrimitive(rhs, t); 829 if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) { 830 return ComparisonOutcome(kComparisonTrue) | 831 ComparisonOutcome(kComparisonFalse); 832 } 833 lhs = ToNumber(lhs, t); 834 rhs = ToNumber(rhs, t); 835 836 // Shortcut for NaNs. 837 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined; 838 839 ComparisonOutcome result; 840 if (lhs->IsConstant() && rhs->Is(lhs)) { 841 // Types are equal and are inhabited only by a single semantic value. 842 result = kComparisonFalse; 843 } else if (lhs->Min() >= rhs->Max()) { 844 result = kComparisonFalse; 845 } else if (lhs->Max() < rhs->Min()) { 846 result = kComparisonTrue; 847 } else { 848 // We cannot figure out the result, return both true and false. (We do not 849 // have to return undefined because that cannot affect the result of 850 // FalsifyUndefined.) 851 return ComparisonOutcome(kComparisonTrue) | 852 ComparisonOutcome(kComparisonFalse); 853 } 854 // Add the undefined if we could see NaN. 855 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { 856 result |= kComparisonUndefined; 857 } 858 return result; 859 } 860 861 862 Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) { 863 return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t); 864 } 865 866 867 Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) { 868 return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t); 869 } 870 871 872 Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) { 873 return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t); 874 } 875 876 877 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( 878 Type* lhs, Type* rhs, Typer* t) { 879 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); 880 } 881 882 // JS bitwise operators. 883 884 885 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 886 lhs = NumberToInt32(ToNumber(lhs, t), t); 887 rhs = NumberToInt32(ToNumber(rhs, t), t); 888 double lmin = lhs->Min(); 889 double rmin = rhs->Min(); 890 double lmax = lhs->Max(); 891 double rmax = rhs->Max(); 892 // Or-ing any two values results in a value no smaller than their minimum. 893 // Even no smaller than their maximum if both values are non-negative. 894 double min = 895 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); 896 double max = Type::Signed32()->Max(); 897 898 // Or-ing with 0 is essentially a conversion to int32. 899 if (rmin == 0 && rmax == 0) { 900 min = lmin; 901 max = lmax; 902 } 903 if (lmin == 0 && lmax == 0) { 904 min = rmin; 905 max = rmax; 906 } 907 908 if (lmax < 0 || rmax < 0) { 909 // Or-ing two values of which at least one is negative results in a negative 910 // value. 911 max = std::min(max, -1.0); 912 } 913 return Type::Range(min, max, t->zone()); 914 } 915 916 917 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 918 lhs = NumberToInt32(ToNumber(lhs, t), t); 919 rhs = NumberToInt32(ToNumber(rhs, t), t); 920 double lmin = lhs->Min(); 921 double rmin = rhs->Min(); 922 double lmax = lhs->Max(); 923 double rmax = rhs->Max(); 924 double min = Type::Signed32()->Min(); 925 // And-ing any two values results in a value no larger than their maximum. 926 // Even no larger than their minimum if both values are non-negative. 927 double max = 928 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); 929 // And-ing with a non-negative value x causes the result to be between 930 // zero and x. 931 if (lmin >= 0) { 932 min = 0; 933 max = std::min(max, lmax); 934 } 935 if (rmin >= 0) { 936 min = 0; 937 max = std::min(max, rmax); 938 } 939 return Type::Range(min, max, t->zone()); 940 } 941 942 943 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { 944 lhs = NumberToInt32(ToNumber(lhs, t), t); 945 rhs = NumberToInt32(ToNumber(rhs, t), t); 946 double lmin = lhs->Min(); 947 double rmin = rhs->Min(); 948 double lmax = lhs->Max(); 949 double rmax = rhs->Max(); 950 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { 951 // Xor-ing negative or non-negative values results in a non-negative value. 952 return Type::Unsigned31(); 953 } 954 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { 955 // Xor-ing a negative and a non-negative value results in a negative value. 956 // TODO(jarin) Use a range here. 957 return Type::Negative32(); 958 } 959 return Type::Signed32(); 960 } 961 962 963 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { 964 return Type::Signed32(); 965 } 966 967 968 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { 969 lhs = NumberToInt32(ToNumber(lhs, t), t); 970 rhs = NumberToUint32(ToNumber(rhs, t), t); 971 double min = kMinInt; 972 double max = kMaxInt; 973 if (lhs->Min() >= 0) { 974 // Right-shifting a non-negative value cannot make it negative, nor larger. 975 min = std::max(min, 0.0); 976 max = std::min(max, lhs->Max()); 977 if (rhs->Min() > 0 && rhs->Max() <= 31) { 978 max = static_cast<int>(max) >> static_cast<int>(rhs->Min()); 979 } 980 } 981 if (lhs->Max() < 0) { 982 // Right-shifting a negative value cannot make it non-negative, nor smaller. 983 min = std::max(min, lhs->Min()); 984 max = std::min(max, -1.0); 985 if (rhs->Min() > 0 && rhs->Max() <= 31) { 986 min = static_cast<int>(min) >> static_cast<int>(rhs->Min()); 987 } 988 } 989 if (rhs->Min() > 0 && rhs->Max() <= 31) { 990 // Right-shifting by a positive value yields a small integer value. 991 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); 992 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); 993 min = std::max(min, shift_min); 994 max = std::min(max, shift_max); 995 } 996 // TODO(jarin) Ideally, the following micro-optimization should be performed 997 // by the type constructor. 998 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { 999 return Type::Range(min, max, t->zone()); 1000 } 1001 return Type::Signed32(); 1002 } 1003 1004 1005 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 1006 lhs = NumberToUint32(ToNumber(lhs, t), t); 1007 // Logical right-shifting any value cannot make it larger. 1008 return Type::Range(0.0, lhs->Max(), t->zone()); 1009 } 1010 1011 1012 // JS arithmetic operators. 1013 1014 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 1015 lhs = ToPrimitive(lhs, t); 1016 rhs = ToPrimitive(rhs, t); 1017 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 1018 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 1019 return Type::String(); 1020 } else { 1021 return Type::NumberOrString(); 1022 } 1023 } 1024 // The addition must be numeric. 1025 return t->operation_typer()->NumericAdd(ToNumber(lhs, t), ToNumber(rhs, t)); 1026 } 1027 1028 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 1029 return t->operation_typer()->NumericSubtract(ToNumber(lhs, t), 1030 ToNumber(rhs, t)); 1031 } 1032 1033 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 1034 return t->operation_typer()->NumericMultiply(ToNumber(lhs, t), 1035 ToNumber(rhs, t)); 1036 } 1037 1038 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 1039 return t->operation_typer()->NumericDivide(ToNumber(lhs, t), 1040 ToNumber(rhs, t)); 1041 lhs = ToNumber(lhs, t); 1042 rhs = ToNumber(rhs, t); 1043 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1044 // Division is tricky, so all we do is try ruling out nan. 1045 bool maybe_nan = 1046 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) || 1047 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 1048 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 1049 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 1050 } 1051 1052 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 1053 return t->operation_typer()->NumericModulus(ToNumber(lhs, t), 1054 ToNumber(rhs, t)); 1055 } 1056 1057 1058 // JS unary operators. 1059 1060 1061 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { 1062 Factory* const f = t->isolate()->factory(); 1063 if (type->Is(Type::Boolean())) { 1064 return Type::Constant(f->boolean_string(), t->zone()); 1065 } else if (type->Is(Type::Number())) { 1066 return Type::Constant(f->number_string(), t->zone()); 1067 } else if (type->Is(Type::String())) { 1068 return Type::Constant(f->string_string(), t->zone()); 1069 } else if (type->Is(Type::Symbol())) { 1070 return Type::Constant(f->symbol_string(), t->zone()); 1071 } else if (type->Is(Type::Union(Type::Undefined(), Type::OtherUndetectable(), 1072 t->zone()))) { 1073 return Type::Constant(f->undefined_string(), t->zone()); 1074 } else if (type->Is(Type::Null())) { 1075 return Type::Constant(f->object_string(), t->zone()); 1076 } else if (type->Is(Type::Function())) { 1077 return Type::Constant(f->function_string(), t->zone()); 1078 } else if (type->IsConstant()) { 1079 return Type::Constant( 1080 Object::TypeOf(t->isolate(), type->AsConstant()->Value()), t->zone()); 1081 } 1082 return Type::InternalizedString(); 1083 } 1084 1085 1086 Type* Typer::Visitor::TypeJSTypeOf(Node* node) { 1087 return TypeUnaryOp(node, JSTypeOfTyper); 1088 } 1089 1090 1091 // JS conversion operators. 1092 1093 1094 Type* Typer::Visitor::TypeJSToBoolean(Node* node) { 1095 return TypeUnaryOp(node, ToBoolean); 1096 } 1097 1098 Type* Typer::Visitor::TypeJSToInteger(Node* node) { 1099 return TypeUnaryOp(node, ToInteger); 1100 } 1101 1102 Type* Typer::Visitor::TypeJSToLength(Node* node) { 1103 return TypeUnaryOp(node, ToLength); 1104 } 1105 1106 Type* Typer::Visitor::TypeJSToName(Node* node) { 1107 return TypeUnaryOp(node, ToName); 1108 } 1109 1110 Type* Typer::Visitor::TypeJSToNumber(Node* node) { 1111 return TypeUnaryOp(node, ToNumber); 1112 } 1113 1114 Type* Typer::Visitor::TypeJSToObject(Node* node) { 1115 return TypeUnaryOp(node, ToObject); 1116 } 1117 1118 Type* Typer::Visitor::TypeJSToString(Node* node) { 1119 return TypeUnaryOp(node, ToString); 1120 } 1121 1122 // JS object operators. 1123 1124 1125 Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); } 1126 1127 1128 Type* Typer::Visitor::TypeJSCreateArguments(Node* node) { 1129 return Type::OtherObject(); 1130 } 1131 1132 1133 Type* Typer::Visitor::TypeJSCreateArray(Node* node) { 1134 return Type::OtherObject(); 1135 } 1136 1137 1138 Type* Typer::Visitor::TypeJSCreateClosure(Node* node) { 1139 return Type::Function(); 1140 } 1141 1142 1143 Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) { 1144 return Type::OtherObject(); 1145 } 1146 1147 1148 Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) { 1149 return Type::OtherObject(); 1150 } 1151 1152 1153 Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) { 1154 return Type::OtherObject(); 1155 } 1156 1157 1158 Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) { 1159 return Type::OtherObject(); 1160 } 1161 1162 1163 Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) { 1164 // TODO(rossberg): Use range types and sized array types to filter undefined. 1165 if (object->IsArray() && name->Is(Type::Integral32())) { 1166 return Type::Union( 1167 object->AsArray()->Element(), Type::Undefined(), t->zone()); 1168 } 1169 return Type::Any(); 1170 } 1171 1172 1173 Type* Typer::Visitor::TypeJSLoadProperty(Node* node) { 1174 return TypeBinaryOp(node, JSLoadPropertyTyper); 1175 } 1176 1177 1178 Type* Typer::Visitor::TypeJSLoadNamed(Node* node) { 1179 return Type::Any(); 1180 } 1181 1182 1183 Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); } 1184 1185 1186 // Returns a somewhat larger range if we previously assigned 1187 // a (smaller) range to this node. This is used to speed up 1188 // the fixpoint calculation in case there appears to be a loop 1189 // in the graph. In the current implementation, we are 1190 // increasing the limits to the closest power of two. 1191 Type* Typer::Visitor::Weaken(Node* node, Type* current_type, 1192 Type* previous_type) { 1193 static const double kWeakenMinLimits[] = { 1194 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0, 1195 -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0, 1196 -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0, 1197 -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0, 1198 -70368744177664.0, -140737488355328.0, -281474976710656.0, 1199 -562949953421312.0}; 1200 static const double kWeakenMaxLimits[] = { 1201 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0, 1202 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0, 1203 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0, 1204 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0, 1205 70368744177663.0, 140737488355327.0, 281474976710655.0, 1206 562949953421311.0}; 1207 STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits)); 1208 1209 // If the types have nothing to do with integers, return the types. 1210 Type* const integer = typer_->cache_.kInteger; 1211 if (!previous_type->Maybe(integer)) { 1212 return current_type; 1213 } 1214 DCHECK(current_type->Maybe(integer)); 1215 1216 Type* current_integer = Type::Intersect(current_type, integer, zone()); 1217 Type* previous_integer = Type::Intersect(previous_type, integer, zone()); 1218 1219 // Once we start weakening a node, we should always weaken. 1220 if (!IsWeakened(node->id())) { 1221 // Only weaken if there is range involved; we should converge quickly 1222 // for all other types (the exception is a union of many constants, 1223 // but we currently do not increase the number of constants in unions). 1224 Type* previous = previous_integer->GetRange(); 1225 Type* current = current_integer->GetRange(); 1226 if (current == nullptr || previous == nullptr) { 1227 return current_type; 1228 } 1229 // Range is involved => we are weakening. 1230 SetWeakened(node->id()); 1231 } 1232 1233 double current_min = current_integer->Min(); 1234 double new_min = current_min; 1235 // Find the closest lower entry in the list of allowed 1236 // minima (or negative infinity if there is no such entry). 1237 if (current_min != previous_integer->Min()) { 1238 new_min = -V8_INFINITY; 1239 for (double const min : kWeakenMinLimits) { 1240 if (min <= current_min) { 1241 new_min = min; 1242 break; 1243 } 1244 } 1245 } 1246 1247 double current_max = current_integer->Max(); 1248 double new_max = current_max; 1249 // Find the closest greater entry in the list of allowed 1250 // maxima (or infinity if there is no such entry). 1251 if (current_max != previous_integer->Max()) { 1252 new_max = V8_INFINITY; 1253 for (double const max : kWeakenMaxLimits) { 1254 if (max >= current_max) { 1255 new_max = max; 1256 break; 1257 } 1258 } 1259 } 1260 1261 return Type::Union(current_type, 1262 Type::Range(new_min, new_max, typer_->zone()), 1263 typer_->zone()); 1264 } 1265 1266 1267 Type* Typer::Visitor::TypeJSStoreProperty(Node* node) { 1268 UNREACHABLE(); 1269 return nullptr; 1270 } 1271 1272 1273 Type* Typer::Visitor::TypeJSStoreNamed(Node* node) { 1274 UNREACHABLE(); 1275 return nullptr; 1276 } 1277 1278 1279 Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) { 1280 UNREACHABLE(); 1281 return nullptr; 1282 } 1283 1284 1285 Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) { 1286 return Type::Boolean(); 1287 } 1288 1289 Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); } 1290 1291 Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); } 1292 1293 // JS context operators. 1294 1295 1296 Type* Typer::Visitor::TypeJSLoadContext(Node* node) { 1297 ContextAccess const& access = ContextAccessOf(node->op()); 1298 if (access.index() == Context::EXTENSION_INDEX) { 1299 return Type::TaggedPointer(); 1300 } 1301 // Since contexts are mutable, we just return the top. 1302 return Type::Any(); 1303 } 1304 1305 1306 Type* Typer::Visitor::TypeJSStoreContext(Node* node) { 1307 UNREACHABLE(); 1308 return nullptr; 1309 } 1310 1311 1312 Type* Typer::Visitor::WrapContextTypeForInput(Node* node) { 1313 Type* outer = TypeOrNone(NodeProperties::GetContextInput(node)); 1314 if (outer->Is(Type::None())) { 1315 return Type::None(); 1316 } else { 1317 DCHECK(outer->Maybe(Type::Internal())); 1318 return Type::Context(outer, zone()); 1319 } 1320 } 1321 1322 1323 Type* Typer::Visitor::TypeJSCreateFunctionContext(Node* node) { 1324 return WrapContextTypeForInput(node); 1325 } 1326 1327 1328 Type* Typer::Visitor::TypeJSCreateCatchContext(Node* node) { 1329 return WrapContextTypeForInput(node); 1330 } 1331 1332 1333 Type* Typer::Visitor::TypeJSCreateWithContext(Node* node) { 1334 return WrapContextTypeForInput(node); 1335 } 1336 1337 1338 Type* Typer::Visitor::TypeJSCreateBlockContext(Node* node) { 1339 return WrapContextTypeForInput(node); 1340 } 1341 1342 1343 Type* Typer::Visitor::TypeJSCreateModuleContext(Node* node) { 1344 // TODO(rossberg): this is probably incorrect 1345 return WrapContextTypeForInput(node); 1346 } 1347 1348 1349 Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) { 1350 return WrapContextTypeForInput(node); 1351 } 1352 1353 1354 // JS other operators. 1355 1356 1357 Type* Typer::Visitor::TypeJSCallConstruct(Node* node) { 1358 return Type::Receiver(); 1359 } 1360 1361 1362 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { 1363 if (fun->IsFunction()) { 1364 return fun->AsFunction()->Result(); 1365 } 1366 if (fun->IsConstant() && fun->AsConstant()->Value()->IsJSFunction()) { 1367 Handle<JSFunction> function = 1368 Handle<JSFunction>::cast(fun->AsConstant()->Value()); 1369 if (function->shared()->HasBuiltinFunctionId()) { 1370 switch (function->shared()->builtin_function_id()) { 1371 case kMathRandom: 1372 return Type::OrderedNumber(); 1373 case kMathFloor: 1374 case kMathCeil: 1375 case kMathRound: 1376 case kMathTrunc: 1377 return t->cache_.kIntegerOrMinusZeroOrNaN; 1378 // Unary math functions. 1379 case kMathExp: 1380 return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone()); 1381 case kMathAbs: 1382 case kMathLog: 1383 case kMathSqrt: 1384 case kMathCos: 1385 case kMathSin: 1386 case kMathTan: 1387 case kMathAcos: 1388 case kMathAsin: 1389 case kMathAtan: 1390 case kMathFround: 1391 return Type::Number(); 1392 // Binary math functions. 1393 case kMathAtan2: 1394 case kMathPow: 1395 case kMathMax: 1396 case kMathMin: 1397 return Type::Number(); 1398 case kMathImul: 1399 return Type::Signed32(); 1400 case kMathClz32: 1401 return t->cache_.kZeroToThirtyTwo; 1402 // String functions. 1403 case kStringCharCodeAt: 1404 return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(), 1405 t->zone()); 1406 case kStringCharAt: 1407 case kStringConcat: 1408 case kStringFromCharCode: 1409 case kStringToLowerCase: 1410 case kStringToUpperCase: 1411 return Type::String(); 1412 // Array functions. 1413 case kArrayIndexOf: 1414 case kArrayLastIndexOf: 1415 return Type::Number(); 1416 default: 1417 break; 1418 } 1419 } 1420 } 1421 return Type::Any(); 1422 } 1423 1424 1425 Type* Typer::Visitor::TypeJSCallFunction(Node* node) { 1426 // TODO(bmeurer): We could infer better types if we wouldn't ignore the 1427 // argument types for the JSCallFunctionTyper above. 1428 return TypeUnaryOp(node, JSCallFunctionTyper); 1429 } 1430 1431 1432 Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { 1433 switch (CallRuntimeParametersOf(node->op()).id()) { 1434 case Runtime::kInlineIsJSReceiver: 1435 return TypeUnaryOp(node, ObjectIsReceiver); 1436 case Runtime::kInlineIsSmi: 1437 return TypeUnaryOp(node, ObjectIsSmi); 1438 case Runtime::kInlineIsArray: 1439 case Runtime::kInlineIsDate: 1440 case Runtime::kInlineIsTypedArray: 1441 case Runtime::kInlineIsRegExp: 1442 return Type::Boolean(); 1443 case Runtime::kInlineDoubleLo: 1444 case Runtime::kInlineDoubleHi: 1445 return Type::Signed32(); 1446 case Runtime::kInlineCreateIterResultObject: 1447 case Runtime::kInlineRegExpConstructResult: 1448 return Type::OtherObject(); 1449 case Runtime::kInlineSubString: 1450 case Runtime::kInlineStringCharFromCode: 1451 return Type::String(); 1452 case Runtime::kInlineToInteger: 1453 return TypeUnaryOp(node, ToInteger); 1454 case Runtime::kInlineToLength: 1455 return TypeUnaryOp(node, ToLength); 1456 case Runtime::kInlineToName: 1457 return TypeUnaryOp(node, ToName); 1458 case Runtime::kInlineToNumber: 1459 return TypeUnaryOp(node, ToNumber); 1460 case Runtime::kInlineToObject: 1461 return TypeUnaryOp(node, ToObject); 1462 case Runtime::kInlineToPrimitive: 1463 case Runtime::kInlineToPrimitive_Number: 1464 case Runtime::kInlineToPrimitive_String: 1465 return TypeUnaryOp(node, ToPrimitive); 1466 case Runtime::kInlineToString: 1467 return TypeUnaryOp(node, ToString); 1468 case Runtime::kHasInPrototypeChain: 1469 return Type::Boolean(); 1470 default: 1471 break; 1472 } 1473 return Type::Any(); 1474 } 1475 1476 1477 Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) { 1478 return Type::Receiver(); 1479 } 1480 1481 1482 Type* Typer::Visitor::TypeJSForInNext(Node* node) { 1483 return Type::Union(Type::Name(), Type::Undefined(), zone()); 1484 } 1485 1486 1487 Type* Typer::Visitor::TypeJSForInPrepare(Node* node) { 1488 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); 1489 Factory* const f = isolate()->factory(); 1490 Type* const cache_type = Type::Union( 1491 typer_->cache_.kSmi, Type::Class(f->meta_map(), zone()), zone()); 1492 Type* const cache_array = Type::Class(f->fixed_array_map(), zone()); 1493 Type* const cache_length = typer_->cache_.kFixedArrayLengthType; 1494 return Type::Tuple(cache_type, cache_array, cache_length, zone()); 1495 } 1496 1497 Type* Typer::Visitor::TypeJSForInDone(Node* node) { return Type::Boolean(); } 1498 1499 Type* Typer::Visitor::TypeJSForInStep(Node* node) { 1500 STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); 1501 return Type::Range(1, FixedArray::kMaxLength + 1, zone()); 1502 } 1503 1504 1505 Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); } 1506 1507 1508 Type* Typer::Visitor::TypeJSStoreMessage(Node* node) { 1509 UNREACHABLE(); 1510 return nullptr; 1511 } 1512 1513 Type* Typer::Visitor::TypeJSGeneratorStore(Node* node) { 1514 UNREACHABLE(); 1515 return nullptr; 1516 } 1517 1518 Type* Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) { 1519 return typer_->cache_.kSmi; 1520 } 1521 1522 Type* Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) { 1523 return Type::Any(); 1524 } 1525 1526 Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); } 1527 1528 // Simplified operators. 1529 1530 Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); } 1531 1532 Type* Typer::Visitor::TypeBooleanToNumber(Node* node) { 1533 return TypeUnaryOp(node, ToNumber); 1534 } 1535 1536 Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); } 1537 1538 Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); } 1539 1540 Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { 1541 return Type::Boolean(); 1542 } 1543 1544 Type* Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) { 1545 return Type::Boolean(); 1546 } 1547 1548 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) { 1549 return Type::Boolean(); 1550 } 1551 1552 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) { 1553 return Type::Boolean(); 1554 } 1555 1556 Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); } 1557 1558 Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); } 1559 1560 Type* Typer::Visitor::TypeSpeculativeNumberAdd(Node* node) { 1561 return Type::Number(); 1562 } 1563 1564 Type* Typer::Visitor::TypeSpeculativeNumberSubtract(Node* node) { 1565 return Type::Number(); 1566 } 1567 1568 Type* Typer::Visitor::TypeSpeculativeNumberMultiply(Node* node) { 1569 return Type::Number(); 1570 } 1571 1572 Type* Typer::Visitor::TypeSpeculativeNumberDivide(Node* node) { 1573 return Type::Number(); 1574 } 1575 1576 Type* Typer::Visitor::TypeSpeculativeNumberModulus(Node* node) { 1577 return Type::Number(); 1578 } 1579 1580 Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); } 1581 1582 Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); } 1583 1584 Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); } 1585 1586 Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) { 1587 return Type::Signed32(); 1588 } 1589 1590 1591 Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) { 1592 return Type::Signed32(); 1593 } 1594 1595 1596 Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) { 1597 return Type::Signed32(); 1598 } 1599 1600 1601 Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) { 1602 return Type::Signed32(); 1603 } 1604 1605 1606 Type* Typer::Visitor::TypeNumberShiftRight(Node* node) { 1607 return Type::Signed32(); 1608 } 1609 1610 1611 Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) { 1612 return Type::Unsigned32(); 1613 } 1614 1615 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { 1616 return TypeUnaryOp(node, ToNumber); 1617 } 1618 1619 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { 1620 return Type::Integral32(); 1621 } 1622 1623 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { 1624 return Type::Number(); 1625 } 1626 1627 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); } 1628 1629 Type* Typer::Visitor::TypeNumberAbs(Node* node) { 1630 return TypeUnaryOp(node, NumberAbs); 1631 } 1632 1633 Type* Typer::Visitor::TypeNumberClz32(Node* node) { 1634 return typer_->cache_.kZeroToThirtyTwo; 1635 } 1636 1637 Type* Typer::Visitor::TypeNumberCeil(Node* node) { 1638 return TypeUnaryOp(node, NumberCeil); 1639 } 1640 1641 Type* Typer::Visitor::TypeNumberFloor(Node* node) { 1642 return TypeUnaryOp(node, NumberFloor); 1643 } 1644 1645 Type* Typer::Visitor::TypeNumberFround(Node* node) { return Type::Number(); } 1646 1647 Type* Typer::Visitor::TypeNumberAtan(Node* node) { return Type::Number(); } 1648 1649 Type* Typer::Visitor::TypeNumberAtan2(Node* node) { return Type::Number(); } 1650 1651 Type* Typer::Visitor::TypeNumberAtanh(Node* node) { return Type::Number(); } 1652 1653 Type* Typer::Visitor::TypeNumberCos(Node* node) { return Type::Number(); } 1654 1655 Type* Typer::Visitor::TypeNumberExp(Node* node) { 1656 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); 1657 } 1658 1659 // TODO(mvstanton): Is this type sufficient, or should it look like Exp()? 1660 Type* Typer::Visitor::TypeNumberExpm1(Node* node) { return Type::Number(); } 1661 1662 Type* Typer::Visitor::TypeNumberLog(Node* node) { return Type::Number(); } 1663 1664 Type* Typer::Visitor::TypeNumberLog1p(Node* node) { return Type::Number(); } 1665 1666 Type* Typer::Visitor::TypeNumberLog2(Node* node) { return Type::Number(); } 1667 1668 Type* Typer::Visitor::TypeNumberLog10(Node* node) { return Type::Number(); } 1669 1670 Type* Typer::Visitor::TypeNumberCbrt(Node* node) { return Type::Number(); } 1671 1672 Type* Typer::Visitor::TypeNumberRound(Node* node) { 1673 return TypeUnaryOp(node, NumberRound); 1674 } 1675 1676 Type* Typer::Visitor::TypeNumberSin(Node* node) { return Type::Number(); } 1677 1678 Type* Typer::Visitor::TypeNumberSqrt(Node* node) { return Type::Number(); } 1679 1680 Type* Typer::Visitor::TypeNumberTan(Node* node) { return Type::Number(); } 1681 1682 Type* Typer::Visitor::TypeNumberTrunc(Node* node) { 1683 return TypeUnaryOp(node, NumberTrunc); 1684 } 1685 1686 Type* Typer::Visitor::TypeNumberToInt32(Node* node) { 1687 return TypeUnaryOp(node, NumberToInt32); 1688 } 1689 1690 1691 Type* Typer::Visitor::TypeNumberToUint32(Node* node) { 1692 return TypeUnaryOp(node, NumberToUint32); 1693 } 1694 1695 1696 // static 1697 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { 1698 if (lhs->IsConstant() && rhs->Is(lhs)) { 1699 return t->singleton_true_; 1700 } 1701 return Type::Boolean(); 1702 } 1703 1704 1705 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { 1706 return TypeBinaryOp(node, ReferenceEqualTyper); 1707 } 1708 1709 Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); } 1710 1711 Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); } 1712 1713 Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { 1714 return Type::Boolean(); 1715 } 1716 1717 Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) { 1718 type = NumberToUint32(ToNumber(type, t), t); 1719 Factory* f = t->isolate()->factory(); 1720 double min = type->Min(); 1721 double max = type->Max(); 1722 if (min == max) { 1723 uint32_t code = static_cast<uint32_t>(min) & String::kMaxUtf16CodeUnitU; 1724 Handle<String> string = f->LookupSingleCharacterStringFromCode(code); 1725 return Type::Constant(string, t->zone()); 1726 } 1727 return Type::String(); 1728 } 1729 1730 Type* Typer::Visitor::TypeStringFromCharCode(Node* node) { 1731 return TypeUnaryOp(node, StringFromCharCodeTyper); 1732 } 1733 1734 Type* Typer::Visitor::TypeStringToNumber(Node* node) { 1735 return TypeUnaryOp(node, ToNumber); 1736 } 1737 1738 namespace { 1739 1740 Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) { 1741 return Type::Union(Type::Semantic(type, zone), 1742 Type::Representation(rep, zone), zone); 1743 } 1744 1745 } // namespace 1746 1747 Type* Typer::Visitor::TypeChangeTaggedSignedToInt32(Node* node) { 1748 Type* arg = Operand(node, 0); 1749 // TODO(jarin): DCHECK(arg->Is(Type::Signed32())); 1750 // Many tests fail this check. 1751 return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone()); 1752 } 1753 1754 Type* Typer::Visitor::TypeChangeTaggedToInt32(Node* node) { 1755 Type* arg = Operand(node, 0); 1756 DCHECK(arg->Is(Type::Signed32())); 1757 return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone()); 1758 } 1759 1760 1761 Type* Typer::Visitor::TypeChangeTaggedToUint32(Node* node) { 1762 Type* arg = Operand(node, 0); 1763 DCHECK(arg->Is(Type::Unsigned32())); 1764 return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone()); 1765 } 1766 1767 1768 Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { 1769 Type* arg = Operand(node, 0); 1770 DCHECK(arg->Is(Type::Number())); 1771 return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone()); 1772 } 1773 1774 Type* Typer::Visitor::TypeTruncateTaggedToFloat64(Node* node) { 1775 Type* arg = Operand(node, 0); 1776 // TODO(jarin) This DCHECK does not work because of speculative feedback. 1777 // Re-enable once we record the speculative feedback in types. 1778 // DCHECK(arg->Is(Type::NumberOrOddball())); 1779 return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone()); 1780 } 1781 1782 Type* Typer::Visitor::TypeChangeInt31ToTaggedSigned(Node* node) { 1783 Type* arg = Operand(node, 0); 1784 // TODO(jarin): DCHECK(arg->Is(Type::Signed31())); 1785 // Some mjsunit/asm and mjsunit/wasm tests fail this check. 1786 // For instance, asm/int32-umod fails with Signed32/UntaggedIntegral32 in 1787 // simplified-lowering (after propagation). 1788 Type* rep = 1789 arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged(); 1790 return ChangeRepresentation(arg, rep, zone()); 1791 } 1792 1793 Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { 1794 Type* arg = Operand(node, 0); 1795 // TODO(jarin): DCHECK(arg->Is(Type::Signed32())); 1796 // Two tests fail this check: mjsunit/asm/sqlite3/sqlite-safe-heap and 1797 // mjsunit/wasm/embenchen/lua_binarytrees. The first one fails with Any/Any in 1798 // simplified-lowering (after propagation). 1799 Type* rep = 1800 arg->Is(Type::SignedSmall()) ? Type::TaggedSigned() : Type::Tagged(); 1801 return ChangeRepresentation(arg, rep, zone()); 1802 } 1803 1804 Type* Typer::Visitor::TypeChangeUint32ToTagged(Node* node) { 1805 Type* arg = Operand(node, 0); 1806 // TODO(jarin): DCHECK(arg->Is(Type::Unsigned32())); 1807 // This fails in benchmarks/octane/mandreel (--turbo). 1808 return ChangeRepresentation(arg, Type::Tagged(), zone()); 1809 } 1810 1811 Type* Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) { 1812 Type* arg = Operand(node, 0); 1813 // TODO(jarin): DCHECK(arg->Is(Type::Number())); 1814 // Some (or all) mjsunit/wasm/embenchen/ tests fail this check when run with 1815 // --turbo and --always-opt. 1816 return ChangeRepresentation(arg, Type::Tagged(), zone()); 1817 } 1818 1819 Type* Typer::Visitor::TypeChangeTaggedToBit(Node* node) { 1820 Type* arg = Operand(node, 0); 1821 DCHECK(arg->Is(Type::Boolean())); 1822 return ChangeRepresentation(arg, Type::UntaggedBit(), zone()); 1823 } 1824 1825 Type* Typer::Visitor::TypeChangeBitToTagged(Node* node) { 1826 Type* arg = Operand(node, 0); 1827 return ChangeRepresentation(arg, Type::TaggedPointer(), zone()); 1828 } 1829 1830 Type* Typer::Visitor::TypeCheckBounds(Node* node) { 1831 // TODO(bmeurer): We could do better here based on the limit. 1832 return Type::Unsigned31(); 1833 } 1834 1835 Type* Typer::Visitor::TypeCheckTaggedPointer(Node* node) { 1836 Type* arg = Operand(node, 0); 1837 return Type::Intersect(arg, Type::TaggedPointer(), zone()); 1838 } 1839 1840 Type* Typer::Visitor::TypeCheckTaggedSigned(Node* node) { 1841 Type* arg = Operand(node, 0); 1842 return Type::Intersect(arg, typer_->cache_.kSmi, zone()); 1843 } 1844 1845 Type* Typer::Visitor::TypeCheckedInt32Add(Node* node) { 1846 return Type::Integral32(); 1847 } 1848 1849 Type* Typer::Visitor::TypeCheckedInt32Sub(Node* node) { 1850 return Type::Integral32(); 1851 } 1852 1853 Type* Typer::Visitor::TypeCheckedUint32ToInt32(Node* node) { 1854 return Type::Signed32(); 1855 } 1856 1857 Type* Typer::Visitor::TypeCheckedFloat64ToInt32(Node* node) { 1858 return Type::Signed32(); 1859 } 1860 1861 Type* Typer::Visitor::TypeCheckedTaggedToInt32(Node* node) { 1862 return Type::Signed32(); 1863 } 1864 1865 Type* Typer::Visitor::TypeCheckedTaggedToFloat64(Node* node) { 1866 return Type::Number(); 1867 } 1868 1869 Type* Typer::Visitor::TypeCheckFloat64Hole(Node* node) { 1870 Type* type = Operand(node, 0); 1871 return type; 1872 } 1873 1874 Type* Typer::Visitor::TypeCheckTaggedHole(Node* node) { 1875 CheckTaggedHoleMode mode = CheckTaggedHoleModeOf(node->op()); 1876 Type* type = Operand(node, 0); 1877 type = Type::Intersect(type, Type::NonInternal(), zone()); 1878 switch (mode) { 1879 case CheckTaggedHoleMode::kConvertHoleToUndefined: { 1880 // The hole is turned into undefined. 1881 type = Type::Union(type, Type::Undefined(), zone()); 1882 break; 1883 } 1884 case CheckTaggedHoleMode::kNeverReturnHole: { 1885 // We deoptimize in case of the hole. 1886 break; 1887 } 1888 } 1889 return type; 1890 } 1891 1892 Type* Typer::Visitor::TypeTruncateTaggedToWord32(Node* node) { 1893 Type* arg = Operand(node, 0); 1894 // TODO(jarin): DCHECK(arg->Is(Type::NumberOrUndefined())); 1895 // Several mjsunit and cctest tests fail this check. For instance, 1896 // mjsunit/compiler/regress-607493 fails with Any/Any in simplified-lowering 1897 // (after propagation). 1898 return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone()); 1899 } 1900 1901 Type* Typer::Visitor::TypeAllocate(Node* node) { return Type::TaggedPointer(); } 1902 1903 1904 namespace { 1905 1906 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { 1907 if (object_type->IsConstant() && 1908 object_type->AsConstant()->Value()->IsHeapObject()) { 1909 Handle<Map> object_map( 1910 Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map()); 1911 if (object_map->is_stable()) return object_map; 1912 } else if (object_type->IsClass()) { 1913 Handle<Map> object_map = object_type->AsClass()->Map(); 1914 if (object_map->is_stable()) return object_map; 1915 } 1916 return MaybeHandle<Map>(); 1917 } 1918 1919 } // namespace 1920 1921 1922 Type* Typer::Visitor::TypeLoadField(Node* node) { 1923 FieldAccess const& access = FieldAccessOf(node->op()); 1924 if (access.base_is_tagged == kTaggedBase && 1925 access.offset == HeapObject::kMapOffset) { 1926 // The type of LoadField[Map](o) is Constant(map) if map is stable and 1927 // either 1928 // (a) o has type Constant(object) and map == object->map, or 1929 // (b) o has type Class(map), 1930 // and either 1931 // (1) map cannot transition further, or 1932 // (2) deoptimization is enabled and we can add a code dependency on the 1933 // stability of map (to guard the Constant type information). 1934 Type* const object = Operand(node, 0); 1935 if (object->Is(Type::None())) return Type::None(); 1936 Handle<Map> object_map; 1937 if (GetStableMapFromObjectType(object).ToHandle(&object_map)) { 1938 if (object_map->CanTransition()) { 1939 if (flags() & kDeoptimizationEnabled) { 1940 dependencies()->AssumeMapStable(object_map); 1941 } else { 1942 return access.type; 1943 } 1944 } 1945 Type* object_map_type = Type::Constant(object_map, zone()); 1946 DCHECK(object_map_type->Is(access.type)); 1947 return object_map_type; 1948 } 1949 } 1950 return access.type; 1951 } 1952 1953 1954 Type* Typer::Visitor::TypeLoadBuffer(Node* node) { 1955 // TODO(bmeurer): This typing is not yet correct. Since we can still access 1956 // out of bounds, the type in the general case has to include Undefined. 1957 switch (BufferAccessOf(node->op()).external_array_type()) { 1958 #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \ 1959 case kExternal##ElemType##Array: \ 1960 return Type::Union(typer_->cache_.k##ElemType, Type::Undefined(), zone()); 1961 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1962 #undef TYPED_ARRAY_CASE 1963 } 1964 UNREACHABLE(); 1965 return nullptr; 1966 } 1967 1968 1969 Type* Typer::Visitor::TypeLoadElement(Node* node) { 1970 return ElementAccessOf(node->op()).type; 1971 } 1972 1973 1974 Type* Typer::Visitor::TypeStoreField(Node* node) { 1975 UNREACHABLE(); 1976 return nullptr; 1977 } 1978 1979 1980 Type* Typer::Visitor::TypeStoreBuffer(Node* node) { 1981 UNREACHABLE(); 1982 return nullptr; 1983 } 1984 1985 1986 Type* Typer::Visitor::TypeStoreElement(Node* node) { 1987 UNREACHABLE(); 1988 return nullptr; 1989 } 1990 1991 Type* Typer::Visitor::TypeObjectIsCallable(Node* node) { 1992 return TypeUnaryOp(node, ObjectIsCallable); 1993 } 1994 1995 Type* Typer::Visitor::TypeObjectIsNumber(Node* node) { 1996 return TypeUnaryOp(node, ObjectIsNumber); 1997 } 1998 1999 2000 Type* Typer::Visitor::TypeObjectIsReceiver(Node* node) { 2001 return TypeUnaryOp(node, ObjectIsReceiver); 2002 } 2003 2004 2005 Type* Typer::Visitor::TypeObjectIsSmi(Node* node) { 2006 return TypeUnaryOp(node, ObjectIsSmi); 2007 } 2008 2009 Type* Typer::Visitor::TypeObjectIsString(Node* node) { 2010 return TypeUnaryOp(node, ObjectIsString); 2011 } 2012 2013 Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) { 2014 return TypeUnaryOp(node, ObjectIsUndetectable); 2015 } 2016 2017 2018 // Machine operators. 2019 2020 Type* Typer::Visitor::TypeDebugBreak(Node* node) { return Type::None(); } 2021 2022 Type* Typer::Visitor::TypeComment(Node* node) { return Type::None(); } 2023 2024 Type* Typer::Visitor::TypeLoad(Node* node) { return Type::Any(); } 2025 2026 Type* Typer::Visitor::TypeStackSlot(Node* node) { return Type::Any(); } 2027 2028 Type* Typer::Visitor::TypeStore(Node* node) { 2029 UNREACHABLE(); 2030 return nullptr; 2031 } 2032 2033 2034 Type* Typer::Visitor::TypeWord32And(Node* node) { return Type::Integral32(); } 2035 2036 2037 Type* Typer::Visitor::TypeWord32Or(Node* node) { return Type::Integral32(); } 2038 2039 2040 Type* Typer::Visitor::TypeWord32Xor(Node* node) { return Type::Integral32(); } 2041 2042 2043 Type* Typer::Visitor::TypeWord32Shl(Node* node) { return Type::Integral32(); } 2044 2045 2046 Type* Typer::Visitor::TypeWord32Shr(Node* node) { return Type::Integral32(); } 2047 2048 2049 Type* Typer::Visitor::TypeWord32Sar(Node* node) { return Type::Integral32(); } 2050 2051 2052 Type* Typer::Visitor::TypeWord32Ror(Node* node) { return Type::Integral32(); } 2053 2054 2055 Type* Typer::Visitor::TypeWord32Equal(Node* node) { return Type::Boolean(); } 2056 2057 2058 Type* Typer::Visitor::TypeWord32Clz(Node* node) { return Type::Integral32(); } 2059 2060 2061 Type* Typer::Visitor::TypeWord32Ctz(Node* node) { return Type::Integral32(); } 2062 2063 2064 Type* Typer::Visitor::TypeWord32ReverseBits(Node* node) { 2065 return Type::Integral32(); 2066 } 2067 2068 2069 Type* Typer::Visitor::TypeWord32Popcnt(Node* node) { 2070 return Type::Integral32(); 2071 } 2072 2073 2074 Type* Typer::Visitor::TypeWord64And(Node* node) { return Type::Internal(); } 2075 2076 2077 Type* Typer::Visitor::TypeWord64Or(Node* node) { return Type::Internal(); } 2078 2079 2080 Type* Typer::Visitor::TypeWord64Xor(Node* node) { return Type::Internal(); } 2081 2082 2083 Type* Typer::Visitor::TypeWord64Shl(Node* node) { return Type::Internal(); } 2084 2085 2086 Type* Typer::Visitor::TypeWord64Shr(Node* node) { return Type::Internal(); } 2087 2088 2089 Type* Typer::Visitor::TypeWord64Sar(Node* node) { return Type::Internal(); } 2090 2091 2092 Type* Typer::Visitor::TypeWord64Ror(Node* node) { return Type::Internal(); } 2093 2094 2095 Type* Typer::Visitor::TypeWord64Clz(Node* node) { return Type::Internal(); } 2096 2097 2098 Type* Typer::Visitor::TypeWord64Ctz(Node* node) { return Type::Internal(); } 2099 2100 2101 Type* Typer::Visitor::TypeWord64ReverseBits(Node* node) { 2102 return Type::Internal(); 2103 } 2104 2105 2106 Type* Typer::Visitor::TypeWord64Popcnt(Node* node) { return Type::Internal(); } 2107 2108 2109 Type* Typer::Visitor::TypeWord64Equal(Node* node) { return Type::Boolean(); } 2110 2111 2112 Type* Typer::Visitor::TypeInt32Add(Node* node) { return Type::Integral32(); } 2113 2114 2115 Type* Typer::Visitor::TypeInt32AddWithOverflow(Node* node) { 2116 return Type::Internal(); 2117 } 2118 2119 2120 Type* Typer::Visitor::TypeInt32Sub(Node* node) { return Type::Integral32(); } 2121 2122 2123 Type* Typer::Visitor::TypeInt32SubWithOverflow(Node* node) { 2124 return Type::Internal(); 2125 } 2126 2127 2128 Type* Typer::Visitor::TypeInt32Mul(Node* node) { return Type::Integral32(); } 2129 2130 2131 Type* Typer::Visitor::TypeInt32MulHigh(Node* node) { return Type::Signed32(); } 2132 2133 2134 Type* Typer::Visitor::TypeInt32Div(Node* node) { return Type::Integral32(); } 2135 2136 2137 Type* Typer::Visitor::TypeInt32Mod(Node* node) { return Type::Integral32(); } 2138 2139 2140 Type* Typer::Visitor::TypeInt32LessThan(Node* node) { return Type::Boolean(); } 2141 2142 2143 Type* Typer::Visitor::TypeInt32LessThanOrEqual(Node* node) { 2144 return Type::Boolean(); 2145 } 2146 2147 2148 Type* Typer::Visitor::TypeUint32Div(Node* node) { return Type::Unsigned32(); } 2149 2150 2151 Type* Typer::Visitor::TypeUint32LessThan(Node* node) { return Type::Boolean(); } 2152 2153 2154 Type* Typer::Visitor::TypeUint32LessThanOrEqual(Node* node) { 2155 return Type::Boolean(); 2156 } 2157 2158 2159 Type* Typer::Visitor::TypeUint32Mod(Node* node) { return Type::Unsigned32(); } 2160 2161 2162 Type* Typer::Visitor::TypeUint32MulHigh(Node* node) { 2163 return Type::Unsigned32(); 2164 } 2165 2166 2167 Type* Typer::Visitor::TypeInt64Add(Node* node) { return Type::Internal(); } 2168 2169 2170 Type* Typer::Visitor::TypeInt64AddWithOverflow(Node* node) { 2171 return Type::Internal(); 2172 } 2173 2174 2175 Type* Typer::Visitor::TypeInt64Sub(Node* node) { return Type::Internal(); } 2176 2177 2178 Type* Typer::Visitor::TypeInt64SubWithOverflow(Node* node) { 2179 return Type::Internal(); 2180 } 2181 2182 2183 Type* Typer::Visitor::TypeInt64Mul(Node* node) { return Type::Internal(); } 2184 2185 2186 Type* Typer::Visitor::TypeInt64Div(Node* node) { return Type::Internal(); } 2187 2188 2189 Type* Typer::Visitor::TypeInt64Mod(Node* node) { return Type::Internal(); } 2190 2191 2192 Type* Typer::Visitor::TypeInt64LessThan(Node* node) { return Type::Boolean(); } 2193 2194 2195 Type* Typer::Visitor::TypeInt64LessThanOrEqual(Node* node) { 2196 return Type::Boolean(); 2197 } 2198 2199 2200 Type* Typer::Visitor::TypeUint64Div(Node* node) { return Type::Internal(); } 2201 2202 2203 Type* Typer::Visitor::TypeUint64LessThan(Node* node) { return Type::Boolean(); } 2204 2205 2206 Type* Typer::Visitor::TypeUint64LessThanOrEqual(Node* node) { 2207 return Type::Boolean(); 2208 } 2209 2210 2211 Type* Typer::Visitor::TypeUint64Mod(Node* node) { return Type::Internal(); } 2212 2213 Type* Typer::Visitor::TypeBitcastWordToTagged(Node* node) { 2214 return Type::TaggedPointer(); 2215 } 2216 2217 Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) { 2218 return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone()); 2219 } 2220 2221 2222 Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) { 2223 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); 2224 } 2225 2226 Type* Typer::Visitor::TypeNumberSilenceNaN(Node* node) { 2227 return Type::Number(); 2228 } 2229 2230 Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) { 2231 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), 2232 zone()); 2233 } 2234 2235 Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) { 2236 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), 2237 zone()); 2238 } 2239 2240 Type* Typer::Visitor::TypeTruncateFloat32ToInt32(Node* node) { 2241 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); 2242 } 2243 2244 2245 Type* Typer::Visitor::TypeTruncateFloat32ToUint32(Node* node) { 2246 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), 2247 zone()); 2248 } 2249 2250 2251 Type* Typer::Visitor::TypeTryTruncateFloat32ToInt64(Node* node) { 2252 return Type::Internal(); 2253 } 2254 2255 2256 Type* Typer::Visitor::TypeTryTruncateFloat64ToInt64(Node* node) { 2257 return Type::Internal(); 2258 } 2259 2260 2261 Type* Typer::Visitor::TypeTryTruncateFloat32ToUint64(Node* node) { 2262 return Type::Internal(); 2263 } 2264 2265 2266 Type* Typer::Visitor::TypeTryTruncateFloat64ToUint64(Node* node) { 2267 return Type::Internal(); 2268 } 2269 2270 2271 Type* Typer::Visitor::TypeChangeInt32ToFloat64(Node* node) { 2272 return Type::Intersect(Type::Signed32(), Type::UntaggedFloat64(), zone()); 2273 } 2274 2275 Type* Typer::Visitor::TypeFloat64SilenceNaN(Node* node) { 2276 return Type::UntaggedFloat64(); 2277 } 2278 2279 Type* Typer::Visitor::TypeChangeInt32ToInt64(Node* node) { 2280 return Type::Internal(); 2281 } 2282 2283 2284 Type* Typer::Visitor::TypeChangeUint32ToFloat64(Node* node) { 2285 return Type::Intersect(Type::Unsigned32(), Type::UntaggedFloat64(), zone()); 2286 } 2287 2288 2289 Type* Typer::Visitor::TypeChangeUint32ToUint64(Node* node) { 2290 return Type::Internal(); 2291 } 2292 2293 2294 Type* Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) { 2295 return Type::Intersect(Type::Number(), Type::UntaggedFloat32(), zone()); 2296 } 2297 2298 Type* Typer::Visitor::TypeTruncateFloat64ToWord32(Node* node) { 2299 return Type::Intersect(Type::Integral32(), Type::UntaggedIntegral32(), 2300 zone()); 2301 } 2302 2303 2304 Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) { 2305 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); 2306 } 2307 2308 Type* Typer::Visitor::TypeRoundFloat64ToInt32(Node* node) { 2309 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); 2310 } 2311 2312 Type* Typer::Visitor::TypeRoundInt32ToFloat32(Node* node) { 2313 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone()); 2314 } 2315 2316 2317 Type* Typer::Visitor::TypeRoundInt64ToFloat32(Node* node) { 2318 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone()); 2319 } 2320 2321 2322 Type* Typer::Visitor::TypeRoundInt64ToFloat64(Node* node) { 2323 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone()); 2324 } 2325 2326 2327 Type* Typer::Visitor::TypeRoundUint32ToFloat32(Node* node) { 2328 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone()); 2329 } 2330 2331 2332 Type* Typer::Visitor::TypeRoundUint64ToFloat32(Node* node) { 2333 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat32(), zone()); 2334 } 2335 2336 2337 Type* Typer::Visitor::TypeRoundUint64ToFloat64(Node* node) { 2338 return Type::Intersect(Type::PlainNumber(), Type::UntaggedFloat64(), zone()); 2339 } 2340 2341 2342 Type* Typer::Visitor::TypeBitcastFloat32ToInt32(Node* node) { 2343 return Type::Number(); 2344 } 2345 2346 2347 Type* Typer::Visitor::TypeBitcastFloat64ToInt64(Node* node) { 2348 return Type::Number(); 2349 } 2350 2351 2352 Type* Typer::Visitor::TypeBitcastInt32ToFloat32(Node* node) { 2353 return Type::Number(); 2354 } 2355 2356 2357 Type* Typer::Visitor::TypeBitcastInt64ToFloat64(Node* node) { 2358 return Type::Number(); 2359 } 2360 2361 2362 Type* Typer::Visitor::TypeFloat32Add(Node* node) { return Type::Number(); } 2363 2364 2365 Type* Typer::Visitor::TypeFloat32Sub(Node* node) { return Type::Number(); } 2366 2367 Type* Typer::Visitor::TypeFloat32SubPreserveNan(Node* node) { 2368 return Type::Number(); 2369 } 2370 2371 Type* Typer::Visitor::TypeFloat32Neg(Node* node) { return Type::Number(); } 2372 2373 Type* Typer::Visitor::TypeFloat32Mul(Node* node) { return Type::Number(); } 2374 2375 2376 Type* Typer::Visitor::TypeFloat32Div(Node* node) { return Type::Number(); } 2377 2378 2379 Type* Typer::Visitor::TypeFloat32Max(Node* node) { return Type::Number(); } 2380 2381 2382 Type* Typer::Visitor::TypeFloat32Min(Node* node) { return Type::Number(); } 2383 2384 2385 Type* Typer::Visitor::TypeFloat32Abs(Node* node) { 2386 // TODO(turbofan): We should be able to infer a better type here. 2387 return Type::Number(); 2388 } 2389 2390 2391 Type* Typer::Visitor::TypeFloat32Sqrt(Node* node) { return Type::Number(); } 2392 2393 2394 Type* Typer::Visitor::TypeFloat32Equal(Node* node) { return Type::Boolean(); } 2395 2396 2397 Type* Typer::Visitor::TypeFloat32LessThan(Node* node) { 2398 return Type::Boolean(); 2399 } 2400 2401 2402 Type* Typer::Visitor::TypeFloat32LessThanOrEqual(Node* node) { 2403 return Type::Boolean(); 2404 } 2405 2406 2407 Type* Typer::Visitor::TypeFloat64Add(Node* node) { return Type::Number(); } 2408 2409 2410 Type* Typer::Visitor::TypeFloat64Sub(Node* node) { return Type::Number(); } 2411 2412 Type* Typer::Visitor::TypeFloat64SubPreserveNan(Node* node) { 2413 return Type::Number(); 2414 } 2415 2416 Type* Typer::Visitor::TypeFloat64Neg(Node* node) { return Type::Number(); } 2417 2418 Type* Typer::Visitor::TypeFloat64Mul(Node* node) { return Type::Number(); } 2419 2420 2421 Type* Typer::Visitor::TypeFloat64Div(Node* node) { return Type::Number(); } 2422 2423 2424 Type* Typer::Visitor::TypeFloat64Mod(Node* node) { return Type::Number(); } 2425 2426 2427 Type* Typer::Visitor::TypeFloat64Max(Node* node) { return Type::Number(); } 2428 2429 2430 Type* Typer::Visitor::TypeFloat64Min(Node* node) { return Type::Number(); } 2431 2432 2433 Type* Typer::Visitor::TypeFloat64Abs(Node* node) { 2434 // TODO(turbofan): We should be able to infer a better type here. 2435 return Type::Number(); 2436 } 2437 2438 Type* Typer::Visitor::TypeFloat64Atan(Node* node) { return Type::Number(); } 2439 2440 Type* Typer::Visitor::TypeFloat64Atan2(Node* node) { return Type::Number(); } 2441 2442 Type* Typer::Visitor::TypeFloat64Atanh(Node* node) { return Type::Number(); } 2443 2444 Type* Typer::Visitor::TypeFloat64Cos(Node* node) { return Type::Number(); } 2445 2446 Type* Typer::Visitor::TypeFloat64Exp(Node* node) { return Type::Number(); } 2447 2448 Type* Typer::Visitor::TypeFloat64Expm1(Node* node) { return Type::Number(); } 2449 2450 Type* Typer::Visitor::TypeFloat64Log(Node* node) { return Type::Number(); } 2451 2452 Type* Typer::Visitor::TypeFloat64Log1p(Node* node) { return Type::Number(); } 2453 2454 Type* Typer::Visitor::TypeFloat64Log2(Node* node) { return Type::Number(); } 2455 2456 Type* Typer::Visitor::TypeFloat64Log10(Node* node) { return Type::Number(); } 2457 2458 Type* Typer::Visitor::TypeFloat64Cbrt(Node* node) { return Type::Number(); } 2459 2460 Type* Typer::Visitor::TypeFloat64Sin(Node* node) { return Type::Number(); } 2461 2462 Type* Typer::Visitor::TypeFloat64Sqrt(Node* node) { return Type::Number(); } 2463 2464 Type* Typer::Visitor::TypeFloat64Tan(Node* node) { return Type::Number(); } 2465 2466 Type* Typer::Visitor::TypeFloat64Equal(Node* node) { return Type::Boolean(); } 2467 2468 2469 Type* Typer::Visitor::TypeFloat64LessThan(Node* node) { 2470 return Type::Boolean(); 2471 } 2472 2473 2474 Type* Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) { 2475 return Type::Boolean(); 2476 } 2477 2478 2479 Type* Typer::Visitor::TypeFloat32RoundDown(Node* node) { 2480 // TODO(sigurds): We could have a tighter bound here. 2481 return Type::Number(); 2482 } 2483 2484 2485 Type* Typer::Visitor::TypeFloat64RoundDown(Node* node) { 2486 // TODO(sigurds): We could have a tighter bound here. 2487 return Type::Number(); 2488 } 2489 2490 2491 Type* Typer::Visitor::TypeFloat32RoundUp(Node* node) { 2492 // TODO(sigurds): We could have a tighter bound here. 2493 return Type::Number(); 2494 } 2495 2496 2497 Type* Typer::Visitor::TypeFloat64RoundUp(Node* node) { 2498 // TODO(sigurds): We could have a tighter bound here. 2499 return Type::Number(); 2500 } 2501 2502 2503 Type* Typer::Visitor::TypeFloat32RoundTruncate(Node* node) { 2504 // TODO(sigurds): We could have a tighter bound here. 2505 return Type::Number(); 2506 } 2507 2508 2509 Type* Typer::Visitor::TypeFloat64RoundTruncate(Node* node) { 2510 // TODO(sigurds): We could have a tighter bound here. 2511 return Type::Number(); 2512 } 2513 2514 2515 Type* Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) { 2516 // TODO(sigurds): We could have a tighter bound here. 2517 return Type::Number(); 2518 } 2519 2520 2521 Type* Typer::Visitor::TypeFloat32RoundTiesEven(Node* node) { 2522 // TODO(sigurds): We could have a tighter bound here. 2523 return Type::Number(); 2524 } 2525 2526 2527 Type* Typer::Visitor::TypeFloat64RoundTiesEven(Node* node) { 2528 // TODO(sigurds): We could have a tighter bound here. 2529 return Type::Number(); 2530 } 2531 2532 2533 Type* Typer::Visitor::TypeFloat64ExtractLowWord32(Node* node) { 2534 return Type::Signed32(); 2535 } 2536 2537 2538 Type* Typer::Visitor::TypeFloat64ExtractHighWord32(Node* node) { 2539 return Type::Signed32(); 2540 } 2541 2542 2543 Type* Typer::Visitor::TypeFloat64InsertLowWord32(Node* node) { 2544 return Type::Number(); 2545 } 2546 2547 2548 Type* Typer::Visitor::TypeFloat64InsertHighWord32(Node* node) { 2549 return Type::Number(); 2550 } 2551 2552 2553 Type* Typer::Visitor::TypeLoadStackPointer(Node* node) { 2554 return Type::Internal(); 2555 } 2556 2557 2558 Type* Typer::Visitor::TypeLoadFramePointer(Node* node) { 2559 return Type::Internal(); 2560 } 2561 2562 Type* Typer::Visitor::TypeLoadParentFramePointer(Node* node) { 2563 return Type::Internal(); 2564 } 2565 2566 Type* Typer::Visitor::TypeCheckedLoad(Node* node) { return Type::Any(); } 2567 2568 Type* Typer::Visitor::TypeCheckedStore(Node* node) { 2569 UNREACHABLE(); 2570 return nullptr; 2571 } 2572 2573 Type* Typer::Visitor::TypeAtomicLoad(Node* node) { return Type::Any(); } 2574 2575 Type* Typer::Visitor::TypeAtomicStore(Node* node) { 2576 UNREACHABLE(); 2577 return nullptr; 2578 } 2579 2580 Type* Typer::Visitor::TypeInt32PairAdd(Node* node) { return Type::Internal(); } 2581 2582 Type* Typer::Visitor::TypeInt32PairSub(Node* node) { return Type::Internal(); } 2583 2584 Type* Typer::Visitor::TypeInt32PairMul(Node* node) { return Type::Internal(); } 2585 2586 Type* Typer::Visitor::TypeWord32PairShl(Node* node) { return Type::Internal(); } 2587 2588 Type* Typer::Visitor::TypeWord32PairShr(Node* node) { return Type::Internal(); } 2589 2590 Type* Typer::Visitor::TypeWord32PairSar(Node* node) { return Type::Internal(); } 2591 2592 // SIMD type methods. 2593 2594 #define SIMD_RETURN_SIMD(Name) \ 2595 Type* Typer::Visitor::Type##Name(Node* node) { return Type::Simd(); } 2596 MACHINE_SIMD_RETURN_SIMD_OP_LIST(SIMD_RETURN_SIMD) 2597 MACHINE_SIMD_GENERIC_OP_LIST(SIMD_RETURN_SIMD) 2598 #undef SIMD_RETURN_SIMD 2599 2600 #define SIMD_RETURN_NUM(Name) \ 2601 Type* Typer::Visitor::Type##Name(Node* node) { return Type::Number(); } 2602 MACHINE_SIMD_RETURN_NUM_OP_LIST(SIMD_RETURN_NUM) 2603 #undef SIMD_RETURN_NUM 2604 2605 #define SIMD_RETURN_BOOL(Name) \ 2606 Type* Typer::Visitor::Type##Name(Node* node) { return Type::Boolean(); } 2607 MACHINE_SIMD_RETURN_BOOL_OP_LIST(SIMD_RETURN_BOOL) 2608 #undef SIMD_RETURN_BOOL 2609 2610 // Heap constants. 2611 2612 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { 2613 if (value->IsJSTypedArray()) { 2614 switch (JSTypedArray::cast(*value)->type()) { 2615 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2616 case kExternal##Type##Array: \ 2617 return typer_->cache_.k##Type##Array; 2618 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2619 #undef TYPED_ARRAY_CASE 2620 } 2621 } 2622 if (Type::IsInteger(*value)) { 2623 return Type::Range(value->Number(), value->Number(), zone()); 2624 } 2625 return Type::Constant(value, zone()); 2626 } 2627 2628 } // namespace compiler 2629 } // namespace internal 2630 } // namespace v8 2631