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