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.
7 #include "src/hydrogen-types.h"
8 #include "src/isolate-inl.h"
10 #include "test/cctest/cctest.h"
12 using namespace v8::internal;
14 // Testing auxiliaries (breaking the Type abstraction).
18 static bool IsStruct(Type* t, int tag) {
19 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
21 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; }
22 static bool IsUnion(Type* t) { return IsStruct(t, 6); }
24 static Struct* AsStruct(Type* t) {
25 return reinterpret_cast<Struct*>(t);
27 static int AsBitset(Type* t) {
28 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1);
30 static Struct* AsUnion(Type* t) {
33 static int Length(Struct* structured) {
34 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
37 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
39 struct BitsetType : Type::BitsetType {
40 using Type::BitsetType::New;
41 using Type::BitsetType::Glb;
42 using Type::BitsetType::Lub;
43 using Type::BitsetType::InherentLub;
49 typedef FixedArray Struct;
51 static bool IsStruct(Handle<HeapType> t, int tag) {
52 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
54 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
55 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
57 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
58 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
59 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
60 static int Length(Struct* structured) { return structured->length() - 1; }
62 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
64 struct BitsetType : HeapType::BitsetType {
65 using HeapType::BitsetType::New;
66 using HeapType::BitsetType::Glb;
67 using HeapType::BitsetType::Lub;
68 using HeapType::BitsetType::InherentLub;
69 static int Glb(Handle<HeapType> type) { return Glb(*type); }
70 static int Lub(Handle<HeapType> type) { return Lub(*type); }
71 static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); }
76 template<class Type, class TypeHandle, class Region>
79 Types(Region* region, Isolate* isolate)
80 : region_(region), rng_(isolate->random_number_generator()) {
81 #define DECLARE_TYPE(name, value) \
82 name = Type::name(region); \
83 types.push_back(name);
84 BITSET_TYPE_LIST(DECLARE_TYPE)
87 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize);
88 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize);
89 uninitialized_map = isolate->factory()->uninitialized_map();
90 ObjectClass = Type::Class(object_map, region);
91 ArrayClass = Type::Class(array_map, region);
92 UninitializedClass = Type::Class(uninitialized_map, region);
94 maps.push_back(object_map);
95 maps.push_back(array_map);
96 maps.push_back(uninitialized_map);
97 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
98 types.push_back(Type::Class(*it, region));
101 smi = handle(Smi::FromInt(666), isolate);
102 signed32 = isolate->factory()->NewHeapNumber(0x40000000);
103 object1 = isolate->factory()->NewJSObjectFromMap(object_map);
104 object2 = isolate->factory()->NewJSObjectFromMap(object_map);
105 array = isolate->factory()->NewJSArray(20);
106 uninitialized = isolate->factory()->uninitialized_value();
107 SmiConstant = Type::Constant(smi, region);
108 Signed32Constant = Type::Constant(signed32, region);
109 ObjectConstant1 = Type::Constant(object1, region);
110 ObjectConstant2 = Type::Constant(object2, region);
111 ArrayConstant = Type::Constant(array, region);
112 UninitializedConstant = Type::Constant(uninitialized, region);
114 values.push_back(smi);
115 values.push_back(signed32);
116 values.push_back(object1);
117 values.push_back(object2);
118 values.push_back(array);
119 values.push_back(uninitialized);
120 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
121 types.push_back(Type::Constant(*it, region));
124 doubles.push_back(-0.0);
125 doubles.push_back(+0.0);
126 doubles.push_back(-std::numeric_limits<double>::infinity());
127 doubles.push_back(+std::numeric_limits<double>::infinity());
128 for (int i = 0; i < 10; ++i) {
129 doubles.push_back(rng_->NextInt());
130 doubles.push_back(rng_->NextDouble() * rng_->NextInt());
133 NumberArray = Type::Array(Number, region);
134 StringArray = Type::Array(String, region);
135 AnyArray = Type::Array(Any, region);
137 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
138 NumberFunction1 = Type::Function(Number, Number, region);
139 NumberFunction2 = Type::Function(Number, Number, Number, region);
140 MethodFunction = Type::Function(String, Object, 0, region);
142 for (int i = 0; i < 30; ++i) {
143 types.push_back(Fuzz());
147 Handle<i::Map> object_map;
148 Handle<i::Map> array_map;
149 Handle<i::Map> uninitialized_map;
152 Handle<i::HeapNumber> signed32;
153 Handle<i::JSObject> object1;
154 Handle<i::JSObject> object2;
155 Handle<i::JSArray> array;
156 Handle<i::Oddball> uninitialized;
158 #define DECLARE_TYPE(name, value) TypeHandle name;
159 BITSET_TYPE_LIST(DECLARE_TYPE)
162 TypeHandle ObjectClass;
163 TypeHandle ArrayClass;
164 TypeHandle UninitializedClass;
166 TypeHandle SmiConstant;
167 TypeHandle Signed32Constant;
168 TypeHandle ObjectConstant1;
169 TypeHandle ObjectConstant2;
170 TypeHandle ArrayConstant;
171 TypeHandle UninitializedConstant;
173 TypeHandle NumberArray;
174 TypeHandle StringArray;
177 TypeHandle SignedFunction1;
178 TypeHandle NumberFunction1;
179 TypeHandle NumberFunction2;
180 TypeHandle MethodFunction;
182 typedef std::vector<TypeHandle> TypeVector;
183 typedef std::vector<Handle<i::Map> > MapVector;
184 typedef std::vector<Handle<i::Object> > ValueVector;
185 typedef std::vector<double> DoubleVector;
190 DoubleVector doubles; // Some floating-point values, excluding NaN.
192 // Range type helper functions, partially copied from types.cc.
193 // Note: dle(dmin(x,y), dmax(x,y)) holds iff neither x nor y is NaN.
194 bool dle(double x, double y) {
195 return x <= y && (x != 0 || IsMinusZero(x) || !IsMinusZero(y));
197 bool deq(double x, double y) {
198 return dle(x, y) && dle(y, x);
200 double dmin(double x, double y) {
201 return dle(x, y) ? x : y;
203 double dmax(double x, double y) {
204 return dle(x, y) ? y : x;
207 TypeHandle Of(Handle<i::Object> value) {
208 return Type::Of(value, region_);
211 TypeHandle NowOf(Handle<i::Object> value) {
212 return Type::NowOf(value, region_);
215 TypeHandle Constant(Handle<i::Object> value) {
216 return Type::Constant(value, region_);
219 TypeHandle Range(double min, double max) {
220 return Type::Range(min, max, region_);
223 TypeHandle Class(Handle<i::Map> map) {
224 return Type::Class(map, region_);
227 TypeHandle Array1(TypeHandle element) {
228 return Type::Array(element, region_);
231 TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
232 return Type::Function(result, receiver, 0, region_);
235 TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
236 TypeHandle type = Type::Function(result, receiver, 1, region_);
237 type->AsFunction()->InitParameter(0, arg);
241 TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
242 return Type::Function(result, arg1, arg2, region_);
245 TypeHandle Union(TypeHandle t1, TypeHandle t2) {
246 return Type::Union(t1, t2, region_);
248 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
249 return Type::Intersect(t1, t2, region_);
252 template<class Type2, class TypeHandle2>
253 TypeHandle Convert(TypeHandle2 t) {
254 return Type::template Convert<Type2>(t, region_);
257 TypeHandle Random() {
258 return types[rng_->NextInt(static_cast<int>(types.size()))];
261 TypeHandle Fuzz(int depth = 5) {
262 switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
265 #define COUNT_BITSET_TYPES(type, value) + 1
266 BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
267 #undef COUNT_BITSET_TYPES
269 int i = rng_->NextInt(n);
270 #define PICK_BITSET_TYPE(type, value) \
271 if (i-- == 0) return Type::type(region_);
272 BITSET_TYPE_LIST(PICK_BITSET_TYPE)
273 #undef PICK_BITSET_TYPE
277 int i = rng_->NextInt(static_cast<int>(maps.size()));
278 return Type::Class(maps[i], region_);
280 case 2: { // constant
281 int i = rng_->NextInt(static_cast<int>(values.size()));
282 return Type::Constant(values[i], region_);
285 int depth = rng_->NextInt(3);
286 TypeHandle type = Type::Internal(region_);
287 for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
291 TypeHandle element = Fuzz(depth / 2);
292 return Type::Array(element, region_);
295 case 6: { // function
296 TypeHandle result = Fuzz(depth / 2);
297 TypeHandle receiver = Fuzz(depth / 2);
298 int arity = rng_->NextInt(3);
299 TypeHandle type = Type::Function(result, receiver, arity, region_);
300 for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
301 TypeHandle parameter = Fuzz(depth / 2);
302 type->AsFunction()->InitParameter(i, parameter);
307 int n = rng_->NextInt(10);
308 TypeHandle type = None;
309 for (int i = 0; i < n; ++i) {
310 TypeHandle operand = Fuzz(depth - 1);
311 type = Type::Union(type, operand, region_);
319 Region* region() { return region_; }
323 v8::base::RandomNumberGenerator* rng_;
327 template<class Type, class TypeHandle, class Region, class Rep>
329 typedef Types<Type, TypeHandle, Region> TypesInstance;
330 typedef typename TypesInstance::TypeVector::iterator TypeIterator;
331 typedef typename TypesInstance::MapVector::iterator MapIterator;
332 typedef typename TypesInstance::ValueVector::iterator ValueIterator;
333 typedef typename TypesInstance::DoubleVector::iterator DoubleIterator;
341 isolate(CcTest::i_isolate()),
344 T(Rep::ToRegion(&zone, isolate), isolate) {
347 bool Equal(TypeHandle type1, TypeHandle type2) {
349 type1->Equals(type2) &&
350 Rep::IsBitset(type1) == Rep::IsBitset(type2) &&
351 Rep::IsUnion(type1) == Rep::IsUnion(type2) &&
352 type1->NumClasses() == type2->NumClasses() &&
353 type1->NumConstants() == type2->NumConstants() &&
354 (!Rep::IsBitset(type1) ||
355 Rep::AsBitset(type1) == Rep::AsBitset(type2)) &&
356 (!Rep::IsUnion(type1) ||
357 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2)));
360 void CheckEqual(TypeHandle type1, TypeHandle type2) {
361 CHECK(Equal(type1, type2));
364 void CheckSub(TypeHandle type1, TypeHandle type2) {
365 CHECK(type1->Is(type2));
366 CHECK(!type2->Is(type1));
367 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
368 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
372 void CheckUnordered(TypeHandle type1, TypeHandle type2) {
373 CHECK(!type1->Is(type2));
374 CHECK(!type2->Is(type1));
375 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
376 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2));
380 void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
381 CHECK(type1->Maybe(type2));
382 CHECK(type2->Maybe(type1));
383 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
385 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
389 void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) {
390 CHECK(!type1->Is(type2));
391 CHECK(!type2->Is(type1));
392 CHECK(!type1->Maybe(type2));
393 CHECK(!type2->Maybe(type1));
394 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) {
396 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask));
401 // None and Any are bitsets.
402 CHECK(this->IsBitset(T.None));
403 CHECK(this->IsBitset(T.Any));
405 CHECK_EQ(0, this->AsBitset(T.None));
406 CHECK_EQ(-1, this->AsBitset(T.Any));
408 // Union(T1, T2) is bitset for bitsets T1,T2
409 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
410 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
411 TypeHandle type1 = *it1;
412 TypeHandle type2 = *it2;
413 TypeHandle union12 = T.Union(type1, type2);
414 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
415 this->IsBitset(union12));
419 // Intersect(T1, T2) is bitset for bitsets T1,T2
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 TypeHandle type1 = *it1;
423 TypeHandle type2 = *it2;
424 TypeHandle intersect12 = T.Intersect(type1, type2);
425 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
426 this->IsBitset(intersect12));
430 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2)
431 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
432 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
433 TypeHandle type1 = *it1;
434 TypeHandle type2 = *it2;
435 TypeHandle union12 = T.Union(type1, type2);
436 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
437 this->IsBitset(union12));
441 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
442 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
443 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
444 TypeHandle type1 = *it1;
445 TypeHandle type2 = *it2;
446 TypeHandle union12 = T.Union(type1, type2);
447 if (this->IsBitset(type1) && this->IsBitset(type2)) {
449 this->AsBitset(type1) | this->AsBitset(type2),
450 this->AsBitset(union12));
455 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2
456 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
457 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
458 TypeHandle type1 = *it1;
459 TypeHandle type2 = *it2;
460 TypeHandle intersect12 = T.Intersect(type1, type2);
461 if (this->IsBitset(type1) && this->IsBitset(type2)) {
463 this->AsBitset(type1) & this->AsBitset(type2),
464 this->AsBitset(intersect12));
472 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
473 Handle<i::Map> map = *mt;
474 TypeHandle type = T.Class(map);
475 CHECK(type->IsClass());
479 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
480 Handle<i::Map> map = *mt;
481 TypeHandle type = T.Class(map);
482 CHECK(*map == *type->AsClass()->Map());
485 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
486 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
487 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
488 Handle<i::Map> map1 = *mt1;
489 Handle<i::Map> map2 = *mt2;
490 TypeHandle type1 = T.Class(map1);
491 TypeHandle type2 = T.Class(map2);
492 CHECK(Equal(type1, type2) == (*map1 == *map2));
499 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
500 Handle<i::Object> value = *vt;
501 TypeHandle type = T.Constant(value);
502 CHECK(type->IsConstant());
506 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
507 Handle<i::Object> value = *vt;
508 TypeHandle type = T.Constant(value);
509 CHECK(*value == *type->AsConstant()->Value());
512 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
513 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
514 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
515 Handle<i::Object> value1 = *vt1;
516 Handle<i::Object> value2 = *vt2;
517 TypeHandle type1 = T.Constant(value1);
518 TypeHandle type2 = T.Constant(value2);
519 CHECK(Equal(type1, type2) == (*value1 == *value2));
524 Factory* fac = isolate->factory();
525 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
526 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
527 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
528 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
529 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
530 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
531 if (SmiValuesAre31Bits()) {
532 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
533 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
534 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
535 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
536 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
538 CHECK(SmiValuesAre32Bits());
539 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
540 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
541 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
542 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
543 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
544 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
545 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
546 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
547 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
548 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
550 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
551 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
552 CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
553 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
554 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
555 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
556 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
557 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
558 CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
559 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
560 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
565 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) {
566 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) {
567 double min = T.dmin(*i, *j);
568 double max = T.dmax(*i, *j);
569 TypeHandle type = T.Range(min, max);
570 CHECK(type->IsRange());
575 for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) {
576 for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) {
577 double min = T.dmin(*i, *j);
578 double max = T.dmax(*i, *j);
579 printf("RangeType: min, max = %f, %f\n", min, max);
580 TypeHandle type = T.Range(min, max);
581 printf("RangeType: Min, Max = %f, %f\n",
582 type->AsRange()->Min(), type->AsRange()->Max());
583 CHECK(min == type->AsRange()->Min());
584 CHECK(max == type->AsRange()->Max());
588 // TODO(neis): enable once subtyping is updated.
589 // // Functionality & Injectivity: Range(min1, max1) = Range(min2, max2) <=>
590 // // min1 = min2 /\ max1 = max2
591 // for (DoubleIterator i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) {
592 // for (DoubleIterator j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) {
593 // for (DoubleIterator i2 = T.doubles.begin();
594 // i2 != T.doubles.end(); ++i2) {
595 // for (DoubleIterator j2 = T.doubles.begin();
596 // j2 != T.doubles.end(); ++j2) {
597 // double min1 = T.dmin(*i1, *j1);
598 // double max1 = T.dmax(*i1, *j1);
599 // double min2 = T.dmin(*i2, *j2);
600 // double max2 = T.dmax(*i2, *j2);
601 // TypeHandle type1 = T.Range(min1, max1);
602 // TypeHandle type2 = T.Range(min2, max2);
603 // CHECK(Equal(type1, type2) ==
604 // (T.deq(min1, min2) && T.deq(max1, max2)));
613 for (int i = 0; i < 20; ++i) {
614 TypeHandle type = T.Random();
615 TypeHandle array = T.Array1(type);
616 CHECK(array->IsArray());
620 for (int i = 0; i < 20; ++i) {
621 TypeHandle type = T.Random();
622 TypeHandle array = T.Array1(type);
623 CheckEqual(type, array->AsArray()->Element());
626 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
627 for (int i = 0; i < 20; ++i) {
628 for (int j = 0; j < 20; ++j) {
629 TypeHandle type1 = T.Random();
630 TypeHandle type2 = T.Random();
631 TypeHandle array1 = T.Array1(type1);
632 TypeHandle array2 = T.Array1(type2);
633 CHECK(Equal(array1, array2) == Equal(type1, type2));
640 for (int i = 0; i < 20; ++i) {
641 for (int j = 0; j < 20; ++j) {
642 for (int k = 0; k < 20; ++k) {
643 TypeHandle type1 = T.Random();
644 TypeHandle type2 = T.Random();
645 TypeHandle type3 = T.Random();
646 TypeHandle function0 = T.Function0(type1, type2);
647 TypeHandle function1 = T.Function1(type1, type2, type3);
648 TypeHandle function2 = T.Function2(type1, type2, type3);
649 CHECK(function0->IsFunction());
650 CHECK(function1->IsFunction());
651 CHECK(function2->IsFunction());
657 for (int i = 0; i < 20; ++i) {
658 for (int j = 0; j < 20; ++j) {
659 for (int k = 0; k < 20; ++k) {
660 TypeHandle type1 = T.Random();
661 TypeHandle type2 = T.Random();
662 TypeHandle type3 = T.Random();
663 TypeHandle function0 = T.Function0(type1, type2);
664 TypeHandle function1 = T.Function1(type1, type2, type3);
665 TypeHandle function2 = T.Function2(type1, type2, type3);
666 CHECK_EQ(0, function0->AsFunction()->Arity());
667 CHECK_EQ(1, function1->AsFunction()->Arity());
668 CHECK_EQ(2, function2->AsFunction()->Arity());
669 CheckEqual(type1, function0->AsFunction()->Result());
670 CheckEqual(type1, function1->AsFunction()->Result());
671 CheckEqual(type1, function2->AsFunction()->Result());
672 CheckEqual(type2, function0->AsFunction()->Receiver());
673 CheckEqual(type2, function1->AsFunction()->Receiver());
674 CheckEqual(T.Any, function2->AsFunction()->Receiver());
675 CheckEqual(type3, function1->AsFunction()->Parameter(0));
676 CheckEqual(type2, function2->AsFunction()->Parameter(0));
677 CheckEqual(type3, function2->AsFunction()->Parameter(1));
682 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
683 for (int i = 0; i < 20; ++i) {
684 for (int j = 0; j < 20; ++j) {
685 for (int k = 0; k < 20; ++k) {
686 TypeHandle type1 = T.Random();
687 TypeHandle type2 = T.Random();
688 TypeHandle type3 = T.Random();
689 TypeHandle function01 = T.Function0(type1, type2);
690 TypeHandle function02 = T.Function0(type1, type3);
691 TypeHandle function03 = T.Function0(type3, type2);
692 TypeHandle function11 = T.Function1(type1, type2, type2);
693 TypeHandle function12 = T.Function1(type1, type2, type3);
694 TypeHandle function21 = T.Function2(type1, type2, type2);
695 TypeHandle function22 = T.Function2(type1, type2, type3);
696 TypeHandle function23 = T.Function2(type1, type3, type2);
697 CHECK(Equal(function01, function02) == Equal(type2, type3));
698 CHECK(Equal(function01, function03) == Equal(type1, type3));
699 CHECK(Equal(function11, function12) == Equal(type2, type3));
700 CHECK(Equal(function21, function22) == Equal(type2, type3));
701 CHECK(Equal(function21, function23) == Equal(type2, type3));
708 // Constant(V)->Is(Of(V))
709 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
710 Handle<i::Object> value = *vt;
711 TypeHandle const_type = T.Constant(value);
712 TypeHandle of_type = T.Of(value);
713 CHECK(const_type->Is(of_type));
716 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V))
717 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
718 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
719 Handle<i::Object> value = *vt;
720 TypeHandle type = *it;
721 TypeHandle const_type = T.Constant(value);
722 TypeHandle of_type = T.Of(value);
723 CHECK(const_type->Is(type) ==
724 (of_type->Is(type) || type->Maybe(const_type)));
730 // Constant(V)->NowIs(NowOf(V))
731 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
732 Handle<i::Object> value = *vt;
733 TypeHandle const_type = T.Constant(value);
734 TypeHandle nowof_type = T.NowOf(value);
735 CHECK(const_type->NowIs(nowof_type));
738 // NowOf(V)->Is(Of(V))
739 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
740 Handle<i::Object> value = *vt;
741 TypeHandle nowof_type = T.NowOf(value);
742 TypeHandle of_type = T.Of(value);
743 CHECK(nowof_type->Is(of_type));
746 // Constant(V)->NowIs(T) iff NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
747 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
748 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
749 Handle<i::Object> value = *vt;
750 TypeHandle type = *it;
751 TypeHandle const_type = T.Constant(value);
752 TypeHandle nowof_type = T.NowOf(value);
753 CHECK(const_type->NowIs(type) ==
754 (nowof_type->NowIs(type) || type->Maybe(const_type)));
758 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V))
759 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
760 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
761 Handle<i::Object> value = *vt;
762 TypeHandle type = *it;
763 TypeHandle const_type = T.Constant(value);
764 TypeHandle nowof_type = T.NowOf(value);
765 CHECK(!const_type->Is(type) ||
766 (nowof_type->Is(type) || type->Maybe(const_type)));
772 // Ordering: (T->BitsetGlb())->Is(T->BitsetLub())
773 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
774 TypeHandle type = *it;
776 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
778 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
782 // Lower bound: (T->BitsetGlb())->Is(T)
783 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
784 TypeHandle type = *it;
786 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
787 CHECK(glb->Is(type));
790 // Upper bound: T->Is(T->BitsetLub())
791 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
792 TypeHandle type = *it;
794 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
795 CHECK(type->Is(lub));
798 // Inherent bound: (T->BitsetLub())->Is(T->InherentBitsetLub())
799 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
800 TypeHandle type = *it;
802 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
803 TypeHandle inherent =
804 Rep::BitsetType::New(Rep::BitsetType::InherentLub(type), T.region());
805 CHECK(lub->Is(inherent));
810 // Least Element (Bottom): None->Is(T)
811 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
812 TypeHandle type = *it;
813 CHECK(T.None->Is(type));
816 // Greatest Element (Top): T->Is(Any)
817 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
818 TypeHandle type = *it;
819 CHECK(type->Is(T.Any));
822 // Bottom Uniqueness: T->Is(None) implies T = None
823 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
824 TypeHandle type = *it;
825 if (type->Is(T.None)) CheckEqual(type, T.None);
828 // Top Uniqueness: Any->Is(T) implies T = Any
829 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
830 TypeHandle type = *it;
831 if (T.Any->Is(type)) CheckEqual(type, T.Any);
834 // Reflexivity: T->Is(T)
835 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
836 TypeHandle type = *it;
837 CHECK(type->Is(type));
840 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
841 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
842 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
843 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
844 TypeHandle type1 = *it1;
845 TypeHandle type2 = *it2;
846 TypeHandle type3 = *it3;
847 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
852 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
853 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
854 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
855 TypeHandle type1 = *it1;
856 TypeHandle type2 = *it2;
857 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
861 // Constant(V1)->Is(Constant(V2)) iff V1 = V2
862 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
863 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
864 Handle<i::Object> value1 = *vt1;
865 Handle<i::Object> value2 = *vt2;
866 TypeHandle const_type1 = T.Constant(value1);
867 TypeHandle const_type2 = T.Constant(value2);
868 CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
872 // Class(M1)->Is(Class(M2)) iff M1 = M2
873 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
874 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
875 Handle<i::Map> map1 = *mt1;
876 Handle<i::Map> map2 = *mt2;
877 TypeHandle class_type1 = T.Class(map1);
878 TypeHandle class_type2 = T.Class(map2);
879 CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
883 // Constant(V)->Is(Class(M)) never
884 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
885 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
886 Handle<i::Map> map = *mt;
887 Handle<i::Object> value = *vt;
888 TypeHandle constant_type = T.Constant(value);
889 TypeHandle class_type = T.Class(map);
890 CHECK(!constant_type->Is(class_type));
894 // Class(M)->Is(Constant(V)) never
895 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
896 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
897 Handle<i::Map> map = *mt;
898 Handle<i::Object> value = *vt;
899 TypeHandle constant_type = T.Constant(value);
900 TypeHandle class_type = T.Class(map);
901 CHECK(!class_type->Is(constant_type));
906 CheckUnordered(T.Boolean, T.Null);
907 CheckUnordered(T.Undefined, T.Null);
908 CheckUnordered(T.Boolean, T.Undefined);
910 CheckSub(T.SignedSmall, T.Number);
911 CheckSub(T.Signed32, T.Number);
912 CheckSub(T.SignedSmall, T.Signed32);
913 CheckUnordered(T.SignedSmall, T.MinusZero);
914 CheckUnordered(T.Signed32, T.Unsigned32);
916 CheckSub(T.UniqueName, T.Name);
917 CheckSub(T.String, T.Name);
918 CheckSub(T.InternalizedString, T.String);
919 CheckSub(T.InternalizedString, T.UniqueName);
920 CheckSub(T.InternalizedString, T.Name);
921 CheckSub(T.Symbol, T.UniqueName);
922 CheckSub(T.Symbol, T.Name);
923 CheckUnordered(T.String, T.UniqueName);
924 CheckUnordered(T.String, T.Symbol);
925 CheckUnordered(T.InternalizedString, T.Symbol);
927 CheckSub(T.Object, T.Receiver);
928 CheckSub(T.Array, T.Object);
929 CheckSub(T.Function, T.Object);
930 CheckSub(T.Proxy, T.Receiver);
931 CheckUnordered(T.Object, T.Proxy);
932 CheckUnordered(T.Array, T.Function);
935 CheckSub(T.ObjectClass, T.Object);
936 CheckSub(T.ArrayClass, T.Object);
937 CheckSub(T.ArrayClass, T.Array);
938 CheckSub(T.UninitializedClass, T.Internal);
939 CheckUnordered(T.ObjectClass, T.ArrayClass);
940 CheckUnordered(T.UninitializedClass, T.Null);
941 CheckUnordered(T.UninitializedClass, T.Undefined);
943 CheckSub(T.SmiConstant, T.SignedSmall);
944 CheckSub(T.SmiConstant, T.Signed32);
945 CheckSub(T.SmiConstant, T.Number);
946 CheckSub(T.ObjectConstant1, T.Object);
947 CheckSub(T.ObjectConstant2, T.Object);
948 CheckSub(T.ArrayConstant, T.Object);
949 CheckSub(T.ArrayConstant, T.Array);
950 CheckSub(T.UninitializedConstant, T.Internal);
951 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
952 CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
953 CheckUnordered(T.UninitializedConstant, T.Null);
954 CheckUnordered(T.UninitializedConstant, T.Undefined);
956 CheckUnordered(T.ObjectConstant1, T.ObjectClass);
957 CheckUnordered(T.ObjectConstant2, T.ObjectClass);
958 CheckUnordered(T.ObjectConstant1, T.ArrayClass);
959 CheckUnordered(T.ObjectConstant2, T.ArrayClass);
960 CheckUnordered(T.ArrayConstant, T.ObjectClass);
962 CheckSub(T.NumberArray, T.Array);
963 CheckSub(T.NumberArray, T.Object);
964 CheckUnordered(T.StringArray, T.AnyArray);
966 CheckSub(T.MethodFunction, T.Function);
967 CheckSub(T.NumberFunction1, T.Object);
968 CheckUnordered(T.SignedFunction1, T.NumberFunction1);
969 CheckUnordered(T.NumberFunction1, T.NumberFunction2);
973 // Least Element (Bottom): None->NowIs(T)
974 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
975 TypeHandle type = *it;
976 CHECK(T.None->NowIs(type));
979 // Greatest Element (Top): T->NowIs(Any)
980 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
981 TypeHandle type = *it;
982 CHECK(type->NowIs(T.Any));
985 // Bottom Uniqueness: T->NowIs(None) implies T = None
986 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
987 TypeHandle type = *it;
988 if (type->NowIs(T.None)) CheckEqual(type, T.None);
991 // Top Uniqueness: Any->NowIs(T) implies T = Any
992 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
993 TypeHandle type = *it;
994 if (T.Any->NowIs(type)) CheckEqual(type, T.Any);
997 // Reflexivity: T->NowIs(T)
998 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
999 TypeHandle type = *it;
1000 CHECK(type->NowIs(type));
1003 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3)
1004 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1005 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1006 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1007 TypeHandle type1 = *it1;
1008 TypeHandle type2 = *it2;
1009 TypeHandle type3 = *it3;
1010 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) ||
1011 type1->NowIs(type3));
1016 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2
1017 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1018 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1019 TypeHandle type1 = *it1;
1020 TypeHandle type2 = *it2;
1021 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) ==
1022 Equal(type1, type2));
1026 // T1->Is(T2) implies T1->NowIs(T2)
1027 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1028 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1029 TypeHandle type1 = *it1;
1030 TypeHandle type2 = *it2;
1031 CHECK(!type1->Is(type2) || type1->NowIs(type2));
1035 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
1036 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1037 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1038 Handle<i::Object> value1 = *vt1;
1039 Handle<i::Object> value2 = *vt2;
1040 TypeHandle const_type1 = T.Constant(value1);
1041 TypeHandle const_type2 = T.Constant(value2);
1042 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2));
1046 // Class(M1)->NowIs(Class(M2)) iff M1 = M2
1047 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1048 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1049 Handle<i::Map> map1 = *mt1;
1050 Handle<i::Map> map2 = *mt2;
1051 TypeHandle class_type1 = T.Class(map1);
1052 TypeHandle class_type2 = T.Class(map2);
1053 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2));
1057 // Constant(V)->NowIs(Class(M)) iff V has map M
1058 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1059 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1060 Handle<i::Map> map = *mt;
1061 Handle<i::Object> value = *vt;
1062 TypeHandle const_type = T.Constant(value);
1063 TypeHandle class_type = T.Class(map);
1064 CHECK((value->IsHeapObject() &&
1065 i::HeapObject::cast(*value)->map() == *map)
1066 == const_type->NowIs(class_type));
1070 // Class(M)->NowIs(Constant(V)) never
1071 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1072 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1073 Handle<i::Map> map = *mt;
1074 Handle<i::Object> value = *vt;
1075 TypeHandle const_type = T.Constant(value);
1076 TypeHandle class_type = T.Class(map);
1077 CHECK(!class_type->NowIs(const_type));
1083 // T->Contains(V) iff Constant(V)->Is(T)
1084 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1085 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1086 TypeHandle type = *it;
1087 Handle<i::Object> value = *vt;
1088 TypeHandle const_type = T.Constant(value);
1089 CHECK(type->Contains(value) == const_type->Is(type));
1093 // Of(V)->Is(T) implies T->Contains(V)
1094 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1095 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1096 TypeHandle type = *it;
1097 Handle<i::Object> value = *vt;
1098 TypeHandle of_type = T.Of(value);
1099 CHECK(!of_type->Is(type) || type->Contains(value));
1104 void NowContains() {
1105 // T->NowContains(V) iff Constant(V)->NowIs(T)
1106 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1107 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1108 TypeHandle type = *it;
1109 Handle<i::Object> value = *vt;
1110 TypeHandle const_type = T.Constant(value);
1111 CHECK(type->NowContains(value) == const_type->NowIs(type));
1115 // T->Contains(V) implies T->NowContains(V)
1116 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1117 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1118 TypeHandle type = *it;
1119 Handle<i::Object> value = *vt;
1120 CHECK(!type->Contains(value) || type->NowContains(value));
1124 // NowOf(V)->Is(T) implies T->NowContains(V)
1125 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1126 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1127 TypeHandle type = *it;
1128 Handle<i::Object> value = *vt;
1129 TypeHandle nowof_type = T.Of(value);
1130 CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
1134 // NowOf(V)->NowIs(T) implies T->NowContains(V)
1135 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1136 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1137 TypeHandle type = *it;
1138 Handle<i::Object> value = *vt;
1139 TypeHandle nowof_type = T.Of(value);
1140 CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
1146 // T->Maybe(Any) iff T inhabited
1147 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1148 TypeHandle type = *it;
1149 CHECK(type->Maybe(T.Any) == type->IsInhabited());
1152 // T->Maybe(None) never
1153 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1154 TypeHandle type = *it;
1155 CHECK(!type->Maybe(T.None));
1158 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited
1159 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1160 TypeHandle type = *it;
1161 CHECK(type->Maybe(type) == type->IsInhabited());
1164 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
1165 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1166 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1167 TypeHandle type1 = *it1;
1168 TypeHandle type2 = *it2;
1169 CHECK(type1->Maybe(type2) == type2->Maybe(type1));
1173 // T1->Maybe(T2) implies T1, T2 inhabited
1174 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1175 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1176 TypeHandle type1 = *it1;
1177 TypeHandle type2 = *it2;
1178 CHECK(!type1->Maybe(type2) ||
1179 (type1->IsInhabited() && type2->IsInhabited()));
1183 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
1184 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1185 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1186 TypeHandle type1 = *it1;
1187 TypeHandle type2 = *it2;
1188 TypeHandle intersect12 = T.Intersect(type1, type2);
1189 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
1193 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2)
1194 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1195 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1196 TypeHandle type1 = *it1;
1197 TypeHandle type2 = *it2;
1198 CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
1199 type1->Maybe(type2));
1203 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
1204 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1205 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1206 Handle<i::Object> value1 = *vt1;
1207 Handle<i::Object> value2 = *vt2;
1208 TypeHandle const_type1 = T.Constant(value1);
1209 TypeHandle const_type2 = T.Constant(value2);
1210 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
1214 // Class(M1)->Maybe(Class(M2)) iff M1 = M2
1215 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1216 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1217 Handle<i::Map> map1 = *mt1;
1218 Handle<i::Map> map2 = *mt2;
1219 TypeHandle class_type1 = T.Class(map1);
1220 TypeHandle class_type2 = T.Class(map2);
1221 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
1225 // Constant(V)->Maybe(Class(M)) never
1226 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1227 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1228 Handle<i::Map> map = *mt;
1229 Handle<i::Object> value = *vt;
1230 TypeHandle const_type = T.Constant(value);
1231 TypeHandle class_type = T.Class(map);
1232 CHECK(!const_type->Maybe(class_type));
1236 // Class(M)->Maybe(Constant(V)) never
1237 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1238 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1239 Handle<i::Map> map = *mt;
1240 Handle<i::Object> value = *vt;
1241 TypeHandle const_type = T.Constant(value);
1242 TypeHandle class_type = T.Class(map);
1243 CHECK(!class_type->Maybe(const_type));
1248 CheckDisjoint(T.Boolean, T.Null, T.Semantic);
1249 CheckDisjoint(T.Undefined, T.Null, T.Semantic);
1250 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
1252 CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
1253 CheckOverlap(T.NaN, T.Number, T.Semantic);
1254 CheckDisjoint(T.Signed32, T.NaN, T.Semantic);
1256 CheckOverlap(T.UniqueName, T.Name, T.Semantic);
1257 CheckOverlap(T.String, T.Name, T.Semantic);
1258 CheckOverlap(T.InternalizedString, T.String, T.Semantic);
1259 CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic);
1260 CheckOverlap(T.InternalizedString, T.Name, T.Semantic);
1261 CheckOverlap(T.Symbol, T.UniqueName, T.Semantic);
1262 CheckOverlap(T.Symbol, T.Name, T.Semantic);
1263 CheckOverlap(T.String, T.UniqueName, T.Semantic);
1264 CheckDisjoint(T.String, T.Symbol, T.Semantic);
1265 CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
1267 CheckOverlap(T.Object, T.Receiver, T.Semantic);
1268 CheckOverlap(T.Array, T.Object, T.Semantic);
1269 CheckOverlap(T.Function, T.Object, T.Semantic);
1270 CheckOverlap(T.Proxy, T.Receiver, T.Semantic);
1271 CheckDisjoint(T.Object, T.Proxy, T.Semantic);
1272 CheckDisjoint(T.Array, T.Function, T.Semantic);
1275 CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
1276 CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
1277 CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
1278 CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic);
1279 CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic);
1281 CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic);
1282 CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic);
1283 CheckOverlap(T.SmiConstant, T.Number, T.Semantic);
1284 CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic);
1285 CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic);
1286 CheckOverlap(T.ArrayConstant, T.Object, T.Semantic);
1287 CheckOverlap(T.ArrayConstant, T.Array, T.Semantic);
1288 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic);
1289 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic);
1290 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic);
1292 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic);
1293 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic);
1294 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic);
1295 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic);
1296 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic);
1298 CheckOverlap(T.NumberArray, T.Array, T.Semantic);
1299 CheckDisjoint(T.NumberArray, T.AnyArray, T.Semantic);
1300 CheckDisjoint(T.NumberArray, T.StringArray, T.Semantic);
1302 CheckOverlap(T.MethodFunction, T.Function, T.Semantic);
1303 CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic);
1304 CheckDisjoint(T.SignedFunction1, T.NumberFunction2, T.Semantic);
1305 CheckDisjoint(T.NumberFunction1, T.NumberFunction2, T.Semantic);
1306 CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic);
1310 // Identity: Union(T, None) = T
1311 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1312 TypeHandle type = *it;
1313 TypeHandle union_type = T.Union(type, T.None);
1314 CheckEqual(union_type, type);
1317 // Domination: Union(T, Any) = Any
1318 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1319 TypeHandle type = *it;
1320 TypeHandle union_type = T.Union(type, T.Any);
1321 CheckEqual(union_type, T.Any);
1324 // Idempotence: Union(T, T) = T
1325 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1326 TypeHandle type = *it;
1327 TypeHandle union_type = T.Union(type, type);
1328 CheckEqual(union_type, type);
1331 // Commutativity: Union(T1, T2) = Union(T2, T1)
1332 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1333 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1334 TypeHandle type1 = *it1;
1335 TypeHandle type2 = *it2;
1336 TypeHandle union12 = T.Union(type1, type2);
1337 TypeHandle union21 = T.Union(type2, type1);
1338 CheckEqual(union12, union21);
1342 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
1343 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1344 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1345 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1346 TypeHandle type1 = *it1;
1347 TypeHandle type2 = *it2;
1348 TypeHandle type3 = *it3;
1349 TypeHandle union12 = T.Union(type1, type2);
1350 TypeHandle union23 = T.Union(type2, type3);
1351 TypeHandle union1_23 = T.Union(type1, union23);
1352 TypeHandle union12_3 = T.Union(union12, type3);
1353 CheckEqual(union1_23, union12_3);
1358 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
1359 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1360 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1361 TypeHandle type1 = *it1;
1362 TypeHandle type2 = *it2;
1363 TypeHandle union12 = T.Union(type1, type2);
1364 CHECK(type1->Is(union12));
1365 CHECK(type2->Is(union12));
1369 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
1370 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1371 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1372 TypeHandle type1 = *it1;
1373 TypeHandle type2 = *it2;
1374 TypeHandle union12 = T.Union(type1, type2);
1375 if (type1->Is(type2)) CheckEqual(union12, type2);
1381 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
1382 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1383 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1384 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1385 TypeHandle type1 = *it1;
1386 TypeHandle type2 = *it2;
1387 TypeHandle type3 = *it3;
1388 TypeHandle union13 = T.Union(type1, type3);
1389 TypeHandle union23 = T.Union(type2, type3);
1390 CHECK(!type1->Is(type2) || union13->Is(union23));
1395 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
1396 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1397 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1398 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1399 TypeHandle type1 = *it1;
1400 TypeHandle type2 = *it2;
1401 TypeHandle type3 = *it3;
1402 TypeHandle union12 = T.Union(type1, type2);
1403 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
1408 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
1409 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1410 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1411 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1412 TypeHandle type1 = *it1;
1413 TypeHandle type2 = *it2;
1414 TypeHandle type3 = *it3;
1415 TypeHandle union23 = T.Union(type2, type3);
1416 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
1422 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
1423 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
1424 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic);
1425 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic);
1427 // Constant-constant
1428 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
1429 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
1431 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
1433 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic);
1435 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic);
1437 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic);
1440 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
1441 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
1443 CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
1444 CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
1445 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object, T.Semantic);
1446 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number, T.Semantic);
1449 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
1450 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
1452 CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
1453 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
1454 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic);
1455 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic);
1459 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
1460 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
1461 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
1462 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic);
1463 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic);
1467 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
1468 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
1469 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
1470 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic);
1471 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic);
1474 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
1475 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
1477 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
1478 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
1480 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2,
1483 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic);
1488 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
1490 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
1491 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
1495 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
1498 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
1499 T.Union(T.ArrayClass, T.ObjectConstant2));
1504 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1505 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1508 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
1510 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
1514 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
1515 T.Union(T.AnyArray, T.NumberArray));
1516 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array);
1520 T.Union(T.NumberFunction1, T.NumberFunction2),
1521 T.Union(T.NumberFunction2, T.NumberFunction1));
1522 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
1527 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1528 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1529 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1532 T.Union(T.Number, T.ArrayClass),
1533 T.Union(T.SignedSmall, T.Array)),
1534 T.Union(T.Number, T.Array));
1538 // Identity: Intersect(T, Any) = T
1539 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1540 TypeHandle type = *it;
1541 TypeHandle intersect_type = T.Intersect(type, T.Any);
1542 CheckEqual(intersect_type, type);
1545 // Domination: Intersect(T, None) = None
1546 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1547 TypeHandle type = *it;
1548 TypeHandle intersect_type = T.Intersect(type, T.None);
1549 CheckEqual(intersect_type, T.None);
1552 // Idempotence: Intersect(T, T) = T
1553 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1554 TypeHandle type = *it;
1555 TypeHandle intersect_type = T.Intersect(type, type);
1556 CheckEqual(intersect_type, type);
1559 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
1560 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1561 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1562 TypeHandle type1 = *it1;
1563 TypeHandle type2 = *it2;
1564 TypeHandle intersect12 = T.Intersect(type1, type2);
1565 TypeHandle intersect21 = T.Intersect(type2, type1);
1566 CheckEqual(intersect12, intersect21);
1571 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
1572 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1573 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1574 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1575 TypeHandle type1 = *it1;
1576 TypeHandle type2 = *it2;
1577 TypeHandle type3 = *it3;
1578 TypeHandle intersect12 = T.Intersect(type1, type2);
1579 TypeHandle intersect23 = T.Intersect(type2, type3);
1580 TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
1581 TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
1582 CheckEqual(intersect1_23, intersect12_3);
1587 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
1588 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1589 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1590 TypeHandle type1 = *it1;
1591 TypeHandle type2 = *it2;
1592 TypeHandle intersect12 = T.Intersect(type1, type2);
1593 CHECK(intersect12->Is(type1));
1594 CHECK(intersect12->Is(type2));
1598 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
1599 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1600 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1601 TypeHandle type1 = *it1;
1602 TypeHandle type2 = *it2;
1603 TypeHandle intersect12 = T.Intersect(type1, type2);
1604 if (type1->Is(type2)) CheckEqual(intersect12, type1);
1610 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
1611 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1612 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1613 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1614 TypeHandle type1 = *it1;
1615 TypeHandle type2 = *it2;
1616 TypeHandle type3 = *it3;
1617 TypeHandle intersect13 = T.Intersect(type1, type3);
1618 TypeHandle intersect23 = T.Intersect(type2, type3);
1619 CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
1624 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
1625 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1626 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1627 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1628 TypeHandle type1 = *it1;
1629 TypeHandle type2 = *it2;
1630 TypeHandle type3 = *it3;
1631 TypeHandle intersect12 = T.Intersect(type1, type2);
1632 CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
1633 intersect12->Is(type3));
1638 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
1639 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1640 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1641 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1642 TypeHandle type1 = *it1;
1643 TypeHandle type2 = *it2;
1644 TypeHandle type3 = *it3;
1645 TypeHandle intersect23 = T.Intersect(type2, type3);
1646 CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
1647 type1->Is(intersect23));
1653 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
1654 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation);
1655 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation);
1658 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
1659 CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation);
1662 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
1663 CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation);
1667 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
1668 T.Union(T.ObjectConstant1, T.ObjectClass));
1670 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
1674 CHECK(!T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited());
1675 CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
1679 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
1682 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
1685 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
1690 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
1693 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
1696 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
1701 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
1704 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
1707 !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
1713 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1716 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
1720 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
1726 T.Union(T.Number, T.ArrayClass),
1727 T.Union(T.SignedSmall, T.Array)),
1728 T.Union(T.SignedSmall, T.ArrayClass));
1731 T.Union(T.Number, T.ObjectClass),
1732 T.Union(T.Signed32, T.Array)),
1736 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1737 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1738 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1742 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass),
1745 T.Union(T.ArrayConstant, T.ObjectConstant2))),
1746 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1749 void Distributivity1() {
1751 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
1752 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1753 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1754 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1755 TypeHandle type1 = *it1;
1756 TypeHandle type2 = *it2;
1757 TypeHandle type3 = *it3;
1758 TypeHandle union12 = T.Union(type1, type2);
1759 TypeHandle union13 = T.Union(type1, type3);
1760 TypeHandle intersect23 = T.Intersect(type2, type3);
1761 TypeHandle union1_23 = T.Union(type1, intersect23);
1762 TypeHandle intersect12_13 = T.Intersect(union12, union13);
1763 CHECK(Equal(union1_23, intersect12_13));
1769 void Distributivity2() {
1771 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
1772 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1773 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1774 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1775 TypeHandle type1 = *it1;
1776 TypeHandle type2 = *it2;
1777 TypeHandle type3 = *it3;
1778 TypeHandle intersect12 = T.Intersect(type1, type2);
1779 TypeHandle intersect13 = T.Intersect(type1, type3);
1780 TypeHandle union23 = T.Union(type2, type3);
1781 TypeHandle intersect1_23 = T.Intersect(type1, union23);
1782 TypeHandle union12_13 = T.Union(intersect12, intersect13);
1783 CHECK(Equal(intersect1_23, union12_13));
1789 template<class Type2, class TypeHandle2, class Region2, class Rep2>
1791 Types<Type2, TypeHandle2, Region2> T2(
1792 Rep2::ToRegion(&zone, isolate), isolate);
1793 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1794 TypeHandle type1 = *it;
1795 TypeHandle2 type2 = T2.template Convert<Type>(type1);
1796 TypeHandle type3 = T.template Convert<Type2>(type2);
1797 CheckEqual(type1, type3);
1801 void HTypeFromType() {
1802 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1803 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1804 TypeHandle type1 = *it1;
1805 TypeHandle type2 = *it2;
1806 HType htype1 = HType::FromType<Type>(type1);
1807 HType htype2 = HType::FromType<Type>(type2);
1808 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
1814 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1815 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1819 CcTest::InitializeVM();
1820 ZoneTests().Bitset();
1821 HeapTests().Bitset();
1826 CcTest::InitializeVM();
1827 ZoneTests().Class();
1828 HeapTests().Class();
1832 TEST(ConstantType) {
1833 CcTest::InitializeVM();
1834 ZoneTests().Constant();
1835 HeapTests().Constant();
1840 CcTest::InitializeVM();
1841 ZoneTests().Range();
1842 HeapTests().Range();
1847 CcTest::InitializeVM();
1848 ZoneTests().Array();
1849 HeapTests().Array();
1853 TEST(FunctionType) {
1854 CcTest::InitializeVM();
1855 ZoneTests().Function();
1856 HeapTests().Function();
1861 CcTest::InitializeVM();
1868 CcTest::InitializeVM();
1869 ZoneTests().NowOf();
1870 HeapTests().NowOf();
1875 CcTest::InitializeVM();
1876 ZoneTests().Bounds();
1877 HeapTests().Bounds();
1882 CcTest::InitializeVM();
1889 CcTest::InitializeVM();
1890 ZoneTests().NowIs();
1891 HeapTests().NowIs();
1896 CcTest::InitializeVM();
1897 ZoneTests().Contains();
1898 HeapTests().Contains();
1903 CcTest::InitializeVM();
1904 ZoneTests().NowContains();
1905 HeapTests().NowContains();
1910 CcTest::InitializeVM();
1911 ZoneTests().Maybe();
1912 HeapTests().Maybe();
1917 CcTest::InitializeVM();
1918 ZoneTests().Union1();
1919 HeapTests().Union1();
1924 CcTest::InitializeVM();
1925 ZoneTests().Union2();
1926 HeapTests().Union2();
1931 CcTest::InitializeVM();
1932 ZoneTests().Intersect1();
1933 HeapTests().Intersect1();
1938 CcTest::InitializeVM();
1939 ZoneTests().Intersect2();
1940 HeapTests().Intersect2();
1944 TEST(Distributivity1) {
1945 CcTest::InitializeVM();
1946 ZoneTests().Distributivity1();
1947 HeapTests().Distributivity1();
1951 TEST(Distributivity2) {
1952 CcTest::InitializeVM();
1953 ZoneTests().Distributivity2();
1954 HeapTests().Distributivity2();
1959 CcTest::InitializeVM();
1960 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
1961 HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
1965 TEST(HTypeFromType) {
1966 CcTest::InitializeVM();
1967 ZoneTests().HTypeFromType();
1968 HeapTests().HTypeFromType();