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/hydrogen-types.h"
8 #include "src/isolate-inl.h"
9 #include "src/types.h"
10 #include "test/cctest/cctest.h"
11
12 using namespace v8::internal;
13
14 // Testing auxiliaries (breaking the Type abstraction).
15 typedef uint32_t bitset;
16
17 struct ZoneRep {
18 typedef void* Struct;
19
IsStructZoneRep20 static bool IsStruct(Type* t, int tag) {
21 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
22 }
IsBitsetZoneRep23 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
IsUnionZoneRep24 static bool IsUnion(Type* t) { return IsStruct(t, 6); }
25
AsStructZoneRep26 static Struct* AsStruct(Type* t) {
27 return reinterpret_cast<Struct*>(t);
28 }
AsBitsetZoneRep29 static bitset AsBitset(Type* t) {
30 return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u);
31 }
AsUnionZoneRep32 static Struct* AsUnion(Type* t) {
33 return AsStruct(t);
34 }
LengthZoneRep35 static int Length(Struct* structured) {
36 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
37 }
38
ToRegionZoneRep39 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
40
41 struct BitsetType : Type::BitsetType {
42 using Type::BitsetType::New;
43 using Type::BitsetType::Glb;
44 using Type::BitsetType::Lub;
45 using Type::BitsetType::IsInhabited;
46 };
47 };
48
49
50 struct HeapRep {
51 typedef FixedArray Struct;
52
IsStructHeapRep53 static bool IsStruct(Handle<HeapType> t, int tag) {
54 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
55 }
IsBitsetHeapRep56 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
IsUnionHeapRep57 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); }
58
AsStructHeapRep59 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
AsBitsetHeapRep60 static bitset AsBitset(Handle<HeapType> t) {
61 return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t));
62 }
AsUnionHeapRep63 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
LengthHeapRep64 static int Length(Struct* structured) { return structured->length() - 1; }
65
ToRegionHeapRep66 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
67
68 struct BitsetType : HeapType::BitsetType {
69 using HeapType::BitsetType::New;
70 using HeapType::BitsetType::Glb;
71 using HeapType::BitsetType::Lub;
72 using HeapType::BitsetType::IsInhabited;
GlbHeapRep::BitsetType73 static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
LubHeapRep::BitsetType74 static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
75 };
76 };
77
78
79 template<class Type, class TypeHandle, class Region>
80 class Types {
81 public:
Types(Region * region,Isolate * isolate)82 Types(Region* region, Isolate* isolate)
83 : region_(region), rng_(isolate->random_number_generator()) {
84 #define DECLARE_TYPE(name, value) \
85 name = Type::name(region); \
86 types.push_back(name);
87 PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
88 #undef DECLARE_TYPE
89
90 object_map = isolate->factory()->NewMap(
91 JS_OBJECT_TYPE, JSObject::kHeaderSize);
92 array_map = isolate->factory()->NewMap(
93 JS_ARRAY_TYPE, JSArray::kSize);
94 number_map = isolate->factory()->NewMap(
95 HEAP_NUMBER_TYPE, HeapNumber::kSize);
96 uninitialized_map = isolate->factory()->uninitialized_map();
97 ObjectClass = Type::Class(object_map, region);
98 ArrayClass = Type::Class(array_map, region);
99 NumberClass = Type::Class(number_map, region);
100 UninitializedClass = Type::Class(uninitialized_map, region);
101
102 maps.push_back(object_map);
103 maps.push_back(array_map);
104 maps.push_back(uninitialized_map);
105 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
106 types.push_back(Type::Class(*it, region));
107 }
108
109 smi = handle(Smi::FromInt(666), isolate);
110 signed32 = isolate->factory()->NewHeapNumber(0x40000000);
111 object1 = isolate->factory()->NewJSObjectFromMap(object_map);
112 object2 = isolate->factory()->NewJSObjectFromMap(object_map);
113 array = isolate->factory()->NewJSArray(20);
114 uninitialized = isolate->factory()->uninitialized_value();
115 SmiConstant = Type::Constant(smi, region);
116 Signed32Constant = Type::Constant(signed32, region);
117 ObjectConstant1 = Type::Constant(object1, region);
118 ObjectConstant2 = Type::Constant(object2, region);
119 ArrayConstant = Type::Constant(array, region);
120 UninitializedConstant = Type::Constant(uninitialized, region);
121
122 values.push_back(smi);
123 values.push_back(signed32);
124 values.push_back(object1);
125 values.push_back(object2);
126 values.push_back(array);
127 values.push_back(uninitialized);
128 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
129 types.push_back(Type::Constant(*it, region));
130 }
131
132 integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
133 integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
134 integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
135 integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
136 for (int i = 0; i < 10; ++i) {
137 double x = rng_->NextInt();
138 integers.push_back(isolate->factory()->NewNumber(x));
139 x *= rng_->NextInt();
140 if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
141 }
142
143 NumberArray = Type::Array(Number, region);
144 StringArray = Type::Array(String, region);
145 AnyArray = Type::Array(Any, region);
146
147 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
148 NumberFunction1 = Type::Function(Number, Number, region);
149 NumberFunction2 = Type::Function(Number, Number, Number, region);
150 MethodFunction = Type::Function(String, Object, 0, region);
151
152 for (int i = 0; i < 30; ++i) {
153 types.push_back(Fuzz());
154 }
155 }
156
157 Handle<i::Map> object_map;
158 Handle<i::Map> array_map;
159 Handle<i::Map> number_map;
160 Handle<i::Map> uninitialized_map;
161
162 Handle<i::Smi> smi;
163 Handle<i::HeapNumber> signed32;
164 Handle<i::JSObject> object1;
165 Handle<i::JSObject> object2;
166 Handle<i::JSArray> array;
167 Handle<i::Oddball> uninitialized;
168
169 #define DECLARE_TYPE(name, value) TypeHandle name;
170 BITSET_TYPE_LIST(DECLARE_TYPE)
171 #undef DECLARE_TYPE
172
173 TypeHandle ObjectClass;
174 TypeHandle ArrayClass;
175 TypeHandle NumberClass;
176 TypeHandle UninitializedClass;
177
178 TypeHandle SmiConstant;
179 TypeHandle Signed32Constant;
180 TypeHandle ObjectConstant1;
181 TypeHandle ObjectConstant2;
182 TypeHandle ArrayConstant;
183 TypeHandle UninitializedConstant;
184
185 TypeHandle NumberArray;
186 TypeHandle StringArray;
187 TypeHandle AnyArray;
188
189 TypeHandle SignedFunction1;
190 TypeHandle NumberFunction1;
191 TypeHandle NumberFunction2;
192 TypeHandle MethodFunction;
193
194 typedef std::vector<TypeHandle> TypeVector;
195 typedef std::vector<Handle<i::Map> > MapVector;
196 typedef std::vector<Handle<i::Object> > ValueVector;
197
198 TypeVector types;
199 MapVector maps;
200 ValueVector values;
201 ValueVector integers; // "Integer" values used for range limits.
202
Of(Handle<i::Object> value)203 TypeHandle Of(Handle<i::Object> value) {
204 return Type::Of(value, region_);
205 }
206
NowOf(Handle<i::Object> value)207 TypeHandle NowOf(Handle<i::Object> value) {
208 return Type::NowOf(value, region_);
209 }
210
Class(Handle<i::Map> map)211 TypeHandle Class(Handle<i::Map> map) {
212 return Type::Class(map, region_);
213 }
214
Constant(Handle<i::Object> value)215 TypeHandle Constant(Handle<i::Object> value) {
216 return Type::Constant(value, region_);
217 }
218
Range(Handle<i::Object> min,Handle<i::Object> max)219 TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
220 return Type::Range(min, max, region_);
221 }
222
Context(TypeHandle outer)223 TypeHandle Context(TypeHandle outer) {
224 return Type::Context(outer, region_);
225 }
226
Array1(TypeHandle element)227 TypeHandle Array1(TypeHandle element) {
228 return Type::Array(element, region_);
229 }
230
Function0(TypeHandle result,TypeHandle receiver)231 TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
232 return Type::Function(result, receiver, 0, region_);
233 }
234
Function1(TypeHandle result,TypeHandle receiver,TypeHandle arg)235 TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
236 TypeHandle type = Type::Function(result, receiver, 1, region_);
237 type->AsFunction()->InitParameter(0, arg);
238 return type;
239 }
240
Function2(TypeHandle result,TypeHandle arg1,TypeHandle arg2)241 TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
242 return Type::Function(result, arg1, arg2, region_);
243 }
244
Union(TypeHandle t1,TypeHandle t2)245 TypeHandle Union(TypeHandle t1, TypeHandle t2) {
246 return Type::Union(t1, t2, region_);
247 }
Intersect(TypeHandle t1,TypeHandle t2)248 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
249 return Type::Intersect(t1, t2, region_);
250 }
251
252 template<class Type2, class TypeHandle2>
Convert(TypeHandle2 t)253 TypeHandle Convert(TypeHandle2 t) {
254 return Type::template Convert<Type2>(t, region_);
255 }
256
Random()257 TypeHandle Random() {
258 return types[rng_->NextInt(static_cast<int>(types.size()))];
259 }
260
Fuzz(int depth=4)261 TypeHandle Fuzz(int depth = 4) {
262 switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
263 case 0: { // bitset
264 int n = 0
265 #define COUNT_BITSET_TYPES(type, value) + 1
266 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
267 #undef COUNT_BITSET_TYPES
268 ;
269 int i = rng_->NextInt(n);
270 #define PICK_BITSET_TYPE(type, value) \
271 if (i-- == 0) return Type::type(region_);
272 PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
273 #undef PICK_BITSET_TYPE
274 UNREACHABLE();
275 }
276 case 1: { // class
277 int i = rng_->NextInt(static_cast<int>(maps.size()));
278 return Type::Class(maps[i], region_);
279 }
280 case 2: { // constant
281 int i = rng_->NextInt(static_cast<int>(values.size()));
282 return Type::Constant(values[i], region_);
283 }
284 case 3: { // range
285 int i = rng_->NextInt(static_cast<int>(integers.size()));
286 int j = rng_->NextInt(static_cast<int>(integers.size()));
287 i::Handle<i::Object> min = integers[i];
288 i::Handle<i::Object> max = integers[j];
289 if (min->Number() > max->Number()) std::swap(min, max);
290 return Type::Range(min, max, region_);
291 }
292 case 4: { // context
293 int depth = rng_->NextInt(3);
294 TypeHandle type = Type::Internal(region_);
295 for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
296 return type;
297 }
298 case 5: { // array
299 TypeHandle element = Fuzz(depth / 2);
300 return Type::Array(element, region_);
301 }
302 case 6:
303 case 7: { // function
304 TypeHandle result = Fuzz(depth / 2);
305 TypeHandle receiver = Fuzz(depth / 2);
306 int arity = rng_->NextInt(3);
307 TypeHandle type = Type::Function(result, receiver, arity, region_);
308 for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
309 TypeHandle parameter = Fuzz(depth / 2);
310 type->AsFunction()->InitParameter(i, parameter);
311 }
312 return type;
313 }
314 default: { // union
315 int n = rng_->NextInt(10);
316 TypeHandle type = None;
317 for (int i = 0; i < n; ++i) {
318 TypeHandle operand = Fuzz(depth - 1);
319 type = Type::Union(type, operand, region_);
320 }
321 return type;
322 }
323 }
324 UNREACHABLE();
325 }
326
region()327 Region* region() { return region_; }
328
329 private:
330 Region* region_;
331 v8::base::RandomNumberGenerator* rng_;
332 };
333
334
335 template<class Type, class TypeHandle, class Region, class Rep>
336 struct Tests : Rep {
337 typedef Types<Type, TypeHandle, Region> TypesInstance;
338 typedef typename TypesInstance::TypeVector::iterator TypeIterator;
339 typedef typename TypesInstance::MapVector::iterator MapIterator;
340 typedef typename TypesInstance::ValueVector::iterator ValueIterator;
341
342 Isolate* isolate;
343 HandleScope scope;
344 Zone zone;
345 TypesInstance T;
346
TestsTests347 Tests() :
348 isolate(CcTest::i_isolate()),
349 scope(isolate),
350 zone(isolate),
351 T(Rep::ToRegion(&zone, isolate), isolate) {
352 }
353
EqualTests354 bool Equal(TypeHandle type1, TypeHandle type2) {
355 return
356 type1->Equals(type2) &&
357 this->IsBitset(type1) == this->IsBitset(type2) &&
358 this->IsUnion(type1) == this->IsUnion(type2) &&
359 type1->NumClasses() == type2->NumClasses() &&
360 type1->NumConstants() == type2->NumConstants() &&
361 (!this->IsBitset(type1) ||
362 this->AsBitset(type1) == this->AsBitset(type2)) &&
363 (!this->IsUnion(type1) ||
364 this->Length(this->AsUnion(type1)) ==
365 this->Length(this->AsUnion(type2)));
366 }
367
CheckEqualTests368 void CheckEqual(TypeHandle type1, TypeHandle type2) {
369 CHECK(Equal(type1, type2));
370 }
371
CheckSubTests372 void CheckSub(TypeHandle type1, TypeHandle type2) {
373 CHECK(type1->Is(type2));
374 CHECK(!type2->Is(type1));
375 if (this->IsBitset(type1) && this->IsBitset(type2)) {
376 CHECK(this->AsBitset(type1) != this->AsBitset(type2));
377 }
378 }
379
CheckUnorderedTests380 void CheckUnordered(TypeHandle type1, TypeHandle type2) {
381 CHECK(!type1->Is(type2));
382 CHECK(!type2->Is(type1));
383 if (this->IsBitset(type1) && this->IsBitset(type2)) {
384 CHECK(this->AsBitset(type1) != this->AsBitset(type2));
385 }
386 }
387
CheckOverlapTests388 void CheckOverlap(TypeHandle type1, TypeHandle type2) {
389 CHECK(type1->Maybe(type2));
390 CHECK(type2->Maybe(type1));
391 }
392
CheckDisjointTests393 void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
394 CHECK(!type1->Is(type2));
395 CHECK(!type2->Is(type1));
396 CHECK(!type1->Maybe(type2));
397 CHECK(!type2->Maybe(type1));
398 }
399
IsSomeTypeTests400 void IsSomeType() {
401 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
402 TypeHandle t = *it;
403 CHECK(1 ==
404 this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() +
405 this->IsUnion(t) + t->IsArray() + t->IsFunction() + t->IsContext());
406 }
407 }
408
BitsetTests409 void Bitset() {
410 // None and Any are bitsets.
411 CHECK(this->IsBitset(T.None));
412 CHECK(this->IsBitset(T.Any));
413
414 CHECK(bitset(0) == this->AsBitset(T.None));
415 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any));
416
417 // Union(T1, T2) is bitset for bitsets T1,T2
418 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
419 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
420 TypeHandle type1 = *it1;
421 TypeHandle type2 = *it2;
422 TypeHandle union12 = T.Union(type1, type2);
423 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
424 this->IsBitset(union12));
425 }
426 }
427
428 // Intersect(T1, T2) is bitset for bitsets T1,T2
429 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
430 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
431 TypeHandle type1 = *it1;
432 TypeHandle type2 = *it2;
433 TypeHandle intersect12 = T.Intersect(type1, type2);
434 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
435 this->IsBitset(intersect12));
436 }
437 }
438
439 // Union(T1, T2) is bitset if T2 is bitset and T1->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 TypeHandle type1 = *it1;
443 TypeHandle type2 = *it2;
444 TypeHandle union12 = T.Union(type1, type2);
445 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
446 this->IsBitset(union12));
447 }
448 }
449
450 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
451 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
452 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
453 TypeHandle type1 = *it1;
454 TypeHandle type2 = *it2;
455 TypeHandle union12 = T.Union(type1, type2);
456 if (this->IsBitset(type1) && this->IsBitset(type2)) {
457 CHECK(
458 (this->AsBitset(type1) | this->AsBitset(type2)) ==
459 this->AsBitset(union12));
460 }
461 }
462 }
463
464 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None)
465 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
466 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
467 TypeHandle type1 = *it1;
468 TypeHandle type2 = *it2;
469 TypeHandle intersect12 = T.Intersect(type1, type2);
470 if (this->IsBitset(type1) && this->IsBitset(type2)) {
471 bitset bits = this->AsBitset(type1) & this->AsBitset(type2);
472 CHECK(
473 (Rep::BitsetType::IsInhabited(bits) ? bits : 0) ==
474 this->AsBitset(intersect12));
475 }
476 }
477 }
478 }
479
ClassTests480 void Class() {
481 // Constructor
482 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
483 Handle<i::Map> map = *mt;
484 TypeHandle type = T.Class(map);
485 CHECK(type->IsClass());
486 }
487
488 // Map attribute
489 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
490 Handle<i::Map> map = *mt;
491 TypeHandle type = T.Class(map);
492 CHECK(*map == *type->AsClass()->Map());
493 }
494
495 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
496 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
497 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
498 Handle<i::Map> map1 = *mt1;
499 Handle<i::Map> map2 = *mt2;
500 TypeHandle type1 = T.Class(map1);
501 TypeHandle type2 = T.Class(map2);
502 CHECK(Equal(type1, type2) == (*map1 == *map2));
503 }
504 }
505 }
506
ConstantTests507 void Constant() {
508 // Constructor
509 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
510 Handle<i::Object> value = *vt;
511 TypeHandle type = T.Constant(value);
512 CHECK(type->IsConstant());
513 }
514
515 // Value attribute
516 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
517 Handle<i::Object> value = *vt;
518 TypeHandle type = T.Constant(value);
519 CHECK(*value == *type->AsConstant()->Value());
520 }
521
522 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
523 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
524 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
525 Handle<i::Object> value1 = *vt1;
526 Handle<i::Object> value2 = *vt2;
527 TypeHandle type1 = T.Constant(value1);
528 TypeHandle type2 = T.Constant(value2);
529 CHECK(Equal(type1, type2) == (*value1 == *value2));
530 }
531 }
532
533 // Typing of numbers
534 Factory* fac = isolate->factory();
535 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
536 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
537 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
538 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
539 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
540 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
541 if (SmiValuesAre31Bits()) {
542 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
543 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
544 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
545 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
546 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
547 } else {
548 CHECK(SmiValuesAre32Bits());
549 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
550 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
551 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
552 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
553 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
554 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
555 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
556 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
557 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
558 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
559 }
560 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
561 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
562 CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
563 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
564 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
565 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
566 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
567 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
568 CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
569 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
570 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
571 }
572
RangeTests573 void Range() {
574 // Constructor
575 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
576 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
577 i::Handle<i::Object> min = *i;
578 i::Handle<i::Object> max = *j;
579 if (min->Number() > max->Number()) std::swap(min, max);
580 TypeHandle type = T.Range(min, max);
581 CHECK(type->IsRange());
582 }
583 }
584
585 // Range attributes
586 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
587 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
588 i::Handle<i::Object> min = *i;
589 i::Handle<i::Object> max = *j;
590 if (min->Number() > max->Number()) std::swap(min, max);
591 TypeHandle type = T.Range(min, max);
592 CHECK(*min == *type->AsRange()->Min());
593 CHECK(*max == *type->AsRange()->Max());
594 }
595 }
596
597 // Functionality & Injectivity:
598 // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2
599 for (ValueIterator i1 = T.integers.begin();
600 i1 != T.integers.end(); ++i1) {
601 for (ValueIterator j1 = T.integers.begin();
602 j1 != T.integers.end(); ++j1) {
603 for (ValueIterator i2 = T.integers.begin();
604 i2 != T.integers.end(); ++i2) {
605 for (ValueIterator j2 = T.integers.begin();
606 j2 != T.integers.end(); ++j2) {
607 i::Handle<i::Object> min1 = *i1;
608 i::Handle<i::Object> max1 = *j1;
609 i::Handle<i::Object> min2 = *i2;
610 i::Handle<i::Object> max2 = *j2;
611 if (min1->Number() > max1->Number()) std::swap(min1, max1);
612 if (min2->Number() > max2->Number()) std::swap(min2, max2);
613 TypeHandle type1 = T.Range(min1, max1);
614 TypeHandle type2 = T.Range(min2, max2);
615 CHECK(Equal(type1, type2) == (*min1 == *min2 && *max1 == *max2));
616 }
617 }
618 }
619 }
620 }
621
ArrayTests622 void Array() {
623 // Constructor
624 for (int i = 0; i < 20; ++i) {
625 TypeHandle type = T.Random();
626 TypeHandle array = T.Array1(type);
627 CHECK(array->IsArray());
628 }
629
630 // Attributes
631 for (int i = 0; i < 20; ++i) {
632 TypeHandle type = T.Random();
633 TypeHandle array = T.Array1(type);
634 CheckEqual(type, array->AsArray()->Element());
635 }
636
637 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
638 for (int i = 0; i < 20; ++i) {
639 for (int j = 0; j < 20; ++j) {
640 TypeHandle type1 = T.Random();
641 TypeHandle type2 = T.Random();
642 TypeHandle array1 = T.Array1(type1);
643 TypeHandle array2 = T.Array1(type2);
644 CHECK(Equal(array1, array2) == Equal(type1, type2));
645 }
646 }
647 }
648
FunctionTests649 void Function() {
650 // Constructors
651 for (int i = 0; i < 20; ++i) {
652 for (int j = 0; j < 20; ++j) {
653 for (int k = 0; k < 20; ++k) {
654 TypeHandle type1 = T.Random();
655 TypeHandle type2 = T.Random();
656 TypeHandle type3 = T.Random();
657 TypeHandle function0 = T.Function0(type1, type2);
658 TypeHandle function1 = T.Function1(type1, type2, type3);
659 TypeHandle function2 = T.Function2(type1, type2, type3);
660 CHECK(function0->IsFunction());
661 CHECK(function1->IsFunction());
662 CHECK(function2->IsFunction());
663 }
664 }
665 }
666
667 // Attributes
668 for (int i = 0; i < 20; ++i) {
669 for (int j = 0; j < 20; ++j) {
670 for (int k = 0; k < 20; ++k) {
671 TypeHandle type1 = T.Random();
672 TypeHandle type2 = T.Random();
673 TypeHandle type3 = T.Random();
674 TypeHandle function0 = T.Function0(type1, type2);
675 TypeHandle function1 = T.Function1(type1, type2, type3);
676 TypeHandle function2 = T.Function2(type1, type2, type3);
677 CHECK_EQ(0, function0->AsFunction()->Arity());
678 CHECK_EQ(1, function1->AsFunction()->Arity());
679 CHECK_EQ(2, function2->AsFunction()->Arity());
680 CheckEqual(type1, function0->AsFunction()->Result());
681 CheckEqual(type1, function1->AsFunction()->Result());
682 CheckEqual(type1, function2->AsFunction()->Result());
683 CheckEqual(type2, function0->AsFunction()->Receiver());
684 CheckEqual(type2, function1->AsFunction()->Receiver());
685 CheckEqual(T.Any, function2->AsFunction()->Receiver());
686 CheckEqual(type3, function1->AsFunction()->Parameter(0));
687 CheckEqual(type2, function2->AsFunction()->Parameter(0));
688 CheckEqual(type3, function2->AsFunction()->Parameter(1));
689 }
690 }
691 }
692
693 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
694 for (int i = 0; i < 20; ++i) {
695 for (int j = 0; j < 20; ++j) {
696 for (int k = 0; k < 20; ++k) {
697 TypeHandle type1 = T.Random();
698 TypeHandle type2 = T.Random();
699 TypeHandle type3 = T.Random();
700 TypeHandle function01 = T.Function0(type1, type2);
701 TypeHandle function02 = T.Function0(type1, type3);
702 TypeHandle function03 = T.Function0(type3, type2);
703 TypeHandle function11 = T.Function1(type1, type2, type2);
704 TypeHandle function12 = T.Function1(type1, type2, type3);
705 TypeHandle function21 = T.Function2(type1, type2, type2);
706 TypeHandle function22 = T.Function2(type1, type2, type3);
707 TypeHandle function23 = T.Function2(type1, type3, type2);
708 CHECK(Equal(function01, function02) == Equal(type2, type3));
709 CHECK(Equal(function01, function03) == Equal(type1, type3));
710 CHECK(Equal(function11, function12) == Equal(type2, type3));
711 CHECK(Equal(function21, function22) == Equal(type2, type3));
712 CHECK(Equal(function21, function23) == Equal(type2, type3));
713 }
714 }
715 }
716 }
717
OfTests718 void Of() {
719 // Constant(V)->Is(Of(V))
720 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
721 Handle<i::Object> value = *vt;
722 TypeHandle const_type = T.Constant(value);
723 TypeHandle of_type = T.Of(value);
724 CHECK(const_type->Is(of_type));
725 }
726
727 // If Of(V)->Is(T), then Constant(V)->Is(T)
728 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
729 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
730 Handle<i::Object> value = *vt;
731 TypeHandle type = *it;
732 TypeHandle const_type = T.Constant(value);
733 TypeHandle of_type = T.Of(value);
734 CHECK(!of_type->Is(type) || const_type->Is(type));
735 }
736 }
737
738 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V))
739 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
740 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
741 Handle<i::Object> value = *vt;
742 TypeHandle type = *it;
743 TypeHandle const_type = T.Constant(value);
744 TypeHandle of_type = T.Of(value);
745 CHECK(!const_type->Is(type) ||
746 of_type->Is(type) || type->Maybe(const_type));
747 }
748 }
749 }
750
NowOfTests751 void NowOf() {
752 // Constant(V)->NowIs(NowOf(V))
753 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
754 Handle<i::Object> value = *vt;
755 TypeHandle const_type = T.Constant(value);
756 TypeHandle nowof_type = T.NowOf(value);
757 CHECK(const_type->NowIs(nowof_type));
758 }
759
760 // NowOf(V)->Is(Of(V))
761 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
762 Handle<i::Object> value = *vt;
763 TypeHandle nowof_type = T.NowOf(value);
764 TypeHandle of_type = T.Of(value);
765 CHECK(nowof_type->Is(of_type));
766 }
767
768 // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T)
769 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
770 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
771 Handle<i::Object> value = *vt;
772 TypeHandle type = *it;
773 TypeHandle const_type = T.Constant(value);
774 TypeHandle nowof_type = T.NowOf(value);
775 CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type));
776 }
777 }
778
779 // If Constant(V)->NowIs(T),
780 // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
781 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
782 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
783 Handle<i::Object> value = *vt;
784 TypeHandle type = *it;
785 TypeHandle const_type = T.Constant(value);
786 TypeHandle nowof_type = T.NowOf(value);
787 CHECK(!const_type->NowIs(type) ||
788 nowof_type->NowIs(type) || type->Maybe(const_type));
789 }
790 }
791
792 // If Constant(V)->Is(T),
793 // then NowOf(V)->Is(T) or T->Maybe(Constant(V))
794 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
795 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
796 Handle<i::Object> value = *vt;
797 TypeHandle type = *it;
798 TypeHandle const_type = T.Constant(value);
799 TypeHandle nowof_type = T.NowOf(value);
800 CHECK(!const_type->Is(type) ||
801 nowof_type->Is(type) || type->Maybe(const_type));
802 }
803 }
804 }
805
BitsetGlbTests806 void BitsetGlb() {
807 // Lower: (T->BitsetGlb())->Is(T)
808 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
809 TypeHandle type = *it;
810 TypeHandle glb =
811 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
812 CHECK(glb->Is(type));
813 }
814
815 // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb())
816 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
817 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
818 TypeHandle type1 = *it1;
819 TypeHandle type2 = *it2;
820 TypeHandle glb2 =
821 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
822 CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2));
823 }
824 }
825
826 // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb())
827 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
828 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
829 TypeHandle type1 = *it1;
830 TypeHandle type2 = *it2;
831 TypeHandle glb1 =
832 Rep::BitsetType::New(Rep::BitsetType::Glb(type1), T.region());
833 TypeHandle glb2 =
834 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
835 CHECK(!type1->Is(type2) || glb1->Is(glb2));
836 }
837 }
838 }
839
BitsetLubTests840 void BitsetLub() {
841 // Upper: T->Is(T->BitsetLub())
842 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
843 TypeHandle type = *it;
844 TypeHandle lub =
845 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
846 CHECK(type->Is(lub));
847 }
848
849 // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2)
850 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
851 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
852 TypeHandle type1 = *it1;
853 TypeHandle type2 = *it2;
854 TypeHandle lub1 =
855 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
856 CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2));
857 }
858 }
859
860 // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub())
861 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
862 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
863 TypeHandle type1 = *it1;
864 TypeHandle type2 = *it2;
865 TypeHandle lub1 =
866 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
867 TypeHandle lub2 =
868 Rep::BitsetType::New(Rep::BitsetType::Lub(type2), T.region());
869 CHECK(!type1->Is(type2) || lub1->Is(lub2));
870 }
871 }
872 }
873
IsTests874 void Is() {
875 // Least Element (Bottom): None->Is(T)
876 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
877 TypeHandle type = *it;
878 CHECK(T.None->Is(type));
879 }
880
881 // Greatest Element (Top): T->Is(Any)
882 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
883 TypeHandle type = *it;
884 CHECK(type->Is(T.Any));
885 }
886
887 // Bottom Uniqueness: T->Is(None) implies T = None
888 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
889 TypeHandle type = *it;
890 if (type->Is(T.None)) CheckEqual(type, T.None);
891 }
892
893 // Top Uniqueness: Any->Is(T) implies T = Any
894 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
895 TypeHandle type = *it;
896 if (T.Any->Is(type)) CheckEqual(type, T.Any);
897 }
898
899 // Reflexivity: T->Is(T)
900 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
901 TypeHandle type = *it;
902 CHECK(type->Is(type));
903 }
904
905 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
906 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
907 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
908 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
909 TypeHandle type1 = *it1;
910 TypeHandle type2 = *it2;
911 TypeHandle type3 = *it3;
912 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
913 }
914 }
915 }
916
917 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
918 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
919 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
920 TypeHandle type1 = *it1;
921 TypeHandle type2 = *it2;
922 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
923 }
924 }
925
926 // Class(M1)->Is(Class(M2)) iff M1 = M2
927 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
928 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
929 Handle<i::Map> map1 = *mt1;
930 Handle<i::Map> map2 = *mt2;
931 TypeHandle class_type1 = T.Class(map1);
932 TypeHandle class_type2 = T.Class(map2);
933 CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
934 }
935 }
936
937 // Constant(V1)->Is(Constant(V2)) iff V1 = V2
938 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
939 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
940 Handle<i::Object> value1 = *vt1;
941 Handle<i::Object> value2 = *vt2;
942 TypeHandle const_type1 = T.Constant(value1);
943 TypeHandle const_type2 = T.Constant(value2);
944 CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
945 }
946 }
947
948 // Range(min1, max1)->Is(Range(min2, max2)) iff
949 // min1 >= min2 /\ max1 <= max2
950 for (ValueIterator i1 = T.integers.begin();
951 i1 != T.integers.end(); ++i1) {
952 for (ValueIterator j1 = T.integers.begin();
953 j1 != T.integers.end(); ++j1) {
954 for (ValueIterator i2 = T.integers.begin();
955 i2 != T.integers.end(); ++i2) {
956 for (ValueIterator j2 = T.integers.begin();
957 j2 != T.integers.end(); ++j2) {
958 i::Handle<i::Object> min1 = *i1;
959 i::Handle<i::Object> max1 = *j1;
960 i::Handle<i::Object> min2 = *i2;
961 i::Handle<i::Object> max2 = *j2;
962 if (min1->Number() > max1->Number()) std::swap(min1, max1);
963 if (min2->Number() > max2->Number()) std::swap(min2, max2);
964 TypeHandle type1 = T.Range(min1, max1);
965 TypeHandle type2 = T.Range(min2, max2);
966 CHECK(type1->Is(type2) ==
967 (min2->Number() <= min1->Number() &&
968 max1->Number() <= max2->Number()));
969 }
970 }
971 }
972 }
973
974 // Context(T1)->Is(Context(T2)) iff T1 = T2
975 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
976 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
977 TypeHandle outer1 = *it1;
978 TypeHandle outer2 = *it2;
979 TypeHandle type1 = T.Context(outer1);
980 TypeHandle type2 = T.Context(outer2);
981 CHECK(type1->Is(type2) == outer1->Equals(outer2));
982 }
983 }
984
985 // Array(T1)->Is(Array(T2)) iff T1 = T2
986 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
987 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
988 TypeHandle element1 = *it1;
989 TypeHandle element2 = *it2;
990 TypeHandle type1 = T.Array1(element1);
991 TypeHandle type2 = T.Array1(element2);
992 CHECK(type1->Is(type2) == element1->Equals(element2));
993 }
994 }
995
996 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2
997 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
998 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
999 TypeHandle result1 = *i;
1000 TypeHandle receiver1 = *j;
1001 TypeHandle type1 = T.Function0(result1, receiver1);
1002 TypeHandle result2 = T.Random();
1003 TypeHandle receiver2 = T.Random();
1004 TypeHandle type2 = T.Function0(result2, receiver2);
1005 CHECK(type1->Is(type2) ==
1006 (result1->Equals(result2) && receiver1->Equals(receiver2)));
1007 }
1008 }
1009
1010 // (In-)Compatibilities.
1011 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
1012 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
1013 TypeHandle type1 = *i;
1014 TypeHandle type2 = *j;
1015 CHECK(!type1->Is(type2) || this->IsBitset(type2) ||
1016 this->IsUnion(type2) || this->IsUnion(type1) ||
1017 (type1->IsClass() && type2->IsClass()) ||
1018 (type1->IsConstant() && type2->IsConstant()) ||
1019 (type1->IsConstant() && type2->IsRange()) ||
1020 (type1->IsRange() && type2->IsRange()) ||
1021 (type1->IsContext() && type2->IsContext()) ||
1022 (type1->IsArray() && type2->IsArray()) ||
1023 (type1->IsFunction() && type2->IsFunction()) ||
1024 type1->Equals(T.None));
1025 }
1026 }
1027
1028 // Basic types
1029 CheckUnordered(T.Boolean, T.Null);
1030 CheckUnordered(T.Undefined, T.Null);
1031 CheckUnordered(T.Boolean, T.Undefined);
1032
1033 CheckSub(T.SignedSmall, T.Number);
1034 CheckSub(T.Signed32, T.Number);
1035 CheckSub(T.SignedSmall, T.Signed32);
1036 CheckUnordered(T.SignedSmall, T.MinusZero);
1037 CheckUnordered(T.Signed32, T.Unsigned32);
1038
1039 CheckSub(T.UniqueName, T.Name);
1040 CheckSub(T.String, T.Name);
1041 CheckSub(T.InternalizedString, T.String);
1042 CheckSub(T.InternalizedString, T.UniqueName);
1043 CheckSub(T.InternalizedString, T.Name);
1044 CheckSub(T.Symbol, T.UniqueName);
1045 CheckSub(T.Symbol, T.Name);
1046 CheckUnordered(T.String, T.UniqueName);
1047 CheckUnordered(T.String, T.Symbol);
1048 CheckUnordered(T.InternalizedString, T.Symbol);
1049
1050 CheckSub(T.Object, T.Receiver);
1051 CheckSub(T.Array, T.Object);
1052 CheckSub(T.Function, T.Object);
1053 CheckSub(T.Proxy, T.Receiver);
1054 CheckUnordered(T.Object, T.Proxy);
1055 CheckUnordered(T.Array, T.Function);
1056
1057 // Structural types
1058 CheckSub(T.ObjectClass, T.Object);
1059 CheckSub(T.ArrayClass, T.Object);
1060 CheckSub(T.ArrayClass, T.Array);
1061 CheckSub(T.UninitializedClass, T.Internal);
1062 CheckUnordered(T.ObjectClass, T.ArrayClass);
1063 CheckUnordered(T.UninitializedClass, T.Null);
1064 CheckUnordered(T.UninitializedClass, T.Undefined);
1065
1066 CheckSub(T.SmiConstant, T.SignedSmall);
1067 CheckSub(T.SmiConstant, T.Signed32);
1068 CheckSub(T.SmiConstant, T.Number);
1069 CheckSub(T.ObjectConstant1, T.Object);
1070 CheckSub(T.ObjectConstant2, T.Object);
1071 CheckSub(T.ArrayConstant, T.Object);
1072 CheckSub(T.ArrayConstant, T.Array);
1073 CheckSub(T.UninitializedConstant, T.Internal);
1074 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
1075 CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
1076 CheckUnordered(T.UninitializedConstant, T.Null);
1077 CheckUnordered(T.UninitializedConstant, T.Undefined);
1078
1079 CheckUnordered(T.ObjectConstant1, T.ObjectClass);
1080 CheckUnordered(T.ObjectConstant2, T.ObjectClass);
1081 CheckUnordered(T.ObjectConstant1, T.ArrayClass);
1082 CheckUnordered(T.ObjectConstant2, T.ArrayClass);
1083 CheckUnordered(T.ArrayConstant, T.ObjectClass);
1084
1085 CheckSub(T.NumberArray, T.Array);
1086 CheckSub(T.NumberArray, T.Object);
1087 CheckUnordered(T.StringArray, T.AnyArray);
1088
1089 CheckSub(T.MethodFunction, T.Function);
1090 CheckSub(T.NumberFunction1, T.Object);
1091 CheckUnordered(T.SignedFunction1, T.NumberFunction1);
1092 CheckUnordered(T.NumberFunction1, T.NumberFunction2);
1093 }
1094
NowIsTests1095 void NowIs() {
1096 // Least Element (Bottom): None->NowIs(T)
1097 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1098 TypeHandle type = *it;
1099 CHECK(T.None->NowIs(type));
1100 }
1101
1102 // Greatest Element (Top): T->NowIs(Any)
1103 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1104 TypeHandle type = *it;
1105 CHECK(type->NowIs(T.Any));
1106 }
1107
1108 // Bottom Uniqueness: T->NowIs(None) implies T = None
1109 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1110 TypeHandle type = *it;
1111 if (type->NowIs(T.None)) CheckEqual(type, T.None);
1112 }
1113
1114 // Top Uniqueness: Any->NowIs(T) implies T = Any
1115 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1116 TypeHandle type = *it;
1117 if (T.Any->NowIs(type)) CheckEqual(type, T.Any);
1118 }
1119
1120 // Reflexivity: T->NowIs(T)
1121 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1122 TypeHandle type = *it;
1123 CHECK(type->NowIs(type));
1124 }
1125
1126 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3)
1127 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1128 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1129 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1130 TypeHandle type1 = *it1;
1131 TypeHandle type2 = *it2;
1132 TypeHandle type3 = *it3;
1133 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) ||
1134 type1->NowIs(type3));
1135 }
1136 }
1137 }
1138
1139 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2
1140 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1141 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1142 TypeHandle type1 = *it1;
1143 TypeHandle type2 = *it2;
1144 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) ==
1145 Equal(type1, type2));
1146 }
1147 }
1148
1149 // T1->Is(T2) implies T1->NowIs(T2)
1150 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1151 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1152 TypeHandle type1 = *it1;
1153 TypeHandle type2 = *it2;
1154 CHECK(!type1->Is(type2) || type1->NowIs(type2));
1155 }
1156 }
1157
1158 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
1159 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1160 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1161 Handle<i::Object> value1 = *vt1;
1162 Handle<i::Object> value2 = *vt2;
1163 TypeHandle const_type1 = T.Constant(value1);
1164 TypeHandle const_type2 = T.Constant(value2);
1165 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2));
1166 }
1167 }
1168
1169 // Class(M1)->NowIs(Class(M2)) iff M1 = M2
1170 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1171 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1172 Handle<i::Map> map1 = *mt1;
1173 Handle<i::Map> map2 = *mt2;
1174 TypeHandle class_type1 = T.Class(map1);
1175 TypeHandle class_type2 = T.Class(map2);
1176 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2));
1177 }
1178 }
1179
1180 // Constant(V)->NowIs(Class(M)) iff V has map M
1181 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1182 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1183 Handle<i::Map> map = *mt;
1184 Handle<i::Object> value = *vt;
1185 TypeHandle const_type = T.Constant(value);
1186 TypeHandle class_type = T.Class(map);
1187 CHECK((value->IsHeapObject() &&
1188 i::HeapObject::cast(*value)->map() == *map)
1189 == const_type->NowIs(class_type));
1190 }
1191 }
1192
1193 // Class(M)->NowIs(Constant(V)) never
1194 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1195 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1196 Handle<i::Map> map = *mt;
1197 Handle<i::Object> value = *vt;
1198 TypeHandle const_type = T.Constant(value);
1199 TypeHandle class_type = T.Class(map);
1200 CHECK(!class_type->NowIs(const_type));
1201 }
1202 }
1203 }
1204
ContainsTests1205 void Contains() {
1206 // T->Contains(V) iff Constant(V)->Is(T)
1207 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1208 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1209 TypeHandle type = *it;
1210 Handle<i::Object> value = *vt;
1211 TypeHandle const_type = T.Constant(value);
1212 CHECK(type->Contains(value) == const_type->Is(type));
1213 }
1214 }
1215 }
1216
NowContainsTests1217 void NowContains() {
1218 // T->NowContains(V) iff Constant(V)->NowIs(T)
1219 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1220 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1221 TypeHandle type = *it;
1222 Handle<i::Object> value = *vt;
1223 TypeHandle const_type = T.Constant(value);
1224 CHECK(type->NowContains(value) == const_type->NowIs(type));
1225 }
1226 }
1227
1228 // T->Contains(V) implies T->NowContains(V)
1229 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1230 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1231 TypeHandle type = *it;
1232 Handle<i::Object> value = *vt;
1233 CHECK(!type->Contains(value) || type->NowContains(value));
1234 }
1235 }
1236
1237 // NowOf(V)->Is(T) implies T->NowContains(V)
1238 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1239 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1240 TypeHandle type = *it;
1241 Handle<i::Object> value = *vt;
1242 TypeHandle nowof_type = T.Of(value);
1243 CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
1244 }
1245 }
1246 }
1247
MaybeTests1248 void Maybe() {
1249 // T->Maybe(Any) iff T inhabited
1250 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1251 TypeHandle type = *it;
1252 CHECK(type->Maybe(T.Any) == type->IsInhabited());
1253 }
1254
1255 // T->Maybe(None) never
1256 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1257 TypeHandle type = *it;
1258 CHECK(!type->Maybe(T.None));
1259 }
1260
1261 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited
1262 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1263 TypeHandle type = *it;
1264 CHECK(type->Maybe(type) == type->IsInhabited());
1265 }
1266
1267 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
1268 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1269 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1270 TypeHandle type1 = *it1;
1271 TypeHandle type2 = *it2;
1272 CHECK(type1->Maybe(type2) == type2->Maybe(type1));
1273 }
1274 }
1275
1276 // T1->Maybe(T2) implies T1, T2 inhabited
1277 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1278 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1279 TypeHandle type1 = *it1;
1280 TypeHandle type2 = *it2;
1281 CHECK(!type1->Maybe(type2) ||
1282 (type1->IsInhabited() && type2->IsInhabited()));
1283 }
1284 }
1285
1286 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
1287 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1288 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1289 TypeHandle type1 = *it1;
1290 TypeHandle type2 = *it2;
1291 TypeHandle intersect12 = T.Intersect(type1, type2);
1292 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
1293 }
1294 }
1295
1296 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2)
1297 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1298 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1299 TypeHandle type1 = *it1;
1300 TypeHandle type2 = *it2;
1301 CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
1302 type1->Maybe(type2));
1303 }
1304 }
1305
1306 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
1307 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1308 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1309 Handle<i::Object> value1 = *vt1;
1310 Handle<i::Object> value2 = *vt2;
1311 TypeHandle const_type1 = T.Constant(value1);
1312 TypeHandle const_type2 = T.Constant(value2);
1313 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
1314 }
1315 }
1316
1317 // Class(M1)->Maybe(Class(M2)) iff M1 = M2
1318 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1319 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1320 Handle<i::Map> map1 = *mt1;
1321 Handle<i::Map> map2 = *mt2;
1322 TypeHandle class_type1 = T.Class(map1);
1323 TypeHandle class_type2 = T.Class(map2);
1324 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
1325 }
1326 }
1327
1328 // Constant(V)->Maybe(Class(M)) never
1329 // This does NOT hold!
1330 /*
1331 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1332 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1333 Handle<i::Map> map = *mt;
1334 Handle<i::Object> value = *vt;
1335 TypeHandle const_type = T.Constant(value);
1336 TypeHandle class_type = T.Class(map);
1337 CHECK(!const_type->Maybe(class_type));
1338 }
1339 }
1340 */
1341
1342 // Class(M)->Maybe(Constant(V)) never
1343 // This does NOT hold!
1344 /*
1345 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1346 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1347 Handle<i::Map> map = *mt;
1348 Handle<i::Object> value = *vt;
1349 TypeHandle const_type = T.Constant(value);
1350 TypeHandle class_type = T.Class(map);
1351 CHECK(!class_type->Maybe(const_type));
1352 }
1353 }
1354 */
1355
1356 // Basic types
1357 CheckDisjoint(T.Boolean, T.Null);
1358 CheckDisjoint(T.Undefined, T.Null);
1359 CheckDisjoint(T.Boolean, T.Undefined);
1360 CheckOverlap(T.SignedSmall, T.Number);
1361 CheckOverlap(T.NaN, T.Number);
1362 CheckDisjoint(T.Signed32, T.NaN);
1363 CheckOverlap(T.UniqueName, T.Name);
1364 CheckOverlap(T.String, T.Name);
1365 CheckOverlap(T.InternalizedString, T.String);
1366 CheckOverlap(T.InternalizedString, T.UniqueName);
1367 CheckOverlap(T.InternalizedString, T.Name);
1368 CheckOverlap(T.Symbol, T.UniqueName);
1369 CheckOverlap(T.Symbol, T.Name);
1370 CheckOverlap(T.String, T.UniqueName);
1371 CheckDisjoint(T.String, T.Symbol);
1372 CheckDisjoint(T.InternalizedString, T.Symbol);
1373 CheckOverlap(T.Object, T.Receiver);
1374 CheckOverlap(T.Array, T.Object);
1375 CheckOverlap(T.Function, T.Object);
1376 CheckOverlap(T.Proxy, T.Receiver);
1377 CheckDisjoint(T.Object, T.Proxy);
1378 CheckDisjoint(T.Array, T.Function);
1379
1380 // Structural types
1381 CheckOverlap(T.ObjectClass, T.Object);
1382 CheckOverlap(T.ArrayClass, T.Object);
1383 CheckOverlap(T.ObjectClass, T.ObjectClass);
1384 CheckOverlap(T.ArrayClass, T.ArrayClass);
1385 CheckDisjoint(T.ObjectClass, T.ArrayClass);
1386 CheckOverlap(T.SmiConstant, T.SignedSmall);
1387 CheckOverlap(T.SmiConstant, T.Signed32);
1388 CheckOverlap(T.SmiConstant, T.Number);
1389 CheckOverlap(T.ObjectConstant1, T.Object);
1390 CheckOverlap(T.ObjectConstant2, T.Object);
1391 CheckOverlap(T.ArrayConstant, T.Object);
1392 CheckOverlap(T.ArrayConstant, T.Array);
1393 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
1394 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
1395 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant);
1396 CheckDisjoint(T.ObjectConstant1, T.ArrayClass);
1397 CheckDisjoint(T.ObjectConstant2, T.ArrayClass);
1398 CheckDisjoint(T.ArrayConstant, T.ObjectClass);
1399 CheckOverlap(T.NumberArray, T.Array);
1400 CheckDisjoint(T.NumberArray, T.AnyArray);
1401 CheckDisjoint(T.NumberArray, T.StringArray);
1402 CheckOverlap(T.MethodFunction, T.Function);
1403 CheckDisjoint(T.SignedFunction1, T.NumberFunction1);
1404 CheckDisjoint(T.SignedFunction1, T.NumberFunction2);
1405 CheckDisjoint(T.NumberFunction1, T.NumberFunction2);
1406 CheckDisjoint(T.SignedFunction1, T.MethodFunction);
1407 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!!
1408 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!!
1409 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Untagged)); // !!!
1410 }
1411
Union1Tests1412 void Union1() {
1413 // Identity: Union(T, None) = T
1414 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1415 TypeHandle type = *it;
1416 TypeHandle union_type = T.Union(type, T.None);
1417 CheckEqual(union_type, type);
1418 }
1419
1420 // Domination: Union(T, Any) = Any
1421 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1422 TypeHandle type = *it;
1423 TypeHandle union_type = T.Union(type, T.Any);
1424 CheckEqual(union_type, T.Any);
1425 }
1426
1427 // Idempotence: Union(T, T) = T
1428 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1429 TypeHandle type = *it;
1430 TypeHandle union_type = T.Union(type, type);
1431 CheckEqual(union_type, type);
1432 }
1433
1434 // Commutativity: Union(T1, T2) = Union(T2, T1)
1435 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1436 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1437 TypeHandle type1 = *it1;
1438 TypeHandle type2 = *it2;
1439 TypeHandle union12 = T.Union(type1, type2);
1440 TypeHandle union21 = T.Union(type2, type1);
1441 CheckEqual(union12, union21);
1442 }
1443 }
1444
1445 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
1446 // This does NOT hold!
1447 /*
1448 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1449 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1450 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1451 TypeHandle type1 = *it1;
1452 TypeHandle type2 = *it2;
1453 TypeHandle type3 = *it3;
1454 TypeHandle union12 = T.Union(type1, type2);
1455 TypeHandle union23 = T.Union(type2, type3);
1456 TypeHandle union1_23 = T.Union(type1, union23);
1457 TypeHandle union12_3 = T.Union(union12, type3);
1458 CheckEqual(union1_23, union12_3);
1459 }
1460 }
1461 }
1462 */
1463
1464 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
1465 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1466 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1467 TypeHandle type1 = *it1;
1468 TypeHandle type2 = *it2;
1469 TypeHandle union12 = T.Union(type1, type2);
1470 CHECK(type1->Is(union12));
1471 CHECK(type2->Is(union12));
1472 }
1473 }
1474
1475 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
1476 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1477 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1478 TypeHandle type1 = *it1;
1479 TypeHandle type2 = *it2;
1480 TypeHandle union12 = T.Union(type1, type2);
1481 if (type1->Is(type2)) CheckEqual(union12, type2);
1482 }
1483 }
1484
1485 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
1486 // This does NOT hold.
1487 /*
1488 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1489 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1490 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1491 TypeHandle type1 = *it1;
1492 TypeHandle type2 = *it2;
1493 TypeHandle type3 = *it3;
1494 TypeHandle union13 = T.Union(type1, type3);
1495 TypeHandle union23 = T.Union(type2, type3);
1496 CHECK(!type1->Is(type2) || union13->Is(union23));
1497 }
1498 }
1499 }
1500 */
1501 }
1502
Union2Tests1503 void Union2() {
1504 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
1505 // This does NOT hold. TODO(neis): Could fix this by splitting
1506 // OtherNumber into a negative and a positive part.
1507 /*
1508 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1509 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1510 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1511 TypeHandle type1 = *it1;
1512 TypeHandle type2 = *it2;
1513 TypeHandle type3 = *it3;
1514 TypeHandle union12 = T.Union(type1, type2);
1515 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
1516 }
1517 }
1518 }
1519 */
1520 }
1521
Union3Tests1522 void Union3() {
1523 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
1524 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1525 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1526 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1527 TypeHandle type1 = *it1;
1528 TypeHandle type2 = *it2;
1529 TypeHandle type3 = *it3;
1530 TypeHandle union23 = T.Union(type2, type3);
1531 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
1532 }
1533 }
1534 }
1535 }
1536
Union4Tests1537 void Union4() {
1538 // Class-class
1539 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
1540 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
1541 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array);
1542 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
1543
1544 // Constant-constant
1545 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
1546 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
1547 CheckUnordered(
1548 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
1549 CheckOverlap(
1550 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array);
1551 CheckDisjoint(
1552 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number);
1553 CheckOverlap(
1554 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass); // !!!
1555
1556 // Bitset-array
1557 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
1558 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
1559
1560 CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
1561 CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
1562 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object);
1563 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number);
1564
1565 // Bitset-function
1566 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
1567 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
1568
1569 CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
1570 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
1571 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object);
1572 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number);
1573
1574 // Bitset-class
1575 CheckSub(
1576 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number));
1577 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object);
1578 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array);
1579 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
1580 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
1581
1582 // Bitset-constant
1583 CheckSub(
1584 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
1585 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object);
1586 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array);
1587 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
1588 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
1589
1590 // Class-constant
1591 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
1592 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
1593 CheckSub(
1594 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object));
1595 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
1596 CheckDisjoint(
1597 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
1598 CheckOverlap(
1599 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); // !!!
1600
1601 // Bitset-union
1602 CheckSub(
1603 T.NaN,
1604 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
1605 CheckSub(
1606 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
1607 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
1608
1609 // Class-union
1610 CheckSub(
1611 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
1612 T.Object);
1613 CheckEqual(
1614 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
1615 T.Union(T.ArrayClass, T.ObjectConstant2));
1616
1617 // Constant-union
1618 CheckEqual(
1619 T.Union(
1620 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1621 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1622 CheckEqual(
1623 T.Union(
1624 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
1625 T.Union(
1626 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
1627
1628 // Array-union
1629 CheckEqual(
1630 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
1631 T.Union(T.AnyArray, T.NumberArray));
1632 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array);
1633
1634 // Function-union
1635 CheckEqual(
1636 T.Union(T.NumberFunction1, T.NumberFunction2),
1637 T.Union(T.NumberFunction2, T.NumberFunction1));
1638 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
1639
1640 // Union-union
1641 CheckEqual(
1642 T.Union(
1643 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1644 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1645 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1646 CheckEqual(
1647 T.Union(
1648 T.Union(T.Number, T.ArrayClass),
1649 T.Union(T.SignedSmall, T.Array)),
1650 T.Union(T.Number, T.Array));
1651 }
1652
IntersectTests1653 void Intersect() {
1654 // Identity: Intersect(T, Any) = T
1655 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1656 TypeHandle type = *it;
1657 TypeHandle intersect_type = T.Intersect(type, T.Any);
1658 CheckEqual(intersect_type, type);
1659 }
1660
1661 // Domination: Intersect(T, None) = None
1662 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1663 TypeHandle type = *it;
1664 TypeHandle intersect_type = T.Intersect(type, T.None);
1665 CheckEqual(intersect_type, T.None);
1666 }
1667
1668 // Idempotence: Intersect(T, T) = T
1669 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1670 TypeHandle type = *it;
1671 TypeHandle intersect_type = T.Intersect(type, type);
1672 CheckEqual(intersect_type, type);
1673 }
1674
1675 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
1676 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1677 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1678 TypeHandle type1 = *it1;
1679 TypeHandle type2 = *it2;
1680 TypeHandle intersect12 = T.Intersect(type1, type2);
1681 TypeHandle intersect21 = T.Intersect(type2, type1);
1682 CheckEqual(intersect12, intersect21);
1683 }
1684 }
1685
1686 // Associativity:
1687 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
1688 // This does NOT hold.
1689 /*
1690 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1691 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1692 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1693 TypeHandle type1 = *it1;
1694 TypeHandle type2 = *it2;
1695 TypeHandle type3 = *it3;
1696 TypeHandle intersect12 = T.Intersect(type1, type2);
1697 TypeHandle intersect23 = T.Intersect(type2, type3);
1698 TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
1699 TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
1700 CheckEqual(intersect1_23, intersect12_3);
1701 }
1702 }
1703 }
1704 */
1705
1706 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
1707 // This does NOT hold. Not even the disjunction.
1708 /*
1709 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1710 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1711 TypeHandle type1 = *it1;
1712 TypeHandle type2 = *it2;
1713 TypeHandle intersect12 = T.Intersect(type1, type2);
1714 CHECK(intersect12->Is(type1));
1715 CHECK(intersect12->Is(type2));
1716 }
1717 }
1718 */
1719
1720 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
1721 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1722 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1723 TypeHandle type1 = *it1;
1724 TypeHandle type2 = *it2;
1725 TypeHandle intersect12 = T.Intersect(type1, type2);
1726 if (type1->Is(type2)) CheckEqual(intersect12, type1);
1727 }
1728 }
1729
1730 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
1731 // This does NOT hold.
1732 /*
1733 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1734 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1735 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1736 TypeHandle type1 = *it1;
1737 TypeHandle type2 = *it2;
1738 TypeHandle type3 = *it3;
1739 TypeHandle intersect13 = T.Intersect(type1, type3);
1740 TypeHandle intersect23 = T.Intersect(type2, type3);
1741 CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
1742 }
1743 }
1744 }
1745 */
1746
1747 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
1748 // This does NOT hold.
1749 /*
1750 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1751 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1752 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1753 TypeHandle type1 = *it1;
1754 TypeHandle type2 = *it2;
1755 TypeHandle type3 = *it3;
1756 TypeHandle intersect12 = T.Intersect(type1, type2);
1757 CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
1758 intersect12->Is(type3));
1759 }
1760 }
1761 }
1762 */
1763
1764 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
1765 // This does NOT hold.
1766 /*
1767 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1768 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1769 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1770 TypeHandle type1 = *it1;
1771 TypeHandle type2 = *it2;
1772 TypeHandle type3 = *it3;
1773 TypeHandle intersect23 = T.Intersect(type2, type3);
1774 CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
1775 type1->Is(intersect23));
1776 }
1777 }
1778 }
1779 */
1780
1781 // Bitset-class
1782 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
1783 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None);
1784 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None);
1785
1786 // Bitset-array
1787 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
1788 CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None);
1789
1790 // Bitset-function
1791 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
1792 CheckEqual(T.Intersect(T.NumberFunction1, T.Array), T.None);
1793
1794 // Bitset-union
1795 CheckEqual(
1796 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
1797 T.Union(T.ObjectConstant1, T.ObjectClass));
1798 CHECK(
1799 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
1800 ->IsInhabited());
1801
1802 // Class-constant
1803 CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); // !!!
1804 CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
1805
1806 // Array-union
1807 CheckEqual(
1808 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
1809 T.NumberArray);
1810 CheckEqual(
1811 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
1812 T.AnyArray);
1813 CHECK(
1814 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
1815 ->IsInhabited());
1816
1817 // Function-union
1818 CheckEqual(
1819 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
1820 T.MethodFunction);
1821 CheckEqual(
1822 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
1823 T.NumberFunction1);
1824 CHECK(
1825 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
1826 ->IsInhabited());
1827
1828 // Class-union
1829 CheckEqual(
1830 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
1831 T.ArrayClass);
1832 CheckEqual(
1833 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
1834 T.ArrayClass);
1835 CHECK(
1836 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
1837 ->IsInhabited()); // !!!
1838
1839 // Constant-union
1840 CheckEqual(
1841 T.Intersect(
1842 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1843 T.ObjectConstant1);
1844 CheckEqual(
1845 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
1846 T.SmiConstant);
1847 CHECK(
1848 T.Intersect(
1849 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
1850 ->IsInhabited()); // !!!
1851
1852 // Union-union
1853 CheckEqual(
1854 T.Intersect(
1855 T.Union(T.Number, T.ArrayClass),
1856 T.Union(T.SignedSmall, T.Array)),
1857 T.Union(T.SignedSmall, T.ArrayClass));
1858 CheckEqual(
1859 T.Intersect(
1860 T.Union(T.Number, T.ObjectClass),
1861 T.Union(T.Signed32, T.Array)),
1862 T.Signed32);
1863 CheckEqual(
1864 T.Intersect(
1865 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1866 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1867 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1868 CheckEqual(
1869 T.Intersect(
1870 T.Union(
1871 T.ArrayClass,
1872 T.Union(T.ObjectConstant2, T.ObjectConstant1)),
1873 T.Union(
1874 T.ObjectConstant1,
1875 T.Union(T.ArrayConstant, T.ObjectConstant2))),
1876 T.Union(
1877 T.ArrayConstant,
1878 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!!
1879 }
1880
DistributivityTests1881 void Distributivity() {
1882 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
1883 // This does NOT hold.
1884 /*
1885 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1886 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1887 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1888 TypeHandle type1 = *it1;
1889 TypeHandle type2 = *it2;
1890 TypeHandle type3 = *it3;
1891 TypeHandle union12 = T.Union(type1, type2);
1892 TypeHandle union13 = T.Union(type1, type3);
1893 TypeHandle intersect23 = T.Intersect(type2, type3);
1894 TypeHandle union1_23 = T.Union(type1, intersect23);
1895 TypeHandle intersect12_13 = T.Intersect(union12, union13);
1896 CHECK(Equal(union1_23, intersect12_13));
1897 }
1898 }
1899 }
1900 */
1901
1902 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
1903 // This does NOT hold.
1904 /*
1905 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1906 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1907 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1908 TypeHandle type1 = *it1;
1909 TypeHandle type2 = *it2;
1910 TypeHandle type3 = *it3;
1911 TypeHandle intersect12 = T.Intersect(type1, type2);
1912 TypeHandle intersect13 = T.Intersect(type1, type3);
1913 TypeHandle union23 = T.Union(type2, type3);
1914 TypeHandle intersect1_23 = T.Intersect(type1, union23);
1915 TypeHandle union12_13 = T.Union(intersect12, intersect13);
1916 CHECK(Equal(intersect1_23, union12_13));
1917 }
1918 }
1919 }
1920 */
1921 }
1922
1923 template<class Type2, class TypeHandle2, class Region2, class Rep2>
ConvertTests1924 void Convert() {
1925 Types<Type2, TypeHandle2, Region2> T2(
1926 Rep2::ToRegion(&zone, isolate), isolate);
1927 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1928 TypeHandle type1 = *it;
1929 TypeHandle2 type2 = T2.template Convert<Type>(type1);
1930 TypeHandle type3 = T.template Convert<Type2>(type2);
1931 CheckEqual(type1, type3);
1932 }
1933 }
1934
HTypeFromTypeTests1935 void HTypeFromType() {
1936 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1937 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1938 TypeHandle type1 = *it1;
1939 TypeHandle type2 = *it2;
1940 HType htype1 = HType::FromType<Type>(type1);
1941 HType htype2 = HType::FromType<Type>(type2);
1942 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
1943 }
1944 }
1945 }
1946 };
1947
1948 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1949 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1950
1951
TEST(IsSomeType)1952 TEST(IsSomeType) {
1953 CcTest::InitializeVM();
1954 ZoneTests().IsSomeType();
1955 HeapTests().IsSomeType();
1956 }
1957
1958
TEST(BitsetType)1959 TEST(BitsetType) {
1960 CcTest::InitializeVM();
1961 ZoneTests().Bitset();
1962 HeapTests().Bitset();
1963 }
1964
1965
TEST(ClassType)1966 TEST(ClassType) {
1967 CcTest::InitializeVM();
1968 ZoneTests().Class();
1969 HeapTests().Class();
1970 }
1971
1972
TEST(ConstantType)1973 TEST(ConstantType) {
1974 CcTest::InitializeVM();
1975 ZoneTests().Constant();
1976 HeapTests().Constant();
1977 }
1978
1979
TEST(RangeType)1980 TEST(RangeType) {
1981 CcTest::InitializeVM();
1982 ZoneTests().Range();
1983 HeapTests().Range();
1984 }
1985
1986
TEST(ArrayType)1987 TEST(ArrayType) {
1988 CcTest::InitializeVM();
1989 ZoneTests().Array();
1990 HeapTests().Array();
1991 }
1992
1993
TEST(FunctionType)1994 TEST(FunctionType) {
1995 CcTest::InitializeVM();
1996 ZoneTests().Function();
1997 HeapTests().Function();
1998 }
1999
2000
TEST(Of)2001 TEST(Of) {
2002 CcTest::InitializeVM();
2003 ZoneTests().Of();
2004 HeapTests().Of();
2005 }
2006
2007
TEST(NowOf)2008 TEST(NowOf) {
2009 CcTest::InitializeVM();
2010 ZoneTests().NowOf();
2011 HeapTests().NowOf();
2012 }
2013
2014
TEST(BitsetGlb)2015 TEST(BitsetGlb) {
2016 CcTest::InitializeVM();
2017 ZoneTests().BitsetGlb();
2018 HeapTests().BitsetGlb();
2019 }
2020
2021
TEST(BitsetLub)2022 TEST(BitsetLub) {
2023 CcTest::InitializeVM();
2024 ZoneTests().BitsetLub();
2025 HeapTests().BitsetLub();
2026 }
2027
2028
TEST(Is)2029 TEST(Is) {
2030 CcTest::InitializeVM();
2031 ZoneTests().Is();
2032 HeapTests().Is();
2033 }
2034
2035
TEST(NowIs)2036 TEST(NowIs) {
2037 CcTest::InitializeVM();
2038 ZoneTests().NowIs();
2039 HeapTests().NowIs();
2040 }
2041
2042
TEST(Contains)2043 TEST(Contains) {
2044 CcTest::InitializeVM();
2045 ZoneTests().Contains();
2046 HeapTests().Contains();
2047 }
2048
2049
TEST(NowContains)2050 TEST(NowContains) {
2051 CcTest::InitializeVM();
2052 ZoneTests().NowContains();
2053 HeapTests().NowContains();
2054 }
2055
2056
TEST(Maybe)2057 TEST(Maybe) {
2058 CcTest::InitializeVM();
2059 ZoneTests().Maybe();
2060 HeapTests().Maybe();
2061 }
2062
2063
TEST(Union1)2064 TEST(Union1) {
2065 CcTest::InitializeVM();
2066 ZoneTests().Union1();
2067 HeapTests().Union1();
2068 }
2069
2070
2071 /*
2072 TEST(Union2) {
2073 CcTest::InitializeVM();
2074 ZoneTests().Union2();
2075 HeapTests().Union2();
2076 }
2077 */
2078
2079
TEST(Union3)2080 TEST(Union3) {
2081 CcTest::InitializeVM();
2082 ZoneTests().Union3();
2083 HeapTests().Union3();
2084 }
2085
2086
TEST(Union4)2087 TEST(Union4) {
2088 CcTest::InitializeVM();
2089 ZoneTests().Union4();
2090 HeapTests().Union4();
2091 }
2092
2093
TEST(Intersect)2094 TEST(Intersect) {
2095 CcTest::InitializeVM();
2096 ZoneTests().Intersect();
2097 HeapTests().Intersect();
2098 }
2099
2100
2101 /*
2102 TEST(Distributivity) {
2103 CcTest::InitializeVM();
2104 ZoneTests().Distributivity();
2105 HeapTests().Distributivity();
2106 }
2107 */
2108
2109
TEST(Convert)2110 TEST(Convert) {
2111 CcTest::InitializeVM();
2112 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
2113 HeapTests().Convert<Type, Type*, Zone, ZoneRep>();
2114 }
2115
2116
TEST(HTypeFromType)2117 TEST(HTypeFromType) {
2118 CcTest::InitializeVM();
2119 ZoneTests().HTypeFromType();
2120 HeapTests().HTypeFromType();
2121 }
2122