Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / test-types.cc
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "cctest.h"
29 #include "types.h"
30
31 using namespace v8::internal;
32
33 template<class Type, class TypeHandle, class Region>
34 class Types {
35  public:
36   Types(Region* region, Isolate* isolate) :
37       None(Type::None(region)),
38       Any(Type::Any(region)),
39       Oddball(Type::Oddball(region)),
40       Boolean(Type::Boolean(region)),
41       Null(Type::Null(region)),
42       Undefined(Type::Undefined(region)),
43       Number(Type::Number(region)),
44       Smi(Type::Smi(region)),
45       Signed32(Type::Signed32(region)),
46       Double(Type::Double(region)),
47       Name(Type::Name(region)),
48       UniqueName(Type::UniqueName(region)),
49       String(Type::String(region)),
50       InternalizedString(Type::InternalizedString(region)),
51       Symbol(Type::Symbol(region)),
52       Receiver(Type::Receiver(region)),
53       Object(Type::Object(region)),
54       Array(Type::Array(region)),
55       Function(Type::Function(region)),
56       Proxy(Type::Proxy(region)),
57       object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
58       array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
59       region_(region) {
60     smi = handle(Smi::FromInt(666), isolate);
61     signed32 = isolate->factory()->NewHeapNumber(0x40000000);
62     object1 = isolate->factory()->NewJSObjectFromMap(object_map);
63     object2 = isolate->factory()->NewJSObjectFromMap(object_map);
64     array = isolate->factory()->NewJSArray(20);
65     ObjectClass = Type::Class(object_map, region);
66     ArrayClass = Type::Class(array_map, region);
67     SmiConstant = Type::Constant(smi, region);
68     Signed32Constant = Type::Constant(signed32, region);
69     ObjectConstant1 = Type::Constant(object1, region);
70     ObjectConstant2 = Type::Constant(object2, region);
71     ArrayConstant1 = Type::Constant(array, region);
72     ArrayConstant2 = Type::Constant(array, region);
73   }
74
75   TypeHandle None;
76   TypeHandle Any;
77   TypeHandle Oddball;
78   TypeHandle Boolean;
79   TypeHandle Null;
80   TypeHandle Undefined;
81   TypeHandle Number;
82   TypeHandle Smi;
83   TypeHandle Signed32;
84   TypeHandle Double;
85   TypeHandle Name;
86   TypeHandle UniqueName;
87   TypeHandle String;
88   TypeHandle InternalizedString;
89   TypeHandle Symbol;
90   TypeHandle Receiver;
91   TypeHandle Object;
92   TypeHandle Array;
93   TypeHandle Function;
94   TypeHandle Proxy;
95
96   TypeHandle ObjectClass;
97   TypeHandle ArrayClass;
98
99   TypeHandle SmiConstant;
100   TypeHandle Signed32Constant;
101   TypeHandle ObjectConstant1;
102   TypeHandle ObjectConstant2;
103   TypeHandle ArrayConstant1;
104   TypeHandle ArrayConstant2;
105
106   Handle<i::Map> object_map;
107   Handle<i::Map> array_map;
108
109   Handle<i::Smi> smi;
110   Handle<i::HeapNumber> signed32;
111   Handle<i::JSObject> object1;
112   Handle<i::JSObject> object2;
113   Handle<i::JSArray> array;
114
115   TypeHandle Union(TypeHandle t1, TypeHandle t2) {
116     return Type::Union(t1, t2, region_);
117   }
118   TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
119     return Type::Intersect(t1, t2, region_);
120   }
121
122   template<class Type2, class TypeHandle2>
123   TypeHandle Convert(TypeHandle2 t) {
124     return Type::template Convert<Type2>(t, region_);
125   }
126
127   TypeHandle Fuzz(int depth = 5) {
128     switch (rand() % (depth == 0 ? 3 : 20)) {
129       case 0: {  // bitset
130         int n = 0
131         #define COUNT_BITSET_TYPES(type, value) + 1
132         BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
133         #undef COUNT_BITSET_TYPES
134         ;
135         int i = rand() % n;
136         #define PICK_BITSET_TYPE(type, value) \
137           if (i-- == 0) return Type::type(region_);
138         BITSET_TYPE_LIST(PICK_BITSET_TYPE)
139         #undef PICK_BITSET_TYPE
140         UNREACHABLE();
141       }
142       case 1:  // class
143         switch (rand() % 2) {
144           case 0: return ObjectClass;
145           case 1: return ArrayClass;
146         }
147         UNREACHABLE();
148       case 2:  // constant
149         switch (rand() % 6) {
150           case 0: return SmiConstant;
151           case 1: return Signed32Constant;
152           case 2: return ObjectConstant1;
153           case 3: return ObjectConstant2;
154           case 4: return ArrayConstant1;
155           case 5: return ArrayConstant2;
156         }
157         UNREACHABLE();
158       default: {  // union
159         int n = rand() % 10;
160         TypeHandle type = None;
161         for (int i = 0; i < n; ++i) {
162           type = Type::Union(type, Fuzz(depth - 1), region_);
163         }
164         return type;
165       }
166     }
167     UNREACHABLE();
168   }
169
170  private:
171   Region* region_;
172 };
173
174
175 // Testing auxiliaries (breaking the Type abstraction).
176 struct ZoneRep {
177   static bool IsTagged(Type* t, int tag) {
178     return !IsBitset(t)
179         && reinterpret_cast<intptr_t>(AsTagged(t)->at(0)) == tag;
180   }
181   static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
182   static bool IsClass(Type* t) { return IsTagged(t, 0); }
183   static bool IsConstant(Type* t) { return IsTagged(t, 1); }
184   static bool IsUnion(Type* t) { return IsTagged(t, 2); }
185
186   static ZoneList<void*>* AsTagged(Type* t) {
187     return reinterpret_cast<ZoneList<void*>*>(t);
188   }
189   static int AsBitset(Type* t) {
190     return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
191   }
192   static Map* AsClass(Type* t) {
193     return *reinterpret_cast<Map**>(AsTagged(t)->at(1));
194   }
195   static Object* AsConstant(Type* t) {
196     return *reinterpret_cast<Object**>(AsTagged(t)->at(1));
197   }
198   static ZoneList<Type*>* AsUnion(Type* t) {
199     return reinterpret_cast<ZoneList<Type*>*>(AsTagged(t));
200   }
201
202   static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
203 };
204
205
206 struct HeapRep {
207   static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
208   static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
209   static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
210   static bool IsUnion(Handle<HeapType> t) { return t->IsFixedArray(); }
211
212   static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
213   static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
214   static Object* AsConstant(Handle<HeapType> t) {
215     return Box::cast(*t)->value();
216   }
217   static FixedArray* AsUnion(Handle<HeapType> t) {
218     return FixedArray::cast(*t);
219   }
220
221   static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
222 };
223
224
225 template<class Type, class TypeHandle, class Region, class Rep>
226 struct Tests : Rep {
227   Isolate* isolate;
228   HandleScope scope;
229   Zone zone;
230   Types<Type, TypeHandle, Region> T;
231
232   Tests() :
233       isolate(CcTest::i_isolate()),
234       scope(isolate),
235       zone(isolate),
236       T(Rep::ToRegion(&zone, isolate), isolate) {
237   }
238
239   static void CheckEqual(TypeHandle type1, TypeHandle type2) {
240     CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2));
241     CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2));
242     CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2));
243     CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2));
244     CHECK_EQ(type1->NumClasses(), type2->NumClasses());
245     CHECK_EQ(type1->NumConstants(), type2->NumConstants());
246     if (Rep::IsBitset(type1)) {
247       CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2));
248     } else if (Rep::IsClass(type1)) {
249       CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2));
250     } else if (Rep::IsConstant(type1)) {
251       CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2));
252     } else if (Rep::IsUnion(type1)) {
253       CHECK_EQ(Rep::AsUnion(type1)->length(), Rep::AsUnion(type2)->length());
254     }
255     CHECK(type1->Is(type2));
256     CHECK(type2->Is(type1));
257   }
258
259   static void CheckSub(TypeHandle type1, TypeHandle type2) {
260     CHECK(type1->Is(type2));
261     CHECK(!type2->Is(type1));
262     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
263       CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
264     }
265   }
266
267   static void CheckUnordered(TypeHandle type1, TypeHandle type2) {
268     CHECK(!type1->Is(type2));
269     CHECK(!type2->Is(type1));
270     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
271       CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
272     }
273   }
274
275   static void CheckOverlap(TypeHandle type1, TypeHandle type2) {
276     CHECK(type1->Maybe(type2));
277     CHECK(type2->Maybe(type1));
278     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
279       CHECK_NE(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
280     }
281   }
282
283   static void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
284     CHECK(!type1->Is(type2));
285     CHECK(!type2->Is(type1));
286     CHECK(!type1->Maybe(type2));
287     CHECK(!type2->Maybe(type1));
288     if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
289       CHECK_EQ(0, Rep::AsBitset(type1) & Rep::AsBitset(type2));
290     }
291   }
292
293   void Bitset() {
294     CHECK(this->IsBitset(T.None));
295     CHECK(this->IsBitset(T.Any));
296     CHECK(this->IsBitset(T.String));
297     CHECK(this->IsBitset(T.Object));
298
299     CHECK(this->IsBitset(T.Union(T.String, T.Number)));
300     CHECK(this->IsBitset(T.Union(T.String, T.Receiver)));
301
302     CHECK_EQ(0, this->AsBitset(T.None));
303     CHECK_EQ(this->AsBitset(T.Number) | this->AsBitset(T.String),
304              this->AsBitset(T.Union(T.String, T.Number)));
305     CHECK_EQ(this->AsBitset(T.Receiver),
306              this->AsBitset(T.Union(T.Receiver, T.Object)));
307   }
308
309   void Class() {
310     CHECK(this->IsClass(T.ObjectClass));
311     CHECK(this->IsClass(T.ArrayClass));
312
313     CHECK(*T.object_map == this->AsClass(T.ObjectClass));
314     CHECK(*T.array_map == this->AsClass(T.ArrayClass));
315   }
316
317   void Constant() {
318     CHECK(this->IsConstant(T.SmiConstant));
319     CHECK(this->IsConstant(T.ObjectConstant1));
320     CHECK(this->IsConstant(T.ObjectConstant2));
321     CHECK(this->IsConstant(T.ArrayConstant1));
322     CHECK(this->IsConstant(T.ArrayConstant2));
323
324     CHECK(*T.smi == this->AsConstant(T.SmiConstant));
325     CHECK(*T.object1 == this->AsConstant(T.ObjectConstant1));
326     CHECK(*T.object2 == this->AsConstant(T.ObjectConstant2));
327     CHECK(*T.object1 != this->AsConstant(T.ObjectConstant2));
328     CHECK(*T.array == this->AsConstant(T.ArrayConstant1));
329     CHECK(*T.array == this->AsConstant(T.ArrayConstant2));
330   }
331
332   void Is() {
333     // Reflexivity
334     CHECK(T.None->Is(T.None));
335     CHECK(T.Any->Is(T.Any));
336     CHECK(T.Object->Is(T.Object));
337
338     CHECK(T.ObjectClass->Is(T.ObjectClass));
339     CHECK(T.ObjectConstant1->Is(T.ObjectConstant1));
340     CHECK(T.ArrayConstant1->Is(T.ArrayConstant2));
341
342     // Symmetry and Transitivity
343     CheckSub(T.None, T.Number);
344     CheckSub(T.None, T.Any);
345
346     CheckSub(T.Oddball, T.Any);
347     CheckSub(T.Boolean, T.Oddball);
348     CheckSub(T.Null, T.Oddball);
349     CheckSub(T.Undefined, T.Oddball);
350     CheckUnordered(T.Boolean, T.Null);
351     CheckUnordered(T.Undefined, T.Null);
352     CheckUnordered(T.Boolean, T.Undefined);
353
354     CheckSub(T.Number, T.Any);
355     CheckSub(T.Smi, T.Number);
356     CheckSub(T.Signed32, T.Number);
357     CheckSub(T.Double, T.Number);
358     CheckSub(T.Smi, T.Signed32);
359     CheckUnordered(T.Smi, T.Double);
360     CheckUnordered(T.Signed32, T.Double);
361
362     CheckSub(T.Name, T.Any);
363     CheckSub(T.UniqueName, T.Any);
364     CheckSub(T.UniqueName, T.Name);
365     CheckSub(T.String, T.Name);
366     CheckSub(T.InternalizedString, T.String);
367     CheckSub(T.InternalizedString, T.UniqueName);
368     CheckSub(T.InternalizedString, T.Name);
369     CheckSub(T.Symbol, T.UniqueName);
370     CheckSub(T.Symbol, T.Name);
371     CheckUnordered(T.String, T.UniqueName);
372     CheckUnordered(T.String, T.Symbol);
373     CheckUnordered(T.InternalizedString, T.Symbol);
374
375     CheckSub(T.Receiver, T.Any);
376     CheckSub(T.Object, T.Any);
377     CheckSub(T.Object, T.Receiver);
378     CheckSub(T.Array, T.Object);
379     CheckSub(T.Function, T.Object);
380     CheckSub(T.Proxy, T.Receiver);
381     CheckUnordered(T.Object, T.Proxy);
382     CheckUnordered(T.Array, T.Function);
383
384     // Structured subtyping
385     CheckSub(T.None, T.ObjectClass);
386     CheckSub(T.None, T.ObjectConstant1);
387     CheckSub(T.ObjectClass, T.Any);
388     CheckSub(T.ObjectConstant1, T.Any);
389
390     CheckSub(T.ObjectClass, T.Object);
391     CheckSub(T.ArrayClass, T.Object);
392     CheckUnordered(T.ObjectClass, T.ArrayClass);
393
394     CheckSub(T.SmiConstant, T.Smi);
395     CheckSub(T.SmiConstant, T.Signed32);
396     CheckSub(T.SmiConstant, T.Number);
397     CheckSub(T.ObjectConstant1, T.Object);
398     CheckSub(T.ObjectConstant2, T.Object);
399     CheckSub(T.ArrayConstant1, T.Object);
400     CheckSub(T.ArrayConstant1, T.Array);
401     CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
402     CheckUnordered(T.ObjectConstant1, T.ArrayConstant1);
403
404     CheckUnordered(T.ObjectConstant1, T.ObjectClass);
405     CheckUnordered(T.ObjectConstant2, T.ObjectClass);
406     CheckUnordered(T.ObjectConstant1, T.ArrayClass);
407     CheckUnordered(T.ObjectConstant2, T.ArrayClass);
408     CheckUnordered(T.ArrayConstant1, T.ObjectClass);
409   }
410
411   void Maybe() {
412     CheckOverlap(T.Any, T.Any);
413     CheckOverlap(T.Object, T.Object);
414
415     CheckOverlap(T.Oddball, T.Any);
416     CheckOverlap(T.Boolean, T.Oddball);
417     CheckOverlap(T.Null, T.Oddball);
418     CheckOverlap(T.Undefined, T.Oddball);
419     CheckDisjoint(T.Boolean, T.Null);
420     CheckDisjoint(T.Undefined, T.Null);
421     CheckDisjoint(T.Boolean, T.Undefined);
422
423     CheckOverlap(T.Number, T.Any);
424     CheckOverlap(T.Smi, T.Number);
425     CheckOverlap(T.Double, T.Number);
426     CheckDisjoint(T.Signed32, T.Double);
427
428     CheckOverlap(T.Name, T.Any);
429     CheckOverlap(T.UniqueName, T.Any);
430     CheckOverlap(T.UniqueName, T.Name);
431     CheckOverlap(T.String, T.Name);
432     CheckOverlap(T.InternalizedString, T.String);
433     CheckOverlap(T.InternalizedString, T.UniqueName);
434     CheckOverlap(T.InternalizedString, T.Name);
435     CheckOverlap(T.Symbol, T.UniqueName);
436     CheckOverlap(T.Symbol, T.Name);
437     CheckOverlap(T.String, T.UniqueName);
438     CheckDisjoint(T.String, T.Symbol);
439     CheckDisjoint(T.InternalizedString, T.Symbol);
440
441     CheckOverlap(T.Receiver, T.Any);
442     CheckOverlap(T.Object, T.Any);
443     CheckOverlap(T.Object, T.Receiver);
444     CheckOverlap(T.Array, T.Object);
445     CheckOverlap(T.Function, T.Object);
446     CheckOverlap(T.Proxy, T.Receiver);
447     CheckDisjoint(T.Object, T.Proxy);
448     CheckDisjoint(T.Array, T.Function);
449
450     CheckOverlap(T.ObjectClass, T.Any);
451     CheckOverlap(T.ObjectConstant1, T.Any);
452
453     CheckOverlap(T.ObjectClass, T.Object);
454     CheckOverlap(T.ArrayClass, T.Object);
455     CheckOverlap(T.ObjectClass, T.ObjectClass);
456     CheckOverlap(T.ArrayClass, T.ArrayClass);
457     CheckDisjoint(T.ObjectClass, T.ArrayClass);
458
459     CheckOverlap(T.SmiConstant, T.Smi);
460     CheckOverlap(T.SmiConstant, T.Signed32);
461     CheckOverlap(T.SmiConstant, T.Number);
462     CheckDisjoint(T.SmiConstant, T.Double);
463     CheckOverlap(T.ObjectConstant1, T.Object);
464     CheckOverlap(T.ObjectConstant2, T.Object);
465     CheckOverlap(T.ArrayConstant1, T.Object);
466     CheckOverlap(T.ArrayConstant1, T.Array);
467     CheckOverlap(T.ArrayConstant1, T.ArrayConstant2);
468     CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
469     CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
470     CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1);
471
472     CheckDisjoint(T.ObjectConstant1, T.ObjectClass);
473     CheckDisjoint(T.ObjectConstant2, T.ObjectClass);
474     CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
475     CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
476     CheckDisjoint(T.ArrayConstant1, T.ObjectClass);
477   }
478
479   void Union() {
480     // Bitset-bitset
481     CHECK(this->IsBitset(T.Union(T.Object, T.Number)));
482     CHECK(this->IsBitset(T.Union(T.Object, T.Object)));
483     CHECK(this->IsBitset(T.Union(T.Any, T.None)));
484
485     CheckEqual(T.Union(T.None, T.Number), T.Number);
486     CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver);
487     CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number));
488     CheckSub(T.Union(T.Number, T.String), T.Any);
489
490     // Class-class
491     CHECK(this->IsClass(T.Union(T.ObjectClass, T.ObjectClass)));
492     CHECK(this->IsUnion(T.Union(T.ObjectClass, T.ArrayClass)));
493
494     CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass);
495     CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass));
496     CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any);
497     CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass));
498     CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass));
499     CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
500     CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
501     CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
502     CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
503
504     // Constant-constant
505     CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1)));
506     CHECK(this->IsConstant(T.Union(T.ArrayConstant1, T.ArrayConstant1)));
507     CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2)));
508
509     CheckEqual(
510         T.Union(T.ObjectConstant1, T.ObjectConstant1),
511         T.ObjectConstant1);
512     CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1);
513     CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2);
514     CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2));
515     CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any);
516     CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2));
517     CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2));
518     CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2));
519     CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
520     CheckUnordered(
521         T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
522     CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
523     CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array);
524     CheckOverlap(
525         T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2);
526     CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number);
527     CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass);
528
529     // Bitset-class
530     CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object)));
531     CHECK(this->IsUnion(T.Union(T.ObjectClass, T.Number)));
532
533     CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object);
534     CheckSub(T.None, T.Union(T.ObjectClass, T.Number));
535     CheckSub(T.Union(T.ObjectClass, T.Number), T.Any);
536     CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number));
537     CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
538     CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
539     CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
540     CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
541
542     // Bitset-constant
543     CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number)));
544     CHECK(this->IsBitset(T.Union(T.ObjectConstant1, T.Object)));
545     CHECK(this->IsUnion(T.Union(T.ObjectConstant2, T.Number)));
546
547     CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number);
548     CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object);
549     CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number));
550     CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any);
551     CheckSub(
552         T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
553     CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
554     CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
555     CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
556     CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
557     CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32);
558
559     // Class-constant
560     CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass)));
561     CHECK(this->IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2)));
562
563     CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass));
564     CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any);
565     CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
566     CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass));
567     CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass));
568     CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
569     CheckSub(
570         T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
571     CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1);
572     CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
573     CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass);
574
575     // Bitset-union
576     CHECK(this->IsBitset(
577         T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
578     CHECK(this->IsUnion(
579         T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
580
581     CheckEqual(
582         T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
583         T.Object);
584     CheckEqual(
585         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
586         T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
587     CheckSub(
588         T.Double,
589         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
590     CheckSub(
591         T.ObjectConstant1,
592         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
593     CheckSub(
594         T.None,
595         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double));
596     CheckSub(
597         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
598         T.Any);
599     CheckSub(
600         T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double),
601         T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
602
603     // Class-union
604     CHECK(this->IsUnion(
605         T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
606     CHECK(this->IsUnion(
607         T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass)));
608
609     CheckEqual(
610         T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
611         T.Union(T.ObjectClass, T.ObjectConstant1));
612     CheckSub(
613         T.None,
614         T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)));
615     CheckSub(
616         T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
617         T.Any);
618     CheckSub(
619         T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
620         T.Object);
621     CheckEqual(
622         T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
623         T.Union(T.ArrayClass, T.ObjectConstant2));
624
625     // Constant-union
626     CHECK(this->IsUnion(T.Union(
627         T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
628     CHECK(this->IsUnion(T.Union(
629         T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
630     CHECK(this->IsUnion(T.Union(
631         T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1)));
632
633     CheckEqual(
634         T.Union(
635             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
636         T.Union(T.ObjectConstant2, T.ObjectConstant1));
637     CheckEqual(
638         T.Union(
639             T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1),
640         T.Union(
641             T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1)));
642
643     // Union-union
644     CHECK(this->IsBitset(T.Union(
645         T.Union(T.Number, T.ArrayClass),
646         T.Union(T.Signed32, T.Array))));
647     CHECK(this->IsUnion(T.Union(
648         T.Union(T.Number, T.ArrayClass),
649         T.Union(T.ObjectClass, T.ArrayClass))));
650
651     CheckEqual(
652         T.Union(
653             T.Union(T.ObjectConstant2, T.ObjectConstant1),
654             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
655         T.Union(T.ObjectConstant2, T.ObjectConstant1));
656     CheckEqual(
657         T.Union(
658             T.Union(T.ObjectConstant2, T.ArrayConstant1),
659             T.Union(T.ObjectConstant1, T.ArrayConstant2)),
660         T.Union(
661             T.Union(T.ObjectConstant1, T.ObjectConstant2),
662             T.ArrayConstant1));
663     CheckEqual(
664         T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)),
665         T.Union(T.Number, T.Array));
666   }
667
668   void Intersect() {
669     // Bitset-bitset
670     CHECK(this->IsBitset(T.Intersect(T.Object, T.Number)));
671     CHECK(this->IsBitset(T.Intersect(T.Object, T.Object)));
672     CHECK(this->IsBitset(T.Intersect(T.Any, T.None)));
673
674     CheckEqual(T.Intersect(T.None, T.Number), T.None);
675     CheckEqual(T.Intersect(T.Object, T.Proxy), T.None);
676     CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name));
677     CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString);
678
679     // Class-class
680     CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass)));
681     CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass)));
682
683     CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass);
684     CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None);
685
686     // Constant-constant
687     CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1)));
688     CHECK(this->IsConstant(T.Intersect(T.ArrayConstant1, T.ArrayConstant2)));
689     CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2)));
690
691     CheckEqual(
692         T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1);
693     CheckEqual(
694         T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
695     CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
696
697     // Bitset-class
698     CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object)));
699     CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number)));
700
701     CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
702     CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
703     CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
704
705     // Bitset-constant
706     CHECK(this->IsBitset(T.Intersect(T.Smi, T.Number)));
707     CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number)));
708     CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object)));
709
710     CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi);
711     CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant);
712     CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1);
713
714     // Class-constant
715     CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass)));
716     CHECK(this->IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2)));
717
718     CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
719     CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None);
720
721     // Bitset-union
722     CHECK(this->IsUnion(
723         T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass))));
724     CHECK(this->IsBitset(
725         T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number)));
726
727     CheckEqual(
728         T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
729         T.Union(T.ObjectConstant1, T.ObjectClass));
730     CheckEqual(
731         T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
732         T.None);
733
734     // Class-union
735     CHECK(this->IsClass(
736         T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
737     CHECK(this->IsClass(
738         T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass)));
739     CHECK(this->IsBitset(
740         T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass)));
741
742     CheckEqual(
743         T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
744         T.ArrayClass);
745     CheckEqual(
746         T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
747         T.ArrayClass);
748     CheckEqual(
749         T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass),
750         T.None);
751
752     // Constant-union
753     CHECK(this->IsConstant(T.Intersect(
754         T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2))));
755     CHECK(this->IsConstant(T.Intersect(
756         T.Union(T.Number, T.ObjectClass), T.SmiConstant)));
757     CHECK(this->IsBitset(T.Intersect(
758         T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1)));
759
760     CheckEqual(
761         T.Intersect(
762             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
763         T.ObjectConstant1);
764     CheckEqual(
765         T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
766         T.SmiConstant);
767     CheckEqual(
768         T.Intersect(
769             T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1),
770         T.None);
771
772     // Union-union
773     CHECK(this->IsUnion(T.Intersect(
774         T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array))));
775     CHECK(this->IsBitset(T.Intersect(
776         T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array))));
777
778     CheckEqual(
779         T.Intersect(
780             T.Union(T.Number, T.ArrayClass),
781             T.Union(T.Smi, T.Array)),
782         T.Union(T.Smi, T.ArrayClass));
783     CheckEqual(
784         T.Intersect(
785             T.Union(T.Number, T.ObjectClass),
786             T.Union(T.Signed32, T.Array)),
787         T.Signed32);
788     CheckEqual(
789         T.Intersect(
790             T.Union(T.ObjectConstant2, T.ObjectConstant1),
791             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
792         T.Union(T.ObjectConstant2, T.ObjectConstant1));
793     CheckEqual(
794         T.Intersect(
795             T.Union(
796                 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
797             T.Union(
798                 T.ObjectConstant1,
799                 T.Union(T.ArrayConstant1, T.ObjectConstant2))),
800         T.Union(T.ObjectConstant2, T.ObjectConstant1));
801     CheckEqual(
802         T.Intersect(
803             T.Union(T.ObjectConstant2, T.ArrayConstant1),
804             T.Union(T.ObjectConstant1, T.ArrayConstant2)),
805         T.ArrayConstant1);
806   }
807
808   template<class Type2, class TypeHandle2, class Region2, class Rep2>
809   void Convert() {
810     Types<Type2, TypeHandle2, Region2> T2(
811         Rep2::ToRegion(&zone, isolate), isolate);
812     for (int i = 0; i < 100; ++i) {
813       TypeHandle type = T.Fuzz();
814       CheckEqual(type,
815                  T.template Convert<Type2>(T2.template Convert<Type>(type)));
816     }
817   }
818 };
819
820 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
821 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
822
823
824 TEST(Bitset) {
825   CcTest::InitializeVM();
826   ZoneTests().Bitset();
827   HeapTests().Bitset();
828 }
829
830
831 TEST(Class) {
832   CcTest::InitializeVM();
833   ZoneTests().Class();
834   HeapTests().Class();
835 }
836
837
838 TEST(Constant) {
839   CcTest::InitializeVM();
840   ZoneTests().Constant();
841   HeapTests().Constant();
842 }
843
844
845 TEST(Is) {
846   CcTest::InitializeVM();
847   ZoneTests().Is();
848   HeapTests().Is();
849 }
850
851
852 TEST(Maybe) {
853   CcTest::InitializeVM();
854   ZoneTests().Maybe();
855   HeapTests().Maybe();
856 }
857
858
859 TEST(Union) {
860   CcTest::InitializeVM();
861   ZoneTests().Union();
862   HeapTests().Union();
863 }
864
865
866 TEST(Intersect) {
867   CcTest::InitializeVM();
868   ZoneTests().Intersect();
869   HeapTests().Intersect();
870 }
871
872
873 TEST(Convert) {
874   CcTest::InitializeVM();
875   ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
876   HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
877 }