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"
1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NOTE: If code is marked as being a "shortcut", this means that removing
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the code won't affect the semantics of the surrounding function definition.
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// static
20f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::IsInteger(i::Object* x) {
21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return x->IsNumber() && AstType::IsInteger(x->Number());
22109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Range-related helper functions.
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
27f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstRangeType::Limits::IsEmpty() { return this->min > this->max; }
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
29f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstRangeType::Limits::Intersect(Limits lhs, Limits rhs) {
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Limits result(lhs);
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.min < rhs.min) result.min = rhs.min;
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.max > rhs.max) result.max = rhs.max;
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstRangeType::Limits::Union(Limits lhs, Limits rhs) {
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.IsEmpty()) return rhs;
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rhs.IsEmpty()) return lhs;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Limits result(lhs);
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.min > rhs.min) result.min = rhs.min;
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (lhs.max < rhs.max) result.max = rhs.max;
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Overlap(AstRangeType* lhs, AstRangeType* rhs) {
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return !AstRangeType::Limits::Intersect(AstRangeType::Limits(lhs),
50f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          AstRangeType::Limits(rhs))
51109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              .IsEmpty();
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* lhs, AstRangeType* rhs) {
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
59f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* lhs, AstConstantType* rhs) {
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
61f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsInteger(*rhs->Value()) && lhs->Min() <= rhs->Value()->Number() &&
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         rhs->Value()->Number() <= lhs->Max();
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(AstRangeType* range, i::Object* val) {
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
67f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsInteger(val) && range->Min() <= val->Number() &&
68f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         val->Number() <= range->Max();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Min and Max computation.
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstType::Min() {
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->SemanticIs(Number()));
76f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (this->IsBitset()) return AstBitsetType::Min(this->AsBitset());
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double min = +V8_INFINITY;
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      min = std::min(min, this->AsUnion()->Get(i)->Min());
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return min;
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsRange()) return this->AsRange()->Min();
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return 0;
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstType::Max() {
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->SemanticIs(Number()));
92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (this->IsBitset()) return AstBitsetType::Max(this->AsBitset());
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double max = -V8_INFINITY;
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max = std::max(max, this->AsUnion()->Get(i)->Max());
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return max;
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsRange()) return this->AsRange()->Max();
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) return this->AsConstant()->Value()->Number();
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return 0;
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Glb and lub computation.
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The largest bitset subsumed by this type.
110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Glb(AstType* type) {
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast case.
113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (IsBitset(type)) {
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsBitset();
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (type->IsUnion()) {
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SLOW_DCHECK(type->AsUnion()->Wellformed());
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type->AsUnion()->Get(0)->BitsetGlb() |
118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           AST_SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb());  // Shortcut.
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (type->IsRange()) {
120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset glb = AST_SEMANTIC(
121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstBitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return glb | AST_REPRESENTATION(type->BitsetLub());
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return type->Representation();
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The smallest bitset subsuming this type, possibly not a proper one.
129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(AstType* type) {
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (IsBitset(type)) return type->AsBitset();
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsUnion()) {
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Take the representation from the first element, which is always
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // a bitset.
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int bitset = type->AsUnion()->Get(0)->BitsetLub();
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Other elements only contribute their semantic part.
138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bitset |= AST_SEMANTIC(type->AsUnion()->Get(i)->BitsetLub());
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return bitset;
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsClass()) return type->AsClass()->Lub();
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsConstant()) return type->AsConstant()->Lub();
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsRange()) return type->AsRange()->Lub();
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (type->IsContext()) return kOtherInternal & kTaggedPointer;
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsArray()) return kOtherObject;
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (type->IsFunction()) return kFunction;
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (type->IsTuple()) return kOtherInternal;
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kNone;
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(i::Map* map) {
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (map->instance_type()) {
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case STRING_TYPE:
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ONE_BYTE_STRING_TYPE:
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CONS_STRING_TYPE:
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CONS_ONE_BYTE_STRING_TYPE:
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case THIN_STRING_TYPE:
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case THIN_ONE_BYTE_STRING_TYPE:
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SLICED_STRING_TYPE:
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SLICED_ONE_BYTE_STRING_TYPE:
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_STRING_TYPE:
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_ONE_BYTE_STRING_TYPE:
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_STRING_TYPE:
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kOtherString;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case INTERNALIZED_STRING_TYPE:
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ONE_BYTE_INTERNALIZED_STRING_TYPE:
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_INTERNALIZED_STRING_TYPE:
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kInternalizedString;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SYMBOL_TYPE:
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kSymbol;
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ODDBALL_TYPE: {
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Heap* heap = map->GetHeap();
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->undefined_map()) return kUndefined;
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->null_map()) return kNull;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map == heap->boolean_map()) return kBoolean;
187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (map == heap->the_hole_map()) return kHole;
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(map == heap->uninitialized_map() ||
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             map == heap->no_interceptor_result_sentinel_map() ||
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             map == heap->termination_exception_map() ||
1913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch             map == heap->arguments_marker_map() ||
192bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             map == heap->optimized_out_map() ||
193bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             map == heap->stale_register_map());
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kOtherInternal & kTaggedPointer;
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case HEAP_NUMBER_TYPE:
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return kNumber & kTaggedPointer;
1983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_OBJECT_TYPE:
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case JS_ARGUMENTS_TYPE:
20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case JS_ERROR_TYPE:
2013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_GLOBAL_OBJECT_TYPE:
2023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_GLOBAL_PROXY_TYPE:
203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case JS_API_OBJECT_TYPE:
2043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case JS_SPECIAL_API_OBJECT_TYPE:
2053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (map->is_undetectable()) return kOtherUndetectable;
2063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return kOtherObject;
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_VALUE_TYPE:
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_MESSAGE_OBJECT_TYPE:
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_DATE_TYPE:
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_GENERATOR_OBJECT_TYPE:
212c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_MODULE_NAMESPACE_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:
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
231c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
232c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
234c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
235c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
236c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
237c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
238c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
239c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
240c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
250c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
251c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
252c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
253c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
257c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_WEAK_MAP_TYPE:
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_WEAK_SET_TYPE:
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case JS_PROMISE_CAPABILITY_TYPE:
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_PROMISE_TYPE:
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JS_BOUND_FUNCTION_TYPE:
2663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kOtherObject;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_FUNCTION_TYPE:
2693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFunction;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case JS_PROXY_TYPE:
2723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      DCHECK(!map->is_undetectable());
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kProxy;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case MAP_TYPE:
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ALLOCATION_SITE_TYPE:
276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case ACCESSOR_INFO_TYPE:
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case SHARED_FUNCTION_INFO_TYPE:
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ACCESSOR_PAIR_TYPE:
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case FIXED_ARRAY_TYPE:
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FIXED_DOUBLE_ARRAY_TYPE:
281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case BYTE_ARRAY_TYPE:
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BYTECODE_ARRAY_TYPE:
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TRANSITION_ARRAY_TYPE:
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case FOREIGN_TYPE:
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SCRIPT_TYPE:
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case CODE_TYPE:
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case PROPERTY_CELL_TYPE:
288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case MODULE_TYPE:
289c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case MODULE_INFO_ENTRY_TYPE:
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kOtherInternal & kTaggedPointer;
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Remaining instance types are unsupported for now. If any of them do
293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // require bit set types, they should get kOtherInternal & kTaggedPointer.
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MUTABLE_HEAP_NUMBER_TYPE:
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FREE_SPACE_TYPE:
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case FIXED_##TYPE##_ARRAY_TYPE:
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef FIXED_TYPED_ARRAY_CASE
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FILLER_TYPE:
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ACCESS_CHECK_INFO_TYPE:
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INTERCEPTOR_INFO_TYPE:
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CALL_HANDLER_INFO_TYPE:
305c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
306c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case PROMISE_REACTION_JOB_INFO_TYPE:
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FUNCTION_TEMPLATE_INFO_TYPE:
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OBJECT_TEMPLATE_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 DEBUG_INFO_TYPE:
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BREAK_POINT_INFO_TYPE:
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CELL_TYPE:
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case WEAK_CELL_TYPE:
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case PROTOTYPE_INFO_TYPE:
31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case TUPLE2_TYPE:
318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case TUPLE3_TYPE:
319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case CONTEXT_EXTENSION_TYPE:
32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case CONSTANT_ELEMENTS_PAIR_TYPE:
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kNone;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNone;
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(i::Object* value) {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value->IsNumber()) {
331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Lub(value->Number()) &
332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           (value->IsSmi() ? kTaggedSigned : kTaggedPointer);
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Lub(i::HeapObject::cast(value)->map());
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(double value) {
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::IsMinusZero(value)) return kMinusZero;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (std::isnan(value)) return kNaN;
341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kOtherNumber;
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Minimum values of plain numeric bitsets.
346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst AstBitsetType::Boundary AstBitsetType::BoundariesArray[] = {
347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherNumber, kPlainNumber, -V8_INFINITY},
348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherSigned32, kNegative32, kMinInt},
349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kNegative31, kNegative31, -0x40000000},
350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kUnsigned30, kUnsigned30, 0},
351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherUnsigned31, kUnsigned31, 0x40000000},
352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherUnsigned32, kUnsigned32, 0x80000000},
353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst AstBitsetType::Boundary* AstBitsetType::Boundaries() {
356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return BoundariesArray;
357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochsize_t AstBitsetType::BoundariesSize() {
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Windows doesn't like arraysize here.
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // return arraysize(BoundariesArray);
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 7;
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::ExpandInternals(AstType::bitset bits) {
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!(bits & AST_SEMANTIC(kPlainNumber))) return bits;  // Shortcut.
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* boundaries = Boundaries();
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < BoundariesSize(); ++i) {
370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(AstBitsetType::Is(boundaries[i].internal, boundaries[i].external));
371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (bits & AST_SEMANTIC(boundaries[i].internal))
372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bits |= AST_SEMANTIC(boundaries[i].external);
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return bits;
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Lub(double min, double max) {
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int lub = kNone;
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i < BoundariesSize(); ++i) {
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (min < mins[i].min) {
384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      lub |= mins[i - 1].internal;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (max < mins[i].min) return lub;
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return lub | mins[BoundariesSize() - 1].internal;
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::NumberBits(bitset bits) {
392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AST_SEMANTIC(bits & kPlainNumber);
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstBitsetType::Glb(double min, double max) {
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int glb = kNone;
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range does not touch 0, the bound is empty.
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (max < -1 || min > 0) return glb;
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (min <= mins[i].min) {
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (max + 1 < mins[i + 1].min) break;
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      glb |= mins[i].external;
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // OtherNumber also contains float numbers, so it can never be
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // in the greatest lower bound.
411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return glb & ~(AST_SEMANTIC(kOtherNumber));
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstBitsetType::Min(bitset bits) {
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(Is(AST_SEMANTIC(bits), kNumber));
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool mz = AST_SEMANTIC(bits & kMinusZero);
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < BoundariesSize(); ++i) {
420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Is(AST_SEMANTIC(mins[i].internal), bits)) {
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return mz ? std::min(0.0, mins[i].min) : mins[i].min;
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mz) return 0;
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return std::numeric_limits<double>::quiet_NaN();
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochdouble AstBitsetType::Max(bitset bits) {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(Is(AST_SEMANTIC(bits), kNumber));
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Boundary* mins = Boundaries();
432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool mz = AST_SEMANTIC(bits & kMinusZero);
433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (AstBitsetType::Is(AST_SEMANTIC(mins[BoundariesSize() - 1].internal),
434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        bits)) {
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return +V8_INFINITY;
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = BoundariesSize() - 1; i-- > 0;) {
438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (Is(AST_SEMANTIC(mins[i].internal), bits)) {
439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mz) return 0;
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return std::numeric_limits<double>::quiet_NaN();
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Predicates.
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SimplyEquals(AstType* that) {
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass()) {
452f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsClass() &&
453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           *this->AsClass()->Map() == *that->AsClass()->Map();
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsConstant() &&
457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           *this->AsConstant()->Value() == *that->AsConstant()->Value();
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsContext()) {
460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsContext() &&
461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           this->AsContext()->Outer()->Equals(that->AsContext()->Outer());
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsArray()) {
464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return that->IsArray() &&
465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           this->AsArray()->Element()->Equals(that->AsArray()->Element());
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsFunction()) {
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!that->IsFunction()) return false;
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstFunctionType* this_fun = this->AsFunction();
470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstFunctionType* that_fun = that->AsFunction();
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this_fun->Arity() != that_fun->Arity() ||
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !this_fun->Result()->Equals(that_fun->Result()) ||
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !this_fun->Receiver()->Equals(that_fun->Receiver())) {
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this_fun->Arity(); i < n; ++i) {
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false;
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsTuple()) {
482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!that->IsTuple()) return false;
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstTupleType* this_tuple = this->AsTuple();
484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstTupleType* that_tuple = that->AsTuple();
485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (this_tuple->Arity() != that_tuple->Arity()) {
486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return true;
492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType::bitset AstType::Representation() {
498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AST_REPRESENTATION(this->BitsetLub());
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] <= [that].
502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SlowIs(AstType* that) {
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast bitset cases
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsBitset()) {
507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(this->BitsetLub(), that->AsBitset());
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsBitset()) {
511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(this->AsBitset(), that->BitsetGlb());
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check the representations.
515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::Is(Representation(), that->Representation())) {
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check the semantic part.
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SemanticIs(that);
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Check if AST_SEMANTIC([this]) <= AST_SEMANTIC([that]). The result of the
524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// method
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// should be independent of the representation axis of the types.
526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SemanticIs(AstType* that) {
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this == that) return true;
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (that->IsBitset()) {
532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(AST_SEMANTIC(this->BitsetLub()), that->AsBitset());
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset()) {
535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::Is(AST_SEMANTIC(this->AsBitset()), that->BitsetGlb());
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!this->AsUnion()->Get(i)->SemanticIs(that)) return false;
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return true;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsUnion()) {
548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (this->SemanticIs(that->AsUnion()->Get(i))) return true;
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i > 1 && this->IsRange()) return false;  // Shortcut.
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsRange()) {
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) ||
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           (this->IsConstant() &&
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Contains(that->AsRange(), this->AsConstant()));
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsRange()) return false;
561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->SimplyEquals(that);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Most precise _current_ type of a value (usually its class).
566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NowOf(i::Object* value, Zone* zone) {
567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (value->IsSmi() ||
568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Of(value, zone);
570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return Class(i::handle(i::HeapObject::cast(value)->map()), zone);
572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
574f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowContains(i::Object* value) {
575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DisallowHeapAllocation no_allocation;
576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsAny()) return true;
577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (value->IsHeapObject()) {
578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    i::Map* map = i::HeapObject::cast(value)->map();
579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (*it.Current() == map) return true;
581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return this->Contains(value);
584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowIs(AstType* that) {
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): this is incorrect for
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //   Union(Constant(V), T)->NowIs(Class(M))
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // but fuzzing does not cover that!
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* object = *this->AsConstant()->Value();
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (object->IsHeapObject()) {
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Map* map = i::HeapObject::cast(object)->map();
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (Iterator<i::Map> it = that->Classes(); !it.Done(); it.Advance()) {
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (*it.Current() == map) return true;
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->Is(that);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] contains only (currently) stable classes.
605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::NowStable() {
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return !this->IsClass() || this->AsClass()->Map()->is_stable();
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Check if [this] and [that] overlap.
611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Maybe(AstType* that) {
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Take care of the representation part (and also approximate
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the semantic part).
616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SemanticMaybe(that);
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::SemanticMaybe(AstType* that) {
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DisallowHeapAllocation no_allocation;
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion()) {
627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (this->AsUnion()->Get(i)->SemanticMaybe(that)) return true;
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsUnion()) {
635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true;
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::SemanticIsInhabited(this->BitsetLub() &
642f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          that->BitsetLub()))
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset() && that->IsBitset()) return true;
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass() != that->IsClass()) return true;
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsRange()) {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (that->IsConstant()) {
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Contains(this->AsRange(), that->AsConstant());
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (that->IsRange()) {
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Overlap(this->AsRange(), that->AsRange());
655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (that->IsBitset()) {
657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bitset number_bits = AstBitsetType::NumberBits(that->AsBitset());
658f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (number_bits == AstBitsetType::kNone) {
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return false;
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      double min = std::max(AstBitsetType::Min(number_bits), this->Min());
662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      double max = std::min(AstBitsetType::Max(number_bits), this->Max());
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return min <= max;
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that->IsRange()) {
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return that->SemanticMaybe(this);  // This case is handled above.
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this->IsBitset() || that->IsBitset()) return true;
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return this->SimplyEquals(that);
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Return the range in [this], or [NULL].
676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::GetRange() {
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
678109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (this->IsRange()) return this;
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return this->AsUnion()->Get(1);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Contains(i::Object* value) {
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (*it.Current() == value) return true;
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsInteger(value)) {
691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstType* range = this->GetRange();
692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (range != NULL && Contains(range->AsRange(), value)) return true;
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstBitsetType::New(AstBitsetType::Lub(value))->Is(this);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstUnionType::Wellformed() {
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This checks the invariants of the union representation:
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 1. There are at least two elements.
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 2. The first element is a bitset, no other element is a bitset.
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 3. At most one element is a range, and it must be the second one.
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 4. No element is itself a union.
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 5. No element (except the bitset) is a subtype of any other.
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 6. If there is a range, then the bitset type does not contain
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //    plain number bits.
707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(this->Length() >= 2);       // (1)
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->Get(0)->IsBitset());  // (2a)
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < this->Length(); ++i) {
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != 0) DCHECK(!this->Get(i)->IsBitset());  // (2b)
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != 1) DCHECK(!this->Get(i)->IsRange());   // (3)
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!this->Get(i)->IsUnion());               // (4)
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int j = 0; j < this->Length(); ++j) {
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (i != j && i != 0)
716109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(!this->Get(i)->SemanticIs(this->Get(j)));  // (5)
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!this->Get(1)->IsRange() ||
720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         (AstBitsetType::NumberBits(this->Get(0)->AsBitset()) ==
721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstBitsetType::kNone));  // (6)
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Union and intersection
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool AddIsSafe(int x, int y) {
729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return x >= 0 ? y <= std::numeric_limits<int>::max() - x
730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                : y >= std::numeric_limits<int>::min() - x;
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Intersect(AstType* type1, AstType* type2, Zone* zone) {
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: bit sets.
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsBitset() && type2->IsBitset()) {
736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::New(type1->AsBitset() & type2->AsBitset());
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: top or bottom types.
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsNone() || type2->IsAny()) return type1;  // Shortcut.
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->IsNone() || type1->IsAny()) return type2;  // Shortcut.
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Semi-fast case.
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->Is(type2)) return type1;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->Is(type1)) return type2;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Slow case: create union.
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Figure out the representation of the result first.
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The rest of the method should not change this representation and
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should not make any decisions based on representations (i.e.,
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should only use the semantic part of types).
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const bitset representation =
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type1->Representation() & type2->Representation();
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Semantic subtyping check - this is needed for consistency with the
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // semi-fast case above - we should behave the same way regardless of
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // representations. Intersection with a universal bitset should only update
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the representations.
760109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (type1->SemanticIs(type2)) {
761109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    type2 = Any();
762109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else if (type2->SemanticIs(type1)) {
763109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    type1 = Any();
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bitset bits =
767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation;
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
770109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size1, size2)) return Any();
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = size1 + size2;
772109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size, 2)) return Any();
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size += 2;
774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* result_type = AstUnionType::New(size, zone);
775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* result = result_type->AsUnion();
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size = 0;
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deal with bitsets.
779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  result->Set(size++, AstBitsetType::New(bits));
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits lims = AstRangeType::Limits::Empty();
782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = IntersectAux(type1, type2, result, size, &lims, zone);
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range is not empty, then insert it into the union and
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // remove the number bits from the bitset.
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!lims.IsEmpty()) {
787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    size = UpdateRange(AstRangeType::New(lims, representation, zone), result,
788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       size, zone);
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Remove the number bits.
791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset number_bits = AstBitsetType::NumberBits(bits);
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bits &= ~number_bits;
793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    result->Set(0, AstBitsetType::New(bits));
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return NormalizeUnion(result_type, size, zone);
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::UpdateRange(AstType* range, AstUnionType* result, int size,
799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         Zone* zone) {
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size == 1) {
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(size++, range);
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make space for the range.
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(size++, result->Get(1));
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->Set(1, range);
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Remove any components that just got subsumed.
809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int i = 2; i < size;) {
810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (result->Get(i)->SemanticIs(range)) {
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result->Set(i, result->Get(--size));
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ++i;
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstType::ToLimits(bitset bits, Zone* zone) {
820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset number_bits = AstBitsetType::NumberBits(bits);
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (number_bits == AstBitsetType::kNone) {
823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstRangeType::Limits::Empty();
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::Limits(AstBitsetType::Min(number_bits),
827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              AstBitsetType::Max(number_bits));
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstRangeType::Limits AstType::IntersectRangeAndBitset(AstType* range,
831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                      AstType* bitset,
832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                      Zone* zone) {
833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits range_lims(range->AsRange());
834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstRangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::Limits::Intersect(range_lims, bitset_lims);
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::IntersectAux(AstType* lhs, AstType* rhs, AstUnionType* result,
839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          int size, AstRangeType::Limits* lims, Zone* zone) {
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsUnion()) {
841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size =
843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rhs->IsUnion()) {
848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size =
850109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!AstBitsetType::SemanticIsInhabited(lhs->BitsetLub() &
856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          rhs->BitsetLub())) {
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsRange()) {
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsBitset()) {
862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstRangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!lim.IsEmpty()) {
865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *lims = AstRangeType::Limits::Union(lim, *lims);
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return size;
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsClass()) {
870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *lims = AstRangeType::Limits::Union(AstRangeType::Limits(lhs->AsRange()),
871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          *lims);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return AddToUnion(rhs, result, size, zone);
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (rhs->IsRange()) {
877f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstRangeType::Limits lim =
878f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AstRangeType::Limits::Intersect(AstRangeType::Limits(lhs->AsRange()),
879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          AstRangeType::Limits(rhs->AsRange()));
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!lim.IsEmpty()) {
881f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        *lims = AstRangeType::Limits::Union(lim, *lims);
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rhs->IsRange()) {
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This case is handled symmetrically above.
888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return IntersectAux(rhs, lhs, result, size, lims, zone);
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsBitset() || rhs->IsBitset()) {
891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (lhs->IsClass() != rhs->IsClass()) {
894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, zone);
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (lhs->SimplyEquals(rhs)) {
897109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddToUnion(lhs, result, size, zone);
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Make sure that we produce a well-formed range and bitset:
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If the range is non-empty, the number bits in the bitset should be
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clear. Moreover, if we have a canonical range (such as Signed32),
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// we want to produce a bitset rather than a range.
906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NormalizeRangeAndBitset(AstType* range, bitset* bits,
907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                          Zone* zone) {
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Fast path: If the bitset does not mention numbers, we can just keep the
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // range.
910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset number_bits = AstBitsetType::NumberBits(*bits);
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (number_bits == 0) {
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return range;
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range is semantically contained within the bitset, return None and
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // leave the bitset untouched.
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset range_lub = AST_SEMANTIC(range->BitsetLub());
918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (AstBitsetType::Is(range_lub, *bits)) {
919109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return None();
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Slow path: reconcile the bitset range and the range.
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  double bitset_min = AstBitsetType::Min(number_bits);
924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  double bitset_max = AstBitsetType::Max(number_bits);
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double range_min = range->Min();
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double range_max = range->Max();
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Remove the number bits from the bitset, they would just confuse us now.
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // case we already returned after the subtype check above.
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *bits &= ~number_bits;
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range_min <= bitset_min && range_max >= bitset_max) {
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Bitset is contained within the range, just return the range.
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return range;
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bitset_min < range_min) {
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range_min = bitset_min;
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (bitset_max > range_max) {
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range_max = bitset_max;
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstRangeType::New(range_min, range_max, AstBitsetType::kNone, zone);
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Union(AstType* type1, AstType* type2, Zone* zone) {
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: bit sets.
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsBitset() && type2->IsBitset()) {
951f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return AstBitsetType::New(type1->AsBitset() | type2->AsBitset());
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Fast case: top or bottom types.
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->IsAny() || type2->IsNone()) return type1;
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->IsAny() || type1->IsNone()) return type2;
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Semi-fast case.
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type1->Is(type2)) return type2;
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type2->Is(type1)) return type1;
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Figure out the representation of the result.
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The rest of the method should not change this representation and
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should not make any decisions based on representations (i.e.,
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it should only use the semantic part of types).
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const bitset representation =
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type1->Representation() | type2->Representation();
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Slow case: create union.
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
972109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size1, size2)) return Any();
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = size1 + size2;
974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!AddIsSafe(size, 2)) return Any();
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size += 2;
976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* result_type = AstUnionType::New(size, zone);
977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* result = result_type->AsUnion();
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size = 0;
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Compute the new bitset.
981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bitset new_bitset = AST_SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb());
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Deal with ranges.
984f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range = None();
985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range1 = type1->GetRange();
986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* range2 = type2->GetRange();
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (range1 != NULL && range2 != NULL) {
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstRangeType::Limits lims =
989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstRangeType::Limits::Union(AstRangeType::Limits(range1->AsRange()),
990f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    AstRangeType::Limits(range2->AsRange()));
991f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstType* union_range = AstRangeType::New(lims, representation, zone);
992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (range1 != NULL) {
994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (range2 != NULL) {
996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
998f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  new_bitset = AST_SEMANTIC(new_bitset) | representation;
999f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* bits = AstBitsetType::New(new_bitset);
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->Set(size++, bits);
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!range->IsNone()) result->Set(size++, range);
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = AddToUnion(type1, result, size, zone);
1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size = AddToUnion(type2, result, size, zone);
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return NormalizeUnion(result_type, size, zone);
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Add [type] to [result] unless [type] is bitset, range, or already subsumed.
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Return new size of [result].
1010f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::AddToUnion(AstType* type, AstUnionType* result, int size,
1011f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        Zone* zone) {
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsBitset() || type->IsRange()) return size;
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type->IsUnion()) {
1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
1015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return size;
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < size; ++i) {
1020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (type->SemanticIs(result->Get(i))) return size;
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->Set(size++, type);
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return size;
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1026f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::NormalizeUnion(AstType* union_type, int size, Zone* zone) {
1027f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstUnionType* unioned = union_type->AsUnion();
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(size >= 1);
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(unioned->Get(0)->IsBitset());
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the union has just one element, return it.
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size == 1) {
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return unioned->Get(0);
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bitset bits = unioned->Get(0)->AsBitset();
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the union only consists of a range, we can get rid of the union.
1036f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (size == 2 && AST_SEMANTIC(bits) == AstBitsetType::kNone) {
1037f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bitset representation = AST_REPRESENTATION(bits);
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (representation == unioned->Get(1)->Representation()) {
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return unioned->Get(1);
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (unioned->Get(1)->IsRange()) {
1042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return AstRangeType::New(unioned->Get(1)->AsRange()->Min(),
1043f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               unioned->Get(1)->AsRange()->Max(),
1044f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               unioned->Get(0)->AsBitset(), zone);
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unioned->Shrink(size);
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SLOW_DCHECK(unioned->Wellformed());
1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return union_type;
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Component extraction
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
1056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Representation(AstType* t, Zone* zone) {
1057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return AstBitsetType::New(t->Representation());
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// static
1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Semantic(AstType* t, Zone* zone) {
1062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Intersect(t, AstBitsetType::New(AstBitsetType::kSemantic), zone);
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -----------------------------------------------------------------------------
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Iteration.
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::NumClasses() {
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsClass()) {
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (this->IsUnion()) {
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int result = 0;
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (this->AsUnion()->Get(i)->IsClass()) ++result;
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint AstType::NumConstants() {
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (this->IsConstant()) {
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (this->IsUnion()) {
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int result = 0;
1089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (this->AsUnion()->Get(i)->IsConstant()) ++result;
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1098109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstType* AstType::Iterator<T>::get_type() {
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!Done());
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// C++ cannot specialise nested templates, so we have to go through this
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contortion with an auxiliary template to simulate it.
1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct TypeImplIteratorAux {
1108f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type);
1109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<T> current(AstType* type);
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <>
1113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct TypeImplIteratorAux<i::Map> {
1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type) { return type->IsClass(); }
1115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<i::Map> current(AstType* type) {
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsClass()->Map();
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <>
1121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct TypeImplIteratorAux<i::Object> {
1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static bool matches(AstType* type) { return type->IsConstant(); }
1123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static i::Handle<i::Object> current(AstType* type) {
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type->AsConstant()->Value();
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool AstType::Iterator<T>::matches(AstType* type) {
1130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return TypeImplIteratorAux<T>::matches(type);
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochi::Handle<T> AstType::Iterator<T>::Current() {
1135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return TypeImplIteratorAux<T>::current(get_type());
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <class T>
1139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::Iterator<T>::Advance() {
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ++index_;
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type_->IsUnion()) {
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) {
1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (matches(type_->AsUnion()->Get(index_))) return;
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (index_ == 0 && matches(type_)) {
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  index_ = -1;
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Printing.
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochconst char* AstBitsetType::Name(bitset bits) {
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (bits) {
1157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case AST_REPRESENTATION(kAny):
1158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return "Any";
1159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
1160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  case AST_REPRESENTATION(k##type):                   \
1161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return #type;
1162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_REPRESENTATION_BITSET_TYPE_LIST(RETURN_NAMED_REPRESENTATION_TYPE)
1163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef RETURN_NAMED_REPRESENTATION_TYPE
1164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define RETURN_NAMED_SEMANTIC_TYPE(type, value) \
1166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  case AST_SEMANTIC(k##type):                   \
1167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return #type;
1168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE)
1169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AST_INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE)
1170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#undef RETURN_NAMED_SEMANTIC_TYPE
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    default:
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return NULL;
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstBitsetType::Print(std::ostream& os,  // NOLINT
1178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          bitset bits) {
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* name = Name(bits);
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (name != NULL) {
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << name;
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // clang-format off
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const bitset named_bitsets[] = {
1188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define BITSET_CONSTANT(type, value) AST_REPRESENTATION(k##type),
1189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT)
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef BITSET_CONSTANT
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#define BITSET_CONSTANT(type, value) AST_SEMANTIC(k##type),
1193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
1194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AST_SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef BITSET_CONSTANT
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // clang-format on
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_first = true;
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "(";
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bitset subset = named_bitsets[i];
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((bits & subset) == subset) {
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!is_first) os << " | ";
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_first = false;
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << Name(subset);
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bits -= subset;
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(bits == 0);
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << ")";
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::PrintTo(std::ostream& os, PrintDimension dim) {
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DisallowHeapAllocation no_allocation;
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim != REPRESENTATION_DIM) {
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->IsBitset()) {
1218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBitsetType::Print(os, AST_SEMANTIC(this->AsBitset()));
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsClass()) {
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Class(" << static_cast<void*>(*this->AsClass()->Map()) << " < ";
1221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      AstBitsetType::New(AstBitsetType::Lub(this))->PrintTo(os, dim);
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsConstant()) {
1224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsRange()) {
1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::streamsize saved_precision = os.precision(0);
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         << ")";
1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os.flags(saved_flags);
1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os.precision(saved_precision);
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsContext()) {
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Context(";
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this->AsContext()->Outer()->PrintTo(os, dim);
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsUnion()) {
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "(";
1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstType* type_i = this->AsUnion()->Get(i);
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (i > 0) os << " | ";
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type_i->PrintTo(os, dim);
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsArray()) {
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "Array(";
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AsArray()->Element()->PrintTo(os, dim);
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")";
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (this->IsFunction()) {
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!this->AsFunction()->Receiver()->IsAny()) {
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->AsFunction()->Receiver()->PrintTo(os, dim);
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        os << ".";
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "(";
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < this->AsFunction()->Arity(); ++i) {
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (i > 0) os << ", ";
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->AsFunction()->Parameter(i)->PrintTo(os, dim);
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << ")->";
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this->AsFunction()->Result()->PrintTo(os, dim);
1260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else if (this->IsTuple()) {
1261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      os << "<";
1262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        AstType* type_i = this->AsTuple()->Element(i);
1264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (i > 0) os << ", ";
1265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        type_i->PrintTo(os, dim);
1266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      os << ">";
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim == BOTH_DIMS) os << "/";
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dim != SEMANTIC_DIM) {
1274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AstBitsetType::Print(os, AST_REPRESENTATION(this->BitsetLub()));
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstType::Print() {
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stdout);
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrintTo(os);
1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  os << std::endl;
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AstBitsetType::Print(bitset bits) {
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OFStream os(stdout);
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Print(os, bits);
1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  os << std::endl;
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstBitsetType::bitset AstBitsetType::SignedSmall() {
1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1293109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochAstBitsetType::bitset AstBitsetType::UnsignedSmall() {
1296109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// -----------------------------------------------------------------------------
1300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Instantiations.
1301f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate class AstType::Iterator<i::Map>;
1303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochtemplate class AstType::Iterator<i::Object>;
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
1307