• 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_TYPES_H_
6 #define V8_TYPES_H_
7 
8 #include "src/conversions.h"
9 #include "src/handles.h"
10 #include "src/objects.h"
11 #include "src/ostreams.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // SUMMARY
17 //
18 // A simple type system for compiler-internal use. It is based entirely on
19 // union types, and all subtyping hence amounts to set inclusion. Besides the
20 // obvious primitive types and some predefined unions, the type language also
21 // can express class types (a.k.a. specific maps) and singleton types (i.e.,
22 // concrete constants).
23 //
24 // Types consist of two dimensions: semantic (value range) and representation.
25 // Both are related through subtyping.
26 //
27 //
28 // SEMANTIC DIMENSION
29 //
30 // The following equations and inequations hold for the semantic axis:
31 //
32 //   None <= T
33 //   T <= Any
34 //
35 //   Number = Signed32 \/ Unsigned32 \/ Double
36 //   Smi <= Signed32
37 //   Name = String \/ Symbol
38 //   UniqueName = InternalizedString \/ Symbol
39 //   InternalizedString < String
40 //
41 //   Receiver = Object \/ Proxy
42 //   Array < Object
43 //   Function < Object
44 //   RegExp < Object
45 //   OtherUndetectable < Object
46 //   DetectableReceiver = Receiver - OtherUndetectable
47 //
48 //   Class(map) < T   iff instance_type(map) < T
49 //   Constant(x) < T  iff instance_type(map(x)) < T
50 //   Array(T) < Array
51 //   Function(R, S, T0, T1, ...) < Function
52 //   Context(T) < Internal
53 //
54 // Both structural Array and Function types are invariant in all parameters;
55 // relaxing this would make Union and Intersect operations more involved.
56 // There is no subtyping relation between Array, Function, or Context types
57 // and respective Constant types, since these types cannot be reconstructed
58 // for arbitrary heap values.
59 // Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
60 // change! (Its instance type cannot, however.)
61 // TODO(rossberg): the latter is not currently true for proxies, because of fix,
62 // but will hold once we implement direct proxies.
63 // However, we also define a 'temporal' variant of the subtyping relation that
64 // considers the _current_ state only, i.e., Constant(x) <_now Class(map(x)).
65 //
66 //
67 // REPRESENTATIONAL DIMENSION
68 //
69 // For the representation axis, the following holds:
70 //
71 //   None <= R
72 //   R <= Any
73 //
74 //   UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/
75 //                 UntaggedInt16 \/ UntaggedInt32
76 //   UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64
77 //   UntaggedNumber = UntaggedInt \/ UntaggedFloat
78 //   Untagged = UntaggedNumber \/ UntaggedPtr
79 //   Tagged = TaggedInt \/ TaggedPtr
80 //
81 // Subtyping relates the two dimensions, for example:
82 //
83 //   Number <= Tagged \/ UntaggedNumber
84 //   Object <= TaggedPtr \/ UntaggedPtr
85 //
86 // That holds because the semantic type constructors defined by the API create
87 // types that allow for all possible representations, and dually, the ones for
88 // representation types initially include all semantic ranges. Representations
89 // can then e.g. be narrowed for a given semantic type using intersection:
90 //
91 //   SignedSmall /\ TaggedInt       (a 'smi')
92 //   Number /\ TaggedPtr            (a heap number)
93 //
94 //
95 // RANGE TYPES
96 //
97 // A range type represents a continuous integer interval by its minimum and
98 // maximum value.  Either value may be an infinity, in which case that infinity
99 // itself is also included in the range.   A range never contains NaN or -0.
100 //
101 // If a value v happens to be an integer n, then Constant(v) is considered a
102 // subtype of Range(n, n) (and therefore also a subtype of any larger range).
103 // In order to avoid large unions, however, it is usually a good idea to use
104 // Range rather than Constant.
105 //
106 //
107 // PREDICATES
108 //
109 // There are two main functions for testing types:
110 //
111 //   T1->Is(T2)     -- tests whether T1 is included in T2 (i.e., T1 <= T2)
112 //   T1->Maybe(T2)  -- tests whether T1 and T2 overlap (i.e., T1 /\ T2 =/= 0)
113 //
114 // Typically, the former is to be used to select representations (e.g., via
115 // T->Is(SignedSmall())), and the latter to check whether a specific case needs
116 // handling (e.g., via T->Maybe(Number())).
117 //
118 // There is no functionality to discover whether a type is a leaf in the
119 // lattice. That is intentional. It should always be possible to refine the
120 // lattice (e.g., splitting up number types further) without invalidating any
121 // existing assumptions or tests.
122 // Consequently, do not normally use Equals for type tests, always use Is!
123 //
124 // The NowIs operator implements state-sensitive subtying, as described above.
125 // Any compilation decision based on such temporary properties requires runtime
126 // guarding!
127 //
128 //
129 // PROPERTIES
130 //
131 // Various formal properties hold for constructors, operators, and predicates
132 // over types. For example, constructors are injective and subtyping is a
133 // complete partial order.
134 //
135 // See test/cctest/test-types.cc for a comprehensive executable specification,
136 // especially with respect to the properties of the more exotic 'temporal'
137 // constructors and predicates (those prefixed 'Now').
138 //
139 //
140 // IMPLEMENTATION
141 //
142 // Internally, all 'primitive' types, and their unions, are represented as
143 // bitsets. Bit 0 is reserved for tagging. Class is a heap pointer to the
144 // respective map. Only structured types require allocation.
145 // Note that the bitset representation is closed under both Union and Intersect.
146 
147 
148 // -----------------------------------------------------------------------------
149 // Values for bitset types
150 
151 // clang-format off
152 
153 #define MASK_BITSET_TYPE_LIST(V) \
154   V(Representation, 0xffc00000u) \
155   V(Semantic,       0x003ffffeu)
156 
157 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
158 #define SEMANTIC(k)       ((k) & BitsetType::kSemantic)
159 
160 #define REPRESENTATION_BITSET_TYPE_LIST(V)    \
161   V(None,               0)                    \
162   V(UntaggedBit,        1u << 22 | kSemantic) \
163   V(UntaggedIntegral8,  1u << 23 | kSemantic) \
164   V(UntaggedIntegral16, 1u << 24 | kSemantic) \
165   V(UntaggedIntegral32, 1u << 25 | kSemantic) \
166   V(UntaggedFloat32,    1u << 26 | kSemantic) \
167   V(UntaggedFloat64,    1u << 27 | kSemantic) \
168   V(UntaggedSimd128,    1u << 28 | kSemantic) \
169   V(UntaggedPointer,    1u << 29 | kSemantic) \
170   V(TaggedSigned,       1u << 30 | kSemantic) \
171   V(TaggedPointer,      1u << 31 | kSemantic) \
172   \
173   V(UntaggedIntegral,   kUntaggedBit | kUntaggedIntegral8 |        \
174                         kUntaggedIntegral16 | kUntaggedIntegral32) \
175   V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)       \
176   V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)        \
177   V(Untagged,           kUntaggedNumber | kUntaggedPointer)        \
178   V(Tagged,             kTaggedSigned | kTaggedPointer)
179 
180 #define INTERNAL_BITSET_TYPE_LIST(V)                                      \
181   V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
182   V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
183   V(OtherSigned32,   1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
184   V(OtherNumber,     1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
185 
186 #define SEMANTIC_BITSET_TYPE_LIST(V) \
187   V(Negative31,          1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
188   V(Null,                1u << 6  | REPRESENTATION(kTaggedPointer)) \
189   V(Undefined,           1u << 7  | REPRESENTATION(kTaggedPointer)) \
190   V(Boolean,             1u << 8  | REPRESENTATION(kTaggedPointer)) \
191   V(Unsigned30,          1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
192   V(MinusZero,           1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
193   V(NaN,                 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
194   V(Symbol,              1u << 12 | REPRESENTATION(kTaggedPointer)) \
195   V(InternalizedString,  1u << 13 | REPRESENTATION(kTaggedPointer)) \
196   V(OtherString,         1u << 14 | REPRESENTATION(kTaggedPointer)) \
197   V(Simd,                1u << 15 | REPRESENTATION(kTaggedPointer)) \
198   V(OtherObject,         1u << 17 | REPRESENTATION(kTaggedPointer)) \
199   V(OtherUndetectable,   1u << 16 | REPRESENTATION(kTaggedPointer)) \
200   V(Proxy,               1u << 18 | REPRESENTATION(kTaggedPointer)) \
201   V(Function,            1u << 19 | REPRESENTATION(kTaggedPointer)) \
202   V(Internal,            1u << 20 | REPRESENTATION(kTagged | kUntagged)) \
203   \
204   V(Signed31,                 kUnsigned30 | kNegative31) \
205   V(Signed32,                 kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
206   V(Negative32,               kNegative31 | kOtherSigned32) \
207   V(Unsigned31,               kUnsigned30 | kOtherUnsigned31) \
208   V(Unsigned32,               kUnsigned30 | kOtherUnsigned31 | \
209                               kOtherUnsigned32) \
210   V(Integral32,               kSigned32 | kUnsigned32) \
211   V(PlainNumber,              kIntegral32 | kOtherNumber) \
212   V(OrderedNumber,            kPlainNumber | kMinusZero) \
213   V(MinusZeroOrNaN,           kMinusZero | kNaN) \
214   V(Number,                   kOrderedNumber | kNaN) \
215   V(String,                   kInternalizedString | kOtherString) \
216   V(UniqueName,               kSymbol | kInternalizedString) \
217   V(Name,                     kSymbol | kString) \
218   V(BooleanOrNumber,          kBoolean | kNumber) \
219   V(BooleanOrNullOrUndefined, kBoolean | kNull | kUndefined) \
220   V(NullOrUndefined,          kNull | kUndefined) \
221   V(Undetectable,             kNullOrUndefined | kOtherUndetectable) \
222   V(NumberOrOddball,          kNumber | kNullOrUndefined | kBoolean) \
223   V(NumberOrSimdOrString,     kNumber | kSimd | kString) \
224   V(NumberOrString,           kNumber | kString) \
225   V(NumberOrUndefined,        kNumber | kUndefined) \
226   V(PlainPrimitive,           kNumberOrString | kBoolean | kNullOrUndefined) \
227   V(Primitive,                kSymbol | kSimd | kPlainPrimitive) \
228   V(DetectableReceiver,       kFunction | kOtherObject | kProxy) \
229   V(Object,                   kFunction | kOtherObject | kOtherUndetectable) \
230   V(Receiver,                 kObject | kProxy) \
231   V(StringOrReceiver,         kString | kReceiver) \
232   V(Unique,                   kBoolean | kUniqueName | kNull | kUndefined | \
233                               kReceiver) \
234   V(NonInternal,              kPrimitive | kReceiver) \
235   V(NonNumber,                kUnique | kString | kInternal) \
236   V(Any,                      0xfffffffeu)
237 
238 // clang-format on
239 
240 /*
241  * The following diagrams show how integers (in the mathematical sense) are
242  * divided among the different atomic numerical types.
243  *
244  *   ON    OS32     N31     U30     OU31    OU32     ON
245  * ______[_______[_______[_______[_______[_______[_______
246  *     -2^31   -2^30     0      2^30    2^31    2^32
247  *
248  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
249  *
250  * Some of the atomic numerical bitsets are internal only (see
251  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
252  * union with certain other bitsets.  For instance, OtherNumber should only
253  * occur as part of PlainNumber.
254  */
255 
256 #define PROPER_BITSET_TYPE_LIST(V) \
257   REPRESENTATION_BITSET_TYPE_LIST(V) \
258   SEMANTIC_BITSET_TYPE_LIST(V)
259 
260 #define BITSET_TYPE_LIST(V)          \
261   MASK_BITSET_TYPE_LIST(V)           \
262   REPRESENTATION_BITSET_TYPE_LIST(V) \
263   INTERNAL_BITSET_TYPE_LIST(V)       \
264   SEMANTIC_BITSET_TYPE_LIST(V)
265 
266 class Type;
267 
268 // -----------------------------------------------------------------------------
269 // Bitset types (internal).
270 
271 class BitsetType {
272  public:
273   typedef uint32_t bitset;  // Internal
274 
275   enum : uint32_t {
276 #define DECLARE_TYPE(type, value) k##type = (value),
277     BITSET_TYPE_LIST(DECLARE_TYPE)
278 #undef DECLARE_TYPE
279         kUnusedEOL = 0
280   };
281 
282   static bitset SignedSmall();
283   static bitset UnsignedSmall();
284 
Bitset()285   bitset Bitset() {
286     return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
287   }
288 
IsInhabited(bitset bits)289   static bool IsInhabited(bitset bits) {
290     return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
291   }
292 
SemanticIsInhabited(bitset bits)293   static bool SemanticIsInhabited(bitset bits) {
294     return SEMANTIC(bits) != kNone;
295   }
296 
Is(bitset bits1,bitset bits2)297   static bool Is(bitset bits1, bitset bits2) {
298     return (bits1 | bits2) == bits2;
299   }
300 
301   static double Min(bitset);
302   static double Max(bitset);
303 
304   static bitset Glb(Type* type);  // greatest lower bound that's a bitset
305   static bitset Glb(double min, double max);
306   static bitset Lub(Type* type);  // least upper bound that's a bitset
307   static bitset Lub(i::Map* map);
308   static bitset Lub(i::Object* value);
309   static bitset Lub(double value);
310   static bitset Lub(double min, double max);
311   static bitset ExpandInternals(bitset bits);
312 
313   static const char* Name(bitset);
314   static void Print(std::ostream& os, bitset);  // NOLINT
315 #ifdef DEBUG
316   static void Print(bitset);
317 #endif
318 
319   static bitset NumberBits(bitset bits);
320 
IsBitset(Type * type)321   static bool IsBitset(Type* type) {
322     return reinterpret_cast<uintptr_t>(type) & 1;
323   }
324 
NewForTesting(bitset bits)325   static Type* NewForTesting(bitset bits) { return New(bits); }
326 
327  private:
328   friend class Type;
329 
New(bitset bits)330   static Type* New(bitset bits) {
331     return reinterpret_cast<Type*>(static_cast<uintptr_t>(bits | 1u));
332   }
333 
334   struct Boundary {
335     bitset internal;
336     bitset external;
337     double min;
338   };
339   static const Boundary BoundariesArray[];
340   static inline const Boundary* Boundaries();
341   static inline size_t BoundariesSize();
342 };
343 
344 // -----------------------------------------------------------------------------
345 // Superclass for non-bitset types (internal).
346 class TypeBase {
347  protected:
348   friend class Type;
349 
350   enum Kind {
351     kClass,
352     kConstant,
353     kContext,
354     kArray,
355     kFunction,
356     kTuple,
357     kUnion,
358     kRange
359   };
360 
kind()361   Kind kind() const { return kind_; }
TypeBase(Kind kind)362   explicit TypeBase(Kind kind) : kind_(kind) {}
363 
IsKind(Type * type,Kind kind)364   static bool IsKind(Type* type, Kind kind) {
365     if (BitsetType::IsBitset(type)) return false;
366     TypeBase* base = reinterpret_cast<TypeBase*>(type);
367     return base->kind() == kind;
368   }
369 
370   // The hacky conversion to/from Type*.
AsType(TypeBase * type)371   static Type* AsType(TypeBase* type) { return reinterpret_cast<Type*>(type); }
FromType(Type * type)372   static TypeBase* FromType(Type* type) {
373     return reinterpret_cast<TypeBase*>(type);
374   }
375 
376  private:
377   Kind kind_;
378 };
379 
380 // -----------------------------------------------------------------------------
381 // Class types.
382 
383 class ClassType : public TypeBase {
384  public:
Map()385   i::Handle<i::Map> Map() { return map_; }
386 
387  private:
388   friend class Type;
389   friend class BitsetType;
390 
New(i::Handle<i::Map> map,Zone * zone)391   static Type* New(i::Handle<i::Map> map, Zone* zone) {
392     return AsType(new (zone->New(sizeof(ClassType)))
393                       ClassType(BitsetType::Lub(*map), map));
394   }
395 
cast(Type * type)396   static ClassType* cast(Type* type) {
397     DCHECK(IsKind(type, kClass));
398     return static_cast<ClassType*>(FromType(type));
399   }
400 
ClassType(BitsetType::bitset bitset,i::Handle<i::Map> map)401   ClassType(BitsetType::bitset bitset, i::Handle<i::Map> map)
402       : TypeBase(kClass), bitset_(bitset), map_(map) {}
403 
Lub()404   BitsetType::bitset Lub() { return bitset_; }
405 
406   BitsetType::bitset bitset_;
407   Handle<i::Map> map_;
408 };
409 
410 // -----------------------------------------------------------------------------
411 // Constant types.
412 
413 class ConstantType : public TypeBase {
414  public:
Value()415   i::Handle<i::Object> Value() { return object_; }
416 
417  private:
418   friend class Type;
419   friend class BitsetType;
420 
New(i::Handle<i::Object> value,Zone * zone)421   static Type* New(i::Handle<i::Object> value, Zone* zone) {
422     BitsetType::bitset bitset = BitsetType::Lub(*value);
423     return AsType(new (zone->New(sizeof(ConstantType)))
424                       ConstantType(bitset, value));
425   }
426 
cast(Type * type)427   static ConstantType* cast(Type* type) {
428     DCHECK(IsKind(type, kConstant));
429     return static_cast<ConstantType*>(FromType(type));
430   }
431 
ConstantType(BitsetType::bitset bitset,i::Handle<i::Object> object)432   ConstantType(BitsetType::bitset bitset, i::Handle<i::Object> object)
433       : TypeBase(kConstant), bitset_(bitset), object_(object) {}
434 
Lub()435   BitsetType::bitset Lub() { return bitset_; }
436 
437   BitsetType::bitset bitset_;
438   Handle<i::Object> object_;
439 };
440 // TODO(neis): Also cache value if numerical.
441 // TODO(neis): Allow restricting the representation.
442 
443 // -----------------------------------------------------------------------------
444 // Range types.
445 
446 class RangeType : public TypeBase {
447  public:
448   struct Limits {
449     double min;
450     double max;
LimitsLimits451     Limits(double min, double max) : min(min), max(max) {}
LimitsLimits452     explicit Limits(RangeType* range) : min(range->Min()), max(range->Max()) {}
453     bool IsEmpty();
EmptyLimits454     static Limits Empty() { return Limits(1, 0); }
455     static Limits Intersect(Limits lhs, Limits rhs);
456     static Limits Union(Limits lhs, Limits rhs);
457   };
458 
Min()459   double Min() { return limits_.min; }
Max()460   double Max() { return limits_.max; }
461 
462  private:
463   friend class Type;
464   friend class BitsetType;
465   friend class UnionType;
466 
New(double min,double max,BitsetType::bitset representation,Zone * zone)467   static Type* New(double min, double max, BitsetType::bitset representation,
468                    Zone* zone) {
469     return New(Limits(min, max), representation, zone);
470   }
471 
IsInteger(double x)472   static bool IsInteger(double x) {
473     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
474   }
475 
New(Limits lim,BitsetType::bitset representation,Zone * zone)476   static Type* New(Limits lim, BitsetType::bitset representation, Zone* zone) {
477     DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
478     DCHECK(lim.min <= lim.max);
479     DCHECK(REPRESENTATION(representation) == representation);
480     BitsetType::bitset bits =
481         SEMANTIC(BitsetType::Lub(lim.min, lim.max)) | representation;
482 
483     return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
484   }
485 
cast(Type * type)486   static RangeType* cast(Type* type) {
487     DCHECK(IsKind(type, kRange));
488     return static_cast<RangeType*>(FromType(type));
489   }
490 
RangeType(BitsetType::bitset bitset,Limits limits)491   RangeType(BitsetType::bitset bitset, Limits limits)
492       : TypeBase(kRange), bitset_(bitset), limits_(limits) {}
493 
Lub()494   BitsetType::bitset Lub() { return bitset_; }
495 
496   BitsetType::bitset bitset_;
497   Limits limits_;
498 };
499 
500 // -----------------------------------------------------------------------------
501 // Context types.
502 
503 class ContextType : public TypeBase {
504  public:
Outer()505   Type* Outer() { return outer_; }
506 
507  private:
508   friend class Type;
509 
New(Type * outer,Zone * zone)510   static Type* New(Type* outer, Zone* zone) {
511     return AsType(new (zone->New(sizeof(ContextType))) ContextType(outer));
512   }
513 
cast(Type * type)514   static ContextType* cast(Type* type) {
515     DCHECK(IsKind(type, kContext));
516     return static_cast<ContextType*>(FromType(type));
517   }
518 
ContextType(Type * outer)519   explicit ContextType(Type* outer) : TypeBase(kContext), outer_(outer) {}
520 
521   Type* outer_;
522 };
523 
524 // -----------------------------------------------------------------------------
525 // Array types.
526 
527 class ArrayType : public TypeBase {
528  public:
Element()529   Type* Element() { return element_; }
530 
531  private:
532   friend class Type;
533 
ArrayType(Type * element)534   explicit ArrayType(Type* element) : TypeBase(kArray), element_(element) {}
535 
New(Type * element,Zone * zone)536   static Type* New(Type* element, Zone* zone) {
537     return AsType(new (zone->New(sizeof(ArrayType))) ArrayType(element));
538   }
539 
cast(Type * type)540   static ArrayType* cast(Type* type) {
541     DCHECK(IsKind(type, kArray));
542     return static_cast<ArrayType*>(FromType(type));
543   }
544 
545   Type* element_;
546 };
547 
548 // -----------------------------------------------------------------------------
549 // Superclass for types with variable number of type fields.
550 class StructuralType : public TypeBase {
551  public:
LengthForTesting()552   int LengthForTesting() { return Length(); }
553 
554  protected:
555   friend class Type;
556 
Length()557   int Length() { return length_; }
558 
Get(int i)559   Type* Get(int i) {
560     DCHECK(0 <= i && i < this->Length());
561     return elements_[i];
562   }
563 
Set(int i,Type * type)564   void Set(int i, Type* type) {
565     DCHECK(0 <= i && i < this->Length());
566     elements_[i] = type;
567   }
568 
Shrink(int length)569   void Shrink(int length) {
570     DCHECK(2 <= length && length <= this->Length());
571     length_ = length;
572   }
573 
StructuralType(Kind kind,int length,i::Zone * zone)574   StructuralType(Kind kind, int length, i::Zone* zone)
575       : TypeBase(kind), length_(length) {
576     elements_ = reinterpret_cast<Type**>(zone->New(sizeof(Type*) * length));
577   }
578 
579  private:
580   int length_;
581   Type** elements_;
582 };
583 
584 // -----------------------------------------------------------------------------
585 // Function types.
586 
587 class FunctionType : public StructuralType {
588  public:
Arity()589   int Arity() { return this->Length() - 2; }
Result()590   Type* Result() { return this->Get(0); }
Receiver()591   Type* Receiver() { return this->Get(1); }
Parameter(int i)592   Type* Parameter(int i) { return this->Get(2 + i); }
593 
InitParameter(int i,Type * type)594   void InitParameter(int i, Type* type) { this->Set(2 + i, type); }
595 
596  private:
597   friend class Type;
598 
FunctionType(Type * result,Type * receiver,int arity,Zone * zone)599   FunctionType(Type* result, Type* receiver, int arity, Zone* zone)
600       : StructuralType(kFunction, 2 + arity, zone) {
601     Set(0, result);
602     Set(1, receiver);
603   }
604 
New(Type * result,Type * receiver,int arity,Zone * zone)605   static Type* New(Type* result, Type* receiver, int arity, Zone* zone) {
606     return AsType(new (zone->New(sizeof(FunctionType)))
607                       FunctionType(result, receiver, arity, zone));
608   }
609 
cast(Type * type)610   static FunctionType* cast(Type* type) {
611     DCHECK(IsKind(type, kFunction));
612     return static_cast<FunctionType*>(FromType(type));
613   }
614 };
615 
616 // -----------------------------------------------------------------------------
617 // Tuple types.
618 
619 class TupleType : public StructuralType {
620  public:
Arity()621   int Arity() { return this->Length(); }
Element(int i)622   Type* Element(int i) { return this->Get(i); }
623 
InitElement(int i,Type * type)624   void InitElement(int i, Type* type) { this->Set(i, type); }
625 
626  private:
627   friend class Type;
628 
TupleType(int length,Zone * zone)629   TupleType(int length, Zone* zone) : StructuralType(kTuple, length, zone) {}
630 
New(int length,Zone * zone)631   static Type* New(int length, Zone* zone) {
632     return AsType(new (zone->New(sizeof(TupleType))) TupleType(length, zone));
633   }
634 
cast(Type * type)635   static TupleType* cast(Type* type) {
636     DCHECK(IsKind(type, kTuple));
637     return static_cast<TupleType*>(FromType(type));
638   }
639 };
640 
641 // -----------------------------------------------------------------------------
642 // Union types (internal).
643 // A union is a structured type with the following invariants:
644 // - its length is at least 2
645 // - at most one field is a bitset, and it must go into index 0
646 // - no field is a union
647 // - no field is a subtype of any other field
648 class UnionType : public StructuralType {
649  private:
650   friend Type;
651   friend BitsetType;
652 
UnionType(int length,Zone * zone)653   UnionType(int length, Zone* zone) : StructuralType(kUnion, length, zone) {}
654 
New(int length,Zone * zone)655   static Type* New(int length, Zone* zone) {
656     return AsType(new (zone->New(sizeof(UnionType))) UnionType(length, zone));
657   }
658 
cast(Type * type)659   static UnionType* cast(Type* type) {
660     DCHECK(IsKind(type, kUnion));
661     return static_cast<UnionType*>(FromType(type));
662   }
663 
664   bool Wellformed();
665 };
666 
667 class Type {
668  public:
669   typedef BitsetType::bitset bitset;  // Internal
670 
671 // Constructors.
672 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
673   static Type* type() { return BitsetType::New(BitsetType::k##type); }
PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)674   PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
675 #undef DEFINE_TYPE_CONSTRUCTOR
676 
677   static Type* SignedSmall() {
678     return BitsetType::New(BitsetType::SignedSmall());
679   }
UnsignedSmall()680   static Type* UnsignedSmall() {
681     return BitsetType::New(BitsetType::UnsignedSmall());
682   }
683 
Class(i::Handle<i::Map> map,Zone * zone)684   static Type* Class(i::Handle<i::Map> map, Zone* zone) {
685     return ClassType::New(map, zone);
686   }
Constant(i::Handle<i::Object> value,Zone * zone)687   static Type* Constant(i::Handle<i::Object> value, Zone* zone) {
688     return ConstantType::New(value, zone);
689   }
Range(double min,double max,Zone * zone)690   static Type* Range(double min, double max, Zone* zone) {
691     return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged |
692                                                    BitsetType::kUntaggedNumber),
693                           zone);
694   }
Context(Type * outer,Zone * zone)695   static Type* Context(Type* outer, Zone* zone) {
696     return ContextType::New(outer, zone);
697   }
Array(Type * element,Zone * zone)698   static Type* Array(Type* element, Zone* zone) {
699     return ArrayType::New(element, zone);
700   }
Function(Type * result,Type * receiver,int arity,Zone * zone)701   static Type* Function(Type* result, Type* receiver, int arity, Zone* zone) {
702     return FunctionType::New(result, receiver, arity, zone);
703   }
Function(Type * result,Zone * zone)704   static Type* Function(Type* result, Zone* zone) {
705     return Function(result, Any(), 0, zone);
706   }
Function(Type * result,Type * param0,Zone * zone)707   static Type* Function(Type* result, Type* param0, Zone* zone) {
708     Type* function = Function(result, Any(), 1, zone);
709     function->AsFunction()->InitParameter(0, param0);
710     return function;
711   }
Function(Type * result,Type * param0,Type * param1,Zone * zone)712   static Type* Function(Type* result, Type* param0, Type* param1, Zone* zone) {
713     Type* function = Function(result, Any(), 2, zone);
714     function->AsFunction()->InitParameter(0, param0);
715     function->AsFunction()->InitParameter(1, param1);
716     return function;
717   }
Function(Type * result,Type * param0,Type * param1,Type * param2,Zone * zone)718   static Type* Function(Type* result, Type* param0, Type* param1, Type* param2,
719                         Zone* zone) {
720     Type* function = Function(result, Any(), 3, zone);
721     function->AsFunction()->InitParameter(0, param0);
722     function->AsFunction()->InitParameter(1, param1);
723     function->AsFunction()->InitParameter(2, param2);
724     return function;
725   }
Function(Type * result,int arity,Type ** params,Zone * zone)726   static Type* Function(Type* result, int arity, Type** params, Zone* zone) {
727     Type* function = Function(result, Any(), arity, zone);
728     for (int i = 0; i < arity; ++i) {
729       function->AsFunction()->InitParameter(i, params[i]);
730     }
731     return function;
732   }
Tuple(Type * first,Type * second,Type * third,Zone * zone)733   static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
734     Type* tuple = TupleType::New(3, zone);
735     tuple->AsTuple()->InitElement(0, first);
736     tuple->AsTuple()->InitElement(1, second);
737     tuple->AsTuple()->InitElement(2, third);
738     return tuple;
739   }
740 
741 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
742   static Type* Name(Isolate* isolate, Zone* zone);
743   SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
744 #undef CONSTRUCT_SIMD_TYPE
745 
746   static Type* Union(Type* type1, Type* type2, Zone* zone);
747   static Type* Intersect(Type* type1, Type* type2, Zone* zone);
748 
Of(double value,Zone * zone)749   static Type* Of(double value, Zone* zone) {
750     return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
751   }
Of(i::Object * value,Zone * zone)752   static Type* Of(i::Object* value, Zone* zone) {
753     return BitsetType::New(BitsetType::ExpandInternals(BitsetType::Lub(value)));
754   }
Of(i::Handle<i::Object> value,Zone * zone)755   static Type* Of(i::Handle<i::Object> value, Zone* zone) {
756     return Of(*value, zone);
757   }
758 
759   // Extraction of components.
760   static Type* Representation(Type* t, Zone* zone);
761   static Type* Semantic(Type* t, Zone* zone);
762 
763   // Predicates.
IsInhabited()764   bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
765 
Is(Type * that)766   bool Is(Type* that) { return this == that || this->SlowIs(that); }
767   bool Maybe(Type* that);
Equals(Type * that)768   bool Equals(Type* that) { return this->Is(that) && that->Is(this); }
769 
770   // Equivalent to Constant(val)->Is(this), but avoiding allocation.
771   bool Contains(i::Object* val);
Contains(i::Handle<i::Object> val)772   bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
773 
774   // State-dependent versions of the above that consider subtyping between
775   // a constant and its map class.
776   static Type* NowOf(i::Object* value, Zone* zone);
NowOf(i::Handle<i::Object> value,Zone * zone)777   static Type* NowOf(i::Handle<i::Object> value, Zone* zone) {
778     return NowOf(*value, zone);
779   }
780   bool NowIs(Type* that);
781   bool NowContains(i::Object* val);
NowContains(i::Handle<i::Object> val)782   bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
783 
784   bool NowStable();
785 
786   // Inspection.
IsRange()787   bool IsRange() { return IsKind(TypeBase::kRange); }
IsClass()788   bool IsClass() { return IsKind(TypeBase::kClass); }
IsConstant()789   bool IsConstant() { return IsKind(TypeBase::kConstant); }
IsContext()790   bool IsContext() { return IsKind(TypeBase::kContext); }
IsArray()791   bool IsArray() { return IsKind(TypeBase::kArray); }
IsFunction()792   bool IsFunction() { return IsKind(TypeBase::kFunction); }
IsTuple()793   bool IsTuple() { return IsKind(TypeBase::kTuple); }
794 
AsClass()795   ClassType* AsClass() { return ClassType::cast(this); }
AsConstant()796   ConstantType* AsConstant() { return ConstantType::cast(this); }
AsRange()797   RangeType* AsRange() { return RangeType::cast(this); }
AsContext()798   ContextType* AsContext() { return ContextType::cast(this); }
AsArray()799   ArrayType* AsArray() { return ArrayType::cast(this); }
AsFunction()800   FunctionType* AsFunction() { return FunctionType::cast(this); }
AsTuple()801   TupleType* AsTuple() { return TupleType::cast(this); }
802 
803   // Minimum and maximum of a numeric type.
804   // These functions do not distinguish between -0 and +0.  If the type equals
805   // kNaN, they return NaN; otherwise kNaN is ignored.  Only call these
806   // functions on subtypes of Number.
807   double Min();
808   double Max();
809 
810   // Extracts a range from the type: if the type is a range or a union
811   // containing a range, that range is returned; otherwise, NULL is returned.
812   Type* GetRange();
813 
814   static bool IsInteger(i::Object* x);
IsInteger(double x)815   static bool IsInteger(double x) {
816     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
817   }
818 
819   int NumClasses();
820   int NumConstants();
821 
822   template <class T>
823   class Iterator {
824    public:
Done()825     bool Done() const { return index_ < 0; }
826     i::Handle<T> Current();
827     void Advance();
828 
829    private:
830     friend class Type;
831 
Iterator()832     Iterator() : index_(-1) {}
Iterator(Type * type)833     explicit Iterator(Type* type) : type_(type), index_(-1) { Advance(); }
834 
835     inline bool matches(Type* type);
836     inline Type* get_type();
837 
838     Type* type_;
839     int index_;
840   };
841 
Classes()842   Iterator<i::Map> Classes() {
843     if (this->IsBitset()) return Iterator<i::Map>();
844     return Iterator<i::Map>(this);
845   }
Constants()846   Iterator<i::Object> Constants() {
847     if (this->IsBitset()) return Iterator<i::Object>();
848     return Iterator<i::Object>(this);
849   }
850 
851   // Printing.
852 
853   enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
854 
855   void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS);  // NOLINT
856 
857 #ifdef DEBUG
858   void Print();
859 #endif
860 
861   // Helpers for testing.
IsBitsetForTesting()862   bool IsBitsetForTesting() { return IsBitset(); }
IsUnionForTesting()863   bool IsUnionForTesting() { return IsUnion(); }
AsBitsetForTesting()864   bitset AsBitsetForTesting() { return AsBitset(); }
AsUnionForTesting()865   UnionType* AsUnionForTesting() { return AsUnion(); }
866 
867  private:
868   // Friends.
869   template <class>
870   friend class Iterator;
871   friend BitsetType;
872   friend UnionType;
873 
874   // Internal inspection.
IsKind(TypeBase::Kind kind)875   bool IsKind(TypeBase::Kind kind) { return TypeBase::IsKind(this, kind); }
876 
IsNone()877   bool IsNone() { return this == None(); }
IsAny()878   bool IsAny() { return this == Any(); }
IsBitset()879   bool IsBitset() { return BitsetType::IsBitset(this); }
IsUnion()880   bool IsUnion() { return IsKind(TypeBase::kUnion); }
881 
AsBitset()882   bitset AsBitset() {
883     DCHECK(this->IsBitset());
884     return reinterpret_cast<BitsetType*>(this)->Bitset();
885   }
AsUnion()886   UnionType* AsUnion() { return UnionType::cast(this); }
887 
888   bitset Representation();
889 
890   // Auxiliary functions.
891   bool SemanticMaybe(Type* that);
892 
BitsetGlb()893   bitset BitsetGlb() { return BitsetType::Glb(this); }
BitsetLub()894   bitset BitsetLub() { return BitsetType::Lub(this); }
895 
896   bool SlowIs(Type* that);
897   bool SemanticIs(Type* that);
898 
899   static bool Overlap(RangeType* lhs, RangeType* rhs);
900   static bool Contains(RangeType* lhs, RangeType* rhs);
901   static bool Contains(RangeType* range, ConstantType* constant);
902   static bool Contains(RangeType* range, i::Object* val);
903 
904   static int UpdateRange(Type* type, UnionType* result, int size, Zone* zone);
905 
906   static RangeType::Limits IntersectRangeAndBitset(Type* range, Type* bits,
907                                                    Zone* zone);
908   static RangeType::Limits ToLimits(bitset bits, Zone* zone);
909 
910   bool SimplyEquals(Type* that);
911 
912   static int AddToUnion(Type* type, UnionType* result, int size, Zone* zone);
913   static int IntersectAux(Type* type, Type* other, UnionType* result, int size,
914                           RangeType::Limits* limits, Zone* zone);
915   static Type* NormalizeUnion(Type* unioned, int size, Zone* zone);
916   static Type* NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone);
917 };
918 
919 // -----------------------------------------------------------------------------
920 // Type bounds. A simple struct to represent a pair of lower/upper types.
921 
922 struct Bounds {
923   Type* lower;
924   Type* upper;
925 
BoundsBounds926   Bounds()
927       :  // Make sure accessing uninitialized bounds crashes big-time.
928         lower(nullptr),
929         upper(nullptr) {}
BoundsBounds930   explicit Bounds(Type* t) : lower(t), upper(t) {}
BoundsBounds931   Bounds(Type* l, Type* u) : lower(l), upper(u) { DCHECK(lower->Is(upper)); }
932 
933   // Unrestricted bounds.
UnboundedBounds934   static Bounds Unbounded() { return Bounds(Type::None(), Type::Any()); }
935 
936   // Meet: both b1 and b2 are known to hold.
BothBounds937   static Bounds Both(Bounds b1, Bounds b2, Zone* zone) {
938     Type* lower = Type::Union(b1.lower, b2.lower, zone);
939     Type* upper = Type::Intersect(b1.upper, b2.upper, zone);
940     // Lower bounds are considered approximate, correct as necessary.
941     if (!lower->Is(upper)) lower = upper;
942     return Bounds(lower, upper);
943   }
944 
945   // Join: either b1 or b2 is known to hold.
EitherBounds946   static Bounds Either(Bounds b1, Bounds b2, Zone* zone) {
947     Type* lower = Type::Intersect(b1.lower, b2.lower, zone);
948     Type* upper = Type::Union(b1.upper, b2.upper, zone);
949     return Bounds(lower, upper);
950   }
951 
NarrowLowerBounds952   static Bounds NarrowLower(Bounds b, Type* t, Zone* zone) {
953     Type* lower = Type::Union(b.lower, t, zone);
954     // Lower bounds are considered approximate, correct as necessary.
955     if (!lower->Is(b.upper)) lower = b.upper;
956     return Bounds(lower, b.upper);
957   }
NarrowUpperBounds958   static Bounds NarrowUpper(Bounds b, Type* t, Zone* zone) {
959     Type* lower = b.lower;
960     Type* upper = Type::Intersect(b.upper, t, zone);
961     // Lower bounds are considered approximate, correct as necessary.
962     if (!lower->Is(upper)) lower = upper;
963     return Bounds(lower, upper);
964   }
965 
NarrowsBounds966   bool Narrows(Bounds that) {
967     return that.lower->Is(this->lower) && this->upper->Is(that.upper);
968   }
969 };
970 
971 }  // namespace internal
972 }  // namespace v8
973 
974 #endif  // V8_TYPES_H_
975