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 
12 using namespace v8::internal;
13 
14 
15 // Testing auxiliaries (breaking the Type abstraction).
16 
17 
IsInteger(double x)18 static bool IsInteger(double x) {
19   return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
20 }
21 
22 
IsInteger(i::Object * x)23 static bool IsInteger(i::Object* x) {
24   return x->IsNumber() && IsInteger(x->Number());
25 }
26 
27 
28 typedef uint32_t bitset;
29 
30 
31 struct ZoneRep {
32   typedef void* Struct;
33 
IsStructZoneRep34   static bool IsStruct(Type* t, int tag) {
35     return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
36   }
IsBitsetZoneRep37   static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
38   // HACK: the number 5 below is the value of StructuralType::kUnionTag.
IsUnionZoneRep39   static bool IsUnion(Type* t) { return t->IsUnionForTesting(); }
40 
AsStructZoneRep41   static Struct* AsStruct(Type* t) {
42     return reinterpret_cast<Struct*>(t);
43   }
AsBitsetZoneRep44   static bitset AsBitset(Type* t) {
45     return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u);
46   }
AsUnionZoneRep47   static Struct* AsUnion(Type* t) {
48     return AsStruct(t);
49   }
LengthZoneRep50   static int Length(Struct* structured) {
51     return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
52   }
53 
ToRegionZoneRep54   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 
65 struct HeapRep {
66   typedef FixedArray Struct;
67 
IsStructHeapRep68   static bool IsStruct(Handle<HeapType> t, int tag) {
69     return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
70   }
IsBitsetHeapRep71   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
72   // HACK: the number 5 below is the value of StructuralType::kUnionTag.
IsUnionHeapRep73   static bool IsUnion(Handle<HeapType> t) { return t->IsUnionForTesting(); }
74 
AsStructHeapRep75   static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
AsBitsetHeapRep76   static bitset AsBitset(Handle<HeapType> t) {
77     return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t));
78   }
AsUnionHeapRep79   static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
LengthHeapRep80   static int Length(Struct* structured) { return structured->length() - 1; }
81 
ToRegionHeapRep82   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;
GlbHeapRep::BitsetType89     static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
LubHeapRep::BitsetType90     static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
91   };
92 };
93 
94 
95 template<class Type, class TypeHandle, class Region, class Rep>
96 struct 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 
TestsTests107   Tests()
108       : isolate(CcTest::InitIsolateOnce()),
109         scope(isolate),
110         zone(),
111         T(Rep::ToRegion(&zone, isolate), isolate,
112           isolate->random_number_generator()) {}
113 
EqualTests114   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 
CheckEqualTests128   void CheckEqual(TypeHandle type1, TypeHandle type2) {
129     CHECK(Equal(type1, type2));
130   }
131 
CheckSubTests132   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 
CheckSubOrEqualTests140   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 
CheckUnorderedTests148   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 
CheckOverlapTests156   void CheckOverlap(TypeHandle type1, TypeHandle type2) {
157     CHECK(type1->Maybe(type2));
158     CHECK(type2->Maybe(type1));
159   }
160 
CheckDisjointTests161   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 
IsSomeTypeTests168   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 
BitsetTests177   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 
PointwiseRepresentationTests246   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 
ClassTests316   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 
ConstantTests343   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 
RangeTests420   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 
ContextTests469   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 
ArrayTests496   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 
FunctionTests523   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 
OfTests592   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 
NowOfTests625   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 
MinMaxTests680   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 
BitsetGlbTests737   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 
BitsetLubTests771   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 
Is1Tests805   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 
Is2Tests877   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 
NowIsTests1068   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 
ContainsTests1178   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 
NowContainsTests1190   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 
MaybeTests1221   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 
Union1Tests1383   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 
Union2Tests1478   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 
Union3Tests1499   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 
Union4Tests1515   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 
IntersectTests1628   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 
DistributivityTests1863   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 
GetRangeTests1912   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>
ConvertTests1939   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 
HTypeFromTypeTests1951   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 
1964 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1965 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1966 
1967 
TEST(IsSomeType_zone)1968 TEST(IsSomeType_zone) { ZoneTests().IsSomeType(); }
1969 
1970 
TEST(IsSomeType_heap)1971 TEST(IsSomeType_heap) { HeapTests().IsSomeType(); }
1972 
1973 
TEST(PointwiseRepresentation_zone)1974 TEST(PointwiseRepresentation_zone) { ZoneTests().PointwiseRepresentation(); }
1975 
1976 
TEST(PointwiseRepresentation_heap)1977 TEST(PointwiseRepresentation_heap) { HeapTests().PointwiseRepresentation(); }
1978 
1979 
TEST(BitsetType_zone)1980 TEST(BitsetType_zone) { ZoneTests().Bitset(); }
1981 
1982 
TEST(BitsetType_heap)1983 TEST(BitsetType_heap) { HeapTests().Bitset(); }
1984 
1985 
TEST(ClassType_zone)1986 TEST(ClassType_zone) { ZoneTests().Class(); }
1987 
1988 
TEST(ClassType_heap)1989 TEST(ClassType_heap) { HeapTests().Class(); }
1990 
1991 
TEST(ConstantType_zone)1992 TEST(ConstantType_zone) { ZoneTests().Constant(); }
1993 
1994 
TEST(ConstantType_heap)1995 TEST(ConstantType_heap) { HeapTests().Constant(); }
1996 
1997 
TEST(RangeType_zone)1998 TEST(RangeType_zone) { ZoneTests().Range(); }
1999 
2000 
TEST(RangeType_heap)2001 TEST(RangeType_heap) { HeapTests().Range(); }
2002 
2003 
TEST(ArrayType_zone)2004 TEST(ArrayType_zone) { ZoneTests().Array(); }
2005 
2006 
TEST(ArrayType_heap)2007 TEST(ArrayType_heap) { HeapTests().Array(); }
2008 
2009 
TEST(FunctionType_zone)2010 TEST(FunctionType_zone) { ZoneTests().Function(); }
2011 
2012 
TEST(FunctionType_heap)2013 TEST(FunctionType_heap) { HeapTests().Function(); }
2014 
2015 
TEST(Of_zone)2016 TEST(Of_zone) { ZoneTests().Of(); }
2017 
2018 
TEST(Of_heap)2019 TEST(Of_heap) { HeapTests().Of(); }
2020 
2021 
TEST(NowOf_zone)2022 TEST(NowOf_zone) { ZoneTests().NowOf(); }
2023 
2024 
TEST(NowOf_heap)2025 TEST(NowOf_heap) { HeapTests().NowOf(); }
2026 
2027 
TEST(MinMax_zone)2028 TEST(MinMax_zone) { ZoneTests().MinMax(); }
2029 
2030 
TEST(MinMax_heap)2031 TEST(MinMax_heap) { HeapTests().MinMax(); }
2032 
2033 
TEST(BitsetGlb_zone)2034 TEST(BitsetGlb_zone) { ZoneTests().BitsetGlb(); }
2035 
2036 
TEST(BitsetGlb_heap)2037 TEST(BitsetGlb_heap) { HeapTests().BitsetGlb(); }
2038 
2039 
TEST(BitsetLub_zone)2040 TEST(BitsetLub_zone) { ZoneTests().BitsetLub(); }
2041 
2042 
TEST(BitsetLub_heap)2043 TEST(BitsetLub_heap) { HeapTests().BitsetLub(); }
2044 
2045 
TEST(Is1_zone)2046 TEST(Is1_zone) { ZoneTests().Is1(); }
2047 
2048 
TEST(Is1_heap)2049 TEST(Is1_heap) { HeapTests().Is1(); }
2050 
2051 
TEST(Is2_zone)2052 TEST(Is2_zone) { ZoneTests().Is2(); }
2053 
2054 
TEST(Is2_heap)2055 TEST(Is2_heap) { HeapTests().Is2(); }
2056 
2057 
TEST(NowIs_zone)2058 TEST(NowIs_zone) { ZoneTests().NowIs(); }
2059 
2060 
TEST(NowIs_heap)2061 TEST(NowIs_heap) { HeapTests().NowIs(); }
2062 
2063 
TEST(Contains_zone)2064 TEST(Contains_zone) { ZoneTests().Contains(); }
2065 
2066 
TEST(Contains_heap)2067 TEST(Contains_heap) { HeapTests().Contains(); }
2068 
2069 
TEST(NowContains_zone)2070 TEST(NowContains_zone) { ZoneTests().NowContains(); }
2071 
2072 
TEST(NowContains_heap)2073 TEST(NowContains_heap) { HeapTests().NowContains(); }
2074 
2075 
TEST(Maybe_zone)2076 TEST(Maybe_zone) { ZoneTests().Maybe(); }
2077 
2078 
TEST(Maybe_heap)2079 TEST(Maybe_heap) { HeapTests().Maybe(); }
2080 
2081 
TEST(Union1_zone)2082 TEST(Union1_zone) { ZoneTests().Union1(); }
2083 
2084 
TEST(Union1_heap)2085 TEST(Union1_heap) { HeapTests().Union1(); }
2086 
2087 
TEST(Union2_zone)2088 TEST(Union2_zone) { ZoneTests().Union2(); }
2089 
2090 
TEST(Union2_heap)2091 TEST(Union2_heap) { HeapTests().Union2(); }
2092 
2093 
TEST(Union3_zone)2094 TEST(Union3_zone) { ZoneTests().Union3(); }
2095 
2096 
TEST(Union3_heap)2097 TEST(Union3_heap) { HeapTests().Union3(); }
2098 
2099 
TEST(Union4_zone)2100 TEST(Union4_zone) { ZoneTests().Union4(); }
2101 
2102 
TEST(Union4_heap)2103 TEST(Union4_heap) { HeapTests().Union4(); }
2104 
2105 
TEST(Intersect_zone)2106 TEST(Intersect_zone) { ZoneTests().Intersect(); }
2107 
2108 
TEST(Intersect_heap)2109 TEST(Intersect_heap) { HeapTests().Intersect(); }
2110 
2111 
TEST(Distributivity_zone)2112 TEST(Distributivity_zone) { ZoneTests().Distributivity(); }
2113 
2114 
TEST(Distributivity_heap)2115 TEST(Distributivity_heap) { HeapTests().Distributivity(); }
2116 
2117 
TEST(GetRange_zone)2118 TEST(GetRange_zone) { ZoneTests().GetRange(); }
2119 
2120 
TEST(GetRange_heap)2121 TEST(GetRange_heap) { HeapTests().GetRange(); }
2122 
2123 
TEST(Convert_zone)2124 TEST(Convert_zone) {
2125   ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
2126 }
2127 
2128 
TEST(Convert_heap)2129 TEST(Convert_heap) { HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); }
2130 
2131 
TEST(HTypeFromType_zone)2132 TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
2133 
2134 
TEST(HTypeFromType_heap)2135 TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }
2136