| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_TYPES_H_ | 5 #ifndef V8_TYPES_H_ |
| 6 #define V8_TYPES_H_ | 6 #define V8_TYPES_H_ |
| 7 | 7 |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/handles.h" | 9 #include "src/handles.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 // None <= T | 32 // None <= T |
| 33 // T <= Any | 33 // T <= Any |
| 34 // | 34 // |
| 35 // Number = Signed32 \/ Unsigned32 \/ Double | 35 // Number = Signed32 \/ Unsigned32 \/ Double |
| 36 // Smi <= Signed32 | 36 // Smi <= Signed32 |
| 37 // Name = String \/ Symbol | 37 // Name = String \/ Symbol |
| 38 // UniqueName = InternalizedString \/ Symbol | 38 // UniqueName = InternalizedString \/ Symbol |
| 39 // InternalizedString < String | 39 // InternalizedString < String |
| 40 // | 40 // |
| 41 // Receiver = Object \/ Proxy | 41 // Receiver = Object \/ Proxy |
| 42 // Array < Object | |
| 43 // Function < Object | |
| 44 // RegExp < Object | 42 // RegExp < Object |
| 45 // OtherUndetectable < Object | 43 // OtherUndetectable < Object |
| 46 // DetectableReceiver = Receiver - OtherUndetectable | 44 // DetectableReceiver = Receiver - OtherUndetectable |
| 47 // | 45 // |
| 48 // Constant(x) < T iff instance_type(map(x)) < T | 46 // Constant(x) < T iff instance_type(map(x)) < T |
| 49 // Array(T) < Array | |
| 50 // Function(R, S, T0, T1, ...) < Function | |
| 51 // | |
| 52 // Both structural Array and Function types are invariant in all parameters; | |
| 53 // relaxing this would make Union and Intersect operations more involved. | |
| 54 // There is no subtyping relation between Array or Function types and | |
| 55 // respective Constant types, since these types cannot be reconstructed | |
| 56 // for arbitrary heap values. | |
| 57 // | 47 // |
| 58 // | 48 // |
| 59 // REPRESENTATIONAL DIMENSION | 49 // REPRESENTATIONAL DIMENSION |
| 60 // | 50 // |
| 61 // For the representation axis, the following holds: | 51 // For the representation axis, the following holds: |
| 62 // | 52 // |
| 63 // None <= R | 53 // None <= R |
| 64 // R <= Any | 54 // R <= Any |
| 65 // | 55 // |
| 66 // UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/ | 56 // UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/ |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 }; | 331 }; |
| 342 | 332 |
| 343 // ----------------------------------------------------------------------------- | 333 // ----------------------------------------------------------------------------- |
| 344 // Superclass for non-bitset types (internal). | 334 // Superclass for non-bitset types (internal). |
| 345 class TypeBase { | 335 class TypeBase { |
| 346 protected: | 336 protected: |
| 347 friend class Type; | 337 friend class Type; |
| 348 | 338 |
| 349 enum Kind { | 339 enum Kind { |
| 350 kConstant, | 340 kConstant, |
| 351 kArray, | |
| 352 kFunction, | |
| 353 kTuple, | 341 kTuple, |
| 354 kUnion, | 342 kUnion, |
| 355 kRange | 343 kRange |
| 356 }; | 344 }; |
| 357 | 345 |
| 358 Kind kind() const { return kind_; } | 346 Kind kind() const { return kind_; } |
| 359 explicit TypeBase(Kind kind) : kind_(kind) {} | 347 explicit TypeBase(Kind kind) : kind_(kind) {} |
| 360 | 348 |
| 361 static bool IsKind(Type* type, Kind kind) { | 349 static bool IsKind(Type* type, Kind kind) { |
| 362 if (BitsetType::IsBitset(type)) return false; | 350 if (BitsetType::IsBitset(type)) return false; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 RangeType(BitsetType::bitset bitset, Limits limits) | 446 RangeType(BitsetType::bitset bitset, Limits limits) |
| 459 : TypeBase(kRange), bitset_(bitset), limits_(limits) {} | 447 : TypeBase(kRange), bitset_(bitset), limits_(limits) {} |
| 460 | 448 |
| 461 BitsetType::bitset Lub() { return bitset_; } | 449 BitsetType::bitset Lub() { return bitset_; } |
| 462 | 450 |
| 463 BitsetType::bitset bitset_; | 451 BitsetType::bitset bitset_; |
| 464 Limits limits_; | 452 Limits limits_; |
| 465 }; | 453 }; |
| 466 | 454 |
| 467 // ----------------------------------------------------------------------------- | 455 // ----------------------------------------------------------------------------- |
| 468 // Array types. | |
| 469 | |
| 470 class ArrayType : public TypeBase { | |
| 471 public: | |
| 472 Type* Element() { return element_; } | |
| 473 | |
| 474 private: | |
| 475 friend class Type; | |
| 476 | |
| 477 explicit ArrayType(Type* element) : TypeBase(kArray), element_(element) {} | |
| 478 | |
| 479 static Type* New(Type* element, Zone* zone) { | |
| 480 return AsType(new (zone->New(sizeof(ArrayType))) ArrayType(element)); | |
| 481 } | |
| 482 | |
| 483 static ArrayType* cast(Type* type) { | |
| 484 DCHECK(IsKind(type, kArray)); | |
| 485 return static_cast<ArrayType*>(FromType(type)); | |
| 486 } | |
| 487 | |
| 488 Type* element_; | |
| 489 }; | |
| 490 | |
| 491 // ----------------------------------------------------------------------------- | |
| 492 // Superclass for types with variable number of type fields. | 456 // Superclass for types with variable number of type fields. |
| 493 class StructuralType : public TypeBase { | 457 class StructuralType : public TypeBase { |
| 494 public: | 458 public: |
| 495 int LengthForTesting() { return Length(); } | 459 int LengthForTesting() { return Length(); } |
| 496 | 460 |
| 497 protected: | 461 protected: |
| 498 friend class Type; | 462 friend class Type; |
| 499 | 463 |
| 500 int Length() { return length_; } | 464 int Length() { return length_; } |
| 501 | 465 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 518 : TypeBase(kind), length_(length) { | 482 : TypeBase(kind), length_(length) { |
| 519 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length)); | 483 elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length)); |
| 520 } | 484 } |
| 521 | 485 |
| 522 private: | 486 private: |
| 523 int length_; | 487 int length_; |
| 524 Type** elements_; | 488 Type** elements_; |
| 525 }; | 489 }; |
| 526 | 490 |
| 527 // ----------------------------------------------------------------------------- | 491 // ----------------------------------------------------------------------------- |
| 528 // Function types. | |
| 529 | |
| 530 class FunctionType : public StructuralType { | |
| 531 public: | |
| 532 int Arity() { return this->Length() - 2; } | |
| 533 Type* Result() { return this->Get(0); } | |
| 534 Type* Receiver() { return this->Get(1); } | |
| 535 Type* Parameter(int i) { return this->Get(2 + i); } | |
| 536 | |
| 537 void InitParameter(int i, Type* type) { this->Set(2 + i, type); } | |
| 538 | |
| 539 private: | |
| 540 friend class Type; | |
| 541 | |
| 542 FunctionType(Type* result, Type* receiver, int arity, Zone* zone) | |
| 543 : StructuralType(kFunction, 2 + arity, zone) { | |
| 544 Set(0, result); | |
| 545 Set(1, receiver); | |
| 546 } | |
| 547 | |
| 548 static Type* New(Type* result, Type* receiver, int arity, Zone* zone) { | |
| 549 return AsType(new (zone->New(sizeof(FunctionType))) | |
| 550 FunctionType(result, receiver, arity, zone)); | |
| 551 } | |
| 552 | |
| 553 static FunctionType* cast(Type* type) { | |
| 554 DCHECK(IsKind(type, kFunction)); | |
| 555 return static_cast<FunctionType*>(FromType(type)); | |
| 556 } | |
| 557 }; | |
| 558 | |
| 559 // ----------------------------------------------------------------------------- | |
| 560 // Tuple types. | 492 // Tuple types. |
| 561 | 493 |
| 562 class TupleType : public StructuralType { | 494 class TupleType : public StructuralType { |
| 563 public: | 495 public: |
| 564 int Arity() { return this->Length(); } | 496 int Arity() { return this->Length(); } |
| 565 Type* Element(int i) { return this->Get(i); } | 497 Type* Element(int i) { return this->Get(i); } |
| 566 | 498 |
| 567 void InitElement(int i, Type* type) { this->Set(i, type); } | 499 void InitElement(int i, Type* type) { this->Set(i, type); } |
| 568 | 500 |
| 569 private: | 501 private: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 } | 557 } |
| 626 | 558 |
| 627 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { | 559 static Type* Constant(i::Handle<i::Object> value, Zone* zone) { |
| 628 return ConstantType::New(value, zone); | 560 return ConstantType::New(value, zone); |
| 629 } | 561 } |
| 630 static Type* Range(double min, double max, Zone* zone) { | 562 static Type* Range(double min, double max, Zone* zone) { |
| 631 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged | | 563 return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged | |
| 632 BitsetType::kUntaggedNumber), | 564 BitsetType::kUntaggedNumber), |
| 633 zone); | 565 zone); |
| 634 } | 566 } |
| 635 static Type* Array(Type* element, Zone* zone) { | |
| 636 return ArrayType::New(element, zone); | |
| 637 } | |
| 638 static Type* Function(Type* result, Type* receiver, int arity, Zone* zone) { | |
| 639 return FunctionType::New(result, receiver, arity, zone); | |
| 640 } | |
| 641 static Type* Function(Type* result, Zone* zone) { | |
| 642 return Function(result, Any(), 0, zone); | |
| 643 } | |
| 644 static Type* Function(Type* result, Type* param0, Zone* zone) { | |
| 645 Type* function = Function(result, Any(), 1, zone); | |
| 646 function->AsFunction()->InitParameter(0, param0); | |
| 647 return function; | |
| 648 } | |
| 649 static Type* Function(Type* result, Type* param0, Type* param1, Zone* zone) { | |
| 650 Type* function = Function(result, Any(), 2, zone); | |
| 651 function->AsFunction()->InitParameter(0, param0); | |
| 652 function->AsFunction()->InitParameter(1, param1); | |
| 653 return function; | |
| 654 } | |
| 655 static Type* Function(Type* result, Type* param0, Type* param1, Type* param2, | |
| 656 Zone* zone) { | |
| 657 Type* function = Function(result, Any(), 3, zone); | |
| 658 function->AsFunction()->InitParameter(0, param0); | |
| 659 function->AsFunction()->InitParameter(1, param1); | |
| 660 function->AsFunction()->InitParameter(2, param2); | |
| 661 return function; | |
| 662 } | |
| 663 static Type* Function(Type* result, int arity, Type** params, Zone* zone) { | |
| 664 Type* function = Function(result, Any(), arity, zone); | |
| 665 for (int i = 0; i < arity; ++i) { | |
| 666 function->AsFunction()->InitParameter(i, params[i]); | |
| 667 } | |
| 668 return function; | |
| 669 } | |
| 670 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { | 567 static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) { |
| 671 Type* tuple = TupleType::New(3, zone); | 568 Type* tuple = TupleType::New(3, zone); |
| 672 tuple->AsTuple()->InitElement(0, first); | 569 tuple->AsTuple()->InitElement(0, first); |
| 673 tuple->AsTuple()->InitElement(1, second); | 570 tuple->AsTuple()->InitElement(1, second); |
| 674 tuple->AsTuple()->InitElement(2, third); | 571 tuple->AsTuple()->InitElement(2, third); |
| 675 return tuple; | 572 return tuple; |
| 676 } | 573 } |
| 677 | 574 |
| 678 static Type* Union(Type* type1, Type* type2, Zone* zone); | 575 static Type* Union(Type* type1, Type* type2, Zone* zone); |
| 679 static Type* Intersect(Type* type1, Type* type2, Zone* zone); | 576 static Type* Intersect(Type* type1, Type* type2, Zone* zone); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 704 bool Maybe(Type* that); | 601 bool Maybe(Type* that); |
| 705 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } | 602 bool Equals(Type* that) { return this->Is(that) && that->Is(this); } |
| 706 | 603 |
| 707 // Equivalent to Constant(val)->Is(this), but avoiding allocation. | 604 // Equivalent to Constant(val)->Is(this), but avoiding allocation. |
| 708 bool Contains(i::Object* val); | 605 bool Contains(i::Object* val); |
| 709 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } | 606 bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); } |
| 710 | 607 |
| 711 // Inspection. | 608 // Inspection. |
| 712 bool IsRange() { return IsKind(TypeBase::kRange); } | 609 bool IsRange() { return IsKind(TypeBase::kRange); } |
| 713 bool IsConstant() { return IsKind(TypeBase::kConstant); } | 610 bool IsConstant() { return IsKind(TypeBase::kConstant); } |
| 714 bool IsArray() { return IsKind(TypeBase::kArray); } | |
| 715 bool IsFunction() { return IsKind(TypeBase::kFunction); } | |
| 716 bool IsTuple() { return IsKind(TypeBase::kTuple); } | 611 bool IsTuple() { return IsKind(TypeBase::kTuple); } |
| 717 | 612 |
| 718 ConstantType* AsConstant() { return ConstantType::cast(this); } | 613 ConstantType* AsConstant() { return ConstantType::cast(this); } |
| 719 RangeType* AsRange() { return RangeType::cast(this); } | 614 RangeType* AsRange() { return RangeType::cast(this); } |
| 720 ArrayType* AsArray() { return ArrayType::cast(this); } | |
| 721 FunctionType* AsFunction() { return FunctionType::cast(this); } | |
| 722 TupleType* AsTuple() { return TupleType::cast(this); } | 615 TupleType* AsTuple() { return TupleType::cast(this); } |
| 723 | 616 |
| 724 // Minimum and maximum of a numeric type. | 617 // Minimum and maximum of a numeric type. |
| 725 // These functions do not distinguish between -0 and +0. If the type equals | 618 // These functions do not distinguish between -0 and +0. If the type equals |
| 726 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these | 619 // kNaN, they return NaN; otherwise kNaN is ignored. Only call these |
| 727 // functions on subtypes of Number. | 620 // functions on subtypes of Number. |
| 728 double Min(); | 621 double Min(); |
| 729 double Max(); | 622 double Max(); |
| 730 | 623 |
| 731 // Extracts a range from the type: if the type is a range or a union | 624 // Extracts a range from the type: if the type is a range or a union |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 } | 773 } |
| 881 | 774 |
| 882 bool Narrows(Bounds that) { | 775 bool Narrows(Bounds that) { |
| 883 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 776 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 884 } | 777 } |
| 885 }; | 778 }; |
| 886 } // namespace internal | 779 } // namespace internal |
| 887 } // namespace v8 | 780 } // namespace v8 |
| 888 | 781 |
| 889 #endif // V8_TYPES_H_ | 782 #endif // V8_TYPES_H_ |
| OLD | NEW |