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