1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 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
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <vector>
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/hydrogen-types.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate-inl.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/types.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing namespace v8::internal;
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Testing auxiliaries (breaking the Type abstraction).
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef uint32_t bitset;
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct ZoneRep {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef void* Struct;
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsStruct(Type* t, int tag) {
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsUnion(Type* t) { return IsStruct(t, 6); }
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Struct* AsStruct(Type* t) {
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Struct*>(t);
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bitset AsBitset(Type* t) {
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u);
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Struct* AsUnion(Type* t) {
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AsStruct(t);
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int Length(Struct* structured) {
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  struct BitsetType : Type::BitsetType {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using Type::BitsetType::New;
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using Type::BitsetType::Glb;
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using Type::BitsetType::Lub;
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using Type::BitsetType::IsInhabited;
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct HeapRep {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef FixedArray Struct;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsStruct(Handle<HeapType> t, int tag) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bitset AsBitset(Handle<HeapType> t) {
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t));
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int Length(Struct* structured) { return structured->length() - 1; }
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  struct BitsetType : HeapType::BitsetType {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using HeapType::BitsetType::New;
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using HeapType::BitsetType::Glb;
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using HeapType::BitsetType::Lub;
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using HeapType::BitsetType::IsInhabited;
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class Type, class TypeHandle, class Region>
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Types {
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Types(Region* region, Isolate* isolate)
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : region_(region), rng_(isolate->random_number_generator()) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    #define DECLARE_TYPE(name, value) \
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      name = Type::name(region); \
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      types.push_back(name);
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    #undef DECLARE_TYPE
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object_map = isolate->factory()->NewMap(
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JS_OBJECT_TYPE, JSObject::kHeaderSize);
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    array_map = isolate->factory()->NewMap(
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        JS_ARRAY_TYPE, JSArray::kSize);
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    number_map = isolate->factory()->NewMap(
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HEAP_NUMBER_TYPE, HeapNumber::kSize);
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uninitialized_map = isolate->factory()->uninitialized_map();
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectClass = Type::Class(object_map, region);
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ArrayClass = Type::Class(array_map, region);
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NumberClass = Type::Class(number_map, region);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UninitializedClass = Type::Class(uninitialized_map, region);
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maps.push_back(object_map);
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maps.push_back(array_map);
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maps.push_back(uninitialized_map);
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      types.push_back(Type::Class(*it, region));
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    smi = handle(Smi::FromInt(666), isolate);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    array = isolate->factory()->NewJSArray(20);
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uninitialized = isolate->factory()->uninitialized_value();
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiConstant = Type::Constant(smi, region);
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Signed32Constant = Type::Constant(signed32, region);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectConstant1 = Type::Constant(object1, region);
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectConstant2 = Type::Constant(object2, region);
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ArrayConstant = Type::Constant(array, region);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UninitializedConstant = Type::Constant(uninitialized, region);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(smi);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(signed32);
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(object1);
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(object2);
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(array);
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    values.push_back(uninitialized);
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      types.push_back(Type::Constant(*it, region));
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 10; ++i) {
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      double x = rng_->NextInt();
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      integers.push_back(isolate->factory()->NewNumber(x));
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      x *= rng_->NextInt();
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NumberArray = Type::Array(Number, region);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StringArray = Type::Array(String, region);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AnyArray = Type::Array(Any, region);
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NumberFunction1 = Type::Function(Number, Number, region);
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NumberFunction2 = Type::Function(Number, Number, Number, region);
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MethodFunction = Type::Function(String, Object, 0, region);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 30; ++i) {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      types.push_back(Fuzz());
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Map> object_map;
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Map> array_map;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Map> number_map;
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Map> uninitialized_map;
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Smi> smi;
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::HeapNumber> signed32;
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::JSObject> object1;
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::JSObject> object2;
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::JSArray> array;
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<i::Oddball> uninitialized;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  #define DECLARE_TYPE(name, value) TypeHandle name;
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BITSET_TYPE_LIST(DECLARE_TYPE)
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  #undef DECLARE_TYPE
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle ObjectClass;
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle ArrayClass;
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle NumberClass;
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle UninitializedClass;
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle SmiConstant;
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Signed32Constant;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle ObjectConstant1;
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle ObjectConstant2;
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle ArrayConstant;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle UninitializedConstant;
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle NumberArray;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle StringArray;
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle AnyArray;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle SignedFunction1;
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle NumberFunction1;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle NumberFunction2;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle MethodFunction;
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef std::vector<TypeHandle> TypeVector;
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef std::vector<Handle<i::Map> > MapVector;
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef std::vector<Handle<i::Object> > ValueVector;
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeVector types;
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapVector maps;
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ValueVector values;
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ValueVector integers;  // "Integer" values used for range limits.
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Of(Handle<i::Object> value) {
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Of(value, region_);
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle NowOf(Handle<i::Object> value) {
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::NowOf(value, region_);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Class(Handle<i::Map> map) {
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Class(map, region_);
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Constant(Handle<i::Object> value) {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Constant(value, region_);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Range(min, max, region_);
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Context(TypeHandle outer) {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Context(outer, region_);
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Array1(TypeHandle element) {
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Array(element, region_);
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Function(result, receiver, 0, region_);
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TypeHandle type = Type::Function(result, receiver, 1, region_);
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    type->AsFunction()->InitParameter(0, arg);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return type;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Function(result, arg1, arg2, region_);
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Union(TypeHandle t1, TypeHandle t2) {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Union(t1, t2, region_);
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::Intersect(t1, t2, region_);
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class Type2, class TypeHandle2>
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Convert(TypeHandle2 t) {
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Type::template Convert<Type2>(t, region_);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Random() {
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return types[rng_->NextInt(static_cast<int>(types.size()))];
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeHandle Fuzz(int depth = 4) {
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 0: {  // bitset
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int n = 0
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        #define COUNT_BITSET_TYPES(type, value) + 1
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        #undef COUNT_BITSET_TYPES
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ;
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int i = rng_->NextInt(n);
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        #define PICK_BITSET_TYPE(type, value) \
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (i-- == 0) return Type::type(region_);
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        #undef PICK_BITSET_TYPE
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 1: {  // class
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int i = rng_->NextInt(static_cast<int>(maps.size()));
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Type::Class(maps[i], region_);
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 2: {  // constant
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int i = rng_->NextInt(static_cast<int>(values.size()));
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Type::Constant(values[i], region_);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 3: {  // range
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int i = rng_->NextInt(static_cast<int>(integers.size()));
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int j = rng_->NextInt(static_cast<int>(integers.size()));
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> min = integers[i];
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> max = integers[j];
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (min->Number() > max->Number()) std::swap(min, max);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Type::Range(min, max, region_);
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 4: {  // context
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int depth = rng_->NextInt(3);
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = Type::Internal(region_);
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return type;
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 5: {  // array
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle element = Fuzz(depth / 2);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Type::Array(element, region_);
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 6:
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case 7: {  // function
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle result = Fuzz(depth / 2);
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle receiver = Fuzz(depth / 2);
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int arity = rng_->NextInt(3);
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = Type::Function(result, receiver, arity, region_);
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle parameter = Fuzz(depth / 2);
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          type->AsFunction()->InitParameter(i, parameter);
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return type;
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default: {  // union
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int n = rng_->NextInt(10);
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = None;
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int i = 0; i < n; ++i) {
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle operand = Fuzz(depth - 1);
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          type = Type::Union(type, operand, region_);
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return type;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Region* region() { return region_; }
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Region* region_;
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::base::RandomNumberGenerator* rng_;
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class Type, class TypeHandle, class Region, class Rep>
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct Tests : Rep {
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef Types<Type, TypeHandle, Region> TypesInstance;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef typename TypesInstance::TypeVector::iterator TypeIterator;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef typename TypesInstance::MapVector::iterator MapIterator;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef typename TypesInstance::ValueVector::iterator ValueIterator;
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate;
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope;
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone zone;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypesInstance T;
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Tests() :
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate(CcTest::i_isolate()),
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      scope(isolate),
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      zone(isolate),
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      T(Rep::ToRegion(&zone, isolate), isolate) {
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Equal(TypeHandle type1, TypeHandle type2) {
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type1->Equals(type2) &&
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->IsBitset(type1) == this->IsBitset(type2) &&
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        this->IsUnion(type1) == this->IsUnion(type2) &&
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type1->NumClasses() == type2->NumClasses() &&
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type1->NumConstants() == type2->NumConstants() &&
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (!this->IsBitset(type1) ||
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          this->AsBitset(type1) == this->AsBitset(type2)) &&
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (!this->IsUnion(type1) ||
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          this->Length(this->AsUnion(type1)) ==
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->Length(this->AsUnion(type2)));
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckEqual(TypeHandle type1, TypeHandle type2) {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(Equal(type1, type2));
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckSub(TypeHandle type1, TypeHandle type2) {
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(type1->Is(type2));
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type2->Is(type1));
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->IsBitset(type1) && this->IsBitset(type2)) {
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(this->AsBitset(type1) != this->AsBitset(type2));
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckUnordered(TypeHandle type1, TypeHandle type2) {
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type1->Is(type2));
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type2->Is(type1));
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (this->IsBitset(type1) && this->IsBitset(type2)) {
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(this->AsBitset(type1) != this->AsBitset(type2));
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckOverlap(TypeHandle type1, TypeHandle type2) {
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(type1->Maybe(type2));
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(type2->Maybe(type1));
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type1->Is(type2));
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type2->Is(type1));
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type1->Maybe(type2));
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!type2->Maybe(type1));
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void IsSomeType() {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle t = *it;
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(1 ==
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() +
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          this->IsUnion(t) + t->IsArray() + t->IsFunction() + t->IsContext());
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Bitset() {
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // None and Any are bitsets.
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsBitset(T.None));
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsBitset(T.Any));
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(bitset(0) == this->AsBitset(T.None));
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any));
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union(T1, T2) is bitset for bitsets T1,T2
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->IsBitset(union12));
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intersect(T1, T2) is bitset for bitsets T1,T2
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->IsBitset(intersect12));
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2)
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->IsBitset(union12));
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (this->IsBitset(type1) && this->IsBitset(type2)) {
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (this->AsBitset(type1) | this->AsBitset(type2)) ==
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->AsBitset(union12));
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None)
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (this->IsBitset(type1) && this->IsBitset(type2)) {
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          bitset bits = this->AsBitset(type1) & this->AsBitset(type2);
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (Rep::BitsetType::IsInhabited(bits) ? bits : 0) ==
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->AsBitset(intersect12));
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Class() {
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constructor
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Map> map = *mt;
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Class(map);
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->IsClass());
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Map attribute
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Map> map = *mt;
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Class(map);
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(*map == *type->AsClass()->Map());
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map1 = *mt1;
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map2 = *mt2;
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Class(map1);
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Class(map2);
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(Equal(type1, type2) == (*map1 == *map2));
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Constant() {
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constructor
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Object> value = *vt;
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Constant(value);
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->IsConstant());
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Value attribute
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Object> value = *vt;
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Constant(value);
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(*value == *type->AsConstant()->Value());
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value1 = *vt1;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value2 = *vt2;
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Constant(value1);
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Constant(value2);
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(Equal(type1, type2) == (*value1 == *value2));
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Typing of numbers
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Factory* fac = isolate->factory();
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre31Bits()) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(SmiValuesAre32Bits());
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Range() {
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constructor
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> min = *i;
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> max = *j;
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (min->Number() > max->Number()) std::swap(min, max);
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = T.Range(min, max);
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type->IsRange());
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Range attributes
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> min = *i;
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object> max = *j;
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (min->Number() > max->Number()) std::swap(min, max);
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = T.Range(min, max);
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(*min == *type->AsRange()->Min());
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(*max == *type->AsRange()->Max());
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Functionality & Injectivity:
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator i1 = T.integers.begin();
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i1 != T.integers.end(); ++i1) {
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator j1 = T.integers.begin();
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          j1 != T.integers.end(); ++j1) {
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (ValueIterator i2 = T.integers.begin();
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i2 != T.integers.end(); ++i2) {
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (ValueIterator j2 = T.integers.begin();
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              j2 != T.integers.end(); ++j2) {
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> min1 = *i1;
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> max1 = *j1;
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> min2 = *i2;
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> max2 = *j2;
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (min1->Number() > max1->Number()) std::swap(min1, max1);
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (min2->Number() > max2->Number()) std::swap(min2, max2);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeHandle type1 = T.Range(min1, max1);
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeHandle type2 = T.Range(min2, max2);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            CHECK(Equal(type1, type2) == (*min1 == *min2 && *max1 == *max2));
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Array() {
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constructor
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Random();
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle array = T.Array1(type);
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(array->IsArray());
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Attributes
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = T.Random();
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle array = T.Array1(type);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(type, array->AsArray()->Element());
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int j = 0; j < 20; ++j) {
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Random();
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Random();
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle array1 = T.Array1(type1);
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle array2 = T.Array1(type2);
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(Equal(array1, array2) == Equal(type1, type2));
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Function() {
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constructors
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int j = 0; j < 20; ++j) {
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int k = 0; k < 20; ++k) {
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = T.Random();
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = T.Random();
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = T.Random();
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function0 = T.Function0(type1, type2);
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function1 = T.Function1(type1, type2, type3);
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function2 = T.Function2(type1, type2, type3);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(function0->IsFunction());
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(function1->IsFunction());
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(function2->IsFunction());
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Attributes
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int j = 0; j < 20; ++j) {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int k = 0; k < 20; ++k) {
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = T.Random();
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = T.Random();
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = T.Random();
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function0 = T.Function0(type1, type2);
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function1 = T.Function1(type1, type2, type3);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function2 = T.Function2(type1, type2, type3);
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK_EQ(0, function0->AsFunction()->Arity());
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK_EQ(1, function1->AsFunction()->Arity());
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK_EQ(2, function2->AsFunction()->Arity());
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type1, function0->AsFunction()->Result());
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type1, function1->AsFunction()->Result());
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type1, function2->AsFunction()->Result());
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type2, function0->AsFunction()->Receiver());
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type2, function1->AsFunction()->Receiver());
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(T.Any, function2->AsFunction()->Receiver());
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type3, function1->AsFunction()->Parameter(0));
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type2, function2->AsFunction()->Parameter(0));
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(type3, function2->AsFunction()->Parameter(1));
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < 20; ++i) {
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int j = 0; j < 20; ++j) {
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int k = 0; k < 20; ++k) {
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = T.Random();
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = T.Random();
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = T.Random();
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function01 = T.Function0(type1, type2);
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function02 = T.Function0(type1, type3);
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function03 = T.Function0(type3, type2);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function11 = T.Function1(type1, type2, type2);
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function12 = T.Function1(type1, type2, type3);
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function21 = T.Function2(type1, type2, type2);
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function22 = T.Function2(type1, type2, type3);
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle function23 = T.Function2(type1, type3, type2);
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(function01, function02) == Equal(type2, type3));
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(function01, function03) == Equal(type1, type3));
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(function11, function12) == Equal(type2, type3));
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(function21, function22) == Equal(type2, type3));
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(function21, function23) == Equal(type2, type3));
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Of() {
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V)->Is(Of(V))
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Object> value = *vt;
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle const_type = T.Constant(value);
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle of_type = T.Of(value);
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(const_type->Is(of_type));
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If Of(V)->Is(T), then Constant(V)->Is(T)
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle of_type = T.Of(value);
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!of_type->Is(type) || const_type->Is(type));
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V))
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle of_type = T.Of(value);
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!const_type->Is(type) ||
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              of_type->Is(type) || type->Maybe(const_type));
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void NowOf() {
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V)->NowIs(NowOf(V))
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Object> value = *vt;
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle const_type = T.Constant(value);
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle nowof_type = T.NowOf(value);
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(const_type->NowIs(nowof_type));
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // NowOf(V)->Is(Of(V))
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<i::Object> value = *vt;
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle nowof_type = T.NowOf(value);
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle of_type = T.Of(value);
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(nowof_type->Is(of_type));
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T)
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle nowof_type = T.NowOf(value);
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type));
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If Constant(V)->NowIs(T),
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle nowof_type = T.NowOf(value);
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!const_type->NowIs(type) ||
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              nowof_type->NowIs(type) || type->Maybe(const_type));
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If Constant(V)->Is(T),
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // then NowOf(V)->Is(T) or T->Maybe(Constant(V))
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle nowof_type = T.NowOf(value);
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!const_type->Is(type) ||
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              nowof_type->Is(type) || type->Maybe(const_type));
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BitsetGlb() {
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Lower: (T->BitsetGlb())->Is(T)
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle glb =
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(glb->Is(type));
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb())
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle glb2 =
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2));
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb())
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle glb1 =
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Glb(type1), T.region());
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle glb2 =
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Is(type2) || glb1->Is(glb2));
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BitsetLub() {
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Upper: T->Is(T->BitsetLub())
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle lub =
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->Is(lub));
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2)
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle lub1 =
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2));
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub())
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle lub1 =
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle lub2 =
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            Rep::BitsetType::New(Rep::BitsetType::Lub(type2), T.region());
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Is(type2) || lub1->Is(lub2));
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Is() {
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Least Element (Bottom): None->Is(T)
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.None->Is(type));
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Greatest Element (Top): T->Is(Any)
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->Is(T.Any));
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bottom Uniqueness: T->Is(None) implies T = None
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (type->Is(T.None)) CheckEqual(type, T.None);
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Top Uniqueness: Any->Is(T) implies T = Any
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (T.Any->Is(type)) CheckEqual(type, T.Any);
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Reflexivity: T->Is(T)
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->Is(type));
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class(M1)->Is(Class(M2)) iff M1 = M2
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map1 = *mt1;
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map2 = *mt2;
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type1 = T.Class(map1);
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type2 = T.Class(map2);
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V1)->Is(Constant(V2)) iff V1 = V2
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value1 = *vt1;
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value2 = *vt2;
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type1 = T.Constant(value1);
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type2 = T.Constant(value2);
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Range(min1, max1)->Is(Range(min2, max2)) iff
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // min1 >= min2 /\ max1 <= max2
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator i1 = T.integers.begin();
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i1 != T.integers.end(); ++i1) {
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator j1 = T.integers.begin();
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          j1 != T.integers.end(); ++j1) {
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (ValueIterator i2 = T.integers.begin();
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             i2 != T.integers.end(); ++i2) {
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          for (ValueIterator j2 = T.integers.begin();
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               j2 != T.integers.end(); ++j2) {
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> min1 = *i1;
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> max1 = *j1;
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> min2 = *i2;
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            i::Handle<i::Object> max2 = *j2;
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (min1->Number() > max1->Number()) std::swap(min1, max1);
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (min2->Number() > max2->Number()) std::swap(min2, max2);
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeHandle type1 = T.Range(min1, max1);
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            TypeHandle type2 = T.Range(min2, max2);
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            CHECK(type1->Is(type2) ==
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                (min2->Number() <= min1->Number() &&
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 max1->Number() <= max2->Number()));
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Context(T1)->Is(Context(T2)) iff T1 = T2
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle outer1 = *it1;
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle outer2 = *it2;
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Context(outer1);
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Context(outer2);
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type1->Is(type2) == outer1->Equals(outer2));
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Array(T1)->Is(Array(T2)) iff T1 = T2
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle element1 = *it1;
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle element2 = *it2;
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Array1(element1);
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Array1(element2);
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type1->Is(type2) == element1->Equals(element2));
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle result1 = *i;
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle receiver1 = *j;
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = T.Function0(result1, receiver1);
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle result2 = T.Random();
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle receiver2 = T.Random();
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = T.Function0(result2, receiver2);
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type1->Is(type2) ==
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            (result1->Equals(result2) && receiver1->Equals(receiver2)));
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (In-)Compatibilities.
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *i;
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *j;
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Is(type2) || this->IsBitset(type2) ||
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              this->IsUnion(type2) || this->IsUnion(type1) ||
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsClass() && type2->IsClass()) ||
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsConstant() && type2->IsConstant()) ||
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsConstant() && type2->IsRange()) ||
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsRange() && type2->IsRange()) ||
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsContext() && type2->IsContext()) ||
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsArray() && type2->IsArray()) ||
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsFunction() && type2->IsFunction()) ||
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              type1->Equals(T.None));
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Basic types
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Boolean, T.Null);
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Undefined, T.Null);
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Boolean, T.Undefined);
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.SignedSmall, T.Number);
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Signed32, T.Number);
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.SignedSmall, T.Signed32);
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.SignedSmall, T.MinusZero);
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Signed32, T.Unsigned32);
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.UniqueName, T.Name);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.String, T.Name);
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.InternalizedString, T.String);
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.InternalizedString, T.UniqueName);
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.InternalizedString, T.Name);
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Symbol, T.UniqueName);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Symbol, T.Name);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.String, T.UniqueName);
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.String, T.Symbol);
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.InternalizedString, T.Symbol);
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Object, T.Receiver);
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Array, T.Object);
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Function, T.Object);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Proxy, T.Receiver);
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Object, T.Proxy);
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Array, T.Function);
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Structural types
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ObjectClass, T.Object);
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ArrayClass, T.Object);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ArrayClass, T.Array);
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.UninitializedClass, T.Internal);
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectClass, T.ArrayClass);
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.UninitializedClass, T.Null);
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.UninitializedClass, T.Undefined);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.SmiConstant, T.SignedSmall);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.SmiConstant, T.Signed32);
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.SmiConstant, T.Number);
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ObjectConstant1, T.Object);
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ObjectConstant2, T.Object);
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ArrayConstant, T.Object);
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.ArrayConstant, T.Array);
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.UninitializedConstant, T.Internal);
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.UninitializedConstant, T.Null);
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.UninitializedConstant, T.Undefined);
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant1, T.ObjectClass);
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant2, T.ObjectClass);
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant1, T.ArrayClass);
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectConstant2, T.ArrayClass);
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ArrayConstant, T.ObjectClass);
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.NumberArray, T.Array);
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.NumberArray, T.Object);
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.StringArray, T.AnyArray);
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.MethodFunction, T.Function);
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.NumberFunction1, T.Object);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.SignedFunction1, T.NumberFunction1);
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.NumberFunction1, T.NumberFunction2);
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void NowIs() {
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Least Element (Bottom): None->NowIs(T)
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(T.None->NowIs(type));
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Greatest Element (Top): T->NowIs(Any)
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->NowIs(T.Any));
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bottom Uniqueness: T->NowIs(None) implies T = None
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (type->NowIs(T.None)) CheckEqual(type, T.None);
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Top Uniqueness: Any->NowIs(T) implies T = Any
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (T.Any->NowIs(type)) CheckEqual(type, T.Any);
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Reflexivity: T->NowIs(T)
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->NowIs(type));
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3)
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) ||
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                type1->NowIs(type3));
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK((type1->NowIs(type2) && type2->NowIs(type1)) ==
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              Equal(type1, type2));
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T1->Is(T2) implies T1->NowIs(T2)
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Is(type2) || type1->NowIs(type2));
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value1 = *vt1;
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value2 = *vt2;
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type1 = T.Constant(value1);
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type2 = T.Constant(value2);
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2));
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class(M1)->NowIs(Class(M2)) iff M1 = M2
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map1 = *mt1;
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map2 = *mt2;
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type1 = T.Class(map1);
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type2 = T.Class(map2);
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2));
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V)->NowIs(Class(M)) iff V has map M
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map = *mt;
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type = T.Class(map);
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK((value->IsHeapObject() &&
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               i::HeapObject::cast(*value)->map() == *map)
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              == const_type->NowIs(class_type));
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class(M)->NowIs(Constant(V)) never
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map = *mt;
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type = T.Class(map);
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!class_type->NowIs(const_type));
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Contains() {
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T->Contains(V) iff Constant(V)->Is(T)
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type->Contains(value) == const_type->Is(type));
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void NowContains() {
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T->NowContains(V) iff Constant(V)->NowIs(T)
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type->NowContains(value) == const_type->NowIs(type));
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T->Contains(V) implies T->NowContains(V)
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type->Contains(value) || type->NowContains(value));
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // NowOf(V)->Is(T) implies T->NowContains(V)
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type = *it;
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle nowof_type = T.Of(value);
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Maybe() {
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T->Maybe(Any) iff T inhabited
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->Maybe(T.Any) == type->IsInhabited());
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T->Maybe(None) never
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(!type->Maybe(T.None));
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CHECK(type->Maybe(type) == type->IsInhabited());
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type1->Maybe(type2) == type2->Maybe(type1));
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T1->Maybe(T2) implies T1, T2 inhabited
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Maybe(type2) ||
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              (type1->IsInhabited() && type2->IsInhabited()));
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2)
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              type1->Maybe(type2));
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value1 = *vt1;
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value2 = *vt2;
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type1 = T.Constant(value1);
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type2 = T.Constant(value2);
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class(M1)->Maybe(Class(M2)) iff M1 = M2
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map1 = *mt1;
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map2 = *mt2;
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type1 = T.Class(map1);
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type2 = T.Class(map2);
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant(V)->Maybe(Class(M)) never
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold!
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map = *mt;
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type = T.Class(map);
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!const_type->Maybe(class_type));
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class(M)->Maybe(Constant(V)) never
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold!
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Map> map = *mt;
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<i::Object> value = *vt;
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle const_type = T.Constant(value);
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle class_type = T.Class(map);
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!class_type->Maybe(const_type));
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Basic types
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Boolean, T.Null);
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Undefined, T.Null);
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Boolean, T.Undefined);
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.SignedSmall, T.Number);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.NaN, T.Number);
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Signed32, T.NaN);
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.UniqueName, T.Name);
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.String, T.Name);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.InternalizedString, T.String);
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.InternalizedString, T.UniqueName);
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.InternalizedString, T.Name);
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Symbol, T.UniqueName);
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Symbol, T.Name);
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.String, T.UniqueName);
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.String, T.Symbol);
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.InternalizedString, T.Symbol);
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Object, T.Receiver);
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Array, T.Object);
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Function, T.Object);
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Proxy, T.Receiver);
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Object, T.Proxy);
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Array, T.Function);
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Structural types
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectClass, T.Object);
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ArrayClass, T.Object);
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectClass, T.ObjectClass);
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ArrayClass, T.ArrayClass);
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ObjectClass, T.ArrayClass);
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.SmiConstant, T.SignedSmall);
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.SmiConstant, T.Signed32);
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.SmiConstant, T.Number);
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectConstant1, T.Object);
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectConstant2, T.Object);
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ArrayConstant, T.Object);
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ArrayConstant, T.Array);
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ObjectConstant1, T.ArrayConstant);
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.ArrayConstant, T.ObjectClass);
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.NumberArray, T.Array);
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.NumberArray, T.AnyArray);
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.NumberArray, T.StringArray);
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.MethodFunction, T.Function);
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.SignedFunction1, T.NumberFunction1);
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.SignedFunction1, T.NumberFunction2);
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.NumberFunction1, T.NumberFunction2);
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.SignedFunction1, T.MethodFunction);
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectConstant1, T.ObjectClass);  // !!!
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.ObjectConstant2, T.ObjectClass);  // !!!
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Untagged));  // !!!
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Union1() {
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Identity: Union(T, None) = T
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle union_type = T.Union(type, T.None);
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(union_type, type);
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Domination: Union(T, Any) = Any
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle union_type = T.Union(type, T.Any);
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(union_type, T.Any);
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Idempotence: Union(T, T) = T
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle union_type = T.Union(type, type);
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(union_type, type);
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Commutativity: Union(T1, T2) = Union(T2, T1)
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union21 = T.Union(type2, type1);
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CheckEqual(union12, union21);
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold!
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union12 = T.Union(type1, type2);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union23 = T.Union(type2, type3);
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union1_23 = T.Union(type1, union23);
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union12_3 = T.Union(union12, type3);
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(union1_23, union12_3);
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type1->Is(union12));
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(type2->Is(union12));
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle union12 = T.Union(type1, type2);
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (type1->Is(type2)) CheckEqual(union12, type2);
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union13 = T.Union(type1, type3);
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union23 = T.Union(type2, type3);
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!type1->Is(type2) || union13->Is(union23));
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Union2() {
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.  TODO(neis): Could fix this by splitting
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // OtherNumber into a negative and a positive part.
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union12 = T.Union(type1, type2);
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Union3() {
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union23 = T.Union(type2, type3);
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Union4() {
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class-class
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant-constant
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number);
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass);  // !!!
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-array
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Union(T.NumberArray, T.String), T.Object);
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number);
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-function
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object);
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number);
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-class
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-constant
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class-constant
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckDisjoint(
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckOverlap(
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);  // !!!
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-union
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.NaN,
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class-union
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Object);
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ArrayClass, T.ObjectConstant2));
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant-union
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant2, T.ObjectConstant1));
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Array-union
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.AnyArray, T.NumberArray));
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array);
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Function-union
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.NumberFunction1, T.NumberFunction2),
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.NumberFunction2, T.NumberFunction1));
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union-union
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ObjectConstant2, T.ObjectConstant1),
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant2, T.ObjectConstant1));
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.Number, T.ArrayClass),
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.SignedSmall, T.Array)),
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.Number, T.Array));
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Intersect() {
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Identity: Intersect(T, Any) = T
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle intersect_type = T.Intersect(type, T.Any);
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(intersect_type, type);
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Domination: Intersect(T, None) = None
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle intersect_type = T.Intersect(type, T.None);
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(intersect_type, T.None);
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Idempotence: Intersect(T, T) = T
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type = *it;
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle intersect_type = T.Intersect(type, type);
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(intersect_type, type);
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect21 = T.Intersect(type2, type1);
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CheckEqual(intersect12, intersect21);
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Associativity:
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect12 = T.Intersect(type1, type2);
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect23 = T.Intersect(type2, type3);
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckEqual(intersect1_23, intersect12_3);
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.  Not even the disjunction.
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(intersect12->Is(type1));
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(intersect12->Is(type2));
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle intersect12 = T.Intersect(type1, type2);
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (type1->Is(type2)) CheckEqual(intersect12, type1);
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect13 = T.Intersect(type1, type3);
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect23 = T.Intersect(type2, type3);
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect12 = T.Intersect(type1, type2);
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                intersect12->Is(type3));
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect23 = T.Intersect(type2, type3);
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                type1->Is(intersect23));
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-class
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-array
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None);
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-function
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(T.Intersect(T.NumberFunction1, T.Array), T.None);
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bitset-union
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant1, T.ObjectClass));
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ->IsInhabited());
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class-constant
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited());  // !!!
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Array-union
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.NumberArray);
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.AnyArray);
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ->IsInhabited());
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Function-union
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.MethodFunction);
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.NumberFunction1);
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ->IsInhabited());
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Class-union
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.ArrayClass);
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.ArrayClass);
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            ->IsInhabited());  // !!!
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Constant-union
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.ObjectConstant1);
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.SmiConstant);
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CHECK(
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                ->IsInhabited());  // !!!
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union-union
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.Number, T.ArrayClass),
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.SignedSmall, T.Array)),
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.SignedSmall, T.ArrayClass));
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.Number, T.ObjectClass),
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.Signed32, T.Array)),
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Signed32);
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ObjectConstant2, T.ObjectConstant1),
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(T.ObjectConstant2, T.ObjectConstant1));
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckEqual(
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Intersect(
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                T.ArrayClass,
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                T.Union(T.ObjectConstant2, T.ObjectConstant1)),
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                T.ObjectConstant1,
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                T.Union(T.ArrayConstant, T.ObjectConstant2))),
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        T.Union(
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.ArrayConstant,
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            T.Union(T.ObjectConstant2, T.ObjectConstant1)));  // !!!
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Distributivity() {
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union12 = T.Union(type1, type2);
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union13 = T.Union(type1, type3);
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect23 = T.Intersect(type2, type3);
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union1_23 = T.Union(type1, intersect23);
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect12_13 = T.Intersect(union12, union13);
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(union1_23, intersect12_13));
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This does NOT hold.
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    /*
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type1 = *it1;
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type2 = *it2;
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle type3 = *it3;
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect12 = T.Intersect(type1, type2);
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect13 = T.Intersect(type1, type3);
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union23 = T.Union(type2, type3);
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle intersect1_23 = T.Intersect(type1, union23);
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          TypeHandle union12_13 = T.Union(intersect12, intersect13);
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(Equal(intersect1_23, union12_13));
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    */
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<class Type2, class TypeHandle2, class Region2, class Rep2>
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Convert() {
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Types<Type2, TypeHandle2, Region2> T2(
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Rep2::ToRegion(&zone, isolate), isolate);
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type1 = *it;
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle2 type2 = T2.template Convert<Type>(type1);
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TypeHandle type3 = T.template Convert<Type2>(type2);
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CheckEqual(type1, type3);
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void HTypeFromType() {
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type1 = *it1;
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TypeHandle type2 = *it2;
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HType htype1 = HType::FromType<Type>(type1);
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        HType htype2 = HType::FromType<Type>(type2);
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(IsSomeType) {
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().IsSomeType();
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().IsSomeType();
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(BitsetType) {
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Bitset();
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Bitset();
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ClassType) {
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Class();
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Class();
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ConstantType) {
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Constant();
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Constant();
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(RangeType) {
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Range();
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Range();
1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ArrayType) {
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Array();
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Array();
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(FunctionType) {
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Function();
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Function();
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Of) {
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Of();
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Of();
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(NowOf) {
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().NowOf();
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().NowOf();
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(BitsetGlb) {
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().BitsetGlb();
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().BitsetGlb();
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(BitsetLub) {
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().BitsetLub();
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().BitsetLub();
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Is) {
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Is();
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Is();
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(NowIs) {
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().NowIs();
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().NowIs();
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Contains) {
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Contains();
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Contains();
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(NowContains) {
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().NowContains();
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().NowContains();
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Maybe) {
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Maybe();
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Maybe();
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Union1) {
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Union1();
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Union1();
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/*
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Union2) {
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Union2();
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Union2();
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch*/
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Union3) {
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Union3();
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Union3();
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Union4) {
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Union4();
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Union4();
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Intersect) {
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Intersect();
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Intersect();
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch/*
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Distributivity) {
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Distributivity();
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Distributivity();
2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch*/
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Convert) {
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HTypeFromType) {
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CcTest::InitializeVM();
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneTests().HTypeFromType();
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapTests().HTypeFromType();
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2122