1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <iomanip>
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/ast-types.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/handles-inl.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NOTE: If code is marked as being a "shortcut", this means that removing
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the code won't affect the semantics of the surrounding function definition.
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
19f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::IsInteger(i::Object* x) {
20f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return x->IsNumber() && AstType::IsInteger(x->Number());
21109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Range-related helper functions.
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstRangeType::Limits::IsEmpty() { return this->min > this->max; }
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
28f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstRangeType::Limits::Intersect(Limits lhs, Limits rhs) {
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Limits result(lhs);
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.min < rhs.min) result.min = rhs.min;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.max > rhs.max) result.max = rhs.max;
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstRangeType::Limits::Union(Limits lhs, Limits rhs) {
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.IsEmpty()) return rhs;
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rhs.IsEmpty()) return lhs;
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Limits result(lhs);
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.min > rhs.min) result.min = rhs.min;
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.max < rhs.max) result.max = rhs.max;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Overlap(AstRangeType* lhs, AstRangeType* rhs) {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
48f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return !AstRangeType::Limits::Intersect(AstRangeType::Limits(lhs),
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          AstRangeType::Limits(rhs))
50109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              .IsEmpty();
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* lhs, AstRangeType* rhs) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
58f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* lhs, AstConstantType* rhs) {
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
60f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsInteger(*rhs->Value()) && lhs->Min() <= rhs->Value()->Number() &&
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         rhs->Value()->Number() <= lhs->Max();
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* range, i::Object* val) {
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
66f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsInteger(val) && range->Min() <= val->Number() &&
67f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         val->Number() <= range->Max();
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Min and Max computation.
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstType::Min() {
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->SemanticIs(Number()));
75f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (this->IsBitset()) return AstBitsetType::Min(this->AsBitset());
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double min = +V8_INFINITY;
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      min = std::min(min, this->AsUnion()->Get(i)->Min());
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return min;
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsRange()) return this->AsRange()->Min();
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return 0;
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstType::Max() {
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->SemanticIs(Number()));
91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (this->IsBitset()) return AstBitsetType::Max(this->AsBitset());
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double max = -V8_INFINITY;
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max = std::max(max, this->AsUnion()->Get(i)->Max());
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return max;
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsRange()) return this->AsRange()->Max();
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return 0;
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Glb and lub computation.
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The largest bitset subsumed by this type.
109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Glb(AstType* type) {
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast case.
112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (IsBitset(type)) {
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsBitset();
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (type->IsUnion()) {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SLOW_DCHECK(type->AsUnion()->Wellformed());
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type->AsUnion()->Get(0)->BitsetGlb() |
117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           AST_SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb());  // Shortcut.
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (type->IsRange()) {
119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset glb = AST_SEMANTIC(
120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstBitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return glb | AST_REPRESENTATION(type->BitsetLub());
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type->Representation();
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The smallest bitset subsuming this type, possibly not a proper one.
128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(AstType* type) {
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (IsBitset(type)) return type->AsBitset();
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsUnion()) {
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Take the representation from the first element, which is always
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a bitset.
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int bitset = type->AsUnion()->Get(0)->BitsetLub();
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Other elements only contribute their semantic part.
137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bitset |= AST_SEMANTIC(type->AsUnion()->Get(i)->BitsetLub());
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return bitset;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsClass()) return type->AsClass()->Lub();
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsConstant()) return type->AsConstant()->Lub();
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsRange()) return type->AsRange()->Lub();
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (type->IsContext()) return kOtherInternal & kTaggedPointer;
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsArray()) return kOtherObject;
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsFunction()) return kFunction;
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (type->IsTuple()) return kOtherInternal;
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kNone;
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(i::Map* map) {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (map->instance_type()) {
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case STRING_TYPE:
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ONE_BYTE_STRING_TYPE:
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CONS_STRING_TYPE:
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CONS_ONE_BYTE_STRING_TYPE:
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SLICED_STRING_TYPE:
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SLICED_ONE_BYTE_STRING_TYPE:
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_STRING_TYPE:
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_ONE_BYTE_STRING_TYPE:
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_STRING_TYPE:
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kOtherString;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case INTERNALIZED_STRING_TYPE:
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ONE_BYTE_INTERNALIZED_STRING_TYPE:
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_INTERNALIZED_STRING_TYPE:
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kInternalizedString;
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SYMBOL_TYPE:
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kSymbol;
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ODDBALL_TYPE: {
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Heap* heap = map->GetHeap();
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->undefined_map()) return kUndefined;
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->null_map()) return kNull;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->boolean_map()) return kBoolean;
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (map == heap->the_hole_map()) return kHole;
185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(map == heap->uninitialized_map() ||
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             map == heap->no_interceptor_result_sentinel_map() ||
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             map == heap->termination_exception_map() ||
1883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             map == heap->arguments_marker_map() ||
189bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             map == heap->optimized_out_map() ||
190bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             map == heap->stale_register_map());
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kOtherInternal & kTaggedPointer;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case HEAP_NUMBER_TYPE:
194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return kNumber & kTaggedPointer;
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SIMD128_VALUE_TYPE:
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSimd;
1973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_OBJECT_TYPE:
19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case JS_ARGUMENTS_TYPE:
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case JS_ERROR_TYPE:
2003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_GLOBAL_OBJECT_TYPE:
2013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_GLOBAL_PROXY_TYPE:
202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case JS_API_OBJECT_TYPE:
2033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_SPECIAL_API_OBJECT_TYPE:
2043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (map->is_undetectable()) return kOtherUndetectable;
2053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return kOtherObject;
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_VALUE_TYPE:
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_MESSAGE_OBJECT_TYPE:
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_DATE_TYPE:
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_GENERATOR_OBJECT_TYPE:
211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_MODULE_NAMESPACE_TYPE:
212c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FIXED_ARRAY_ITERATOR_TYPE:
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_ARRAY_BUFFER_TYPE:
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_ARRAY_TYPE:
2153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_REGEXP_TYPE:  // TODO(rossberg): there should be a RegExp type.
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_TYPED_ARRAY_TYPE:
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_DATA_VIEW_TYPE:
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_SET_TYPE:
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_MAP_TYPE:
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_SET_ITERATOR_TYPE:
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_MAP_ITERATOR_TYPE:
222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case JS_STRING_ITERATOR_TYPE:
223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
231c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
232c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
234c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
235c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
236c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
237c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
238c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
239c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
240c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
250c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
251c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
252c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
253c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
257c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_WEAK_MAP_TYPE:
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_WEAK_SET_TYPE:
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_PROMISE_TYPE:
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_BOUND_FUNCTION_TYPE:
2643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kOtherObject;
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_FUNCTION_TYPE:
2673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFunction;
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_PROXY_TYPE:
2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kProxy;
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_TYPE:
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ALLOCATION_SITE_TYPE:
274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case ACCESSOR_INFO_TYPE:
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHARED_FUNCTION_INFO_TYPE:
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ACCESSOR_PAIR_TYPE:
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case FIXED_ARRAY_TYPE:
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FIXED_DOUBLE_ARRAY_TYPE:
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case BYTE_ARRAY_TYPE:
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BYTECODE_ARRAY_TYPE:
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TRANSITION_ARRAY_TYPE:
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case FOREIGN_TYPE:
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SCRIPT_TYPE:
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_TYPE:
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case PROPERTY_CELL_TYPE:
286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case MODULE_TYPE:
287c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case MODULE_INFO_ENTRY_TYPE:
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kOtherInternal & kTaggedPointer;
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Remaining instance types are unsupported for now. If any of them do
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // require bit set types, they should get kOtherInternal & kTaggedPointer.
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MUTABLE_HEAP_NUMBER_TYPE:
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FREE_SPACE_TYPE:
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case FIXED_##TYPE##_ARRAY_TYPE:
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef FIXED_TYPED_ARRAY_CASE
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FILLER_TYPE:
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ACCESS_CHECK_INFO_TYPE:
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INTERCEPTOR_INFO_TYPE:
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CALL_HANDLER_INFO_TYPE:
303c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
304c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case PROMISE_REACTION_JOB_INFO_TYPE:
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FUNCTION_TEMPLATE_INFO_TYPE:
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OBJECT_TEMPLATE_INFO_TYPE:
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SIGNATURE_INFO_TYPE:
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TYPE_SWITCH_INFO_TYPE:
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ALLOCATION_MEMENTO_TYPE:
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TYPE_FEEDBACK_INFO_TYPE:
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ALIASED_ARGUMENTS_ENTRY_TYPE:
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BOX_TYPE:
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DEBUG_INFO_TYPE:
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BREAK_POINT_INFO_TYPE:
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CELL_TYPE:
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case WEAK_CELL_TYPE:
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case PROTOTYPE_INFO_TYPE:
318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case TUPLE3_TYPE:
319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case CONTEXT_EXTENSION_TYPE:
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kNone;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNone;
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(i::Object* value) {
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value->IsNumber()) {
330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Lub(value->Number()) &
331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           (value->IsSmi() ? kTaggedSigned : kTaggedPointer);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Lub(i::HeapObject::cast(value)->map());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(double value) {
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::IsMinusZero(value)) return kMinusZero;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (std::isnan(value)) return kNaN;
340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kOtherNumber;
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Minimum values of plain numeric bitsets.
345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst AstBitsetType::Boundary AstBitsetType::BoundariesArray[] = {
346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherNumber, kPlainNumber, -V8_INFINITY},
347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherSigned32, kNegative32, kMinInt},
348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kNegative31, kNegative31, -0x40000000},
349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kUnsigned30, kUnsigned30, 0},
350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherUnsigned31, kUnsigned31, 0x40000000},
351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherUnsigned32, kUnsigned32, 0x80000000},
352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst AstBitsetType::Boundary* AstBitsetType::Boundaries() {
355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return BoundariesArray;
356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochsize_t AstBitsetType::BoundariesSize() {
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Windows doesn't like arraysize here.
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // return arraysize(BoundariesArray);
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 7;
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::ExpandInternals(AstType::bitset bits) {
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!(bits & AST_SEMANTIC(kPlainNumber))) return bits;  // Shortcut.
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* boundaries = Boundaries();
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < BoundariesSize(); ++i) {
369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(AstBitsetType::Is(boundaries[i].internal, boundaries[i].external));
370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (bits & AST_SEMANTIC(boundaries[i].internal))
371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bits |= AST_SEMANTIC(boundaries[i].external);
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return bits;
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(double min, double max) {
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int lub = kNone;
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i < BoundariesSize(); ++i) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (min < mins[i].min) {
383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      lub |= mins[i - 1].internal;
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (max < mins[i].min) return lub;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return lub | mins[BoundariesSize() - 1].internal;
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::NumberBits(bitset bits) {
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AST_SEMANTIC(bits & kPlainNumber);
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Glb(double min, double max) {
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int glb = kNone;
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range does not touch 0, the bound is empty.
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max < -1 || min > 0) return glb;
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (min <= mins[i].min) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (max + 1 < mins[i + 1].min) break;
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      glb |= mins[i].external;
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // OtherNumber also contains float numbers, so it can never be
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // in the greatest lower bound.
410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return glb & ~(AST_SEMANTIC(kOtherNumber));
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstBitsetType::Min(bitset bits) {
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(Is(AST_SEMANTIC(bits), kNumber));
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool mz = AST_SEMANTIC(bits & kMinusZero);
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < BoundariesSize(); ++i) {
419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Is(AST_SEMANTIC(mins[i].internal), bits)) {
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return mz ? std::min(0.0, mins[i].min) : mins[i].min;
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mz) return 0;
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return std::numeric_limits<double>::quiet_NaN();
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstBitsetType::Max(bitset bits) {
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(Is(AST_SEMANTIC(bits), kNumber));
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool mz = AST_SEMANTIC(bits & kMinusZero);
432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (AstBitsetType::Is(AST_SEMANTIC(mins[BoundariesSize() - 1].internal),
433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        bits)) {
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return +V8_INFINITY;
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = BoundariesSize() - 1; i-- > 0;) {
437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Is(AST_SEMANTIC(mins[i].internal), bits)) {
438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mz) return 0;
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return std::numeric_limits<double>::quiet_NaN();
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Predicates.
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SimplyEquals(AstType* that) {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass()) {
451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsClass() &&
452f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           *this->AsClass()->Map() == *that->AsClass()->Map();
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
455f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsConstant() &&
456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           *this->AsConstant()->Value() == *that->AsConstant()->Value();
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsContext()) {
459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsContext() &&
460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           this->AsContext()->Outer()->Equals(that->AsContext()->Outer());
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsArray()) {
463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsArray() &&
464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           this->AsArray()->Element()->Equals(that->AsArray()->Element());
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsFunction()) {
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!that->IsFunction()) return false;
468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstFunctionType* this_fun = this->AsFunction();
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstFunctionType* that_fun = that->AsFunction();
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this_fun->Arity() != that_fun->Arity() ||
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !this_fun->Result()->Equals(that_fun->Result()) ||
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !this_fun->Receiver()->Equals(that_fun->Receiver())) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this_fun->Arity(); i < n; ++i) {
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false;
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsTuple()) {
481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!that->IsTuple()) return false;
482f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstTupleType* this_tuple = this->AsTuple();
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstTupleType* that_tuple = that->AsTuple();
484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (this_tuple->Arity() != that_tuple->Arity()) {
485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return true;
491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstType::Representation() {
497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AST_REPRESENTATION(this->BitsetLub());
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] <= [that].
501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SlowIs(AstType* that) {
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast bitset cases
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsBitset()) {
506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(this->BitsetLub(), that->AsBitset());
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsBitset()) {
510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(this->AsBitset(), that->BitsetGlb());
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check the representations.
514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::Is(Representation(), that->Representation())) {
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check the semantic part.
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SemanticIs(that);
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Check if AST_SEMANTIC([this]) <= AST_SEMANTIC([that]). The result of the
523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// method
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// should be independent of the representation axis of the types.
525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SemanticIs(AstType* that) {
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this == that) return true;
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (that->IsBitset()) {
531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(AST_SEMANTIC(this->BitsetLub()), that->AsBitset());
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset()) {
534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(AST_SEMANTIC(this->AsBitset()), that->BitsetGlb());
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!this->AsUnion()->Get(i)->SemanticIs(that)) return false;
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsUnion()) {
547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (this->SemanticIs(that->AsUnion()->Get(i))) return true;
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i > 1 && this->IsRange()) return false;  // Shortcut.
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsRange()) {
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) ||
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (this->IsConstant() &&
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Contains(that->AsRange(), this->AsConstant()));
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsRange()) return false;
560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->SimplyEquals(that);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Most precise _current_ type of a value (usually its class).
565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NowOf(i::Object* value, Zone* zone) {
566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (value->IsSmi() ||
567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Of(value, zone);
569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return Class(i::handle(i::HeapObject::cast(value)->map()), zone);
571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowContains(i::Object* value) {
574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DisallowHeapAllocation no_allocation;
575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsAny()) return true;
576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (value->IsHeapObject()) {
577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    i::Map* map = i::HeapObject::cast(value)->map();
578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (*it.Current() == map) return true;
580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return this->Contains(value);
583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowIs(AstType* that) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): this is incorrect for
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //   Union(Constant(V), T)->NowIs(Class(M))
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // but fuzzing does not cover that!
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* object = *this->AsConstant()->Value();
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (object->IsHeapObject()) {
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Map* map = i::HeapObject::cast(object)->map();
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (*it.Current() == map) return true;
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->Is(that);
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] contains only (currently) stable classes.
604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowStable() {
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return !this->IsClass() || this->AsClass()->Map()->is_stable();
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] and [that] overlap.
610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Maybe(AstType* that) {
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Take care of the representation part (and also approximate
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the semantic part).
615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SemanticMaybe(that);
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SemanticMaybe(AstType* that) {
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (this->AsUnion()->Get(i)->SemanticMaybe(that)) return true;
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsUnion()) {
634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true;
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::SemanticIsInhabited(this->BitsetLub() &
641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          that->BitsetLub()))
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset() && that->IsBitset()) return true;
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass() != that->IsClass()) return true;
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsRange()) {
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (that->IsConstant()) {
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Contains(this->AsRange(), that->AsConstant());
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (that->IsRange()) {
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Overlap(this->AsRange(), that->AsRange());
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (that->IsBitset()) {
656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bitset number_bits = AstBitsetType::NumberBits(that->AsBitset());
657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (number_bits == AstBitsetType::kNone) {
658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return false;
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      double min = std::max(AstBitsetType::Min(number_bits), this->Min());
661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      double max = std::min(AstBitsetType::Max(number_bits), this->Max());
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return min <= max;
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsRange()) {
666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return that->SemanticMaybe(this);  // This case is handled above.
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset() || that->IsBitset()) return true;
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->SimplyEquals(that);
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Return the range in [this], or [NULL].
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::GetRange() {
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
677109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsRange()) return this;
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
679109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return this->AsUnion()->Get(1);
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(i::Object* value) {
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (*it.Current() == value) return true;
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsInteger(value)) {
690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstType* range = this->GetRange();
691109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (range != NULL && Contains(range->AsRange(), value)) return true;
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstBitsetType::New(AstBitsetType::Lub(value))->Is(this);
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstUnionType::Wellformed() {
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This checks the invariants of the union representation:
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 1. There are at least two elements.
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 2. The first element is a bitset, no other element is a bitset.
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 3. At most one element is a range, and it must be the second one.
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 4. No element is itself a union.
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 5. No element (except the bitset) is a subtype of any other.
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 6. If there is a range, then the bitset type does not contain
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //    plain number bits.
706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(this->Length() >= 2);       // (1)
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->Get(0)->IsBitset());  // (2a)
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < this->Length(); ++i) {
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != 0) DCHECK(!this->Get(i)->IsBitset());  // (2b)
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != 1) DCHECK(!this->Get(i)->IsRange());   // (3)
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!this->Get(i)->IsUnion());               // (4)
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int j = 0; j < this->Length(); ++j) {
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (i != j && i != 0)
715109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(!this->Get(i)->SemanticIs(this->Get(j)));  // (5)
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!this->Get(1)->IsRange() ||
719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         (AstBitsetType::NumberBits(this->Get(0)->AsBitset()) ==
720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstBitsetType::kNone));  // (6)
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Union and intersection
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool AddIsSafe(int x, int y) {
728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return x >= 0 ? y <= std::numeric_limits<int>::max() - x
729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                : y >= std::numeric_limits<int>::min() - x;
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Intersect(AstType* type1, AstType* type2, Zone* zone) {
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: bit sets.
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsBitset() && type2->IsBitset()) {
735f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::New(type1->AsBitset() & type2->AsBitset());
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: top or bottom types.
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsNone() || type2->IsAny()) return type1;  // Shortcut.
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->IsNone() || type1->IsAny()) return type2;  // Shortcut.
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Semi-fast case.
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->Is(type2)) return type1;
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->Is(type1)) return type2;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Slow case: create union.
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Figure out the representation of the result first.
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The rest of the method should not change this representation and
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should not make any decisions based on representations (i.e.,
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should only use the semantic part of types).
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const bitset representation =
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type1->Representation() & type2->Representation();
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Semantic subtyping check - this is needed for consistency with the
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // semi-fast case above - we should behave the same way regardless of
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // representations. Intersection with a universal bitset should only update
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the representations.
759109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (type1->SemanticIs(type2)) {
760109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    type2 = Any();
761109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else if (type2->SemanticIs(type1)) {
762109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    type1 = Any();
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bitset bits =
766f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation;
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
769109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size1, size2)) return Any();
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = size1 + size2;
771109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size, 2)) return Any();
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size += 2;
773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* result_type = AstUnionType::New(size, zone);
774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* result = result_type->AsUnion();
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size = 0;
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deal with bitsets.
778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  result->Set(size++, AstBitsetType::New(bits));
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits lims = AstRangeType::Limits::Empty();
781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = IntersectAux(type1, type2, result, size, &lims, zone);
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range is not empty, then insert it into the union and
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // remove the number bits from the bitset.
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!lims.IsEmpty()) {
786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    size = UpdateRange(AstRangeType::New(lims, representation, zone), result,
787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       size, zone);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Remove the number bits.
790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset number_bits = AstBitsetType::NumberBits(bits);
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bits &= ~number_bits;
792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    result->Set(0, AstBitsetType::New(bits));
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return NormalizeUnion(result_type, size, zone);
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::UpdateRange(AstType* range, AstUnionType* result, int size,
798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         Zone* zone) {
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size == 1) {
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(size++, range);
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make space for the range.
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(size++, result->Get(1));
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(1, range);
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remove any components that just got subsumed.
808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int i = 2; i < size;) {
809109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (result->Get(i)->SemanticIs(range)) {
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result->Set(i, result->Get(--size));
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ++i;
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstType::ToLimits(bitset bits, Zone* zone) {
819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset number_bits = AstBitsetType::NumberBits(bits);
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (number_bits == AstBitsetType::kNone) {
822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstRangeType::Limits::Empty();
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::Limits(AstBitsetType::Min(number_bits),
826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              AstBitsetType::Max(number_bits));
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstType::IntersectRangeAndBitset(AstType* range,
830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                      AstType* bitset,
831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                      Zone* zone) {
832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits range_lims(range->AsRange());
833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::Limits::Intersect(range_lims, bitset_lims);
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::IntersectAux(AstType* lhs, AstType* rhs, AstUnionType* result,
838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          int size, AstRangeType::Limits* lims, Zone* zone) {
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsUnion()) {
840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size =
842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rhs->IsUnion()) {
847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size =
849109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::SemanticIsInhabited(lhs->BitsetLub() &
855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          rhs->BitsetLub())) {
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsRange()) {
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsBitset()) {
861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstRangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!lim.IsEmpty()) {
864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *lims = AstRangeType::Limits::Union(lim, *lims);
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return size;
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsClass()) {
869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *lims = AstRangeType::Limits::Union(AstRangeType::Limits(lhs->AsRange()),
870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          *lims);
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return AddToUnion(rhs, result, size, zone);
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsRange()) {
876f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstRangeType::Limits lim =
877f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstRangeType::Limits::Intersect(AstRangeType::Limits(lhs->AsRange()),
878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          AstRangeType::Limits(rhs->AsRange()));
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!lim.IsEmpty()) {
880f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *lims = AstRangeType::Limits::Union(lim, *lims);
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rhs->IsRange()) {
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This case is handled symmetrically above.
887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return IntersectAux(rhs, lhs, result, size, lims, zone);
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsBitset() || rhs->IsBitset()) {
890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsClass() != rhs->IsClass()) {
893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, zone);
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
895109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (lhs->SimplyEquals(rhs)) {
896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs, result, size, zone);
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Make sure that we produce a well-formed range and bitset:
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If the range is non-empty, the number bits in the bitset should be
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clear. Moreover, if we have a canonical range (such as Signed32),
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// we want to produce a bitset rather than a range.
905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NormalizeRangeAndBitset(AstType* range, bitset* bits,
906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          Zone* zone) {
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast path: If the bitset does not mention numbers, we can just keep the
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // range.
909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset number_bits = AstBitsetType::NumberBits(*bits);
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (number_bits == 0) {
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return range;
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range is semantically contained within the bitset, return None and
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // leave the bitset untouched.
916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset range_lub = AST_SEMANTIC(range->BitsetLub());
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (AstBitsetType::Is(range_lub, *bits)) {
918109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return None();
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Slow path: reconcile the bitset range and the range.
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  double bitset_min = AstBitsetType::Min(number_bits);
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  double bitset_max = AstBitsetType::Max(number_bits);
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double range_min = range->Min();
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double range_max = range->Max();
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Remove the number bits from the bitset, they would just confuse us now.
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // case we already returned after the subtype check above.
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *bits &= ~number_bits;
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range_min <= bitset_min && range_max >= bitset_max) {
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Bitset is contained within the range, just return the range.
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return range;
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bitset_min < range_min) {
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range_min = bitset_min;
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bitset_max > range_max) {
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range_max = bitset_max;
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::New(range_min, range_max, AstBitsetType::kNone, zone);
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Union(AstType* type1, AstType* type2, Zone* zone) {
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: bit sets.
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsBitset() && type2->IsBitset()) {
950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::New(type1->AsBitset() | type2->AsBitset());
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: top or bottom types.
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsAny() || type2->IsNone()) return type1;
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->IsAny() || type1->IsNone()) return type2;
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Semi-fast case.
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->Is(type2)) return type2;
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->Is(type1)) return type1;
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Figure out the representation of the result.
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The rest of the method should not change this representation and
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should not make any decisions based on representations (i.e.,
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should only use the semantic part of types).
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const bitset representation =
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type1->Representation() | type2->Representation();
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Slow case: create union.
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size1, size2)) return Any();
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = size1 + size2;
973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size, 2)) return Any();
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size += 2;
975f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* result_type = AstUnionType::New(size, zone);
976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* result = result_type->AsUnion();
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size = 0;
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Compute the new bitset.
980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset new_bitset = AST_SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb());
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deal with ranges.
983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range = None();
984f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range1 = type1->GetRange();
985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range2 = type2->GetRange();
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (range1 != NULL && range2 != NULL) {
987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstRangeType::Limits lims =
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstRangeType::Limits::Union(AstRangeType::Limits(range1->AsRange()),
989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    AstRangeType::Limits(range2->AsRange()));
990f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstType* union_range = AstRangeType::New(lims, representation, zone);
991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (range1 != NULL) {
993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (range2 != NULL) {
995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
997f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_bitset = AST_SEMANTIC(new_bitset) | representation;
998f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* bits = AstBitsetType::New(new_bitset);
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->Set(size++, bits);
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!range->IsNone()) result->Set(size++, range);
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = AddToUnion(type1, result, size, zone);
1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = AddToUnion(type2, result, size, zone);
1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return NormalizeUnion(result_type, size, zone);
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Add [type] to [result] unless [type] is bitset, range, or already subsumed.
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Return new size of [result].
1009f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::AddToUnion(AstType* type, AstUnionType* result, int size,
1010f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        Zone* zone) {
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsBitset() || type->IsRange()) return size;
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsUnion()) {
1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
1014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < size; ++i) {
1019109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (type->SemanticIs(result->Get(i))) return size;
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->Set(size++, type);
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1025f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NormalizeUnion(AstType* union_type, int size, Zone* zone) {
1026f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* unioned = union_type->AsUnion();
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(size >= 1);
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(unioned->Get(0)->IsBitset());
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the union has just one element, return it.
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size == 1) {
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return unioned->Get(0);
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bitset bits = unioned->Get(0)->AsBitset();
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the union only consists of a range, we can get rid of the union.
1035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (size == 2 && AST_SEMANTIC(bits) == AstBitsetType::kNone) {
1036f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset representation = AST_REPRESENTATION(bits);
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (representation == unioned->Get(1)->Representation()) {
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return unioned->Get(1);
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (unioned->Get(1)->IsRange()) {
1041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return AstRangeType::New(unioned->Get(1)->AsRange()->Min(),
1042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               unioned->Get(1)->AsRange()->Max(),
1043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               unioned->Get(0)->AsBitset(), zone);
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unioned->Shrink(size);
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SLOW_DCHECK(unioned->Wellformed());
1048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return union_type;
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Component extraction
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
1055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Representation(AstType* t, Zone* zone) {
1056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstBitsetType::New(t->Representation());
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
1060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Semantic(AstType* t, Zone* zone) {
1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Intersect(t, AstBitsetType::New(AstBitsetType::kSemantic), zone);
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -----------------------------------------------------------------------------
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iteration.
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::NumClasses() {
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass()) {
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (this->IsUnion()) {
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int result = 0;
1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (this->AsUnion()->Get(i)->IsClass()) ++result;
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1082f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::NumConstants() {
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (this->IsUnion()) {
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int result = 0;
1088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (this->AsUnion()->Get(i)->IsConstant()) ++result;
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1097109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Iterator<T>::get_type() {
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!Done());
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// C++ cannot specialise nested templates, so we have to go through this
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contortion with an auxiliary template to simulate it.
1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct TypeImplIteratorAux {
1107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type);
1108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<T> current(AstType* type);
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <>
1112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct TypeImplIteratorAux<i::Map> {
1113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type) { return type->IsClass(); }
1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<i::Map> current(AstType* type) {
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsClass()->Map();
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <>
1120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct TypeImplIteratorAux<i::Object> {
1121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type) { return type->IsConstant(); }
1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<i::Object> current(AstType* type) {
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsConstant()->Value();
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Iterator<T>::matches(AstType* type) {
1129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return TypeImplIteratorAux<T>::matches(type);
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochi::Handle<T> AstType::Iterator<T>::Current() {
1134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return TypeImplIteratorAux<T>::current(get_type());
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::Iterator<T>::Advance() {
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ++index_;
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type_->IsUnion()) {
1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) {
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (matches(type_->AsUnion()->Get(index_))) return;
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (index_ == 0 && matches(type_)) {
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  index_ = -1;
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Printing.
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst char* AstBitsetType::Name(bitset bits) {
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (bits) {
1156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case AST_REPRESENTATION(kAny):
1157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "Any";
1158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
1159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  case AST_REPRESENTATION(k##type):                   \
1160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return #type;
1161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE)
1162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef RETURN_NAMED_REPRESENTATION_TYPE
1163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define RETURN_NAMED_SEMANTIC_TYPE(type, value) \
1165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  case AST_SEMANTIC(k##type):                   \
1166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return #type;
1167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE)
1168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE)
1169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef RETURN_NAMED_SEMANTIC_TYPE
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstBitsetType::Print(std::ostream& os,  // NOLINT
1177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          bitset bits) {
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* name = Name(bits);
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (name != NULL) {
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << name;
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // clang-format off
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const bitset named_bitsets[] = {
1187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define BITSET_CONSTANT(type, value) AST_REPRESENTATION(k##type),
1188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef BITSET_CONSTANT
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define BITSET_CONSTANT(type, value) AST_SEMANTIC(k##type),
1192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
1193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef BITSET_CONSTANT
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // clang-format on
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_first = true;
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "(";
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bitset subset = named_bitsets[i];
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((bits & subset) == subset) {
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!is_first) os << " | ";
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_first = false;
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << Name(subset);
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bits -= subset;
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(bits == 0);
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << ")";
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::PrintTo(std::ostream& os, PrintDimension dim) {
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim != REPRESENTATION_DIM) {
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->IsBitset()) {
1217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBitsetType::Print(os, AST_SEMANTIC(this->AsBitset()));
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsClass()) {
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < ";
1220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBitsetType::New(AstBitsetType::Lub(this))->PrintTo(os, dim);
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsConstant()) {
1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsRange()) {
1225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::streamsize saved_precision = os.precision(0);
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         << ")";
1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os.flags(saved_flags);
1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os.precision(saved_precision);
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsContext()) {
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Context(";
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this->AsContext()->Outer()->PrintTo(os, dim);
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsUnion()) {
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "(";
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstType* type_i = this->AsUnion()->Get(i);
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (i > 0) os << " | ";
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type_i->PrintTo(os, dim);
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsArray()) {
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Array(";
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AsArray()->Element()->PrintTo(os, dim);
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsFunction()) {
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!this->AsFunction()->Receiver()->IsAny()) {
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->AsFunction()->Receiver()->PrintTo(os, dim);
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        os << ".";
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "(";
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (i > 0) os << ", ";
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->AsFunction()->Parameter(i)->PrintTo(os, dim);
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")->";
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this->AsFunction()->Result()->PrintTo(os, dim);
1259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else if (this->IsTuple()) {
1260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      os << "<";
1261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstType* type_i = this->AsTuple()->Element(i);
1263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (i > 0) os << ", ";
1264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        type_i->PrintTo(os, dim);
1265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      os << ">";
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim == BOTH_DIMS) os << "/";
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim != SEMANTIC_DIM) {
1273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstBitsetType::Print(os, AST_REPRESENTATION(this->BitsetLub()));
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::Print() {
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stdout);
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintTo(os);
1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  os << std::endl;
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstBitsetType::Print(bitset bits) {
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stdout);
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Print(os, bits);
1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  os << std::endl;
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstBitsetType::bitset AstBitsetType::SignedSmall() {
1291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstBitsetType::bitset AstBitsetType::UnsignedSmall() {
1295109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1296109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
1299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* AstType::Name(Isolate* isolate, Zone* zone) {             \
1300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Class(i::handle(isolate->heap()->name##_map()), zone);    \
1301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochSIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
1303109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#undef CONSTRUCT_SIMD_TYPE
1304f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// -----------------------------------------------------------------------------
1306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Instantiations.
1307f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate class AstType::Iterator<i::Map>;
1309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate class AstType::Iterator<i::Object>;
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
1313