• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef V8_COMPILER_TYPES_H_
6 #define V8_COMPILER_TYPES_H_
7 
8 #include "src/base/compiler-specific.h"
9 #include "src/conversions.h"
10 #include "src/globals.h"
11 #include "src/handles.h"
12 #include "src/objects.h"
13 #include "src/ostreams.h"
14 
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18 
19 // SUMMARY
20 //
21 // A simple type system for compiler-internal use. It is based entirely on
22 // union types, and all subtyping hence amounts to set inclusion. Besides the
23 // obvious primitive types and some predefined unions, the type language also
24 // can express class types (a.k.a. specific maps) and singleton types (i.e.,
25 // concrete constants).
26 //
27 // The following equations and inequations hold:
28 //
29 //   None <= T
30 //   T <= Any
31 //
32 //   Number = Signed32 \/ Unsigned32 \/ Double
33 //   Smi <= Signed32
34 //   Name = String \/ Symbol
35 //   UniqueName = InternalizedString \/ Symbol
36 //   InternalizedString < String
37 //
38 //   Receiver = Object \/ Proxy
39 //   OtherUndetectable < Object
40 //   DetectableReceiver = Receiver - OtherUndetectable
41 //
42 //   Constant(x) < T  iff instance_type(map(x)) < T
43 //
44 //
45 // RANGE TYPES
46 //
47 // A range type represents a continuous integer interval by its minimum and
48 // maximum value.  Either value may be an infinity, in which case that infinity
49 // itself is also included in the range.   A range never contains NaN or -0.
50 //
51 // If a value v happens to be an integer n, then Constant(v) is considered a
52 // subtype of Range(n, n) (and therefore also a subtype of any larger range).
53 // In order to avoid large unions, however, it is usually a good idea to use
54 // Range rather than Constant.
55 //
56 //
57 // PREDICATES
58 //
59 // There are two main functions for testing types:
60 //
61 //   T1->Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
62 //   T1->Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
63 //
64 // Typically, the former is to be used to select representations (e.g., via
65 // T->Is(SignedSmall())), and the latter to check whether a specific case needs
66 // handling (e.g., via T->Maybe(Number())).
67 //
68 // There is no functionality to discover whether a type is a leaf in the
69 // lattice. That is intentional. It should always be possible to refine the
70 // lattice (e.g., splitting up number types further) without invalidating any
71 // existing assumptions or tests.
72 // Consequently, do not normally use Equals for type tests, always use Is!
73 //
74 // The NowIs operator implements state-sensitive subtying, as described above.
75 // Any compilation decision based on such temporary properties requires runtime
76 // guarding!
77 //
78 //
79 // PROPERTIES
80 //
81 // Various formal properties hold for constructors, operators, and predicates
82 // over types. For example, constructors are injective and subtyping is a
83 // complete partial order.
84 //
85 // See test/cctest/test-types.cc for a comprehensive executable specification,
86 // especially with respect to the properties of the more exotic 'temporal'
87 // constructors and predicates (those prefixed 'Now').
88 //
89 //
90 // IMPLEMENTATION
91 //
92 // Internally, all 'primitive' types, and their unions, are represented as
93 // bitsets. Bit 0 is reserved for tagging. Only structured types require
94 // allocation.
95 
96 // -----------------------------------------------------------------------------
97 // Values for bitset types
98 
99 // clang-format off
100 
101 #define INTERNAL_BITSET_TYPE_LIST(V)                                      \
102   V(OtherUnsigned31, 1u << 1)  \
103   V(OtherUnsigned32, 1u << 2)  \
104   V(OtherSigned32,   1u << 3)  \
105   V(OtherNumber,     1u << 4)  \
106 
107 #define PROPER_BITSET_TYPE_LIST(V) \
108   V(None,                0u)        \
109   V(Negative31,          1u << 5)   \
110   V(Null,                1u << 6)   \
111   V(Undefined,           1u << 7)   \
112   V(Boolean,             1u << 8)   \
113   V(Unsigned30,          1u << 9)   \
114   V(MinusZero,           1u << 10)  \
115   V(NaN,                 1u << 11)  \
116   V(Symbol,              1u << 12)  \
117   V(InternalizedString,  1u << 13)  \
118   V(OtherString,         1u << 14)  \
119   V(OtherCallable,       1u << 15)  \
120   V(OtherObject,         1u << 16)  \
121   V(OtherUndetectable,   1u << 17)  \
122   V(CallableProxy,       1u << 18)  \
123   V(OtherProxy,          1u << 19)  \
124   V(Function,            1u << 20)  \
125   V(BoundFunction,       1u << 21)  \
126   V(Hole,                1u << 22)  \
127   V(OtherInternal,       1u << 23)  \
128   V(ExternalPointer,     1u << 24)  \
129   \
130   V(Signed31,                     kUnsigned30 | kNegative31) \
131   V(Signed32,                     kSigned31 | kOtherUnsigned31 | \
132                                   kOtherSigned32) \
133   V(Signed32OrMinusZero,          kSigned32 | kMinusZero) \
134   V(Signed32OrMinusZeroOrNaN,     kSigned32 | kMinusZero | kNaN) \
135   V(Negative32,                   kNegative31 | kOtherSigned32) \
136   V(Unsigned31,                   kUnsigned30 | kOtherUnsigned31) \
137   V(Unsigned32,                   kUnsigned30 | kOtherUnsigned31 | \
138                                   kOtherUnsigned32) \
139   V(Unsigned32OrMinusZero,        kUnsigned32 | kMinusZero) \
140   V(Unsigned32OrMinusZeroOrNaN,   kUnsigned32 | kMinusZero | kNaN) \
141   V(Integral32,                   kSigned32 | kUnsigned32) \
142   V(Integral32OrMinusZeroOrNaN,   kIntegral32 | kMinusZero | kNaN) \
143   V(PlainNumber,                  kIntegral32 | kOtherNumber) \
144   V(OrderedNumber,                kPlainNumber | kMinusZero) \
145   V(MinusZeroOrNaN,               kMinusZero | kNaN) \
146   V(Number,                       kOrderedNumber | kNaN) \
147   V(String,                       kInternalizedString | kOtherString) \
148   V(UniqueName,                   kSymbol | kInternalizedString) \
149   V(Name,                         kSymbol | kString) \
150   V(InternalizedStringOrNull,     kInternalizedString | kNull) \
151   V(BooleanOrNumber,              kBoolean | kNumber) \
152   V(BooleanOrNullOrNumber,        kBooleanOrNumber | kNull) \
153   V(BooleanOrNullOrUndefined,     kBoolean | kNull | kUndefined) \
154   V(Oddball,                      kBooleanOrNullOrUndefined | kHole) \
155   V(NullOrNumber,                 kNull | kNumber) \
156   V(NullOrUndefined,              kNull | kUndefined) \
157   V(Undetectable,                 kNullOrUndefined | kOtherUndetectable) \
158   V(NumberOrOddball,              kNumber | kNullOrUndefined | kBoolean | \
159                                   kHole) \
160   V(NumberOrString,               kNumber | kString) \
161   V(NumberOrUndefined,            kNumber | kUndefined) \
162   V(PlainPrimitive,               kNumberOrString | kBoolean | \
163                                   kNullOrUndefined) \
164   V(Primitive,                    kSymbol | kPlainPrimitive) \
165   V(OtherUndetectableOrUndefined, kOtherUndetectable | kUndefined) \
166   V(Proxy,                        kCallableProxy | kOtherProxy) \
167   V(DetectableCallable,           kFunction | kBoundFunction | \
168                                   kOtherCallable | kCallableProxy) \
169   V(Callable,                     kDetectableCallable | kOtherUndetectable) \
170   V(NonCallable,                  kOtherObject | kOtherProxy) \
171   V(NonCallableOrNull,            kNonCallable | kNull) \
172   V(DetectableObject,             kFunction | kBoundFunction | \
173                                   kOtherCallable | kOtherObject) \
174   V(DetectableReceiver,           kDetectableObject | kProxy) \
175   V(DetectableReceiverOrNull,     kDetectableReceiver | kNull) \
176   V(Object,                       kDetectableObject | kOtherUndetectable) \
177   V(Receiver,                     kObject | kProxy) \
178   V(ReceiverOrUndefined,          kReceiver | kUndefined) \
179   V(ReceiverOrNullOrUndefined,    kReceiver | kNull | kUndefined) \
180   V(SymbolOrReceiver,             kSymbol | kReceiver) \
181   V(StringOrReceiver,             kString | kReceiver) \
182   V(Unique,                       kBoolean | kUniqueName | kNull | \
183                                   kUndefined | kReceiver) \
184   V(Internal,                     kHole | kExternalPointer | kOtherInternal) \
185   V(NonInternal,                  kPrimitive | kReceiver) \
186   V(NonNumber,                    kUnique | kString | kInternal) \
187   V(Any,                          0xfffffffeu)
188 
189 // clang-format on
190 
191 /*
192  * The following diagrams show how integers (in the mathematical sense) are
193  * divided among the different atomic numerical types.
194  *
195  *   ON    OS32     N31     U30     OU31    OU32     ON
196  * ______[_______[_______[_______[_______[_______[_______
197  *     -2^31   -2^30     0      2^30    2^31    2^32
198  *
199  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
200  *
201  * Some of the atomic numerical bitsets are internal only (see
202  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
203  * union with certain other bitsets.  For instance, OtherNumber should only
204  * occur as part of PlainNumber.
205  */
206 
207 #define BITSET_TYPE_LIST(V)    \
208   INTERNAL_BITSET_TYPE_LIST(V) \
209   PROPER_BITSET_TYPE_LIST(V)
210 
211 class Type;
212 
213 // -----------------------------------------------------------------------------
214 // Bitset types (internal).
215 
216 class V8_EXPORT_PRIVATE BitsetType {
217  public:
218   typedef uint32_t bitset;  // Internal
219 
220   enum : uint32_t {
221 #define DECLARE_TYPE(type, value) k##type = (value),
222     BITSET_TYPE_LIST(DECLARE_TYPE)
223 #undef DECLARE_TYPE
224         kUnusedEOL = 0
225   };
226 
227   static bitset SignedSmall();
228   static bitset UnsignedSmall();
229 
Bitset()230   bitset Bitset() {
231     return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
232   }
233 
IsInhabited(bitset bits)234   static bool IsInhabited(bitset bits) { return bits != kNone; }
235 
Is(bitset bits1,bitset bits2)236   static bool Is(bitset bits1, bitset bits2) {
237     return (bits1 | bits2) == bits2;
238   }
239 
240   static double Min(bitset);
241   static double Max(bitset);
242 
243   static bitset Glb(Type* type);  // greatest lower bound that's a bitset
244   static bitset Glb(double min, double max);
245   static bitset Lub(Type* type);  // least upper bound that's a bitset
246   static bitset Lub(i::Map* map);
247   static bitset Lub(i::Object* value);
248   static bitset Lub(double value);
249   static bitset Lub(double min, double max);
250   static bitset ExpandInternals(bitset bits);
251 
252   static const char* Name(bitset);
253   static void Print(std::ostream& os, bitset);  // NOLINT
254 #ifdef DEBUG
255   static void Print(bitset);
256 #endif
257 
258   static bitset NumberBits(bitset bits);
259 
IsBitset(Type * type)260   static bool IsBitset(Type* type) {
261     return reinterpret_cast<uintptr_t>(type) & 1;
262   }
263 
NewForTesting(bitset bits)264   static Type* NewForTesting(bitset bits) { return New(bits); }
265 
266  private:
267   friend class Type;
268 
New(bitset bits)269   static Type* New(bitset bits) {
270     return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
271   }
272 
273   struct Boundary {
274     bitset internal;
275     bitset external;
276     double min;
277   };
278   static const Boundary BoundariesArray[];
279   static inline const Boundary* Boundaries();
280   static inline size_t BoundariesSize();
281 };
282 
283 // -----------------------------------------------------------------------------
284 // Superclass for non-bitset types (internal).
285 class TypeBase {
286  protected:
287   friend class Type;
288 
289   enum Kind { kHeapConstant, kOtherNumberConstant, kTuple, kUnion, kRange };
290 
kind()291   Kind kind() const { return kind_; }
TypeBase(Kind kind)292   explicit TypeBase(Kind kind) : kind_(kind) {}
293 
IsKind(Type * type,Kind kind)294   static bool IsKind(Type* type, Kind kind) {
295     if (BitsetType::IsBitset(type)) return false;
296     TypeBase* base = reinterpret_cast<TypeBase*>(type);
297     return base->kind() == kind;
298   }
299 
300   // The hacky conversion to/from Type*.
AsType(TypeBase * type)301   static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
FromType(Type * type)302   static TypeBase* FromType(Type* type) {
303     return reinterpret_cast<TypeBase*>(type);
304   }
305 
306  private:
307   Kind kind_;
308 };
309 
310 // -----------------------------------------------------------------------------
311 // Constant types.
312 
313 class OtherNumberConstantType : public TypeBase {
314  public:
Value()315   double Value() { return value_; }
316 
317   static bool IsOtherNumberConstant(double value);
318   static bool IsOtherNumberConstant(Object* value);
319 
320  private:
321   friend class Type;
322   friend class BitsetType;
323 
New(double value,Zone * zone)324   static Type* New(double value, Zone* zone) {
325     return AsType(new (zone->New(sizeof(OtherNumberConstantType)))
326                       OtherNumberConstantType(value));  // NOLINT
327   }
328 
cast(Type * type)329   static OtherNumberConstantType* cast(Type* type) {
330     DCHECK(IsKind(type, kOtherNumberConstant));
331     return static_cast<OtherNumberConstantType*>(FromType(type));
332   }
333 
OtherNumberConstantType(double value)334   explicit OtherNumberConstantType(double value)
335       : TypeBase(kOtherNumberConstant), value_(value) {
336     CHECK(IsOtherNumberConstant(value));
337   }
338 
Lub()339   BitsetType::bitset Lub() { return BitsetType::kOtherNumber; }
340 
341   double value_;
342 };
343 
NON_EXPORTED_BASE(TypeBase)344 class V8_EXPORT_PRIVATE HeapConstantType : public NON_EXPORTED_BASE(TypeBase) {
345  public:
346   i::Handle<i::HeapObject> Value() { return object_; }
347 
348  private:
349   friend class Type;
350   friend class BitsetType;
351 
352   static Type* New(i::Handle<i::HeapObject> value, Zone* zone) {
353     BitsetType::bitset bitset = BitsetType::Lub(*value);
354     return AsType(new (zone->New(sizeof(HeapConstantType)))
355                       HeapConstantType(bitset, value));
356   }
357 
358   static HeapConstantType* cast(Type* type) {
359     DCHECK(IsKind(type, kHeapConstant));
360     return static_cast<HeapConstantType*>(FromType(type));
361   }
362 
363   HeapConstantType(BitsetType::bitset bitset, i::Handle<i::HeapObject> object);
364 
365   BitsetType::bitset Lub() { return bitset_; }
366 
367   BitsetType::bitset bitset_;
368   Handle<i::HeapObject> object_;
369 };
370 
371 // -----------------------------------------------------------------------------
372 // Range types.
373 
374 class RangeType : public TypeBase {
375  public:
376   struct Limits {
377     double min;
378     double max;
LimitsLimits379     Limits(double min, double max) : min(min), max(max) {}
LimitsLimits380     explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
381     bool IsEmpty();
EmptyLimits382     static Limits Empty() { return Limits(1, 0); }
383     static Limits Intersect(Limits lhs, Limits rhs);
384     static Limits Union(Limits lhs, Limits rhs);
385   };
386 
Min()387   double Min() { return limits_.min; }
Max()388   double Max() { return limits_.max; }
389 
390  private:
391   friend class Type;
392   friend class BitsetType;
393   friend class UnionType;
394 
New(double min,double max,Zone * zone)395   static Type* New(double min, double max, Zone* zone) {
396     return New(Limits(min, max), zone);
397   }
398 
IsInteger(double x)399   static bool IsInteger(double x) {
400     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
401   }
402 
New(Limits lim,Zone * zone)403   static Type* New(Limits lim, Zone* zone) {
404     DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
405     DCHECK(lim.min <= lim.max);
406     BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
407 
408     return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
409   }
410 
cast(Type * type)411   static RangeType* cast(Type* type) {
412     DCHECK(IsKind(type, kRange));
413     return static_cast<RangeType*>(FromType(type));
414   }
415 
RangeType(BitsetType::bitset bitset,Limits limits)416   RangeType(BitsetType::bitset bitset, Limits limits)
417       : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
418 
Lub()419   BitsetType::bitset Lub() { return bitset_; }
420 
421   BitsetType::bitset bitset_;
422   Limits limits_;
423 };
424 
425 // -----------------------------------------------------------------------------
426 // Superclass for types with variable number of type fields.
427 class StructuralType : public TypeBase {
428  public:
LengthForTesting()429   int LengthForTesting() { return Length(); }
430 
431  protected:
432   friend class Type;
433 
Length()434   int Length() { return length_; }
435 
Get(int i)436   Type* Get(int i) {
437     DCHECK(0 <= i && i < this->Length());
438     return elements_[i];
439   }
440 
Set(int i,Type * type)441   void Set(int i, Type* type) {
442     DCHECK(0 <= i && i < this->Length());
443     elements_[i] = type;
444   }
445 
Shrink(int length)446   void Shrink(int length) {
447     DCHECK(2 <= length && length <= this->Length());
448     length_ = length;
449   }
450 
StructuralType(Kind kind,int length,i::Zone * zone)451   StructuralType(Kind kind, int length, i::Zone* zone)
452       : TypeBase(kind), length_(length) {
453     elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
454   }
455 
456  private:
457   int length_;
458   Type** elements_;
459 };
460 
461 // -----------------------------------------------------------------------------
462 // Tuple types.
463 
464 class TupleType : public StructuralType {
465  public:
Arity()466   int Arity() { return this->Length(); }
Element(int i)467   Type* Element(int i) { return this->Get(i); }
468 
InitElement(int i,Type * type)469   void InitElement(int i, Type* type) { this->Set(i, type); }
470 
471  private:
472   friend class Type;
473 
TupleType(int length,Zone * zone)474   TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
475 
New(int length,Zone * zone)476   static Type* New(int length, Zone* zone) {
477     return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
478   }
479 
cast(Type * type)480   static TupleType* cast(Type* type) {
481     DCHECK(IsKind(type, kTuple));
482     return static_cast<TupleType*>(FromType(type));
483   }
484 };
485 
486 // -----------------------------------------------------------------------------
487 // Union types (internal).
488 // A union is a structured type with the following invariants:
489 // - its length is at least 2
490 // - at most one field is a bitset, and it must go into index 0
491 // - no field is a union
492 // - no field is a subtype of any other field
493 class UnionType : public StructuralType {
494  private:
495   friend Type;
496   friend BitsetType;
497 
UnionType(int length,Zone * zone)498   UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
499 
New(int length,Zone * zone)500   static Type* New(int length, Zone* zone) {
501     return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
502   }
503 
cast(Type * type)504   static UnionType* cast(Type* type) {
505     DCHECK(IsKind(type, kUnion));
506     return static_cast<UnionType*>(FromType(type));
507   }
508 
509   bool Wellformed();
510 };
511 
512 class V8_EXPORT_PRIVATE Type {
513  public:
514   typedef BitsetType::bitset bitset;  // Internal
515 
516 // Constructors.
517 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
518   static Type* type() { return BitsetType::New(BitsetType::k##type); }
PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)519   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
520 #undef DEFINE_TYPE_CONSTRUCTOR
521 
522   static Type* SignedSmall() {
523     return BitsetType::New(BitsetType::SignedSmall());
524   }
UnsignedSmall()525   static Type* UnsignedSmall() {
526     return BitsetType::New(BitsetType::UnsignedSmall());
527   }
528 
OtherNumberConstant(double value,Zone * zone)529   static Type* OtherNumberConstant(double value, Zone* zone) {
530     return OtherNumberConstantType::New(value, zone);
531   }
HeapConstant(i::Handle<i::HeapObject> value,Zone * zone)532   static Type* HeapConstant(i::Handle<i::HeapObject> value, Zone* zone) {
533     return HeapConstantType::New(value, zone);
534   }
Range(double min,double max,Zone * zone)535   static Type* Range(double min, double max, Zone* zone) {
536     return RangeType::New(min, max, zone);
537   }
Tuple(Type * first,Type * second,Type * third,Zone * zone)538   static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
539     Type* tuple = TupleType::New(3, zone);
540     tuple->AsTuple()->InitElement(0, first);
541     tuple->AsTuple()->InitElement(1, second);
542     tuple->AsTuple()->InitElement(2, third);
543     return tuple;
544   }
545 
546   // NewConstant is a factory that returns Constant, Range or Number.
547   static Type* NewConstant(i::Handle<i::Object> value, Zone* zone);
548   static Type* NewConstant(double value, Zone* zone);
549 
550   static Type* Union(Type* type1, Type* type2, Zone* zone);
551   static Type* Intersect(Type* type1, Type* type2, Zone* zone);
552 
Of(double value,Zone * zone)553   static Type* Of(double value, Zone* zone) {
554     return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
555   }
Of(i::Object * value,Zone * zone)556   static Type* Of(i::Object* value, Zone* zone) {
557     return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
558   }
Of(i::Handle<i::Object> value,Zone * zone)559   static Type* Of(i::Handle<i::Object> value, Zone* zone) {
560     return Of(*value, zone);
561   }
562 
For(i::Map * map)563   static Type* For(i::Map* map) {
564     return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(map)));
565   }
For(i::Handle<i::Map> map)566   static Type* For(i::Handle<i::Map> map) { return For(*map); }
567 
568   // Predicates.
IsInhabited()569   bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
570 
Is(Type * that)571   bool Is(Type* that) { return this == that || this->SlowIs(that); }
572   bool Maybe(Type* that);
Equals(Type * that)573   bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
574 
575   // Inspection.
IsRange()576   bool IsRange() { return IsKind(TypeBase::kRange); }
IsHeapConstant()577   bool IsHeapConstant() { return IsKind(TypeBase::kHeapConstant); }
IsOtherNumberConstant()578   bool IsOtherNumberConstant() {
579     return IsKind(TypeBase::kOtherNumberConstant);
580   }
IsTuple()581   bool IsTuple() { return IsKind(TypeBase::kTuple); }
582 
AsHeapConstant()583   HeapConstantType* AsHeapConstant() { return HeapConstantType::cast(this); }
AsOtherNumberConstant()584   OtherNumberConstantType* AsOtherNumberConstant() {
585     return OtherNumberConstantType::cast(this);
586   }
AsRange()587   RangeType* AsRange() { return RangeType::cast(this); }
AsTuple()588   TupleType* AsTuple() { return TupleType::cast(this); }
589 
590   // Minimum and maximum of a numeric type.
591   // These functions do not distinguish between -0 and +0.  If the type equals
592   // kNaN, they return NaN; otherwise kNaN is ignored.  Only call these
593   // functions on subtypes of Number.
594   double Min();
595   double Max();
596 
597   // Extracts a range from the type: if the type is a range or a union
598   // containing a range, that range is returned; otherwise, NULL is returned.
599   Type* GetRange();
600 
601   static bool IsInteger(i::Object* x);
IsInteger(double x)602   static bool IsInteger(double x) {
603     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
604   }
605 
606   int NumConstants();
607 
608   // Printing.
609 
610   void PrintTo(std::ostream& os);
611 
612 #ifdef DEBUG
613   void Print();
614 #endif
615 
616   // Helpers for testing.
IsBitsetForTesting()617   bool IsBitsetForTesting() { return IsBitset(); }
IsUnionForTesting()618   bool IsUnionForTesting() { return IsUnion(); }
AsBitsetForTesting()619   bitset AsBitsetForTesting() { return AsBitset(); }
AsUnionForTesting()620   UnionType* AsUnionForTesting() { return AsUnion(); }
621 
622  private:
623   // Friends.
624   template <class>
625   friend class Iterator;
626   friend BitsetType;
627   friend UnionType;
628 
629   // Internal inspection.
IsKind(TypeBase::Kind kind)630   bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
631 
IsNone()632   bool IsNone() { return this == None(); }
IsAny()633   bool IsAny() { return this == Any(); }
IsBitset()634   bool IsBitset() { return BitsetType::IsBitset(this); }
IsUnion()635   bool IsUnion() { return IsKind(TypeBase::kUnion); }
636 
AsBitset()637   bitset AsBitset() {
638     DCHECK(this->IsBitset());
639     return reinterpret_cast<BitsetType*>(this)->Bitset();
640   }
AsUnion()641   UnionType* AsUnion() { return UnionType::cast(this); }
642 
BitsetGlb()643   bitset BitsetGlb() { return BitsetType::Glb(this); }
BitsetLub()644   bitset BitsetLub() { return BitsetType::Lub(this); }
645 
646   bool SlowIs(Type* that);
647 
648   static bool Overlap(RangeType* lhs, RangeType* rhs);
649   static bool Contains(RangeType* lhs, RangeType* rhs);
650   static bool Contains(RangeType* range, i::Object* val);
651 
652   static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
653 
654   static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
655                                                    Zone* zone);
656   static RangeType::Limits ToLimits(bitset bits, Zone* zone);
657 
658   bool SimplyEquals(Type* that);
659 
660   static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
661   static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
662                           RangeType::Limits* limits, Zone* zone);
663   static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
664   static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
665 };
666 
667 }  // namespace compiler
668 }  // namespace internal
669 }  // namespace v8
670 
671 #endif  // V8_COMPILER_TYPES_H_
672