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