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_AST_AST_TYPES_H_
6 #define V8_AST_AST_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 // Values for bitset types
149 
150 // clang-format off
151 
152 #define AST_MASK_BITSET_TYPE_LIST(V) \
153   V(Representation, 0xffc00000u) \
154   V(Semantic,       0x003ffffeu)
155 
156 #define AST_REPRESENTATION(k) ((k) & AstBitsetType::kRepresentation)
157 #define AST_SEMANTIC(k)       ((k) & AstBitsetType::kSemantic)
158 
159 #define AST_REPRESENTATION_BITSET_TYPE_LIST(V)    \
160   V(None,               0)                    \
161   V(UntaggedBit,        1u << 22 | kSemantic) \
162   V(UntaggedIntegral8,  1u << 23 | kSemantic) \
163   V(UntaggedIntegral16, 1u << 24 | kSemantic) \
164   V(UntaggedIntegral32, 1u << 25 | kSemantic) \
165   V(UntaggedFloat32,    1u << 26 | kSemantic) \
166   V(UntaggedFloat64,    1u << 27 | kSemantic) \
167   V(UntaggedSimd128,    1u << 28 | kSemantic) \
168   V(UntaggedPointer,    1u << 29 | kSemantic) \
169   V(TaggedSigned,       1u << 30 | kSemantic) \
170   V(TaggedPointer,      1u << 31 | kSemantic) \
171   \
172   V(UntaggedIntegral,   kUntaggedBit | kUntaggedIntegral8 |        \
173                         kUntaggedIntegral16 | kUntaggedIntegral32) \
174   V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)       \
175   V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)        \
176   V(Untagged,           kUntaggedNumber | kUntaggedPointer)        \
177   V(Tagged,             kTaggedSigned | kTaggedPointer)
178 
179 #define AST_INTERNAL_BITSET_TYPE_LIST(V)                                      \
180   V(OtherUnsigned31, 1u << 1 | AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
181   V(OtherUnsigned32, 1u << 2 | AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
182   V(OtherSigned32,   1u << 3 | AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
183   V(OtherNumber,     1u << 4 | AST_REPRESENTATION(kTagged | kUntaggedNumber))
184 
185 #define AST_SEMANTIC_BITSET_TYPE_LIST(V)                                \
186   V(Negative31,          1u << 5  |                                     \
187                          AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
188   V(Null,                1u << 6  | AST_REPRESENTATION(kTaggedPointer)) \
189   V(Undefined,           1u << 7  | AST_REPRESENTATION(kTaggedPointer)) \
190   V(Boolean,             1u << 8  | AST_REPRESENTATION(kTaggedPointer)) \
191   V(Unsigned30,          1u << 9  |                                     \
192                          AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
193   V(MinusZero,           1u << 10 |                                     \
194                          AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
195   V(NaN,                 1u << 11 |                                     \
196                          AST_REPRESENTATION(kTagged | kUntaggedNumber)) \
197   V(Symbol,              1u << 12 | AST_REPRESENTATION(kTaggedPointer)) \
198   V(InternalizedString,  1u << 13 | AST_REPRESENTATION(kTaggedPointer)) \
199   V(OtherString,         1u << 14 | AST_REPRESENTATION(kTaggedPointer)) \
200   V(Simd,                1u << 15 | AST_REPRESENTATION(kTaggedPointer)) \
201   V(OtherObject,         1u << 17 | AST_REPRESENTATION(kTaggedPointer)) \
202   V(OtherUndetectable,   1u << 16 | AST_REPRESENTATION(kTaggedPointer)) \
203   V(Proxy,               1u << 18 | AST_REPRESENTATION(kTaggedPointer)) \
204   V(Function,            1u << 19 | AST_REPRESENTATION(kTaggedPointer)) \
205   V(Hole,                1u << 20 | AST_REPRESENTATION(kTaggedPointer)) \
206   V(OtherInternal,       1u << 21 |                                     \
207                          AST_REPRESENTATION(kTagged | kUntagged))       \
208   \
209   V(Signed31,                   kUnsigned30 | kNegative31) \
210   V(Signed32,                   kSigned31 | kOtherUnsigned31 |          \
211                                 kOtherSigned32)                         \
212   V(Signed32OrMinusZero,        kSigned32 | kMinusZero) \
213   V(Signed32OrMinusZeroOrNaN,   kSigned32 | kMinusZero | kNaN) \
214   V(Negative32,                 kNegative31 | kOtherSigned32) \
215   V(Unsigned31,                 kUnsigned30 | kOtherUnsigned31) \
216   V(Unsigned32,                 kUnsigned30 | kOtherUnsigned31 | \
217                                 kOtherUnsigned32) \
218   V(Unsigned32OrMinusZero,      kUnsigned32 | kMinusZero) \
219   V(Unsigned32OrMinusZeroOrNaN, kUnsigned32 | kMinusZero | kNaN) \
220   V(Integral32,                 kSigned32 | kUnsigned32) \
221   V(PlainNumber,                kIntegral32 | kOtherNumber) \
222   V(OrderedNumber,              kPlainNumber | kMinusZero) \
223   V(MinusZeroOrNaN,             kMinusZero | kNaN) \
224   V(Number,                     kOrderedNumber | kNaN) \
225   V(String,                     kInternalizedString | kOtherString) \
226   V(UniqueName,                 kSymbol | kInternalizedString) \
227   V(Name,                       kSymbol | kString) \
228   V(BooleanOrNumber,            kBoolean | kNumber) \
229   V(BooleanOrNullOrNumber,      kBooleanOrNumber | kNull) \
230   V(BooleanOrNullOrUndefined,   kBoolean | kNull | kUndefined) \
231   V(NullOrNumber,               kNull | kNumber) \
232   V(NullOrUndefined,            kNull | kUndefined) \
233   V(Undetectable,               kNullOrUndefined | kOtherUndetectable) \
234   V(NumberOrOddball,            kNumber | kNullOrUndefined | kBoolean | kHole) \
235   V(NumberOrSimdOrString,       kNumber | kSimd | kString) \
236   V(NumberOrString,             kNumber | kString) \
237   V(NumberOrUndefined,          kNumber | kUndefined) \
238   V(PlainPrimitive,             kNumberOrString | kBoolean | kNullOrUndefined) \
239   V(Primitive,                  kSymbol | kSimd | kPlainPrimitive) \
240   V(DetectableReceiver,         kFunction | kOtherObject | kProxy) \
241   V(Object,                     kFunction | kOtherObject | kOtherUndetectable) \
242   V(Receiver,                   kObject | kProxy) \
243   V(StringOrReceiver,           kString | kReceiver) \
244   V(Unique,                     kBoolean | kUniqueName | kNull | kUndefined | \
245                                 kReceiver) \
246   V(Internal,                   kHole | kOtherInternal) \
247   V(NonInternal,                kPrimitive | kReceiver) \
248   V(NonNumber,                  kUnique | kString | kInternal) \
249   V(Any,                        0xfffffffeu)
250 
251 // clang-format on
252 
253 /*
254  * The following diagrams show how integers (in the mathematical sense) are
255  * divided among the different atomic numerical types.
256  *
257  *   ON    OS32     N31     U30     OU31    OU32     ON
258  * ______[_______[_______[_______[_______[_______[_______
259  *     -2^31   -2^30     0      2^30    2^31    2^32
260  *
261  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
262  *
263  * Some of the atomic numerical bitsets are internal only (see
264  * INTERNAL_BITSET_TYPE_LIST).  To a types user, they should only occur in
265  * union with certain other bitsets.  For instance, OtherNumber should only
266  * occur as part of PlainNumber.
267  */
268 
269 #define AST_PROPER_BITSET_TYPE_LIST(V)   \
270   AST_REPRESENTATION_BITSET_TYPE_LIST(V) \
271   AST_SEMANTIC_BITSET_TYPE_LIST(V)
272 
273 #define AST_BITSET_TYPE_LIST(V)          \
274   AST_MASK_BITSET_TYPE_LIST(V)           \
275   AST_REPRESENTATION_BITSET_TYPE_LIST(V) \
276   AST_INTERNAL_BITSET_TYPE_LIST(V)       \
277   AST_SEMANTIC_BITSET_TYPE_LIST(V)
278 
279 class AstType;
280 
281 // -----------------------------------------------------------------------------
282 // Bitset types (internal).
283 
284 class AstBitsetType {
285  public:
286   typedef uint32_t bitset;  // Internal
287 
288   enum : uint32_t {
289 #define DECLARE_TYPE(type, value) k##type = (value),
290     AST_BITSET_TYPE_LIST(DECLARE_TYPE)
291 #undef DECLARE_TYPE
292         kUnusedEOL = 0
293   };
294 
295   static bitset SignedSmall();
296   static bitset UnsignedSmall();
297 
Bitset()298   bitset Bitset() {
299     return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
300   }
301 
IsInhabited(bitset bits)302   static bool IsInhabited(bitset bits) {
303     return AST_SEMANTIC(bits) != kNone && AST_REPRESENTATION(bits) != kNone;
304   }
305 
SemanticIsInhabited(bitset bits)306   static bool SemanticIsInhabited(bitset bits) {
307     return AST_SEMANTIC(bits) != kNone;
308   }
309 
Is(bitset bits1,bitset bits2)310   static bool Is(bitset bits1, bitset bits2) {
311     return (bits1 | bits2) == bits2;
312   }
313 
314   static double Min(bitset);
315   static double Max(bitset);
316 
317   static bitset Glb(AstType* type);  // greatest lower bound that's a bitset
318   static bitset Glb(double min, double max);
319   static bitset Lub(AstType* type);  // least upper bound that's a bitset
320   static bitset Lub(i::Map* map);
321   static bitset Lub(i::Object* value);
322   static bitset Lub(double value);
323   static bitset Lub(double min, double max);
324   static bitset ExpandInternals(bitset bits);
325 
326   static const char* Name(bitset);
327   static void Print(std::ostream& os, bitset);  // NOLINT
328 #ifdef DEBUG
329   static void Print(bitset);
330 #endif
331 
332   static bitset NumberBits(bitset bits);
333 
IsBitset(AstType * type)334   static bool IsBitset(AstType* type) {
335     return reinterpret_cast<uintptr_t>(type) & 1;
336   }
337 
NewForTesting(bitset bits)338   static AstType* NewForTesting(bitset bits) { return New(bits); }
339 
340  private:
341   friend class AstType;
342 
New(bitset bits)343   static AstType* New(bitset bits) {
344     return reinterpret_cast<AstType*>(static_cast<uintptr_t>(bits | 1u));
345   }
346 
347   struct Boundary {
348     bitset internal;
349     bitset external;
350     double min;
351   };
352   static const Boundary BoundariesArray[];
353   static inline const Boundary* Boundaries();
354   static inline size_t BoundariesSize();
355 };
356 
357 // -----------------------------------------------------------------------------
358 // Superclass for non-bitset types (internal).
359 class AstTypeBase {
360  protected:
361   friend class AstType;
362 
363   enum Kind {
364     kClass,
365     kConstant,
366     kContext,
367     kArray,
368     kFunction,
369     kTuple,
370     kUnion,
371     kRange
372   };
373 
kind()374   Kind kind() const { return kind_; }
AstTypeBase(Kind kind)375   explicit AstTypeBase(Kind kind) : kind_(kind) {}
376 
IsKind(AstType * type,Kind kind)377   static bool IsKind(AstType* type, Kind kind) {
378     if (AstBitsetType::IsBitset(type)) return false;
379     AstTypeBase* base = reinterpret_cast<AstTypeBase*>(type);
380     return base->kind() == kind;
381   }
382 
383   // The hacky conversion to/from AstType*.
AsType(AstTypeBase * type)384   static AstType* AsType(AstTypeBase* type) {
385     return reinterpret_cast<AstType*>(type);
386   }
FromType(AstType * type)387   static AstTypeBase* FromType(AstType* type) {
388     return reinterpret_cast<AstTypeBase*>(type);
389   }
390 
391  private:
392   Kind kind_;
393 };
394 
395 // -----------------------------------------------------------------------------
396 // Class types.
397 
398 class AstClassType : public AstTypeBase {
399  public:
Map()400   i::Handle<i::Map> Map() { return map_; }
401 
402  private:
403   friend class AstType;
404   friend class AstBitsetType;
405 
New(i::Handle<i::Map> map,Zone * zone)406   static AstType* New(i::Handle<i::Map> map, Zone* zone) {
407     return AsType(new (zone->New(sizeof(AstClassType)))
408                       AstClassType(AstBitsetType::Lub(*map), map));
409   }
410 
cast(AstType * type)411   static AstClassType* cast(AstType* type) {
412     DCHECK(IsKind(type, kClass));
413     return static_cast<AstClassType*>(FromType(type));
414   }
415 
AstClassType(AstBitsetType::bitset bitset,i::Handle<i::Map> map)416   AstClassType(AstBitsetType::bitset bitset, i::Handle<i::Map> map)
417       : AstTypeBase(kClass), bitset_(bitset), map_(map) {}
418 
Lub()419   AstBitsetType::bitset Lub() { return bitset_; }
420 
421   AstBitsetType::bitset bitset_;
422   Handle<i::Map> map_;
423 };
424 
425 // -----------------------------------------------------------------------------
426 // Constant types.
427 
428 class AstConstantType : public AstTypeBase {
429  public:
Value()430   i::Handle<i::Object> Value() { return object_; }
431 
432  private:
433   friend class AstType;
434   friend class AstBitsetType;
435 
New(i::Handle<i::Object> value,Zone * zone)436   static AstType* New(i::Handle<i::Object> value, Zone* zone) {
437     AstBitsetType::bitset bitset = AstBitsetType::Lub(*value);
438     return AsType(new (zone->New(sizeof(AstConstantType)))
439                       AstConstantType(bitset, value));
440   }
441 
cast(AstType * type)442   static AstConstantType* cast(AstType* type) {
443     DCHECK(IsKind(type, kConstant));
444     return static_cast<AstConstantType*>(FromType(type));
445   }
446 
AstConstantType(AstBitsetType::bitset bitset,i::Handle<i::Object> object)447   AstConstantType(AstBitsetType::bitset bitset, i::Handle<i::Object> object)
448       : AstTypeBase(kConstant), bitset_(bitset), object_(object) {}
449 
Lub()450   AstBitsetType::bitset Lub() { return bitset_; }
451 
452   AstBitsetType::bitset bitset_;
453   Handle<i::Object> object_;
454 };
455 // TODO(neis): Also cache value if numerical.
456 // TODO(neis): Allow restricting the representation.
457 
458 // -----------------------------------------------------------------------------
459 // Range types.
460 
461 class AstRangeType : public AstTypeBase {
462  public:
463   struct Limits {
464     double min;
465     double max;
LimitsLimits466     Limits(double min, double max) : min(min), max(max) {}
LimitsLimits467     explicit Limits(AstRangeType* range)
468         : min(range->Min()), max(range->Max()) {}
469     bool IsEmpty();
EmptyLimits470     static Limits Empty() { return Limits(1, 0); }
471     static Limits Intersect(Limits lhs, Limits rhs);
472     static Limits Union(Limits lhs, Limits rhs);
473   };
474 
Min()475   double Min() { return limits_.min; }
Max()476   double Max() { return limits_.max; }
477 
478  private:
479   friend class AstType;
480   friend class AstBitsetType;
481   friend class AstUnionType;
482 
New(double min,double max,AstBitsetType::bitset representation,Zone * zone)483   static AstType* New(double min, double max,
484                       AstBitsetType::bitset representation, Zone* zone) {
485     return New(Limits(min, max), representation, zone);
486   }
487 
IsInteger(double x)488   static bool IsInteger(double x) {
489     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
490   }
491 
New(Limits lim,AstBitsetType::bitset representation,Zone * zone)492   static AstType* New(Limits lim, AstBitsetType::bitset representation,
493                       Zone* zone) {
494     DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
495     DCHECK(lim.min <= lim.max);
496     DCHECK(AST_REPRESENTATION(representation) == representation);
497     AstBitsetType::bitset bits =
498         AST_SEMANTIC(AstBitsetType::Lub(lim.min, lim.max)) | representation;
499 
500     return AsType(new (zone->New(sizeof(AstRangeType)))
501                       AstRangeType(bits, lim));
502   }
503 
cast(AstType * type)504   static AstRangeType* cast(AstType* type) {
505     DCHECK(IsKind(type, kRange));
506     return static_cast<AstRangeType*>(FromType(type));
507   }
508 
AstRangeType(AstBitsetType::bitset bitset,Limits limits)509   AstRangeType(AstBitsetType::bitset bitset, Limits limits)
510       : AstTypeBase(kRange), bitset_(bitset), limits_(limits) {}
511 
Lub()512   AstBitsetType::bitset Lub() { return bitset_; }
513 
514   AstBitsetType::bitset bitset_;
515   Limits limits_;
516 };
517 
518 // -----------------------------------------------------------------------------
519 // Context types.
520 
521 class AstContextType : public AstTypeBase {
522  public:
Outer()523   AstType* Outer() { return outer_; }
524 
525  private:
526   friend class AstType;
527 
New(AstType * outer,Zone * zone)528   static AstType* New(AstType* outer, Zone* zone) {
529     return AsType(new (zone->New(sizeof(AstContextType)))
530                       AstContextType(outer));  // NOLINT
531   }
532 
cast(AstType * type)533   static AstContextType* cast(AstType* type) {
534     DCHECK(IsKind(type, kContext));
535     return static_cast<AstContextType*>(FromType(type));
536   }
537 
AstContextType(AstType * outer)538   explicit AstContextType(AstType* outer)
539       : AstTypeBase(kContext), outer_(outer) {}
540 
541   AstType* outer_;
542 };
543 
544 // -----------------------------------------------------------------------------
545 // Array types.
546 
547 class AstArrayType : public AstTypeBase {
548  public:
Element()549   AstType* Element() { return element_; }
550 
551  private:
552   friend class AstType;
553 
AstArrayType(AstType * element)554   explicit AstArrayType(AstType* element)
555       : AstTypeBase(kArray), element_(element) {}
556 
New(AstType * element,Zone * zone)557   static AstType* New(AstType* element, Zone* zone) {
558     return AsType(new (zone->New(sizeof(AstArrayType))) AstArrayType(element));
559   }
560 
cast(AstType * type)561   static AstArrayType* cast(AstType* type) {
562     DCHECK(IsKind(type, kArray));
563     return static_cast<AstArrayType*>(FromType(type));
564   }
565 
566   AstType* element_;
567 };
568 
569 // -----------------------------------------------------------------------------
570 // Superclass for types with variable number of type fields.
571 class AstStructuralType : public AstTypeBase {
572  public:
LengthForTesting()573   int LengthForTesting() { return Length(); }
574 
575  protected:
576   friend class AstType;
577 
Length()578   int Length() { return length_; }
579 
Get(int i)580   AstType* Get(int i) {
581     DCHECK(0 <= i && i < this->Length());
582     return elements_[i];
583   }
584 
Set(int i,AstType * type)585   void Set(int i, AstType* type) {
586     DCHECK(0 <= i && i < this->Length());
587     elements_[i] = type;
588   }
589 
Shrink(int length)590   void Shrink(int length) {
591     DCHECK(2 <= length && length <= this->Length());
592     length_ = length;
593   }
594 
AstStructuralType(Kind kind,int length,i::Zone * zone)595   AstStructuralType(Kind kind, int length, i::Zone* zone)
596       : AstTypeBase(kind), length_(length) {
597     elements_ =
598         reinterpret_cast<AstType**>(zone->New(sizeof(AstType*) * length));
599   }
600 
601  private:
602   int length_;
603   AstType** elements_;
604 };
605 
606 // -----------------------------------------------------------------------------
607 // Function types.
608 
609 class AstFunctionType : public AstStructuralType {
610  public:
Arity()611   int Arity() { return this->Length() - 2; }
Result()612   AstType* Result() { return this->Get(0); }
Receiver()613   AstType* Receiver() { return this->Get(1); }
Parameter(int i)614   AstType* Parameter(int i) { return this->Get(2 + i); }
615 
InitParameter(int i,AstType * type)616   void InitParameter(int i, AstType* type) { this->Set(2 + i, type); }
617 
618  private:
619   friend class AstType;
620 
AstFunctionType(AstType * result,AstType * receiver,int arity,Zone * zone)621   AstFunctionType(AstType* result, AstType* receiver, int arity, Zone* zone)
622       : AstStructuralType(kFunction, 2 + arity, zone) {
623     Set(0, result);
624     Set(1, receiver);
625   }
626 
New(AstType * result,AstType * receiver,int arity,Zone * zone)627   static AstType* New(AstType* result, AstType* receiver, int arity,
628                       Zone* zone) {
629     return AsType(new (zone->New(sizeof(AstFunctionType)))
630                       AstFunctionType(result, receiver, arity, zone));
631   }
632 
cast(AstType * type)633   static AstFunctionType* cast(AstType* type) {
634     DCHECK(IsKind(type, kFunction));
635     return static_cast<AstFunctionType*>(FromType(type));
636   }
637 };
638 
639 // -----------------------------------------------------------------------------
640 // Tuple types.
641 
642 class AstTupleType : public AstStructuralType {
643  public:
Arity()644   int Arity() { return this->Length(); }
Element(int i)645   AstType* Element(int i) { return this->Get(i); }
646 
InitElement(int i,AstType * type)647   void InitElement(int i, AstType* type) { this->Set(i, type); }
648 
649  private:
650   friend class AstType;
651 
AstTupleType(int length,Zone * zone)652   AstTupleType(int length, Zone* zone)
653       : AstStructuralType(kTuple, length, zone) {}
654 
New(int length,Zone * zone)655   static AstType* New(int length, Zone* zone) {
656     return AsType(new (zone->New(sizeof(AstTupleType)))
657                       AstTupleType(length, zone));
658   }
659 
cast(AstType * type)660   static AstTupleType* cast(AstType* type) {
661     DCHECK(IsKind(type, kTuple));
662     return static_cast<AstTupleType*>(FromType(type));
663   }
664 };
665 
666 // -----------------------------------------------------------------------------
667 // Union types (internal).
668 // A union is a structured type with the following invariants:
669 // - its length is at least 2
670 // - at most one field is a bitset, and it must go into index 0
671 // - no field is a union
672 // - no field is a subtype of any other field
673 class AstUnionType : public AstStructuralType {
674  private:
675   friend AstType;
676   friend AstBitsetType;
677 
AstUnionType(int length,Zone * zone)678   AstUnionType(int length, Zone* zone)
679       : AstStructuralType(kUnion, length, zone) {}
680 
New(int length,Zone * zone)681   static AstType* New(int length, Zone* zone) {
682     return AsType(new (zone->New(sizeof(AstUnionType)))
683                       AstUnionType(length, zone));
684   }
685 
cast(AstType * type)686   static AstUnionType* cast(AstType* type) {
687     DCHECK(IsKind(type, kUnion));
688     return static_cast<AstUnionType*>(FromType(type));
689   }
690 
691   bool Wellformed();
692 };
693 
694 class AstType {
695  public:
696   typedef AstBitsetType::bitset bitset;  // Internal
697 
698 // Constructors.
699 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
700   static AstType* type() { return AstBitsetType::New(AstBitsetType::k##type); }
AST_PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)701   AST_PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
702 #undef DEFINE_TYPE_CONSTRUCTOR
703 
704   static AstType* SignedSmall() {
705     return AstBitsetType::New(AstBitsetType::SignedSmall());
706   }
UnsignedSmall()707   static AstType* UnsignedSmall() {
708     return AstBitsetType::New(AstBitsetType::UnsignedSmall());
709   }
710 
Class(i::Handle<i::Map> map,Zone * zone)711   static AstType* Class(i::Handle<i::Map> map, Zone* zone) {
712     return AstClassType::New(map, zone);
713   }
Constant(i::Handle<i::Object> value,Zone * zone)714   static AstType* Constant(i::Handle<i::Object> value, Zone* zone) {
715     return AstConstantType::New(value, zone);
716   }
Range(double min,double max,Zone * zone)717   static AstType* Range(double min, double max, Zone* zone) {
718     return AstRangeType::New(min, max,
719                              AST_REPRESENTATION(AstBitsetType::kTagged |
720                                                 AstBitsetType::kUntaggedNumber),
721                              zone);
722   }
Context(AstType * outer,Zone * zone)723   static AstType* Context(AstType* outer, Zone* zone) {
724     return AstContextType::New(outer, zone);
725   }
Array(AstType * element,Zone * zone)726   static AstType* Array(AstType* element, Zone* zone) {
727     return AstArrayType::New(element, zone);
728   }
Function(AstType * result,AstType * receiver,int arity,Zone * zone)729   static AstType* Function(AstType* result, AstType* receiver, int arity,
730                            Zone* zone) {
731     return AstFunctionType::New(result, receiver, arity, zone);
732   }
Function(AstType * result,Zone * zone)733   static AstType* Function(AstType* result, Zone* zone) {
734     return Function(result, Any(), 0, zone);
735   }
Function(AstType * result,AstType * param0,Zone * zone)736   static AstType* Function(AstType* result, AstType* param0, Zone* zone) {
737     AstType* function = Function(result, Any(), 1, zone);
738     function->AsFunction()->InitParameter(0, param0);
739     return function;
740   }
Function(AstType * result,AstType * param0,AstType * param1,Zone * zone)741   static AstType* Function(AstType* result, AstType* param0, AstType* param1,
742                            Zone* zone) {
743     AstType* function = Function(result, Any(), 2, zone);
744     function->AsFunction()->InitParameter(0, param0);
745     function->AsFunction()->InitParameter(1, param1);
746     return function;
747   }
Function(AstType * result,AstType * param0,AstType * param1,AstType * param2,Zone * zone)748   static AstType* Function(AstType* result, AstType* param0, AstType* param1,
749                            AstType* param2, Zone* zone) {
750     AstType* function = Function(result, Any(), 3, zone);
751     function->AsFunction()->InitParameter(0, param0);
752     function->AsFunction()->InitParameter(1, param1);
753     function->AsFunction()->InitParameter(2, param2);
754     return function;
755   }
Function(AstType * result,int arity,AstType ** params,Zone * zone)756   static AstType* Function(AstType* result, int arity, AstType** params,
757                            Zone* zone) {
758     AstType* function = Function(result, Any(), arity, zone);
759     for (int i = 0; i < arity; ++i) {
760       function->AsFunction()->InitParameter(i, params[i]);
761     }
762     return function;
763   }
Tuple(AstType * first,AstType * second,AstType * third,Zone * zone)764   static AstType* Tuple(AstType* first, AstType* second, AstType* third,
765                         Zone* zone) {
766     AstType* tuple = AstTupleType::New(3, zone);
767     tuple->AsTuple()->InitElement(0, first);
768     tuple->AsTuple()->InitElement(1, second);
769     tuple->AsTuple()->InitElement(2, third);
770     return tuple;
771   }
772 
773 #define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
774   static AstType* Name(Isolate* isolate, Zone* zone);
775   SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
776 #undef CONSTRUCT_SIMD_TYPE
777 
778   static AstType* Union(AstType* type1, AstType* type2, Zone* zone);
779   static AstType* Intersect(AstType* type1, AstType* type2, Zone* zone);
780 
Of(double value,Zone * zone)781   static AstType* Of(double value, Zone* zone) {
782     return AstBitsetType::New(
783         AstBitsetType::ExpandInternals(AstBitsetType::Lub(value)));
784   }
Of(i::Object * value,Zone * zone)785   static AstType* Of(i::Object* value, Zone* zone) {
786     return AstBitsetType::New(
787         AstBitsetType::ExpandInternals(AstBitsetType::Lub(value)));
788   }
Of(i::Handle<i::Object> value,Zone * zone)789   static AstType* Of(i::Handle<i::Object> value, Zone* zone) {
790     return Of(*value, zone);
791   }
792 
For(i::Map * map)793   static AstType* For(i::Map* map) {
794     return AstBitsetType::New(
795         AstBitsetType::ExpandInternals(AstBitsetType::Lub(map)));
796   }
For(i::Handle<i::Map> map)797   static AstType* For(i::Handle<i::Map> map) { return For(*map); }
798 
799   // Extraction of components.
800   static AstType* Representation(AstType* t, Zone* zone);
801   static AstType* Semantic(AstType* t, Zone* zone);
802 
803   // Predicates.
IsInhabited()804   bool IsInhabited() { return AstBitsetType::IsInhabited(this->BitsetLub()); }
805 
Is(AstType * that)806   bool Is(AstType* that) { return this == that || this->SlowIs(that); }
807   bool Maybe(AstType* that);
Equals(AstType * that)808   bool Equals(AstType* that) { return this->Is(that) && that->Is(this); }
809 
810   // Equivalent to Constant(val)->Is(this), but avoiding allocation.
811   bool Contains(i::Object* val);
Contains(i::Handle<i::Object> val)812   bool Contains(i::Handle<i::Object> val) { return this->Contains(*val); }
813 
814   // State-dependent versions of the above that consider subtyping between
815   // a constant and its map class.
816   static AstType* NowOf(i::Object* value, Zone* zone);
NowOf(i::Handle<i::Object> value,Zone * zone)817   static AstType* NowOf(i::Handle<i::Object> value, Zone* zone) {
818     return NowOf(*value, zone);
819   }
820   bool NowIs(AstType* that);
821   bool NowContains(i::Object* val);
NowContains(i::Handle<i::Object> val)822   bool NowContains(i::Handle<i::Object> val) { return this->NowContains(*val); }
823 
824   bool NowStable();
825 
826   // Inspection.
IsRange()827   bool IsRange() { return IsKind(AstTypeBase::kRange); }
IsClass()828   bool IsClass() { return IsKind(AstTypeBase::kClass); }
IsConstant()829   bool IsConstant() { return IsKind(AstTypeBase::kConstant); }
IsContext()830   bool IsContext() { return IsKind(AstTypeBase::kContext); }
IsArray()831   bool IsArray() { return IsKind(AstTypeBase::kArray); }
IsFunction()832   bool IsFunction() { return IsKind(AstTypeBase::kFunction); }
IsTuple()833   bool IsTuple() { return IsKind(AstTypeBase::kTuple); }
834 
AsClass()835   AstClassType* AsClass() { return AstClassType::cast(this); }
AsConstant()836   AstConstantType* AsConstant() { return AstConstantType::cast(this); }
AsRange()837   AstRangeType* AsRange() { return AstRangeType::cast(this); }
AsContext()838   AstContextType* AsContext() { return AstContextType::cast(this); }
AsArray()839   AstArrayType* AsArray() { return AstArrayType::cast(this); }
AsFunction()840   AstFunctionType* AsFunction() { return AstFunctionType::cast(this); }
AsTuple()841   AstTupleType* AsTuple() { return AstTupleType::cast(this); }
842 
843   // Minimum and maximum of a numeric type.
844   // These functions do not distinguish between -0 and +0.  If the type equals
845   // kNaN, they return NaN; otherwise kNaN is ignored.  Only call these
846   // functions on subtypes of Number.
847   double Min();
848   double Max();
849 
850   // Extracts a range from the type: if the type is a range or a union
851   // containing a range, that range is returned; otherwise, NULL is returned.
852   AstType* GetRange();
853 
854   static bool IsInteger(i::Object* x);
IsInteger(double x)855   static bool IsInteger(double x) {
856     return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
857   }
858 
859   int NumClasses();
860   int NumConstants();
861 
862   template <class T>
863   class Iterator {
864    public:
Done()865     bool Done() const { return index_ < 0; }
866     i::Handle<T> Current();
867     void Advance();
868 
869    private:
870     friend class AstType;
871 
Iterator()872     Iterator() : index_(-1) {}
Iterator(AstType * type)873     explicit Iterator(AstType* type) : type_(type), index_(-1) { Advance(); }
874 
875     inline bool matches(AstType* type);
876     inline AstType* get_type();
877 
878     AstType* type_;
879     int index_;
880   };
881 
Classes()882   Iterator<i::Map> Classes() {
883     if (this->IsBitset()) return Iterator<i::Map>();
884     return Iterator<i::Map>(this);
885   }
Constants()886   Iterator<i::Object> Constants() {
887     if (this->IsBitset()) return Iterator<i::Object>();
888     return Iterator<i::Object>(this);
889   }
890 
891   // Printing.
892 
893   enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
894 
895   void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS);  // NOLINT
896 
897 #ifdef DEBUG
898   void Print();
899 #endif
900 
901   // Helpers for testing.
IsBitsetForTesting()902   bool IsBitsetForTesting() { return IsBitset(); }
IsUnionForTesting()903   bool IsUnionForTesting() { return IsUnion(); }
AsBitsetForTesting()904   bitset AsBitsetForTesting() { return AsBitset(); }
AsUnionForTesting()905   AstUnionType* AsUnionForTesting() { return AsUnion(); }
906 
907  private:
908   // Friends.
909   template <class>
910   friend class Iterator;
911   friend AstBitsetType;
912   friend AstUnionType;
913 
914   // Internal inspection.
IsKind(AstTypeBase::Kind kind)915   bool IsKind(AstTypeBase::Kind kind) {
916     return AstTypeBase::IsKind(this, kind);
917   }
918 
IsNone()919   bool IsNone() { return this == None(); }
IsAny()920   bool IsAny() { return this == Any(); }
IsBitset()921   bool IsBitset() { return AstBitsetType::IsBitset(this); }
IsUnion()922   bool IsUnion() { return IsKind(AstTypeBase::kUnion); }
923 
AsBitset()924   bitset AsBitset() {
925     DCHECK(this->IsBitset());
926     return reinterpret_cast<AstBitsetType*>(this)->Bitset();
927   }
AsUnion()928   AstUnionType* AsUnion() { return AstUnionType::cast(this); }
929 
930   bitset Representation();
931 
932   // Auxiliary functions.
933   bool SemanticMaybe(AstType* that);
934 
BitsetGlb()935   bitset BitsetGlb() { return AstBitsetType::Glb(this); }
BitsetLub()936   bitset BitsetLub() { return AstBitsetType::Lub(this); }
937 
938   bool SlowIs(AstType* that);
939   bool SemanticIs(AstType* that);
940 
941   static bool Overlap(AstRangeType* lhs, AstRangeType* rhs);
942   static bool Contains(AstRangeType* lhs, AstRangeType* rhs);
943   static bool Contains(AstRangeType* range, AstConstantType* constant);
944   static bool Contains(AstRangeType* range, i::Object* val);
945 
946   static int UpdateRange(AstType* type, AstUnionType* result, int size,
947                          Zone* zone);
948 
949   static AstRangeType::Limits IntersectRangeAndBitset(AstType* range,
950                                                       AstType* bits,
951                                                       Zone* zone);
952   static AstRangeType::Limits ToLimits(bitset bits, Zone* zone);
953 
954   bool SimplyEquals(AstType* that);
955 
956   static int AddToUnion(AstType* type, AstUnionType* result, int size,
957                         Zone* zone);
958   static int IntersectAux(AstType* type, AstType* other, AstUnionType* result,
959                           int size, AstRangeType::Limits* limits, Zone* zone);
960   static AstType* NormalizeUnion(AstType* unioned, int size, Zone* zone);
961   static AstType* NormalizeRangeAndBitset(AstType* range, bitset* bits,
962                                           Zone* zone);
963 };
964 
965 // -----------------------------------------------------------------------------
966 // Type bounds. A simple struct to represent a pair of lower/upper types.
967 
968 struct AstBounds {
969   AstType* lower;
970   AstType* upper;
971 
AstBoundsAstBounds972   AstBounds()
973       :  // Make sure accessing uninitialized bounds crashes big-time.
974         lower(nullptr),
975         upper(nullptr) {}
AstBoundsAstBounds976   explicit AstBounds(AstType* t) : lower(t), upper(t) {}
AstBoundsAstBounds977   AstBounds(AstType* l, AstType* u) : lower(l), upper(u) {
978     DCHECK(lower->Is(upper));
979   }
980 
981   // Unrestricted bounds.
UnboundedAstBounds982   static AstBounds Unbounded() {
983     return AstBounds(AstType::None(), AstType::Any());
984   }
985 
986   // Meet: both b1 and b2 are known to hold.
BothAstBounds987   static AstBounds Both(AstBounds b1, AstBounds b2, Zone* zone) {
988     AstType* lower = AstType::Union(b1.lower, b2.lower, zone);
989     AstType* upper = AstType::Intersect(b1.upper, b2.upper, zone);
990     // Lower bounds are considered approximate, correct as necessary.
991     if (!lower->Is(upper)) lower = upper;
992     return AstBounds(lower, upper);
993   }
994 
995   // Join: either b1 or b2 is known to hold.
EitherAstBounds996   static AstBounds Either(AstBounds b1, AstBounds b2, Zone* zone) {
997     AstType* lower = AstType::Intersect(b1.lower, b2.lower, zone);
998     AstType* upper = AstType::Union(b1.upper, b2.upper, zone);
999     return AstBounds(lower, upper);
1000   }
1001 
NarrowLowerAstBounds1002   static AstBounds NarrowLower(AstBounds b, AstType* t, Zone* zone) {
1003     AstType* lower = AstType::Union(b.lower, t, zone);
1004     // Lower bounds are considered approximate, correct as necessary.
1005     if (!lower->Is(b.upper)) lower = b.upper;
1006     return AstBounds(lower, b.upper);
1007   }
NarrowUpperAstBounds1008   static AstBounds NarrowUpper(AstBounds b, AstType* t, Zone* zone) {
1009     AstType* lower = b.lower;
1010     AstType* upper = AstType::Intersect(b.upper, t, zone);
1011     // Lower bounds are considered approximate, correct as necessary.
1012     if (!lower->Is(upper)) lower = upper;
1013     return AstBounds(lower, upper);
1014   }
1015 
NarrowsAstBounds1016   bool Narrows(AstBounds that) {
1017     return that.lower->Is(this->lower) && this->upper->Is(that.upper);
1018   }
1019 };
1020 
1021 }  // namespace internal
1022 }  // namespace v8
1023 
1024 #endif  // V8_AST_AST_TYPES_H_
1025