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/factory.h" |
8 #include "src/handles.h" | 9 #include "src/handles.h" |
9 #include "src/ostreams.h" | 10 #include "src/ostreams.h" |
10 | 11 |
11 namespace v8 { | 12 namespace v8 { |
12 namespace internal { | 13 namespace internal { |
13 | 14 |
14 // SUMMARY | 15 // SUMMARY |
15 // | 16 // |
16 // A simple type system for compiler-internal use. It is based entirely on | 17 // A simple type system for compiler-internal use. It is based entirely on |
17 // union types, and all subtyping hence amounts to set inclusion. Besides the | 18 // union types, and all subtyping hence amounts to set inclusion. Besides the |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 class TypeImpl : public Config::Base { | 248 class TypeImpl : public Config::Base { |
248 public: | 249 public: |
249 // Auxiliary types. | 250 // Auxiliary types. |
250 | 251 |
251 class BitsetType; // Internal | 252 class BitsetType; // Internal |
252 class StructuralType; // Internal | 253 class StructuralType; // Internal |
253 class UnionType; // Internal | 254 class UnionType; // Internal |
254 | 255 |
255 class ClassType; | 256 class ClassType; |
256 class ConstantType; | 257 class ConstantType; |
| 258 class RangeType; |
257 class ContextType; | 259 class ContextType; |
258 class ArrayType; | 260 class ArrayType; |
259 class FunctionType; | 261 class FunctionType; |
260 | 262 |
261 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; | 263 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; |
262 typedef typename Config::template Handle<ClassType>::type ClassHandle; | 264 typedef typename Config::template Handle<ClassType>::type ClassHandle; |
263 typedef typename Config::template Handle<ConstantType>::type ConstantHandle; | 265 typedef typename Config::template Handle<ConstantType>::type ConstantHandle; |
| 266 typedef typename Config::template Handle<RangeType>::type RangeHandle; |
264 typedef typename Config::template Handle<ContextType>::type ContextHandle; | 267 typedef typename Config::template Handle<ContextType>::type ContextHandle; |
265 typedef typename Config::template Handle<ArrayType>::type ArrayHandle; | 268 typedef typename Config::template Handle<ArrayType>::type ArrayHandle; |
266 typedef typename Config::template Handle<FunctionType>::type FunctionHandle; | 269 typedef typename Config::template Handle<FunctionType>::type FunctionHandle; |
267 typedef typename Config::template Handle<UnionType>::type UnionHandle; | 270 typedef typename Config::template Handle<UnionType>::type UnionHandle; |
268 typedef typename Config::Region Region; | 271 typedef typename Config::Region Region; |
269 | 272 |
270 // Constructors. | 273 // Constructors. |
271 | 274 |
272 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 275 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
273 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \ | 276 static TypeImpl* type() { return BitsetType::New(BitsetType::k##type); } \ |
274 static TypeHandle type(Region* region) { \ | 277 static TypeHandle type(Region* region) { \ |
275 return BitsetType::New(BitsetType::k##type, region); \ | 278 return BitsetType::New(BitsetType::k##type, region); \ |
276 } | 279 } |
277 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 280 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
278 #undef DEFINE_TYPE_CONSTRUCTOR | 281 #undef DEFINE_TYPE_CONSTRUCTOR |
279 | 282 |
280 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 283 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { |
281 return ClassType::New(map, region); | 284 return ClassType::New(map, region); |
282 } | 285 } |
283 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 286 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
| 287 // TODO(neis): return RangeType for numerical values |
284 return ConstantType::New(value, region); | 288 return ConstantType::New(value, region); |
285 } | 289 } |
| 290 static TypeHandle Range(double min, double max, Region* region) { |
| 291 return RangeType::New(min, max, region); |
| 292 } |
286 static TypeHandle Context(TypeHandle outer, Region* region) { | 293 static TypeHandle Context(TypeHandle outer, Region* region) { |
287 return ContextType::New(outer, region); | 294 return ContextType::New(outer, region); |
288 } | 295 } |
289 static TypeHandle Array(TypeHandle element, Region* region) { | 296 static TypeHandle Array(TypeHandle element, Region* region) { |
290 return ArrayType::New(element, region); | 297 return ArrayType::New(element, region); |
291 } | 298 } |
292 static FunctionHandle Function( | 299 static FunctionHandle Function( |
293 TypeHandle result, TypeHandle receiver, int arity, Region* region) { | 300 TypeHandle result, TypeHandle receiver, int arity, Region* region) { |
294 return FunctionType::New(result, receiver, arity, region); | 301 return FunctionType::New(result, receiver, arity, region); |
295 } | 302 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 | 375 |
369 // Inspection. | 376 // Inspection. |
370 | 377 |
371 bool IsClass() { | 378 bool IsClass() { |
372 return Config::is_class(this) | 379 return Config::is_class(this) |
373 || Config::is_struct(this, StructuralType::kClassTag); | 380 || Config::is_struct(this, StructuralType::kClassTag); |
374 } | 381 } |
375 bool IsConstant() { | 382 bool IsConstant() { |
376 return Config::is_struct(this, StructuralType::kConstantTag); | 383 return Config::is_struct(this, StructuralType::kConstantTag); |
377 } | 384 } |
| 385 bool IsRange() { |
| 386 return Config::is_struct(this, StructuralType::kRangeTag); |
| 387 } |
378 bool IsContext() { | 388 bool IsContext() { |
379 return Config::is_struct(this, StructuralType::kContextTag); | 389 return Config::is_struct(this, StructuralType::kContextTag); |
380 } | 390 } |
381 bool IsArray() { | 391 bool IsArray() { |
382 return Config::is_struct(this, StructuralType::kArrayTag); | 392 return Config::is_struct(this, StructuralType::kArrayTag); |
383 } | 393 } |
384 bool IsFunction() { | 394 bool IsFunction() { |
385 return Config::is_struct(this, StructuralType::kFunctionTag); | 395 return Config::is_struct(this, StructuralType::kFunctionTag); |
386 } | 396 } |
387 | 397 |
388 ClassType* AsClass() { return ClassType::cast(this); } | 398 ClassType* AsClass() { return ClassType::cast(this); } |
389 ConstantType* AsConstant() { return ConstantType::cast(this); } | 399 ConstantType* AsConstant() { return ConstantType::cast(this); } |
| 400 RangeType* AsRange() { return RangeType::cast(this); } |
390 ContextType* AsContext() { return ContextType::cast(this); } | 401 ContextType* AsContext() { return ContextType::cast(this); } |
391 ArrayType* AsArray() { return ArrayType::cast(this); } | 402 ArrayType* AsArray() { return ArrayType::cast(this); } |
392 FunctionType* AsFunction() { return FunctionType::cast(this); } | 403 FunctionType* AsFunction() { return FunctionType::cast(this); } |
393 | 404 |
394 int NumClasses(); | 405 int NumClasses(); |
395 int NumConstants(); | 406 int NumConstants(); |
396 | 407 |
397 template<class T> class Iterator; | 408 template<class T> class Iterator; |
398 Iterator<i::Map> Classes() { | 409 Iterator<i::Map> Classes() { |
399 if (this->IsBitset()) return Iterator<i::Map>(); | 410 if (this->IsBitset()) return Iterator<i::Map>(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 template<class Config> | 524 template<class Config> |
514 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { | 525 class TypeImpl<Config>::StructuralType : public TypeImpl<Config> { |
515 protected: | 526 protected: |
516 template<class> friend class TypeImpl; | 527 template<class> friend class TypeImpl; |
517 friend struct ZoneTypeConfig; // For tags. | 528 friend struct ZoneTypeConfig; // For tags. |
518 friend struct HeapTypeConfig; | 529 friend struct HeapTypeConfig; |
519 | 530 |
520 enum Tag { | 531 enum Tag { |
521 kClassTag, | 532 kClassTag, |
522 kConstantTag, | 533 kConstantTag, |
| 534 kRangeTag, |
523 kContextTag, | 535 kContextTag, |
524 kArrayTag, | 536 kArrayTag, |
525 kFunctionTag, | 537 kFunctionTag, |
526 kUnionTag | 538 kUnionTag |
527 }; | 539 }; |
528 | 540 |
529 int Length() { | 541 int Length() { |
530 return Config::struct_length(Config::as_struct(this)); | 542 return Config::struct_length(Config::as_struct(this)); |
531 } | 543 } |
532 TypeHandle Get(int i) { | 544 TypeHandle Get(int i) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 } | 661 } |
650 | 662 |
651 static ConstantType* cast(TypeImpl* type) { | 663 static ConstantType* cast(TypeImpl* type) { |
652 ASSERT(type->IsConstant()); | 664 ASSERT(type->IsConstant()); |
653 return static_cast<ConstantType*>(type); | 665 return static_cast<ConstantType*>(type); |
654 } | 666 } |
655 }; | 667 }; |
656 | 668 |
657 | 669 |
658 // ----------------------------------------------------------------------------- | 670 // ----------------------------------------------------------------------------- |
| 671 // Range types. |
| 672 |
| 673 template<class Config> |
| 674 class TypeImpl<Config>::RangeType : public StructuralType { |
| 675 public: |
| 676 TypeHandle Bound() { return this->Get(0); } |
| 677 double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } |
| 678 double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } |
| 679 |
| 680 static RangeHandle New( |
| 681 double min, double max, TypeHandle bound, Region* region) { |
| 682 ASSERT(SEMANTIC(bound->AsBitset() | BitsetType::kNumber) |
| 683 == SEMANTIC(BitsetType::kNumber)); |
| 684 ASSERT(!std::isnan(min) && !std::isnan(max) && min <= max); |
| 685 RangeHandle type = Config::template cast<RangeType>( |
| 686 StructuralType::New(StructuralType::kRangeTag, 3, region)); |
| 687 type->Set(0, bound); |
| 688 Factory* factory = Config::isolate(region)->factory(); |
| 689 type->SetValue(1, factory->NewHeapNumber(min)); |
| 690 type->SetValue(2, factory->NewHeapNumber(max)); |
| 691 return type; |
| 692 } |
| 693 |
| 694 static RangeHandle New(double min, double max, Region* region) { |
| 695 TypeHandle bound = BitsetType::New(BitsetType::kNumber, region); |
| 696 return New(min, max, bound, region); |
| 697 } |
| 698 |
| 699 static RangeType* cast(TypeImpl* type) { |
| 700 ASSERT(type->IsRange()); |
| 701 return static_cast<RangeType*>(type); |
| 702 } |
| 703 }; |
| 704 |
| 705 |
| 706 // ----------------------------------------------------------------------------- |
659 // Context types. | 707 // Context types. |
660 | 708 |
661 template<class Config> | 709 template<class Config> |
662 class TypeImpl<Config>::ContextType : public StructuralType { | 710 class TypeImpl<Config>::ContextType : public StructuralType { |
663 public: | 711 public: |
664 TypeHandle Bound() { return this->Get(0); } | 712 TypeHandle Bound() { return this->Get(0); } |
665 TypeHandle Outer() { return this->Get(1); } | 713 TypeHandle Outer() { return this->Get(1); } |
666 | 714 |
667 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) { | 715 static ContextHandle New(TypeHandle outer, TypeHandle bound, Region* region) { |
668 ContextHandle type = Config::template cast<ContextType>( | 716 ContextHandle type = Config::template cast<ContextType>( |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 // Zone-allocated types; they are either (odd) integers to represent bitsets, or | 832 // Zone-allocated types; they are either (odd) integers to represent bitsets, or |
785 // (even) pointers to structures for everything else. | 833 // (even) pointers to structures for everything else. |
786 | 834 |
787 struct ZoneTypeConfig { | 835 struct ZoneTypeConfig { |
788 typedef TypeImpl<ZoneTypeConfig> Type; | 836 typedef TypeImpl<ZoneTypeConfig> Type; |
789 class Base {}; | 837 class Base {}; |
790 typedef void* Struct; | 838 typedef void* Struct; |
791 typedef i::Zone Region; | 839 typedef i::Zone Region; |
792 template<class T> struct Handle { typedef T* type; }; | 840 template<class T> struct Handle { typedef T* type; }; |
793 | 841 |
| 842 // TODO(neis): This will be removed again once we have struct_get_double(). |
| 843 static inline i::Isolate* isolate(Region* region) { |
| 844 return region->isolate(); |
| 845 } |
| 846 |
794 template<class T> static inline T* handle(T* type); | 847 template<class T> static inline T* handle(T* type); |
795 template<class T> static inline T* cast(Type* type); | 848 template<class T> static inline T* cast(Type* type); |
796 | 849 |
797 static inline bool is_bitset(Type* type); | 850 static inline bool is_bitset(Type* type); |
798 static inline bool is_class(Type* type); | 851 static inline bool is_class(Type* type); |
799 static inline bool is_struct(Type* type, int tag); | 852 static inline bool is_struct(Type* type, int tag); |
800 | 853 |
801 static inline int as_bitset(Type* type); | 854 static inline int as_bitset(Type* type); |
802 static inline i::Handle<i::Map> as_class(Type* type); | 855 static inline i::Handle<i::Map> as_class(Type* type); |
803 static inline Struct* as_struct(Type* type); | 856 static inline Struct* as_struct(Type* type); |
(...skipping 22 matching lines...) Expand all Loading... |
826 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for | 879 // Heap-allocated types; either smis for bitsets, maps for classes, boxes for |
827 // constants, or fixed arrays for unions. | 880 // constants, or fixed arrays for unions. |
828 | 881 |
829 struct HeapTypeConfig { | 882 struct HeapTypeConfig { |
830 typedef TypeImpl<HeapTypeConfig> Type; | 883 typedef TypeImpl<HeapTypeConfig> Type; |
831 typedef i::Object Base; | 884 typedef i::Object Base; |
832 typedef i::FixedArray Struct; | 885 typedef i::FixedArray Struct; |
833 typedef i::Isolate Region; | 886 typedef i::Isolate Region; |
834 template<class T> struct Handle { typedef i::Handle<T> type; }; | 887 template<class T> struct Handle { typedef i::Handle<T> type; }; |
835 | 888 |
| 889 // TODO(neis): This will be removed again once we have struct_get_double(). |
| 890 static inline i::Isolate* isolate(Region* region) { |
| 891 return region; |
| 892 } |
| 893 |
836 template<class T> static inline i::Handle<T> handle(T* type); | 894 template<class T> static inline i::Handle<T> handle(T* type); |
837 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); | 895 template<class T> static inline i::Handle<T> cast(i::Handle<Type> type); |
838 | 896 |
839 static inline bool is_bitset(Type* type); | 897 static inline bool is_bitset(Type* type); |
840 static inline bool is_class(Type* type); | 898 static inline bool is_class(Type* type); |
841 static inline bool is_struct(Type* type, int tag); | 899 static inline bool is_struct(Type* type, int tag); |
842 | 900 |
843 static inline int as_bitset(Type* type); | 901 static inline int as_bitset(Type* type); |
844 static inline i::Handle<i::Map> as_class(Type* type); | 902 static inline i::Handle<i::Map> as_class(Type* type); |
845 static inline i::Handle<Struct> as_struct(Type* type); | 903 static inline i::Handle<Struct> as_struct(Type* type); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 bool Narrows(BoundsImpl that) { | 981 bool Narrows(BoundsImpl that) { |
924 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 982 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
925 } | 983 } |
926 }; | 984 }; |
927 | 985 |
928 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 986 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
929 | 987 |
930 } } // namespace v8::internal | 988 } } // namespace v8::internal |
931 | 989 |
932 #endif // V8_TYPES_H_ | 990 #endif // V8_TYPES_H_ |
OLD | NEW |