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/base/strings.h"
8 #include "src/compiler/types.h"
9 #include "src/execution/isolate.h"
10 #include "src/heap/factory-inl.h"
11 #include "src/heap/heap.h"
12 #include "src/objects/objects.h"
13 #include "test/cctest/cctest.h"
14 #include "test/common/types-fuzz.h"
15 
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19 
20 namespace {
21 
22 // Testing auxiliaries (breaking the Type abstraction).
23 
24 
IsInteger(double x)25 static bool IsInteger(double x) {
26   return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
27 }
28 
29 using bitset = uint32_t;
30 
31 struct Tests {
32   using TypeIterator = Types::TypeVector::iterator;
33   using ValueIterator = Types::ValueVector::iterator;
34 
35   Isolate* isolate;
36   HandleScope scope;
37   CanonicalHandleScope canonical;
38   Zone zone;
39   Types T;
40 
Testsv8::internal::compiler::__anonb59da7f10111::Tests41   Tests()
42       : isolate(CcTest::InitIsolateOnce()),
43         scope(isolate),
44         canonical(isolate),
45         zone(isolate->allocator(), ZONE_NAME),
46         T(&zone, isolate, isolate->random_number_generator()) {}
47 
IsBitsetv8::internal::compiler::__anonb59da7f10111::Tests48   bool IsBitset(Type type) { return type.IsBitset(); }
IsUnionv8::internal::compiler::__anonb59da7f10111::Tests49   bool IsUnion(Type type) { return type.IsUnionForTesting(); }
AsBitsetv8::internal::compiler::__anonb59da7f10111::Tests50   BitsetType::bitset AsBitset(Type type) { return type.AsBitsetForTesting(); }
AsUnionv8::internal::compiler::__anonb59da7f10111::Tests51   const UnionType* AsUnion(Type type) { return type.AsUnionForTesting(); }
52 
Equalv8::internal::compiler::__anonb59da7f10111::Tests53   bool Equal(Type type1, Type type2) {
54     return type1.Equals(type2) &&
55            this->IsBitset(type1) == this->IsBitset(type2) &&
56            this->IsUnion(type1) == this->IsUnion(type2) &&
57            type1.NumConstants() == type2.NumConstants() &&
58            (!this->IsBitset(type1) ||
59             this->AsBitset(type1) == this->AsBitset(type2)) &&
60            (!this->IsUnion(type1) ||
61             this->AsUnion(type1)->LengthForTesting() ==
62                 this->AsUnion(type2)->LengthForTesting());
63   }
64 
CheckEqualv8::internal::compiler::__anonb59da7f10111::Tests65   void CheckEqual(Type type1, Type type2) { CHECK(Equal(type1, type2)); }
66 
CheckSubv8::internal::compiler::__anonb59da7f10111::Tests67   void CheckSub(Type type1, Type type2) {
68     CHECK(type1.Is(type2));
69     CHECK(!type2.Is(type1));
70     if (this->IsBitset(type1) && this->IsBitset(type2)) {
71       CHECK(this->AsBitset(type1) != this->AsBitset(type2));
72     }
73   }
74 
CheckSubOrEqualv8::internal::compiler::__anonb59da7f10111::Tests75   void CheckSubOrEqual(Type type1, Type type2) {
76     CHECK(type1.Is(type2));
77     if (this->IsBitset(type1) && this->IsBitset(type2)) {
78       CHECK((this->AsBitset(type1) | this->AsBitset(type2))
79             == this->AsBitset(type2));
80     }
81   }
82 
CheckUnorderedv8::internal::compiler::__anonb59da7f10111::Tests83   void CheckUnordered(Type type1, Type type2) {
84     CHECK(!type1.Is(type2));
85     CHECK(!type2.Is(type1));
86     if (this->IsBitset(type1) && this->IsBitset(type2)) {
87       CHECK(this->AsBitset(type1) != this->AsBitset(type2));
88     }
89   }
90 
CheckOverlapv8::internal::compiler::__anonb59da7f10111::Tests91   void CheckOverlap(Type type1, Type type2) {
92     CHECK(type1.Maybe(type2));
93     CHECK(type2.Maybe(type1));
94   }
95 
CheckDisjointv8::internal::compiler::__anonb59da7f10111::Tests96   void CheckDisjoint(Type type1, Type type2) {
97     CHECK(!type1.Is(type2));
98     CHECK(!type2.Is(type1));
99     CHECK(!type1.Maybe(type2));
100     CHECK(!type2.Maybe(type1));
101   }
102 
IsSomeTypev8::internal::compiler::__anonb59da7f10111::Tests103   void IsSomeType() {
104     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
105       Type t = *it;
106       CHECK_EQ(1, this->IsBitset(t) + t.IsHeapConstant() + t.IsRange() +
107                       t.IsOtherNumberConstant() + this->IsUnion(t));
108     }
109   }
110 
Bitsetv8::internal::compiler::__anonb59da7f10111::Tests111   void Bitset() {
112     // None and Any are bitsets.
113     CHECK(this->IsBitset(T.None));
114     CHECK(this->IsBitset(T.Any));
115 
116     CHECK(bitset(0) == this->AsBitset(T.None));
117     CHECK(bitset(0xFFFFFFFEu) == this->AsBitset(T.Any));
118 
119     // Union(T1, T2) is bitset for bitsets T1,T2
120     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
121       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
122         Type type1 = *it1;
123         Type type2 = *it2;
124         Type union12 = T.Union(type1, type2);
125         CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
126               this->IsBitset(union12));
127       }
128     }
129 
130     // Intersect(T1, T2) is bitset for bitsets T1,T2
131     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
132       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
133         Type type1 = *it1;
134         Type type2 = *it2;
135         Type intersect12 = T.Intersect(type1, type2);
136         CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
137               this->IsBitset(intersect12));
138       }
139     }
140 
141     // Union(T1, T2) is bitset if T2 is bitset and T1.Is(T2)
142     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
143       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
144         Type type1 = *it1;
145         Type type2 = *it2;
146         Type union12 = T.Union(type1, type2);
147         CHECK(!(this->IsBitset(type2) && type1.Is(type2)) ||
148               this->IsBitset(union12));
149       }
150     }
151 
152     // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
153     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
154       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
155         Type type1 = *it1;
156         Type type2 = *it2;
157         Type union12 = T.Union(type1, type2);
158         if (this->IsBitset(type1) && this->IsBitset(type2)) {
159           CHECK(
160               (this->AsBitset(type1) | this->AsBitset(type2)) ==
161               this->AsBitset(union12));
162         }
163       }
164     }
165 
166     // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None)
167     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
168       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
169         Type type1 = *it1;
170         Type type2 = *it2;
171         if (this->IsBitset(type1) && this->IsBitset(type2)) {
172           Type intersect12 = T.Intersect(type1, type2);
173           bitset bits = this->AsBitset(type1) & this->AsBitset(type2);
174           CHECK(bits == this->AsBitset(intersect12));
175         }
176       }
177     }
178   }
179 
Constantv8::internal::compiler::__anonb59da7f10111::Tests180   void Constant() {
181     // Constructor
182     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
183       Handle<i::Object> value = *vt;
184       Type type = T.Constant(value);
185       CHECK(type.IsBitset() || type.IsHeapConstant() ||
186             type.IsOtherNumberConstant() || type.IsRange());
187     }
188 
189     // Value attribute
190     for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
191       Handle<i::Object> value = *vt;
192       Type type = T.Constant(value);
193       if (type.IsHeapConstant()) {
194         CHECK(value.address() == type.AsHeapConstant()->Value().address());
195       } else if (type.IsOtherNumberConstant()) {
196         CHECK(value->IsHeapNumber());
197         CHECK(value->Number() == type.AsOtherNumberConstant()->Value());
198       } else if (type.IsBitset()) {
199         CHECK(type.IsSingleton());
200       } else {
201         CHECK(type.IsRange());
202         double v = value->Number();
203         CHECK(v == type.AsRange()->Min() && v == type.AsRange()->Max());
204       }
205     }
206 
207     // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
208     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
209       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
210         Handle<i::Object> value1 = *vt1;
211         Handle<i::Object> value2 = *vt2;
212         Type type1 = T.Constant(value1);
213         Type type2 = T.Constant(value2);
214         if (type1.IsOtherNumberConstant() && type2.IsOtherNumberConstant()) {
215           CHECK(Equal(type1, type2) ==
216                 (type1.AsOtherNumberConstant()->Value() ==
217                  type2.AsOtherNumberConstant()->Value()));
218         } else if (type1.IsRange() && type2.IsRange()) {
219           CHECK(Equal(type1, type2) ==
220                 ((type1.AsRange()->Min() == type2.AsRange()->Min()) &&
221                  (type1.AsRange()->Max() == type2.AsRange()->Max())));
222         } else {
223           CHECK(Equal(type1, type2) == (*value1 == *value2));
224         }
225       }
226     }
227 
228     // Typing of numbers
229     Factory* fac = isolate->factory();
230     CHECK(T.Constant(fac->NewNumber(0)).Is(T.UnsignedSmall));
231     CHECK(T.Constant(fac->NewNumber(1)).Is(T.UnsignedSmall));
232     CHECK(T.Constant(fac->NewNumber(42)).Equals(T.Range(42, 42)));
233     CHECK(T.Constant(fac->NewNumber(0x3FFFFFFF)).Is(T.UnsignedSmall));
234     CHECK(T.Constant(fac->NewNumber(-1)).Is(T.Negative31));
235     CHECK(T.Constant(fac->NewNumber(-0x3FFFFFFF)).Is(T.Negative31));
236     CHECK(T.Constant(fac->NewNumber(-0x40000000)).Is(T.Negative31));
237     CHECK(T.Constant(fac->NewNumber(0x40000000)).Is(T.Unsigned31));
238     CHECK(!T.Constant(fac->NewNumber(0x40000000)).Is(T.Unsigned30));
239     CHECK(T.Constant(fac->NewNumber(0x7FFFFFFF)).Is(T.Unsigned31));
240     CHECK(!T.Constant(fac->NewNumber(0x7FFFFFFF)).Is(T.Unsigned30));
241     CHECK(T.Constant(fac->NewNumber(-0x40000001)).Is(T.Negative32));
242     CHECK(!T.Constant(fac->NewNumber(-0x40000001)).Is(T.Negative31));
243     CHECK(T.Constant(fac->NewNumber(-0x7FFFFFFF)).Is(T.Negative32));
244     CHECK(!T.Constant(fac->NewNumber(-0x7FFFFFFF - 1)).Is(T.Negative31));
245     if (SmiValuesAre31Bits()) {
246       CHECK(!T.Constant(fac->NewNumber(0x40000000)).Is(T.UnsignedSmall));
247       CHECK(!T.Constant(fac->NewNumber(0x7FFFFFFF)).Is(T.UnsignedSmall));
248       CHECK(!T.Constant(fac->NewNumber(-0x40000001)).Is(T.SignedSmall));
249       CHECK(!T.Constant(fac->NewNumber(-0x7FFFFFFF - 1)).Is(T.SignedSmall));
250     } else {
251       CHECK(SmiValuesAre32Bits());
252       CHECK(T.Constant(fac->NewNumber(0x40000000)).Is(T.UnsignedSmall));
253       CHECK(T.Constant(fac->NewNumber(0x7FFFFFFF)).Is(T.UnsignedSmall));
254       CHECK(T.Constant(fac->NewNumber(-0x40000001)).Is(T.SignedSmall));
255       CHECK(T.Constant(fac->NewNumber(-0x7FFFFFFF - 1)).Is(T.SignedSmall));
256     }
257     CHECK(T.Constant(fac->NewNumber(0x80000000u)).Is(T.Unsigned32));
258     CHECK(!T.Constant(fac->NewNumber(0x80000000u)).Is(T.Unsigned31));
259     CHECK(T.Constant(fac->NewNumber(0xFFFFFFFFu)).Is(T.Unsigned32));
260     CHECK(!T.Constant(fac->NewNumber(0xFFFFFFFFu)).Is(T.Unsigned31));
261     CHECK(T.Constant(fac->NewNumber(0xFFFFFFFFu + 1.0)).Is(T.PlainNumber));
262     CHECK(!T.Constant(fac->NewNumber(0xFFFFFFFFu + 1.0)).Is(T.Integral32));
263     CHECK(T.Constant(fac->NewNumber(-0x7FFFFFFF - 2.0)).Is(T.PlainNumber));
264     CHECK(!T.Constant(fac->NewNumber(-0x7FFFFFFF - 2.0)).Is(T.Integral32));
265     CHECK(T.Constant(fac->NewNumber(0.1)).Is(T.PlainNumber));
266     CHECK(!T.Constant(fac->NewNumber(0.1)).Is(T.Integral32));
267     CHECK(T.Constant(fac->NewNumber(-10.1)).Is(T.PlainNumber));
268     CHECK(!T.Constant(fac->NewNumber(-10.1)).Is(T.Integral32));
269     CHECK(T.Constant(fac->NewNumber(10e60)).Is(T.PlainNumber));
270     CHECK(!T.Constant(fac->NewNumber(10e60)).Is(T.Integral32));
271     CHECK(T.Constant(fac->NewNumber(-1.0 * 0.0)).Is(T.MinusZero));
272     CHECK(T.Constant(fac->NewNumber(V8_INFINITY)).Is(T.PlainNumber));
273     CHECK(!T.Constant(fac->NewNumber(V8_INFINITY)).Is(T.Integral32));
274     CHECK(T.Constant(fac->NewNumber(-V8_INFINITY)).Is(T.PlainNumber));
275     CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY)).Is(T.Integral32));
276 
277     // Typing of Strings
278     Handle<String> s1 = fac->NewStringFromAsciiChecked("a");
279     CHECK(T.Constant(s1).Is(T.InternalizedString));
280     const base::uc16 two_byte[1] = {0x2603};
281     Handle<String> s2 = fac->NewTwoByteInternalizedString(
282         base::Vector<const base::uc16>(two_byte, 1), 1);
283     CHECK(T.Constant(s2).Is(T.InternalizedString));
284 
285     // Typing of special constants
286     CHECK(T.Constant(fac->the_hole_value()).Equals(T.Hole));
287     CHECK(T.Constant(fac->null_value()).Equals(T.Null));
288     CHECK(T.Constant(fac->undefined_value()).Equals(T.Undefined));
289     CHECK(T.Constant(fac->minus_zero_value()).Equals(T.MinusZero));
290     CHECK(T.Constant(fac->NewNumber(-0.0)).Equals(T.MinusZero));
291     CHECK(T.Constant(fac->nan_value()).Equals(T.NaN));
292     CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN()))
293               .Equals(T.NaN));
294   }
295 
Rangev8::internal::compiler::__anonb59da7f10111::Tests296   void Range() {
297     // Constructor
298     for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
299       for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
300         double min = (*i)->Number();
301         double max = (*j)->Number();
302         if (min > max) std::swap(min, max);
303         Type type = T.Range(min, max);
304         CHECK(type.IsRange());
305       }
306     }
307 
308     // Range attributes
309     for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
310       for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
311         double min = (*i)->Number();
312         double max = (*j)->Number();
313         if (min > max) std::swap(min, max);
314         Type type = T.Range(min, max);
315         CHECK(min == type.AsRange()->Min());
316         CHECK(max == type.AsRange()->Max());
317       }
318     }
319 
320     // Functionality & Injectivity:
321     // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2
322     for (ValueIterator i1 = T.integers.begin();
323         i1 != T.integers.end(); ++i1) {
324       for (ValueIterator j1 = i1;
325           j1 != T.integers.end(); ++j1) {
326         for (ValueIterator i2 = T.integers.begin();
327             i2 != T.integers.end(); ++i2) {
328           for (ValueIterator j2 = i2;
329               j2 != T.integers.end(); ++j2) {
330             double min1 = (*i1)->Number();
331             double max1 = (*j1)->Number();
332             double min2 = (*i2)->Number();
333             double max2 = (*j2)->Number();
334             if (min1 > max1) std::swap(min1, max1);
335             if (min2 > max2) std::swap(min2, max2);
336             Type type1 = T.Range(min1, max1);
337             Type type2 = T.Range(min2, max2);
338             CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2));
339           }
340         }
341       }
342     }
343   }
344 
MinMaxv8::internal::compiler::__anonb59da7f10111::Tests345   void MinMax() {
346     // If b is regular numeric bitset, then Range(b.Min(), b.Max()).Is(b).
347     // TODO(neis): Need to ignore representation for this to be true.
348     /*
349     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
350       Type type = *it;
351       if (this->IsBitset(type) && type.Is(T.Number) &&
352           !type.Is(T.None) && !type.Is(T.NaN)) {
353         Type range = T.Range(
354             isolate->factory()->NewNumber(type.Min()),
355             isolate->factory()->NewNumber(type.Max()));
356         CHECK(range.Is(type));
357       }
358     }
359     */
360 
361     // If b is regular numeric bitset, then b.Min() and b.Max() are integers.
362     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
363       Type type = *it;
364       if (this->IsBitset(type) && type.Is(T.Number) && !type.Is(T.NaN)) {
365         CHECK(IsInteger(type.Min()) && IsInteger(type.Max()));
366       }
367     }
368 
369     // If b1 and b2 are regular numeric bitsets with b1.Is(b2), then
370     // b1.Min() >= b2.Min() and b1.Max() <= b2.Max().
371     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
372       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
373         Type type1 = *it1;
374         Type type2 = *it2;
375         if (this->IsBitset(type1) && type1.Is(type2) && type2.Is(T.Number) &&
376             !type1.Is(T.NaN) && !type2.Is(T.NaN)) {
377           CHECK(type1.Min() >= type2.Min());
378           CHECK(type1.Max() <= type2.Max());
379         }
380       }
381     }
382 
383     // Lub(Range(x,y)).Min() <= x and y <= Lub(Range(x,y)).Max()
384     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
385       Type type = *it;
386       if (type.IsRange()) {
387         Type lub = type.BitsetLubForTesting();
388         CHECK(lub.Min() <= type.Min() && type.Max() <= lub.Max());
389       }
390     }
391 
392     // Rangification: If T.Is(Range(-inf,+inf)) and T is inhabited, then
393     // T.Is(Range(T.Min(), T.Max())).
394     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
395       Type type = *it;
396       CHECK(!type.Is(T.Integer) || type.IsNone() ||
397             type.Is(T.Range(type.Min(), type.Max())));
398     }
399   }
400 
BitsetGlbv8::internal::compiler::__anonb59da7f10111::Tests401   void BitsetGlb() {
402     // Lower: (T->BitsetGlb()).Is(T)
403     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
404       Type type = *it;
405       Type glb = type.BitsetGlbForTesting();
406       CHECK(glb.Is(type));
407     }
408 
409     // Greatest: If T1.IsBitset() and T1.Is(T2), then T1.Is(T2->BitsetGlb())
410     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
411       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
412         Type type1 = *it1;
413         Type type2 = *it2;
414         Type glb2 = type2.BitsetGlbForTesting();
415         CHECK(!this->IsBitset(type1) || !type1.Is(type2) || type1.Is(glb2));
416       }
417     }
418 
419     // Monotonicity: T1.Is(T2) implies (T1->BitsetGlb()).Is(T2->BitsetGlb())
420     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
421       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
422         Type type1 = *it1;
423         Type type2 = *it2;
424         Type glb1 = type1.BitsetGlbForTesting();
425         Type glb2 = type2.BitsetGlbForTesting();
426         CHECK(!type1.Is(type2) || glb1.Is(glb2));
427       }
428     }
429   }
430 
BitsetLubv8::internal::compiler::__anonb59da7f10111::Tests431   void BitsetLub() {
432     // Upper: T.Is(T->BitsetLub())
433     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
434       Type type = *it;
435       Type lub = type.BitsetLubForTesting();
436       CHECK(type.Is(lub));
437     }
438 
439     // Least: If T2.IsBitset() and T1.Is(T2), then (T1->BitsetLub()).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         Type type1 = *it1;
443         Type type2 = *it2;
444         Type lub1 = type1.BitsetLubForTesting();
445         CHECK(!this->IsBitset(type2) || !type1.Is(type2) || lub1.Is(type2));
446       }
447     }
448 
449     // Monotonicity: T1.Is(T2) implies (T1->BitsetLub()).Is(T2->BitsetLub())
450     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
451       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
452         Type type1 = *it1;
453         Type type2 = *it2;
454         Type lub1 = type1.BitsetLubForTesting();
455         Type lub2 = type2.BitsetLubForTesting();
456         CHECK(!type1.Is(type2) || lub1.Is(lub2));
457       }
458     }
459   }
460 
Is1v8::internal::compiler::__anonb59da7f10111::Tests461   void Is1() {
462     // Least Element (Bottom): None.Is(T)
463     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
464       Type type = *it;
465       CHECK(T.None.Is(type));
466     }
467 
468     // Greatest Element (Top): T.Is(Any)
469     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
470       Type type = *it;
471       CHECK(type.Is(T.Any));
472     }
473 
474     // Bottom Uniqueness: T.Is(None) implies T = None
475     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
476       Type type = *it;
477       if (type.Is(T.None)) CheckEqual(type, T.None);
478     }
479 
480     // Top Uniqueness: Any.Is(T) implies T = Any
481     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
482       Type type = *it;
483       if (T.Any.Is(type)) CheckEqual(type, T.Any);
484     }
485 
486     // Reflexivity: T.Is(T)
487     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
488       Type type = *it;
489       CHECK(type.Is(type));
490     }
491 
492     // Transitivity: T1.Is(T2) and T2.Is(T3) implies T1.Is(T3)
493     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
494       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
495         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
496           Type type1 = *it1;
497           Type type2 = *it2;
498           Type type3 = *it3;
499           CHECK(!(type1.Is(type2) && type2.Is(type3)) || type1.Is(type3));
500         }
501       }
502     }
503 
504     // Antisymmetry: T1.Is(T2) and T2.Is(T1) iff T1 = T2
505     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
506       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
507         Type type1 = *it1;
508         Type type2 = *it2;
509         CHECK((type1.Is(type2) && type2.Is(type1)) == Equal(type1, type2));
510       }
511     }
512 
513     // (In-)Compatibilities.
514     for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
515       for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
516         Type type1 = *i;
517         Type type2 = *j;
518         CHECK(
519             !type1.Is(type2) || this->IsBitset(type2) || this->IsUnion(type2) ||
520             this->IsUnion(type1) ||
521             (type1.IsHeapConstant() && type2.IsHeapConstant()) ||
522             (this->IsBitset(type1) && type2.IsRange()) ||
523             (type1.IsRange() && type2.IsRange()) ||
524             (type1.IsOtherNumberConstant() && type2.IsOtherNumberConstant()) ||
525             type1.IsNone());
526       }
527     }
528   }
529 
Is2v8::internal::compiler::__anonb59da7f10111::Tests530   void Is2() {
531     // Range(X1, Y1).Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2
532     for (ValueIterator i1 = T.integers.begin();
533         i1 != T.integers.end(); ++i1) {
534       for (ValueIterator j1 = i1;
535           j1 != T.integers.end(); ++j1) {
536         for (ValueIterator i2 = T.integers.begin();
537              i2 != T.integers.end(); ++i2) {
538           for (ValueIterator j2 = i2;
539                j2 != T.integers.end(); ++j2) {
540             double min1 = (*i1)->Number();
541             double max1 = (*j1)->Number();
542             double min2 = (*i2)->Number();
543             double max2 = (*j2)->Number();
544             if (min1 > max1) std::swap(min1, max1);
545             if (min2 > max2) std::swap(min2, max2);
546             Type type1 = T.Range(min1, max1);
547             Type type2 = T.Range(min2, max2);
548             CHECK(type1.Is(type2) == (min1 >= min2 && max1 <= max2));
549           }
550         }
551       }
552     }
553 
554     // Constant(V1).Is(Constant(V2)) iff V1 = V2
555     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
556       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
557         Handle<i::Object> value1 = *vt1;
558         Handle<i::Object> value2 = *vt2;
559         Type const_type1 = T.Constant(value1);
560         Type const_type2 = T.Constant(value2);
561         if (const_type1.IsOtherNumberConstant() &&
562             const_type2.IsOtherNumberConstant()) {
563           CHECK(const_type1.Is(const_type2) ==
564                 (const_type1.AsOtherNumberConstant()->Value() ==
565                  const_type2.AsOtherNumberConstant()->Value()));
566         } else if (const_type1.IsRange() && const_type2.IsRange()) {
567           CHECK(
568               Equal(const_type1, const_type2) ==
569               ((const_type1.AsRange()->Min() == const_type2.AsRange()->Min()) &&
570                (const_type1.AsRange()->Max() == const_type2.AsRange()->Max())));
571         } else {
572           CHECK(const_type1.Is(const_type2) == (*value1 == *value2));
573         }
574       }
575     }
576 
577     // Range-specific subtyping
578 
579     // Lub(Range(x,y)).Is(T.Union(T.Integral32, T.OtherNumber))
580     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
581       Type type = *it;
582       if (type.IsRange()) {
583         Type lub = type.BitsetLubForTesting();
584         CHECK(lub.Is(T.PlainNumber));
585       }
586     }
587 
588 
589     // Subtyping between concrete basic types
590 
591     CheckUnordered(T.Boolean, T.Null);
592     CheckUnordered(T.Undefined, T.Null);
593     CheckUnordered(T.Boolean, T.Undefined);
594 
595     CheckSub(T.SignedSmall, T.Number);
596     CheckSub(T.Signed32, T.Number);
597     CheckSubOrEqual(T.SignedSmall, T.Signed32);
598     CheckUnordered(T.SignedSmall, T.MinusZero);
599     CheckUnordered(T.Signed32, T.Unsigned32);
600 
601     CheckSub(T.UniqueName, T.Name);
602     CheckSub(T.String, T.Name);
603     CheckSub(T.InternalizedString, T.String);
604     CheckSub(T.InternalizedString, T.UniqueName);
605     CheckSub(T.InternalizedString, T.Name);
606     CheckSub(T.Symbol, T.UniqueName);
607     CheckSub(T.Symbol, T.Name);
608     CheckUnordered(T.String, T.UniqueName);
609     CheckUnordered(T.String, T.Symbol);
610     CheckUnordered(T.InternalizedString, T.Symbol);
611 
612     CheckSub(T.Object, T.Receiver);
613     CheckSub(T.Proxy, T.Receiver);
614     CheckSub(T.Array, T.Object);
615     CheckSub(T.OtherObject, T.Object);
616     CheckSub(T.OtherUndetectable, T.Object);
617 
618     CheckUnordered(T.Object, T.Proxy);
619     CheckUnordered(T.Array, T.Undetectable);
620     CheckUnordered(T.OtherObject, T.Undetectable);
621 
622     // Subtyping between concrete structural types
623 
624     CheckSub(T.SmiConstant, T.SignedSmall);
625     CheckSub(T.SmiConstant, T.Signed32);
626     CheckSub(T.SmiConstant, T.Number);
627     CheckSub(T.ObjectConstant1, T.Object);
628     CheckSub(T.ObjectConstant2, T.Object);
629     CheckSub(T.ArrayConstant, T.Object);
630     CheckSub(T.ArrayConstant, T.Array);
631     CheckSub(T.ArrayConstant, T.Receiver);
632     CheckSub(T.UninitializedConstant, T.Internal);
633     CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
634     CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
635     CheckUnordered(T.UninitializedConstant, T.Null);
636     CheckUnordered(T.UninitializedConstant, T.Undefined);
637   }
638 
Maybev8::internal::compiler::__anonb59da7f10111::Tests639   void Maybe() {
640     // T.Maybe(Any) iff T inhabited
641     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
642       Type type = *it;
643       CHECK(type.Maybe(T.Any) == !type.IsNone());
644     }
645 
646     // T.Maybe(None) never
647     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
648       Type type = *it;
649       CHECK(!type.Maybe(T.None));
650     }
651 
652     // Reflexivity upto Inhabitation: T.Maybe(T) iff T inhabited
653     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
654       Type type = *it;
655       CHECK(type.Maybe(type) == !type.IsNone());
656     }
657 
658     // Symmetry: T1.Maybe(T2) iff T2.Maybe(T1)
659     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
660       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
661         Type type1 = *it1;
662         Type type2 = *it2;
663         CHECK(type1.Maybe(type2) == type2.Maybe(type1));
664       }
665     }
666 
667     // T1.Maybe(T2) implies T1, T2 inhabited
668     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
669       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
670         Type type1 = *it1;
671         Type type2 = *it2;
672         CHECK(!type1.Maybe(type2) || (!type1.IsNone() && !type2.IsNone()));
673       }
674     }
675 
676     // T1.Maybe(T2) implies Intersect(T1, T2) inhabited
677     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
678       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
679         Type type1 = *it1;
680         Type type2 = *it2;
681         Type intersect12 = T.Intersect(type1, type2);
682         CHECK(!type1.Maybe(type2) || !intersect12.IsNone());
683       }
684     }
685 
686     // T1.Is(T2) and T1 inhabited implies T1.Maybe(T2)
687     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
688       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
689         Type type1 = *it1;
690         Type type2 = *it2;
691         CHECK(!(type1.Is(type2) && !type1.IsNone()) || type1.Maybe(type2));
692       }
693     }
694 
695     // Constant(V1).Maybe(Constant(V2)) iff V1 = V2
696     for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
697       for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
698         Handle<i::Object> value1 = *vt1;
699         Handle<i::Object> value2 = *vt2;
700         Type const_type1 = T.Constant(value1);
701         Type const_type2 = T.Constant(value2);
702         if (const_type1.IsOtherNumberConstant() &&
703             const_type2.IsOtherNumberConstant()) {
704           CHECK(const_type1.Maybe(const_type2) ==
705                 (const_type1.AsOtherNumberConstant()->Value() ==
706                  const_type2.AsOtherNumberConstant()->Value()));
707         } else if (const_type1.IsRange() && const_type2.IsRange()) {
708           CHECK(
709               Equal(const_type1, const_type2) ==
710               ((const_type1.AsRange()->Min() == const_type2.AsRange()->Min()) &&
711                (const_type1.AsRange()->Max() == const_type2.AsRange()->Max())));
712         } else {
713           CHECK(const_type1.Maybe(const_type2) == (*value1 == *value2));
714         }
715       }
716     }
717 
718     // Basic types
719     CheckDisjoint(T.Boolean, T.Null);
720     CheckDisjoint(T.Undefined, T.Null);
721     CheckDisjoint(T.Boolean, T.Undefined);
722     CheckOverlap(T.SignedSmall, T.Number);
723     CheckOverlap(T.NaN, T.Number);
724     CheckDisjoint(T.Signed32, T.NaN);
725     CheckOverlap(T.UniqueName, T.Name);
726     CheckOverlap(T.String, T.Name);
727     CheckOverlap(T.InternalizedString, T.String);
728     CheckOverlap(T.InternalizedString, T.UniqueName);
729     CheckOverlap(T.InternalizedString, T.Name);
730     CheckOverlap(T.Symbol, T.UniqueName);
731     CheckOverlap(T.Symbol, T.Name);
732     CheckOverlap(T.String, T.UniqueName);
733     CheckDisjoint(T.String, T.Symbol);
734     CheckDisjoint(T.InternalizedString, T.Symbol);
735     CheckOverlap(T.Object, T.Receiver);
736     CheckOverlap(T.OtherObject, T.Object);
737     CheckOverlap(T.Proxy, T.Receiver);
738     CheckDisjoint(T.Object, T.Proxy);
739 
740     // Structural types
741     CheckOverlap(T.SmiConstant, T.SignedSmall);
742     CheckOverlap(T.SmiConstant, T.Signed32);
743     CheckOverlap(T.SmiConstant, T.Number);
744     CheckOverlap(T.ObjectConstant1, T.Object);
745     CheckOverlap(T.ObjectConstant2, T.Object);
746     CheckOverlap(T.ArrayConstant, T.Object);
747     CheckOverlap(T.ArrayConstant, T.Receiver);
748     CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
749     CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
750     CheckDisjoint(T.ObjectConstant1, T.ArrayConstant);
751   }
752 
Union1v8::internal::compiler::__anonb59da7f10111::Tests753   void Union1() {
754     // Identity: Union(T, None) = T
755     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
756       Type type = *it;
757       Type union_type = T.Union(type, T.None);
758       CheckEqual(union_type, type);
759     }
760 
761     // Domination: Union(T, Any) = Any
762     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
763       Type type = *it;
764       Type union_type = T.Union(type, T.Any);
765       CheckEqual(union_type, T.Any);
766     }
767 
768     // Idempotence: Union(T, T) = T
769     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
770       Type type = *it;
771       Type union_type = T.Union(type, type);
772       CheckEqual(union_type, type);
773     }
774 
775     // Commutativity: Union(T1, T2) = Union(T2, T1)
776     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
777       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
778         Type type1 = *it1;
779         Type type2 = *it2;
780         Type union12 = T.Union(type1, type2);
781         Type union21 = T.Union(type2, type1);
782         CheckEqual(union12, union21);
783       }
784     }
785 
786     // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
787     // This does NOT hold!  For example:
788     // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0)
789     // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5)
790     /*
791     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
792       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
793         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
794           Type type1 = *it1;
795           Type type2 = *it2;
796           Type type3 = *it3;
797           Type union12 = T.Union(type1, type2);
798           Type union23 = T.Union(type2, type3);
799           Type union1_23 = T.Union(type1, union23);
800           Type union12_3 = T.Union(union12, type3);
801           CheckEqual(union1_23, union12_3);
802         }
803       }
804     }
805     */
806 
807     // Meet: T1.Is(Union(T1, T2)) and T2.Is(Union(T1, T2))
808     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
809       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
810         Type type1 = *it1;
811         Type type2 = *it2;
812         Type union12 = T.Union(type1, type2);
813         CHECK(type1.Is(union12));
814         CHECK(type2.Is(union12));
815       }
816     }
817 
818     // Upper Boundedness: T1.Is(T2) implies Union(T1, T2) = T2
819     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
820       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
821         Type type1 = *it1;
822         Type type2 = *it2;
823         Type union12 = T.Union(type1, type2);
824         if (type1.Is(type2)) CheckEqual(union12, type2);
825       }
826     }
827 
828     // Monotonicity: T1.Is(T2) implies Union(T1, T3).Is(Union(T2, T3))
829     // This does NOT hold.  For example:
830     // Range(-5,-1) <= Signed32
831     // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5)
832     /*
833     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
834       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
835         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
836           Type type1 = *it1;
837           Type type2 = *it2;
838           Type type3 = *it3;
839           Type union13 = T.Union(type1, type3);
840           Type union23 = T.Union(type2, type3);
841           CHECK(!type1.Is(type2) || union13.Is(union23));
842         }
843       }
844     }
845     */
846   }
847 
Union2v8::internal::compiler::__anonb59da7f10111::Tests848   void Union2() {
849     // Monotonicity: T1.Is(T3) and T2.Is(T3) implies Union(T1, T2).Is(T3)
850     // This does NOT hold.  For example:
851     // Range(-2^33, -2^33) <= OtherNumber
852     // Range(2^33, 2^33) <= OtherNumber
853     // Range(-2^33, 2^33) </= OtherNumber
854     /*
855     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
856       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
857         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
858           Type type1 = *it1;
859           Type type2 = *it2;
860           Type type3 = *it3;
861           Type union12 = T.Union(type1, type2);
862           CHECK(!(type1.Is(type3) && type2.Is(type3)) || union12.Is(type3));
863         }
864       }
865     }
866     */
867   }
868 
Union3v8::internal::compiler::__anonb59da7f10111::Tests869   void Union3() {
870     // Monotonicity: T1.Is(T2) or T1.Is(T3) implies T1.Is(Union(T2, T3))
871     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
872       HandleScope scope(isolate);
873       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
874         for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) {
875           Type type1 = *it1;
876           Type type2 = *it2;
877           Type type3 = *it3;
878           Type union23 = T.Union(type2, type3);
879           CHECK(!(type1.Is(type2) || type1.Is(type3)) || type1.Is(union23));
880         }
881       }
882     }
883   }
884 
Union4v8::internal::compiler::__anonb59da7f10111::Tests885   void Union4() {
886     // Constant-constant
887     CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
888     CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject);
889     CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject);
890     CheckDisjoint(
891         T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number);
892 
893     // Bitset-constant
894     CheckSub(
895         T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
896     CheckSub(T.Union(T.ObjectConstant1, T.OtherObject), T.Object);
897     CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.OtherObject);
898     CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
899     CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
900 
901     // Constant-union
902     CheckEqual(
903         T.Union(
904             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
905         T.Union(T.ObjectConstant2, T.ObjectConstant1));
906     CheckEqual(
907         T.Union(
908             T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
909         T.Union(
910             T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
911 
912     // Union-union
913     CheckEqual(
914         T.Union(
915             T.Union(T.ObjectConstant2, T.ObjectConstant1),
916             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
917         T.Union(T.ObjectConstant2, T.ObjectConstant1));
918   }
919 
Intersectv8::internal::compiler::__anonb59da7f10111::Tests920   void Intersect() {
921     // Identity: Intersect(T, Any) = T
922     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
923       Type type = *it;
924       Type intersect_type = T.Intersect(type, T.Any);
925       CheckEqual(intersect_type, type);
926     }
927 
928     // Domination: Intersect(T, None) = None
929     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
930       Type type = *it;
931       Type intersect_type = T.Intersect(type, T.None);
932       CheckEqual(intersect_type, T.None);
933     }
934 
935     // Idempotence: Intersect(T, T) = T
936     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
937       Type type = *it;
938       Type intersect_type = T.Intersect(type, type);
939       CheckEqual(intersect_type, type);
940     }
941 
942     // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
943     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
944       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
945         Type type1 = *it1;
946         Type type2 = *it2;
947         Type intersect12 = T.Intersect(type1, type2);
948         Type intersect21 = T.Intersect(type2, type1);
949         CheckEqual(intersect12, intersect21);
950       }
951     }
952 
953     // Lower Boundedness: T1.Is(T2) implies Intersect(T1, T2) = T1
954     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
955       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
956         Type type1 = *it1;
957         Type type2 = *it2;
958         Type intersect12 = T.Intersect(type1, type2);
959         if (type1.Is(type2)) CheckEqual(intersect12, type1);
960       }
961     }
962 
963     // Monotonicity: T1.Is(T2) and T1.Is(T3) implies T1.Is(Intersect(T2, T3))
964     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
965       HandleScope scope(isolate);
966       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
967         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
968           Type type1 = *it1;
969           Type type2 = *it2;
970           Type type3 = *it3;
971           Type intersect23 = T.Intersect(type2, type3);
972           CHECK(!(type1.Is(type2) && type1.Is(type3)) || type1.Is(intersect23));
973         }
974       }
975     }
976 
977     // Constant-union
978     CheckEqual(
979         T.Intersect(
980             T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
981         T.ObjectConstant1);
982     CheckEqual(
983         T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
984         T.SmiConstant);
985 
986     // Union-union
987     CheckEqual(
988         T.Intersect(
989             T.Union(T.ObjectConstant2, T.ObjectConstant1),
990             T.Union(T.ObjectConstant1, T.ObjectConstant2)),
991         T.Union(T.ObjectConstant2, T.ObjectConstant1));
992   }
993 
Distributivityv8::internal::compiler::__anonb59da7f10111::Tests994   void Distributivity() {
995     // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
996     // This does NOT hold.  For example:
997     // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged)
998     // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) =
999     // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
1000     // because Untagged <= Untagged \/ Class(../Tagged)
1001     /*
1002     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1003       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1004         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1005           Type type1 = *it1;
1006           Type type2 = *it2;
1007           Type type3 = *it3;
1008           Type union12 = T.Union(type1, type2);
1009           Type union13 = T.Union(type1, type3);
1010           Type intersect23 = T.Intersect(type2, type3);
1011           Type union1_23 = T.Union(type1, intersect23);
1012           Type intersect12_13 = T.Intersect(union12, union13);
1013           CHECK(Equal(union1_23, intersect12_13));
1014         }
1015       }
1016     }
1017     */
1018 
1019     // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
1020     // This does NOT hold.  For example:
1021     // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
1022     // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) =
1023     // Untagged \/ Class(../Tagged)
1024     /*
1025     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1026       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1027         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1028           Type type1 = *it1;
1029           Type type2 = *it2;
1030           Type type3 = *it3;
1031           Type intersect12 = T.Intersect(type1, type2);
1032           Type intersect13 = T.Intersect(type1, type3);
1033           Type union23 = T.Union(type2, type3);
1034           Type intersect1_23 = T.Intersect(type1, union23);
1035           Type union12_13 = T.Union(intersect12, intersect13);
1036           CHECK(Equal(intersect1_23, union12_13));
1037         }
1038       }
1039     }
1040     */
1041   }
1042 
GetRangev8::internal::compiler::__anonb59da7f10111::Tests1043   void GetRange() {
1044     // GetRange(Range(a, b)) = Range(a, b).
1045     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1046       Type type1 = *it1;
1047       if (type1.IsRange()) {
1048         const RangeType* range = type1.GetRange().AsRange();
1049         CHECK(type1.Min() == range->Min());
1050         CHECK(type1.Max() == range->Max());
1051       }
1052     }
1053   }
1054 };
1055 
1056 }  // namespace
1057 
TEST(IsSomeType)1058 TEST(IsSomeType) { Tests().IsSomeType(); }
TEST(BitsetType)1059 TEST(BitsetType) { Tests().Bitset(); }
TEST(ConstantType)1060 TEST(ConstantType) { Tests().Constant(); }
TEST(RangeType)1061 TEST(RangeType) { Tests().Range(); }
TEST(MinMax)1062 TEST(MinMax) { Tests().MinMax(); }
TEST(BitsetGlb)1063 TEST(BitsetGlb) { Tests().BitsetGlb(); }
TEST(BitsetLub)1064 TEST(BitsetLub) { Tests().BitsetLub(); }
TEST(Is1)1065 TEST(Is1) { Tests().Is1(); }
TEST(Is2)1066 TEST(Is2) { Tests().Is2(); }
TEST(Maybe)1067 TEST(Maybe) { Tests().Maybe(); }
TEST(Union1)1068 TEST(Union1) { Tests().Union1(); }
TEST(Union2)1069 TEST(Union2) { Tests().Union2(); }
TEST(Union3)1070 TEST(Union3) { Tests().Union3(); }
TEST(Union4)1071 TEST(Union4) { Tests().Union4(); }
TEST(Intersect)1072 TEST(Intersect) { Tests().Intersect(); }
TEST(Distributivity)1073 TEST(Distributivity) { Tests().Distributivity(); }
TEST(GetRange)1074 TEST(GetRange) { Tests().GetRange(); }
1075 
1076 }  // namespace compiler
1077 }  // namespace internal
1078 }  // namespace v8
1079