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