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 |