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