blob: 4549654501d5cedc2f9e8fa5e289f761a33e5388 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/crankshaft/hydrogen-types.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/types.h"
9#include "test/cctest/cctest.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "test/cctest/types-fuzz.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
12using namespace v8::internal;
13
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015// Testing auxiliaries (breaking the Type abstraction).
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016
17
18static bool IsInteger(double x) {
19 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
20}
21
22
23static bool IsInteger(i::Object* x) {
24 return x->IsNumber() && IsInteger(x->Number());
25}
26
27
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028typedef uint32_t bitset;
29
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031struct ZoneRep {
32 typedef void* Struct;
33
34 static bool IsStruct(Type* t, int tag) {
35 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag;
36 }
37 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 // HACK: the number 5 below is the value of StructuralType::kUnionTag.
39 static bool IsUnion(Type* t) { return t->IsUnionForTesting(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040
41 static Struct* AsStruct(Type* t) {
42 return reinterpret_cast<Struct*>(t);
43 }
44 static bitset AsBitset(Type* t) {
45 return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u);
46 }
47 static Struct* AsUnion(Type* t) {
48 return AsStruct(t);
49 }
50 static int Length(Struct* structured) {
51 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1]));
52 }
53
54 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; }
55
56 struct BitsetType : Type::BitsetType {
57 using Type::BitsetType::New;
58 using Type::BitsetType::Glb;
59 using Type::BitsetType::Lub;
60 using Type::BitsetType::IsInhabited;
61 };
62};
63
64
65struct HeapRep {
66 typedef FixedArray Struct;
67
68 static bool IsStruct(Handle<HeapType> t, int tag) {
69 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
70 }
71 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072 // HACK: the number 5 below is the value of StructuralType::kUnionTag.
73 static bool IsUnion(Handle<HeapType> t) { return t->IsUnionForTesting(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074
75 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
76 static bitset AsBitset(Handle<HeapType> t) {
77 return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t));
78 }
79 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
80 static int Length(Struct* structured) { return structured->length() - 1; }
81
82 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; }
83
84 struct BitsetType : HeapType::BitsetType {
85 using HeapType::BitsetType::New;
86 using HeapType::BitsetType::Glb;
87 using HeapType::BitsetType::Lub;
88 using HeapType::BitsetType::IsInhabited;
89 static bitset Glb(Handle<HeapType> type) { return Glb(*type); }
90 static bitset Lub(Handle<HeapType> type) { return Lub(*type); }
91 };
92};
93
94
Ben Murdochb8a8cc12014-11-26 15:28:44 +000095template<class Type, class TypeHandle, class Region, class Rep>
96struct Tests : Rep {
97 typedef Types<Type, TypeHandle, Region> TypesInstance;
98 typedef typename TypesInstance::TypeVector::iterator TypeIterator;
99 typedef typename TypesInstance::MapVector::iterator MapIterator;
100 typedef typename TypesInstance::ValueVector::iterator ValueIterator;
101
102 Isolate* isolate;
103 HandleScope scope;
104 Zone zone;
105 TypesInstance T;
106
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 Tests()
108 : isolate(CcTest::InitIsolateOnce()),
109 scope(isolate),
110 zone(),
111 T(Rep::ToRegion(&zone, isolate), isolate,
112 isolate->random_number_generator()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113
114 bool Equal(TypeHandle type1, TypeHandle type2) {
115 return
116 type1->Equals(type2) &&
117 this->IsBitset(type1) == this->IsBitset(type2) &&
118 this->IsUnion(type1) == this->IsUnion(type2) &&
119 type1->NumClasses() == type2->NumClasses() &&
120 type1->NumConstants() == type2->NumConstants() &&
121 (!this->IsBitset(type1) ||
122 this->AsBitset(type1) == this->AsBitset(type2)) &&
123 (!this->IsUnion(type1) ||
124 this->Length(this->AsUnion(type1)) ==
125 this->Length(this->AsUnion(type2)));
126 }
127
128 void CheckEqual(TypeHandle type1, TypeHandle type2) {
129 CHECK(Equal(type1, type2));
130 }
131
132 void CheckSub(TypeHandle type1, TypeHandle type2) {
133 CHECK(type1->Is(type2));
134 CHECK(!type2->Is(type1));
135 if (this->IsBitset(type1) && this->IsBitset(type2)) {
136 CHECK(this->AsBitset(type1) != this->AsBitset(type2));
137 }
138 }
139
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 void CheckSubOrEqual(TypeHandle type1, TypeHandle type2) {
141 CHECK(type1->Is(type2));
142 if (this->IsBitset(type1) && this->IsBitset(type2)) {
143 CHECK((this->AsBitset(type1) | this->AsBitset(type2))
144 == this->AsBitset(type2));
145 }
146 }
147
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 void CheckUnordered(TypeHandle type1, TypeHandle type2) {
149 CHECK(!type1->Is(type2));
150 CHECK(!type2->Is(type1));
151 if (this->IsBitset(type1) && this->IsBitset(type2)) {
152 CHECK(this->AsBitset(type1) != this->AsBitset(type2));
153 }
154 }
155
156 void CheckOverlap(TypeHandle type1, TypeHandle type2) {
157 CHECK(type1->Maybe(type2));
158 CHECK(type2->Maybe(type1));
159 }
160
161 void CheckDisjoint(TypeHandle type1, TypeHandle type2) {
162 CHECK(!type1->Is(type2));
163 CHECK(!type2->Is(type1));
164 CHECK(!type1->Maybe(type2));
165 CHECK(!type2->Maybe(type1));
166 }
167
168 void IsSomeType() {
169 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
170 TypeHandle t = *it;
171 CHECK(1 ==
172 this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() +
173 this->IsUnion(t) + t->IsArray() + t->IsFunction() + t->IsContext());
174 }
175 }
176
177 void Bitset() {
178 // None and Any are bitsets.
179 CHECK(this->IsBitset(T.None));
180 CHECK(this->IsBitset(T.Any));
181
182 CHECK(bitset(0) == this->AsBitset(T.None));
183 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any));
184
185 // Union(T1, T2) is bitset for bitsets T1,T2
186 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
187 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
188 TypeHandle type1 = *it1;
189 TypeHandle type2 = *it2;
190 TypeHandle union12 = T.Union(type1, type2);
191 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
192 this->IsBitset(union12));
193 }
194 }
195
196 // Intersect(T1, T2) is bitset for bitsets T1,T2
197 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
198 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
199 TypeHandle type1 = *it1;
200 TypeHandle type2 = *it2;
201 TypeHandle intersect12 = T.Intersect(type1, type2);
202 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
203 this->IsBitset(intersect12));
204 }
205 }
206
207 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2)
208 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
209 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
210 TypeHandle type1 = *it1;
211 TypeHandle type2 = *it2;
212 TypeHandle union12 = T.Union(type1, type2);
213 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
214 this->IsBitset(union12));
215 }
216 }
217
218 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2
219 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
220 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
221 TypeHandle type1 = *it1;
222 TypeHandle type2 = *it2;
223 TypeHandle union12 = T.Union(type1, type2);
224 if (this->IsBitset(type1) && this->IsBitset(type2)) {
225 CHECK(
226 (this->AsBitset(type1) | this->AsBitset(type2)) ==
227 this->AsBitset(union12));
228 }
229 }
230 }
231
232 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None)
233 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
234 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
235 TypeHandle type1 = *it1;
236 TypeHandle type2 = *it2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 if (this->IsBitset(type1) && this->IsBitset(type2)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238 TypeHandle intersect12 = T.Intersect(type1, type2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239 bitset bits = this->AsBitset(type1) & this->AsBitset(type2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000240 CHECK(bits == this->AsBitset(intersect12));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 }
242 }
243 }
244 }
245
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 void PointwiseRepresentation() {
247 // Check we can decompose type into semantics and representation and
248 // then compose it back to get an equivalent type.
249 int counter = 0;
250 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
251 counter++;
252 printf("Counter: %i\n", counter);
253 fflush(stdout);
254 TypeHandle type1 = *it1;
255 TypeHandle representation = T.Representation(type1);
256 TypeHandle semantic = T.Semantic(type1);
257 TypeHandle composed = T.Union(representation, semantic);
258 CHECK(type1->Equals(composed));
259 }
260
261 // Pointwiseness of Union.
262 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
263 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
264 TypeHandle type1 = *it1;
265 TypeHandle type2 = *it2;
266 TypeHandle representation1 = T.Representation(type1);
267 TypeHandle semantic1 = T.Semantic(type1);
268 TypeHandle representation2 = T.Representation(type2);
269 TypeHandle semantic2 = T.Semantic(type2);
270 TypeHandle direct_union = T.Union(type1, type2);
271 TypeHandle representation_union =
272 T.Union(representation1, representation2);
273 TypeHandle semantic_union = T.Union(semantic1, semantic2);
274 TypeHandle composed_union =
275 T.Union(representation_union, semantic_union);
276 CHECK(direct_union->Equals(composed_union));
277 }
278 }
279
280 // Pointwiseness of Intersect.
281 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
282 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
283 TypeHandle type1 = *it1;
284 TypeHandle type2 = *it2;
285 TypeHandle representation1 = T.Representation(type1);
286 TypeHandle semantic1 = T.Semantic(type1);
287 TypeHandle representation2 = T.Representation(type2);
288 TypeHandle semantic2 = T.Semantic(type2);
289 TypeHandle direct_intersection = T.Intersect(type1, type2);
290 TypeHandle representation_intersection =
291 T.Intersect(representation1, representation2);
292 TypeHandle semantic_intersection = T.Intersect(semantic1, semantic2);
293 TypeHandle composed_intersection =
294 T.Union(representation_intersection, semantic_intersection);
295 CHECK(direct_intersection->Equals(composed_intersection));
296 }
297 }
298
299 // Pointwiseness of Is.
300 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
301 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
302 TypeHandle type1 = *it1;
303 TypeHandle type2 = *it2;
304 TypeHandle representation1 = T.Representation(type1);
305 TypeHandle semantic1 = T.Semantic(type1);
306 TypeHandle representation2 = T.Representation(type2);
307 TypeHandle semantic2 = T.Semantic(type2);
308 bool representation_is = representation1->Is(representation2);
309 bool semantic_is = semantic1->Is(semantic2);
310 bool direct_is = type1->Is(type2);
311 CHECK(direct_is == (semantic_is && representation_is));
312 }
313 }
314 }
315
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316 void Class() {
317 // Constructor
318 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
319 Handle<i::Map> map = *mt;
320 TypeHandle type = T.Class(map);
321 CHECK(type->IsClass());
322 }
323
324 // Map attribute
325 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
326 Handle<i::Map> map = *mt;
327 TypeHandle type = T.Class(map);
328 CHECK(*map == *type->AsClass()->Map());
329 }
330
331 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2
332 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
333 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
334 Handle<i::Map> map1 = *mt1;
335 Handle<i::Map> map2 = *mt2;
336 TypeHandle type1 = T.Class(map1);
337 TypeHandle type2 = T.Class(map2);
338 CHECK(Equal(type1, type2) == (*map1 == *map2));
339 }
340 }
341 }
342
343 void Constant() {
344 // Constructor
345 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
346 Handle<i::Object> value = *vt;
347 TypeHandle type = T.Constant(value);
348 CHECK(type->IsConstant());
349 }
350
351 // Value attribute
352 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
353 Handle<i::Object> value = *vt;
354 TypeHandle type = T.Constant(value);
355 CHECK(*value == *type->AsConstant()->Value());
356 }
357
358 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2
359 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
360 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
361 Handle<i::Object> value1 = *vt1;
362 Handle<i::Object> value2 = *vt2;
363 TypeHandle type1 = T.Constant(value1);
364 TypeHandle type2 = T.Constant(value2);
365 CHECK(Equal(type1, type2) == (*value1 == *value2));
366 }
367 }
368
369 // Typing of numbers
370 Factory* fac = isolate->factory();
371 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
372 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
373 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31));
375 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.Negative31));
376 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.Negative31));
377 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned31));
378 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned30));
379 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned31));
380 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned30));
381 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative32));
382 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative31));
383 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.Negative32));
384 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.Negative31));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 if (SmiValuesAre31Bits()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400386 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400387 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall));
389 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390 } else {
391 CHECK(SmiValuesAre32Bits());
392 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
393 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000394 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall));
395 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400397 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000398 CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned31));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400399 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000400 CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned31));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400401 CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber));
402 CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32));
403 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber));
404 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32));
405 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber));
406 CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32));
407 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber));
408 CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32));
409 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber));
410 CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000411 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000412 CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN()))
413 ->Is(T.NaN));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400414 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber));
415 CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32));
416 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber));
417 CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000418 }
419
420 void Range() {
421 // Constructor
422 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
423 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424 double min = (*i)->Number();
425 double max = (*j)->Number();
426 if (min > max) std::swap(min, max);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000427 TypeHandle type = T.Range(min, max);
428 CHECK(type->IsRange());
429 }
430 }
431
432 // Range attributes
433 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) {
434 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 double min = (*i)->Number();
436 double max = (*j)->Number();
437 if (min > max) std::swap(min, max);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000438 TypeHandle type = T.Range(min, max);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 CHECK(min == type->AsRange()->Min());
440 CHECK(max == type->AsRange()->Max());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441 }
442 }
443
444 // Functionality & Injectivity:
445 // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2
446 for (ValueIterator i1 = T.integers.begin();
447 i1 != T.integers.end(); ++i1) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400448 for (ValueIterator j1 = i1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 j1 != T.integers.end(); ++j1) {
450 for (ValueIterator i2 = T.integers.begin();
451 i2 != T.integers.end(); ++i2) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400452 for (ValueIterator j2 = i2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000453 j2 != T.integers.end(); ++j2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000454 double min1 = (*i1)->Number();
455 double max1 = (*j1)->Number();
456 double min2 = (*i2)->Number();
457 double max2 = (*j2)->Number();
458 if (min1 > max1) std::swap(min1, max1);
459 if (min2 > max2) std::swap(min2, max2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000460 TypeHandle type1 = T.Range(min1, max1);
461 TypeHandle type2 = T.Range(min2, max2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000463 }
464 }
465 }
466 }
467 }
468
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400469 void Context() {
470 // Constructor
471 for (int i = 0; i < 20; ++i) {
472 TypeHandle type = T.Random();
473 TypeHandle context = T.Context(type);
474 CHECK(context->Iscontext());
475 }
476
477 // Attributes
478 for (int i = 0; i < 20; ++i) {
479 TypeHandle type = T.Random();
480 TypeHandle context = T.Context(type);
481 CheckEqual(type, context->AsContext()->Outer());
482 }
483
484 // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2
485 for (int i = 0; i < 20; ++i) {
486 for (int j = 0; j < 20; ++j) {
487 TypeHandle type1 = T.Random();
488 TypeHandle type2 = T.Random();
489 TypeHandle context1 = T.Context(type1);
490 TypeHandle context2 = T.Context(type2);
491 CHECK(Equal(context1, context2) == Equal(type1, type2));
492 }
493 }
494 }
495
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000496 void Array() {
497 // Constructor
498 for (int i = 0; i < 20; ++i) {
499 TypeHandle type = T.Random();
500 TypeHandle array = T.Array1(type);
501 CHECK(array->IsArray());
502 }
503
504 // Attributes
505 for (int i = 0; i < 20; ++i) {
506 TypeHandle type = T.Random();
507 TypeHandle array = T.Array1(type);
508 CheckEqual(type, array->AsArray()->Element());
509 }
510
511 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2
512 for (int i = 0; i < 20; ++i) {
513 for (int j = 0; j < 20; ++j) {
514 TypeHandle type1 = T.Random();
515 TypeHandle type2 = T.Random();
516 TypeHandle array1 = T.Array1(type1);
517 TypeHandle array2 = T.Array1(type2);
518 CHECK(Equal(array1, array2) == Equal(type1, type2));
519 }
520 }
521 }
522
523 void Function() {
524 // Constructors
525 for (int i = 0; i < 20; ++i) {
526 for (int j = 0; j < 20; ++j) {
527 for (int k = 0; k < 20; ++k) {
528 TypeHandle type1 = T.Random();
529 TypeHandle type2 = T.Random();
530 TypeHandle type3 = T.Random();
531 TypeHandle function0 = T.Function0(type1, type2);
532 TypeHandle function1 = T.Function1(type1, type2, type3);
533 TypeHandle function2 = T.Function2(type1, type2, type3);
534 CHECK(function0->IsFunction());
535 CHECK(function1->IsFunction());
536 CHECK(function2->IsFunction());
537 }
538 }
539 }
540
541 // Attributes
542 for (int i = 0; i < 20; ++i) {
543 for (int j = 0; j < 20; ++j) {
544 for (int k = 0; k < 20; ++k) {
545 TypeHandle type1 = T.Random();
546 TypeHandle type2 = T.Random();
547 TypeHandle type3 = T.Random();
548 TypeHandle function0 = T.Function0(type1, type2);
549 TypeHandle function1 = T.Function1(type1, type2, type3);
550 TypeHandle function2 = T.Function2(type1, type2, type3);
551 CHECK_EQ(0, function0->AsFunction()->Arity());
552 CHECK_EQ(1, function1->AsFunction()->Arity());
553 CHECK_EQ(2, function2->AsFunction()->Arity());
554 CheckEqual(type1, function0->AsFunction()->Result());
555 CheckEqual(type1, function1->AsFunction()->Result());
556 CheckEqual(type1, function2->AsFunction()->Result());
557 CheckEqual(type2, function0->AsFunction()->Receiver());
558 CheckEqual(type2, function1->AsFunction()->Receiver());
559 CheckEqual(T.Any, function2->AsFunction()->Receiver());
560 CheckEqual(type3, function1->AsFunction()->Parameter(0));
561 CheckEqual(type2, function2->AsFunction()->Parameter(0));
562 CheckEqual(type3, function2->AsFunction()->Parameter(1));
563 }
564 }
565 }
566
567 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2
568 for (int i = 0; i < 20; ++i) {
569 for (int j = 0; j < 20; ++j) {
570 for (int k = 0; k < 20; ++k) {
571 TypeHandle type1 = T.Random();
572 TypeHandle type2 = T.Random();
573 TypeHandle type3 = T.Random();
574 TypeHandle function01 = T.Function0(type1, type2);
575 TypeHandle function02 = T.Function0(type1, type3);
576 TypeHandle function03 = T.Function0(type3, type2);
577 TypeHandle function11 = T.Function1(type1, type2, type2);
578 TypeHandle function12 = T.Function1(type1, type2, type3);
579 TypeHandle function21 = T.Function2(type1, type2, type2);
580 TypeHandle function22 = T.Function2(type1, type2, type3);
581 TypeHandle function23 = T.Function2(type1, type3, type2);
582 CHECK(Equal(function01, function02) == Equal(type2, type3));
583 CHECK(Equal(function01, function03) == Equal(type1, type3));
584 CHECK(Equal(function11, function12) == Equal(type2, type3));
585 CHECK(Equal(function21, function22) == Equal(type2, type3));
586 CHECK(Equal(function21, function23) == Equal(type2, type3));
587 }
588 }
589 }
590 }
591
592 void Of() {
593 // Constant(V)->Is(Of(V))
594 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
595 Handle<i::Object> value = *vt;
596 TypeHandle const_type = T.Constant(value);
597 TypeHandle of_type = T.Of(value);
598 CHECK(const_type->Is(of_type));
599 }
600
601 // If Of(V)->Is(T), then Constant(V)->Is(T)
602 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
603 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
604 Handle<i::Object> value = *vt;
605 TypeHandle type = *it;
606 TypeHandle const_type = T.Constant(value);
607 TypeHandle of_type = T.Of(value);
608 CHECK(!of_type->Is(type) || const_type->Is(type));
609 }
610 }
611
612 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V))
613 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
614 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
615 Handle<i::Object> value = *vt;
616 TypeHandle type = *it;
617 TypeHandle const_type = T.Constant(value);
618 TypeHandle of_type = T.Of(value);
619 CHECK(!const_type->Is(type) ||
620 of_type->Is(type) || type->Maybe(const_type));
621 }
622 }
623 }
624
625 void NowOf() {
626 // Constant(V)->NowIs(NowOf(V))
627 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
628 Handle<i::Object> value = *vt;
629 TypeHandle const_type = T.Constant(value);
630 TypeHandle nowof_type = T.NowOf(value);
631 CHECK(const_type->NowIs(nowof_type));
632 }
633
634 // NowOf(V)->Is(Of(V))
635 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
636 Handle<i::Object> value = *vt;
637 TypeHandle nowof_type = T.NowOf(value);
638 TypeHandle of_type = T.Of(value);
639 CHECK(nowof_type->Is(of_type));
640 }
641
642 // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T)
643 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
644 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
645 Handle<i::Object> value = *vt;
646 TypeHandle type = *it;
647 TypeHandle const_type = T.Constant(value);
648 TypeHandle nowof_type = T.NowOf(value);
649 CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type));
650 }
651 }
652
653 // If Constant(V)->NowIs(T),
654 // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
655 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
656 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
657 Handle<i::Object> value = *vt;
658 TypeHandle type = *it;
659 TypeHandle const_type = T.Constant(value);
660 TypeHandle nowof_type = T.NowOf(value);
661 CHECK(!const_type->NowIs(type) ||
662 nowof_type->NowIs(type) || type->Maybe(const_type));
663 }
664 }
665
666 // If Constant(V)->Is(T),
667 // then NowOf(V)->Is(T) or T->Maybe(Constant(V))
668 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
669 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
670 Handle<i::Object> value = *vt;
671 TypeHandle type = *it;
672 TypeHandle const_type = T.Constant(value);
673 TypeHandle nowof_type = T.NowOf(value);
674 CHECK(!const_type->Is(type) ||
675 nowof_type->Is(type) || type->Maybe(const_type));
676 }
677 }
678 }
679
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400680 void MinMax() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400681 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b).
682 // TODO(neis): Need to ignore representation for this to be true.
683 /*
684 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
685 TypeHandle type = *it;
686 if (this->IsBitset(type) && type->Is(T.Number) &&
687 !type->Is(T.None) && !type->Is(T.NaN)) {
688 TypeHandle range = T.Range(
689 isolate->factory()->NewNumber(type->Min()),
690 isolate->factory()->NewNumber(type->Max()));
691 CHECK(range->Is(type));
692 }
693 }
694 */
695
696 // If b is regular numeric bitset, then b->Min() and b->Max() are integers.
697 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
698 TypeHandle type = *it;
699 if (this->IsBitset(type) && type->Is(T.Number) && !type->Is(T.NaN)) {
700 CHECK(IsInteger(type->Min()) && IsInteger(type->Max()));
701 }
702 }
703
704 // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then
705 // b1->Min() >= b2->Min() and b1->Max() <= b2->Max().
706 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
707 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
708 TypeHandle type1 = *it1;
709 TypeHandle type2 = *it2;
710 if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) &&
711 !type1->Is(T.NaN) && !type2->Is(T.NaN)) {
712 CHECK(type1->Min() >= type2->Min());
713 CHECK(type1->Max() <= type2->Max());
714 }
715 }
716 }
717
718 // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max()
719 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
720 TypeHandle type = *it;
721 if (type->IsRange()) {
722 TypeHandle lub = Rep::BitsetType::New(
723 Rep::BitsetType::Lub(type), T.region());
724 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max());
725 }
726 }
727
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 // Rangification: If T->Is(Range(-inf,+inf)) and T is inhabited, then
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400729 // T->Is(Range(T->Min(), T->Max())).
730 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
731 TypeHandle type = *it;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732 CHECK(!type->Is(T.Integer) || !type->IsInhabited() ||
733 type->Is(T.Range(type->Min(), type->Max())));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400734 }
735 }
736
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000737 void BitsetGlb() {
738 // Lower: (T->BitsetGlb())->Is(T)
739 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
740 TypeHandle type = *it;
741 TypeHandle glb =
742 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region());
743 CHECK(glb->Is(type));
744 }
745
746 // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb())
747 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
748 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
749 TypeHandle type1 = *it1;
750 TypeHandle type2 = *it2;
751 TypeHandle glb2 =
752 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
753 CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2));
754 }
755 }
756
757 // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb())
758 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
759 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
760 TypeHandle type1 = *it1;
761 TypeHandle type2 = *it2;
762 TypeHandle glb1 =
763 Rep::BitsetType::New(Rep::BitsetType::Glb(type1), T.region());
764 TypeHandle glb2 =
765 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region());
766 CHECK(!type1->Is(type2) || glb1->Is(glb2));
767 }
768 }
769 }
770
771 void BitsetLub() {
772 // Upper: T->Is(T->BitsetLub())
773 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
774 TypeHandle type = *it;
775 TypeHandle lub =
776 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region());
777 CHECK(type->Is(lub));
778 }
779
780 // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2)
781 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
782 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
783 TypeHandle type1 = *it1;
784 TypeHandle type2 = *it2;
785 TypeHandle lub1 =
786 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
787 CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2));
788 }
789 }
790
791 // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub())
792 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
793 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
794 TypeHandle type1 = *it1;
795 TypeHandle type2 = *it2;
796 TypeHandle lub1 =
797 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region());
798 TypeHandle lub2 =
799 Rep::BitsetType::New(Rep::BitsetType::Lub(type2), T.region());
800 CHECK(!type1->Is(type2) || lub1->Is(lub2));
801 }
802 }
803 }
804
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400805 void Is1() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806 // Least Element (Bottom): None->Is(T)
807 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
808 TypeHandle type = *it;
809 CHECK(T.None->Is(type));
810 }
811
812 // Greatest Element (Top): T->Is(Any)
813 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
814 TypeHandle type = *it;
815 CHECK(type->Is(T.Any));
816 }
817
818 // Bottom Uniqueness: T->Is(None) implies T = None
819 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
820 TypeHandle type = *it;
821 if (type->Is(T.None)) CheckEqual(type, T.None);
822 }
823
824 // Top Uniqueness: Any->Is(T) implies T = Any
825 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
826 TypeHandle type = *it;
827 if (T.Any->Is(type)) CheckEqual(type, T.Any);
828 }
829
830 // Reflexivity: T->Is(T)
831 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
832 TypeHandle type = *it;
833 CHECK(type->Is(type));
834 }
835
836 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3)
837 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
838 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
839 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
840 TypeHandle type1 = *it1;
841 TypeHandle type2 = *it2;
842 TypeHandle type3 = *it3;
843 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
844 }
845 }
846 }
847
848 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2
849 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
850 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
851 TypeHandle type1 = *it1;
852 TypeHandle type2 = *it2;
853 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2));
854 }
855 }
856
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400857 // (In-)Compatibilities.
858 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
859 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
860 TypeHandle type1 = *i;
861 TypeHandle type2 = *j;
862 CHECK(!type1->Is(type2) || this->IsBitset(type2) ||
863 this->IsUnion(type2) || this->IsUnion(type1) ||
864 (type1->IsClass() && type2->IsClass()) ||
865 (type1->IsConstant() && type2->IsConstant()) ||
866 (type1->IsConstant() && type2->IsRange()) ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 (this->IsBitset(type1) && type2->IsRange()) ||
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400868 (type1->IsRange() && type2->IsRange()) ||
869 (type1->IsContext() && type2->IsContext()) ||
870 (type1->IsArray() && type2->IsArray()) ||
871 (type1->IsFunction() && type2->IsFunction()) ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000872 !type1->IsInhabited());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400873 }
874 }
875 }
876
877 void Is2() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000878 // Class(M1)->Is(Class(M2)) iff M1 = M2
879 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
880 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
881 Handle<i::Map> map1 = *mt1;
882 Handle<i::Map> map2 = *mt2;
883 TypeHandle class_type1 = T.Class(map1);
884 TypeHandle class_type2 = T.Class(map2);
885 CHECK(class_type1->Is(class_type2) == (*map1 == *map2));
886 }
887 }
888
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400889 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000890 for (ValueIterator i1 = T.integers.begin();
891 i1 != T.integers.end(); ++i1) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400892 for (ValueIterator j1 = i1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000893 j1 != T.integers.end(); ++j1) {
894 for (ValueIterator i2 = T.integers.begin();
895 i2 != T.integers.end(); ++i2) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400896 for (ValueIterator j2 = i2;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000897 j2 != T.integers.end(); ++j2) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 double min1 = (*i1)->Number();
899 double max1 = (*j1)->Number();
900 double min2 = (*i2)->Number();
901 double max2 = (*j2)->Number();
902 if (min1 > max1) std::swap(min1, max1);
903 if (min2 > max2) std::swap(min2, max2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904 TypeHandle type1 = T.Range(min1, max1);
905 TypeHandle type2 = T.Range(min2, max2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000906 CHECK(type1->Is(type2) == (min1 >= min2 && max1 <= max2));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 }
908 }
909 }
910 }
911
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400912 // Constant(V1)->Is(Constant(V2)) iff V1 = V2
913 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
914 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
915 Handle<i::Object> value1 = *vt1;
916 Handle<i::Object> value2 = *vt2;
917 TypeHandle const_type1 = T.Constant(value1);
918 TypeHandle const_type2 = T.Constant(value2);
919 CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
920 }
921 }
922
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923 // Context(T1)->Is(Context(T2)) iff T1 = T2
924 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
925 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
926 TypeHandle outer1 = *it1;
927 TypeHandle outer2 = *it2;
928 TypeHandle type1 = T.Context(outer1);
929 TypeHandle type2 = T.Context(outer2);
930 CHECK(type1->Is(type2) == outer1->Equals(outer2));
931 }
932 }
933
934 // Array(T1)->Is(Array(T2)) iff T1 = T2
935 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
936 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
937 TypeHandle element1 = *it1;
938 TypeHandle element2 = *it2;
939 TypeHandle type1 = T.Array1(element1);
940 TypeHandle type2 = T.Array1(element2);
941 CHECK(type1->Is(type2) == element1->Equals(element2));
942 }
943 }
944
945 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2
946 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
947 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
948 TypeHandle result1 = *i;
949 TypeHandle receiver1 = *j;
950 TypeHandle type1 = T.Function0(result1, receiver1);
951 TypeHandle result2 = T.Random();
952 TypeHandle receiver2 = T.Random();
953 TypeHandle type2 = T.Function0(result2, receiver2);
954 CHECK(type1->Is(type2) ==
955 (result1->Equals(result2) && receiver1->Equals(receiver2)));
956 }
957 }
958
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400959
960 // Range-specific subtyping
961
962 // If IsInteger(v) then Constant(v)->Is(Range(v, v)).
963 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
964 TypeHandle type = *it;
965 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(),
967 type->AsConstant()->Value()->Number())));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000968 }
969 }
970
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400971 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max.
972 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
973 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
974 TypeHandle type1 = *it1;
975 TypeHandle type2 = *it2;
976 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) {
977 double x = type1->AsConstant()->Value()->Number();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000978 double min = type2->AsRange()->Min();
979 double max = type2->AsRange()->Max();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400980 CHECK(IsInteger(x) && min <= x && x <= max);
981 }
982 }
983 }
984
985 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber))
986 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
987 TypeHandle type = *it;
988 if (type->IsRange()) {
989 TypeHandle lub = Rep::BitsetType::New(
990 Rep::BitsetType::Lub(type), T.region());
991 CHECK(lub->Is(T.PlainNumber));
992 }
993 }
994
995
996 // Subtyping between concrete basic types
997
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000998 CheckUnordered(T.Boolean, T.Null);
999 CheckUnordered(T.Undefined, T.Null);
1000 CheckUnordered(T.Boolean, T.Undefined);
1001
1002 CheckSub(T.SignedSmall, T.Number);
1003 CheckSub(T.Signed32, T.Number);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001004 CheckSubOrEqual(T.SignedSmall, T.Signed32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001005 CheckUnordered(T.SignedSmall, T.MinusZero);
1006 CheckUnordered(T.Signed32, T.Unsigned32);
1007
1008 CheckSub(T.UniqueName, T.Name);
1009 CheckSub(T.String, T.Name);
1010 CheckSub(T.InternalizedString, T.String);
1011 CheckSub(T.InternalizedString, T.UniqueName);
1012 CheckSub(T.InternalizedString, T.Name);
1013 CheckSub(T.Symbol, T.UniqueName);
1014 CheckSub(T.Symbol, T.Name);
1015 CheckUnordered(T.String, T.UniqueName);
1016 CheckUnordered(T.String, T.Symbol);
1017 CheckUnordered(T.InternalizedString, T.Symbol);
1018
1019 CheckSub(T.Object, T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001020 CheckSub(T.Proxy, T.Receiver);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021 CheckSub(T.OtherObject, T.Object);
1022 CheckSub(T.Undetectable, T.Object);
1023 CheckSub(T.OtherObject, T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001025 CheckUnordered(T.Object, T.Proxy);
1026 CheckUnordered(T.OtherObject, T.Undetectable);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001027
1028 // Subtyping between concrete structural types
1029
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001030 CheckSub(T.ObjectClass, T.Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001031 CheckSub(T.ArrayClass, T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001032 CheckSub(T.UninitializedClass, T.Internal);
1033 CheckUnordered(T.ObjectClass, T.ArrayClass);
1034 CheckUnordered(T.UninitializedClass, T.Null);
1035 CheckUnordered(T.UninitializedClass, T.Undefined);
1036
1037 CheckSub(T.SmiConstant, T.SignedSmall);
1038 CheckSub(T.SmiConstant, T.Signed32);
1039 CheckSub(T.SmiConstant, T.Number);
1040 CheckSub(T.ObjectConstant1, T.Object);
1041 CheckSub(T.ObjectConstant2, T.Object);
1042 CheckSub(T.ArrayConstant, T.Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001043 CheckSub(T.ArrayConstant, T.OtherObject);
1044 CheckSub(T.ArrayConstant, T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001045 CheckSub(T.UninitializedConstant, T.Internal);
1046 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2);
1047 CheckUnordered(T.ObjectConstant1, T.ArrayConstant);
1048 CheckUnordered(T.UninitializedConstant, T.Null);
1049 CheckUnordered(T.UninitializedConstant, T.Undefined);
1050
1051 CheckUnordered(T.ObjectConstant1, T.ObjectClass);
1052 CheckUnordered(T.ObjectConstant2, T.ObjectClass);
1053 CheckUnordered(T.ObjectConstant1, T.ArrayClass);
1054 CheckUnordered(T.ObjectConstant2, T.ArrayClass);
1055 CheckUnordered(T.ArrayConstant, T.ObjectClass);
1056
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001057 CheckSub(T.NumberArray, T.OtherObject);
1058 CheckSub(T.NumberArray, T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059 CheckSub(T.NumberArray, T.Object);
1060 CheckUnordered(T.StringArray, T.AnyArray);
1061
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001062 CheckSub(T.MethodFunction, T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001063 CheckSub(T.NumberFunction1, T.Object);
1064 CheckUnordered(T.SignedFunction1, T.NumberFunction1);
1065 CheckUnordered(T.NumberFunction1, T.NumberFunction2);
1066 }
1067
1068 void NowIs() {
1069 // Least Element (Bottom): None->NowIs(T)
1070 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1071 TypeHandle type = *it;
1072 CHECK(T.None->NowIs(type));
1073 }
1074
1075 // Greatest Element (Top): T->NowIs(Any)
1076 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1077 TypeHandle type = *it;
1078 CHECK(type->NowIs(T.Any));
1079 }
1080
1081 // Bottom Uniqueness: T->NowIs(None) implies T = None
1082 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1083 TypeHandle type = *it;
1084 if (type->NowIs(T.None)) CheckEqual(type, T.None);
1085 }
1086
1087 // Top Uniqueness: Any->NowIs(T) implies T = Any
1088 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1089 TypeHandle type = *it;
1090 if (T.Any->NowIs(type)) CheckEqual(type, T.Any);
1091 }
1092
1093 // Reflexivity: T->NowIs(T)
1094 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1095 TypeHandle type = *it;
1096 CHECK(type->NowIs(type));
1097 }
1098
1099 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3)
1100 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1101 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1102 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1103 TypeHandle type1 = *it1;
1104 TypeHandle type2 = *it2;
1105 TypeHandle type3 = *it3;
1106 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) ||
1107 type1->NowIs(type3));
1108 }
1109 }
1110 }
1111
1112 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2
1113 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1114 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1115 TypeHandle type1 = *it1;
1116 TypeHandle type2 = *it2;
1117 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) ==
1118 Equal(type1, type2));
1119 }
1120 }
1121
1122 // T1->Is(T2) implies T1->NowIs(T2)
1123 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1124 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1125 TypeHandle type1 = *it1;
1126 TypeHandle type2 = *it2;
1127 CHECK(!type1->Is(type2) || type1->NowIs(type2));
1128 }
1129 }
1130
1131 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
1132 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1133 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1134 Handle<i::Object> value1 = *vt1;
1135 Handle<i::Object> value2 = *vt2;
1136 TypeHandle const_type1 = T.Constant(value1);
1137 TypeHandle const_type2 = T.Constant(value2);
1138 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2));
1139 }
1140 }
1141
1142 // Class(M1)->NowIs(Class(M2)) iff M1 = M2
1143 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1144 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1145 Handle<i::Map> map1 = *mt1;
1146 Handle<i::Map> map2 = *mt2;
1147 TypeHandle class_type1 = T.Class(map1);
1148 TypeHandle class_type2 = T.Class(map2);
1149 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2));
1150 }
1151 }
1152
1153 // Constant(V)->NowIs(Class(M)) iff V has map M
1154 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1155 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1156 Handle<i::Map> map = *mt;
1157 Handle<i::Object> value = *vt;
1158 TypeHandle const_type = T.Constant(value);
1159 TypeHandle class_type = T.Class(map);
1160 CHECK((value->IsHeapObject() &&
1161 i::HeapObject::cast(*value)->map() == *map)
1162 == const_type->NowIs(class_type));
1163 }
1164 }
1165
1166 // Class(M)->NowIs(Constant(V)) never
1167 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1168 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1169 Handle<i::Map> map = *mt;
1170 Handle<i::Object> value = *vt;
1171 TypeHandle const_type = T.Constant(value);
1172 TypeHandle class_type = T.Class(map);
1173 CHECK(!class_type->NowIs(const_type));
1174 }
1175 }
1176 }
1177
1178 void Contains() {
1179 // T->Contains(V) iff Constant(V)->Is(T)
1180 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1181 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1182 TypeHandle type = *it;
1183 Handle<i::Object> value = *vt;
1184 TypeHandle const_type = T.Constant(value);
1185 CHECK(type->Contains(value) == const_type->Is(type));
1186 }
1187 }
1188 }
1189
1190 void NowContains() {
1191 // T->NowContains(V) iff Constant(V)->NowIs(T)
1192 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1193 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1194 TypeHandle type = *it;
1195 Handle<i::Object> value = *vt;
1196 TypeHandle const_type = T.Constant(value);
1197 CHECK(type->NowContains(value) == const_type->NowIs(type));
1198 }
1199 }
1200
1201 // T->Contains(V) implies T->NowContains(V)
1202 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1203 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1204 TypeHandle type = *it;
1205 Handle<i::Object> value = *vt;
1206 CHECK(!type->Contains(value) || type->NowContains(value));
1207 }
1208 }
1209
1210 // NowOf(V)->Is(T) implies T->NowContains(V)
1211 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1212 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1213 TypeHandle type = *it;
1214 Handle<i::Object> value = *vt;
1215 TypeHandle nowof_type = T.Of(value);
1216 CHECK(!nowof_type->NowIs(type) || type->NowContains(value));
1217 }
1218 }
1219 }
1220
1221 void Maybe() {
1222 // T->Maybe(Any) iff T inhabited
1223 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1224 TypeHandle type = *it;
1225 CHECK(type->Maybe(T.Any) == type->IsInhabited());
1226 }
1227
1228 // T->Maybe(None) never
1229 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1230 TypeHandle type = *it;
1231 CHECK(!type->Maybe(T.None));
1232 }
1233
1234 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited
1235 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1236 TypeHandle type = *it;
1237 CHECK(type->Maybe(type) == type->IsInhabited());
1238 }
1239
1240 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1)
1241 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1242 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1243 TypeHandle type1 = *it1;
1244 TypeHandle type2 = *it2;
1245 CHECK(type1->Maybe(type2) == type2->Maybe(type1));
1246 }
1247 }
1248
1249 // T1->Maybe(T2) implies T1, T2 inhabited
1250 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1251 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1252 TypeHandle type1 = *it1;
1253 TypeHandle type2 = *it2;
1254 CHECK(!type1->Maybe(type2) ||
1255 (type1->IsInhabited() && type2->IsInhabited()));
1256 }
1257 }
1258
1259 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited
1260 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1261 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1262 TypeHandle type1 = *it1;
1263 TypeHandle type2 = *it2;
1264 TypeHandle intersect12 = T.Intersect(type1, type2);
1265 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited());
1266 }
1267 }
1268
1269 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2)
1270 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1271 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1272 TypeHandle type1 = *it1;
1273 TypeHandle type2 = *it2;
1274 CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
1275 type1->Maybe(type2));
1276 }
1277 }
1278
1279 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
1280 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
1281 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
1282 Handle<i::Object> value1 = *vt1;
1283 Handle<i::Object> value2 = *vt2;
1284 TypeHandle const_type1 = T.Constant(value1);
1285 TypeHandle const_type2 = T.Constant(value2);
1286 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2));
1287 }
1288 }
1289
1290 // Class(M1)->Maybe(Class(M2)) iff M1 = M2
1291 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
1292 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
1293 Handle<i::Map> map1 = *mt1;
1294 Handle<i::Map> map2 = *mt2;
1295 TypeHandle class_type1 = T.Class(map1);
1296 TypeHandle class_type2 = T.Class(map2);
1297 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2));
1298 }
1299 }
1300
1301 // Constant(V)->Maybe(Class(M)) never
1302 // This does NOT hold!
1303 /*
1304 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1305 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1306 Handle<i::Map> map = *mt;
1307 Handle<i::Object> value = *vt;
1308 TypeHandle const_type = T.Constant(value);
1309 TypeHandle class_type = T.Class(map);
1310 CHECK(!const_type->Maybe(class_type));
1311 }
1312 }
1313 */
1314
1315 // Class(M)->Maybe(Constant(V)) never
1316 // This does NOT hold!
1317 /*
1318 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
1319 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
1320 Handle<i::Map> map = *mt;
1321 Handle<i::Object> value = *vt;
1322 TypeHandle const_type = T.Constant(value);
1323 TypeHandle class_type = T.Class(map);
1324 CHECK(!class_type->Maybe(const_type));
1325 }
1326 }
1327 */
1328
1329 // Basic types
1330 CheckDisjoint(T.Boolean, T.Null);
1331 CheckDisjoint(T.Undefined, T.Null);
1332 CheckDisjoint(T.Boolean, T.Undefined);
1333 CheckOverlap(T.SignedSmall, T.Number);
1334 CheckOverlap(T.NaN, T.Number);
1335 CheckDisjoint(T.Signed32, T.NaN);
1336 CheckOverlap(T.UniqueName, T.Name);
1337 CheckOverlap(T.String, T.Name);
1338 CheckOverlap(T.InternalizedString, T.String);
1339 CheckOverlap(T.InternalizedString, T.UniqueName);
1340 CheckOverlap(T.InternalizedString, T.Name);
1341 CheckOverlap(T.Symbol, T.UniqueName);
1342 CheckOverlap(T.Symbol, T.Name);
1343 CheckOverlap(T.String, T.UniqueName);
1344 CheckDisjoint(T.String, T.Symbol);
1345 CheckDisjoint(T.InternalizedString, T.Symbol);
1346 CheckOverlap(T.Object, T.Receiver);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001347 CheckOverlap(T.OtherObject, T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001348 CheckOverlap(T.Proxy, T.Receiver);
1349 CheckDisjoint(T.Object, T.Proxy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001350
1351 // Structural types
1352 CheckOverlap(T.ObjectClass, T.Object);
1353 CheckOverlap(T.ArrayClass, T.Object);
1354 CheckOverlap(T.ObjectClass, T.ObjectClass);
1355 CheckOverlap(T.ArrayClass, T.ArrayClass);
1356 CheckDisjoint(T.ObjectClass, T.ArrayClass);
1357 CheckOverlap(T.SmiConstant, T.SignedSmall);
1358 CheckOverlap(T.SmiConstant, T.Signed32);
1359 CheckOverlap(T.SmiConstant, T.Number);
1360 CheckOverlap(T.ObjectConstant1, T.Object);
1361 CheckOverlap(T.ObjectConstant2, T.Object);
1362 CheckOverlap(T.ArrayConstant, T.Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001363 CheckOverlap(T.ArrayConstant, T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001364 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1);
1365 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2);
1366 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001367 CheckOverlap(T.ObjectConstant1, T.ArrayClass);
1368 CheckOverlap(T.ObjectConstant2, T.ArrayClass);
1369 CheckOverlap(T.ArrayConstant, T.ObjectClass);
1370 CheckOverlap(T.NumberArray, T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001371 CheckDisjoint(T.NumberArray, T.AnyArray);
1372 CheckDisjoint(T.NumberArray, T.StringArray);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001373 CheckOverlap(T.MethodFunction, T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001374 CheckDisjoint(T.SignedFunction1, T.NumberFunction1);
1375 CheckDisjoint(T.SignedFunction1, T.NumberFunction2);
1376 CheckDisjoint(T.NumberFunction1, T.NumberFunction2);
1377 CheckDisjoint(T.SignedFunction1, T.MethodFunction);
1378 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!!
1379 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001380 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged)); // !!!
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001381 }
1382
1383 void Union1() {
1384 // Identity: Union(T, None) = T
1385 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1386 TypeHandle type = *it;
1387 TypeHandle union_type = T.Union(type, T.None);
1388 CheckEqual(union_type, type);
1389 }
1390
1391 // Domination: Union(T, Any) = Any
1392 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1393 TypeHandle type = *it;
1394 TypeHandle union_type = T.Union(type, T.Any);
1395 CheckEqual(union_type, T.Any);
1396 }
1397
1398 // Idempotence: Union(T, T) = T
1399 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1400 TypeHandle type = *it;
1401 TypeHandle union_type = T.Union(type, type);
1402 CheckEqual(union_type, type);
1403 }
1404
1405 // Commutativity: Union(T1, T2) = Union(T2, T1)
1406 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1407 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1408 TypeHandle type1 = *it1;
1409 TypeHandle type2 = *it2;
1410 TypeHandle union12 = T.Union(type1, type2);
1411 TypeHandle union21 = T.Union(type2, type1);
1412 CheckEqual(union12, union21);
1413 }
1414 }
1415
1416 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001417 // This does NOT hold! For example:
1418 // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0)
1419 // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420 /*
1421 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1422 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1423 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1424 TypeHandle type1 = *it1;
1425 TypeHandle type2 = *it2;
1426 TypeHandle type3 = *it3;
1427 TypeHandle union12 = T.Union(type1, type2);
1428 TypeHandle union23 = T.Union(type2, type3);
1429 TypeHandle union1_23 = T.Union(type1, union23);
1430 TypeHandle union12_3 = T.Union(union12, type3);
1431 CheckEqual(union1_23, union12_3);
1432 }
1433 }
1434 }
1435 */
1436
1437 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2))
1438 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1439 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1440 TypeHandle type1 = *it1;
1441 TypeHandle type2 = *it2;
1442 TypeHandle union12 = T.Union(type1, type2);
1443 CHECK(type1->Is(union12));
1444 CHECK(type2->Is(union12));
1445 }
1446 }
1447
1448 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2
1449 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1450 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1451 TypeHandle type1 = *it1;
1452 TypeHandle type2 = *it2;
1453 TypeHandle union12 = T.Union(type1, type2);
1454 if (type1->Is(type2)) CheckEqual(union12, type2);
1455 }
1456 }
1457
1458 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001459 // This does NOT hold. For example:
1460 // Range(-5,-1) <= Signed32
1461 // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001462 /*
1463 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1464 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1465 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1466 TypeHandle type1 = *it1;
1467 TypeHandle type2 = *it2;
1468 TypeHandle type3 = *it3;
1469 TypeHandle union13 = T.Union(type1, type3);
1470 TypeHandle union23 = T.Union(type2, type3);
1471 CHECK(!type1->Is(type2) || union13->Is(union23));
1472 }
1473 }
1474 }
1475 */
1476 }
1477
1478 void Union2() {
1479 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001480 // This does NOT hold. For example:
1481 // Range(-2^33, -2^33) <= OtherNumber
1482 // Range(2^33, 2^33) <= OtherNumber
1483 // Range(-2^33, 2^33) </= OtherNumber
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001484 /*
1485 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1486 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1487 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1488 TypeHandle type1 = *it1;
1489 TypeHandle type2 = *it2;
1490 TypeHandle type3 = *it3;
1491 TypeHandle union12 = T.Union(type1, type2);
1492 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3));
1493 }
1494 }
1495 }
1496 */
1497 }
1498
1499 void Union3() {
1500 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
1501 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001502 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001503 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001504 for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001505 TypeHandle type1 = *it1;
1506 TypeHandle type2 = *it2;
1507 TypeHandle type3 = *it3;
1508 TypeHandle union23 = T.Union(type2, type3);
1509 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23));
1510 }
1511 }
1512 }
1513 }
1514
1515 void Union4() {
1516 // Class-class
1517 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001518 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.OtherObject);
1519 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001520 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number);
1521
1522 // Constant-constant
1523 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001524 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001525 CheckUnordered(
1526 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001527 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001528 CheckDisjoint(
1529 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number);
1530 CheckOverlap(
1531 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass); // !!!
1532
1533 // Bitset-array
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001534 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Receiver)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001535 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number)));
1536
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001537 CheckEqual(T.Union(T.AnyArray, T.Receiver), T.Receiver);
1538 CheckEqual(T.Union(T.AnyArray, T.OtherObject), T.OtherObject);
1539 CheckUnordered(T.Union(T.AnyArray, T.String), T.Receiver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001540 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object);
1541 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number);
1542
1543 // Bitset-function
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001544 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001545 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
1546
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001547 CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object);
1548 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object);
1550 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number);
1551
1552 // Bitset-class
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001553 CheckSub(T.Union(T.ObjectClass, T.SignedSmall),
1554 T.Union(T.Object, T.Number));
1555 CheckSub(T.Union(T.ObjectClass, T.OtherObject), T.Object);
1556 CheckUnordered(T.Union(T.ObjectClass, T.String), T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001557 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object);
1558 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number);
1559
1560 // Bitset-constant
1561 CheckSub(
1562 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 CheckSub(T.Union(T.ObjectConstant1, T.OtherObject), T.Object);
1564 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001565 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object);
1566 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number);
1567
1568 // Class-constant
1569 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object);
1570 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001571 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass),
1572 T.Union(T.Receiver, T.Object));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001573 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001574 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001575 CheckOverlap(
1576 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); // !!!
1577
1578 // Bitset-union
1579 CheckSub(
1580 T.NaN,
1581 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number));
1582 CheckSub(
1583 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32),
1584 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
1585
1586 // Class-union
1587 CheckSub(
1588 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)),
1589 T.Object);
1590 CheckEqual(
1591 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass),
1592 T.Union(T.ArrayClass, T.ObjectConstant2));
1593
1594 // Constant-union
1595 CheckEqual(
1596 T.Union(
1597 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1598 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1599 CheckEqual(
1600 T.Union(
1601 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1),
1602 T.Union(
1603 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1)));
1604
1605 // Array-union
1606 CheckEqual(
1607 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)),
1608 T.Union(T.AnyArray, T.NumberArray));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001609 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.OtherObject);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001610
1611 // Function-union
1612 CheckEqual(
1613 T.Union(T.NumberFunction1, T.NumberFunction2),
1614 T.Union(T.NumberFunction2, T.NumberFunction1));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001615 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001616
1617 // Union-union
1618 CheckEqual(
1619 T.Union(
1620 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1621 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1622 T.Union(T.ObjectConstant2, T.ObjectConstant1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001623 CheckEqual(T.Union(T.Union(T.Number, T.ArrayClass),
1624 T.Union(T.SignedSmall, T.Receiver)),
1625 T.Union(T.Number, T.Receiver));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626 }
1627
1628 void Intersect() {
1629 // Identity: Intersect(T, Any) = T
1630 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1631 TypeHandle type = *it;
1632 TypeHandle intersect_type = T.Intersect(type, T.Any);
1633 CheckEqual(intersect_type, type);
1634 }
1635
1636 // Domination: Intersect(T, None) = None
1637 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1638 TypeHandle type = *it;
1639 TypeHandle intersect_type = T.Intersect(type, T.None);
1640 CheckEqual(intersect_type, T.None);
1641 }
1642
1643 // Idempotence: Intersect(T, T) = T
1644 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1645 TypeHandle type = *it;
1646 TypeHandle intersect_type = T.Intersect(type, type);
1647 CheckEqual(intersect_type, type);
1648 }
1649
1650 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1)
1651 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1652 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1653 TypeHandle type1 = *it1;
1654 TypeHandle type2 = *it2;
1655 TypeHandle intersect12 = T.Intersect(type1, type2);
1656 TypeHandle intersect21 = T.Intersect(type2, type1);
1657 CheckEqual(intersect12, intersect21);
1658 }
1659 }
1660
1661 // Associativity:
1662 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001663 // This does NOT hold. For example:
1664 // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) =
1665 // None
1666 // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) =
1667 // Constant(..string..)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001668 /*
1669 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1670 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1671 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1672 TypeHandle type1 = *it1;
1673 TypeHandle type2 = *it2;
1674 TypeHandle type3 = *it3;
1675 TypeHandle intersect12 = T.Intersect(type1, type2);
1676 TypeHandle intersect23 = T.Intersect(type2, type3);
1677 TypeHandle intersect1_23 = T.Intersect(type1, intersect23);
1678 TypeHandle intersect12_3 = T.Intersect(intersect12, type3);
1679 CheckEqual(intersect1_23, intersect12_3);
1680 }
1681 }
1682 }
1683 */
1684
1685 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001686 // This does NOT hold. For example:
1687 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..)
1688 // Currently, not even the disjunction holds:
1689 // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) =
1690 // Class(Internal/TaggedPtr) \/ Context(..)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001691 /*
1692 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1693 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1694 TypeHandle type1 = *it1;
1695 TypeHandle type2 = *it2;
1696 TypeHandle intersect12 = T.Intersect(type1, type2);
1697 CHECK(intersect12->Is(type1));
1698 CHECK(intersect12->Is(type2));
1699 }
1700 }
1701 */
1702
1703 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1
1704 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1705 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1706 TypeHandle type1 = *it1;
1707 TypeHandle type2 = *it2;
1708 TypeHandle intersect12 = T.Intersect(type1, type2);
1709 if (type1->Is(type2)) CheckEqual(intersect12, type1);
1710 }
1711 }
1712
1713 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001714 // This does NOT hold. For example:
1715 // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr
1716 // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..)
1717 // Any/TaggedPtr /\ Any/UntaggedInt1 = None
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001718 /*
1719 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1720 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1721 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1722 TypeHandle type1 = *it1;
1723 TypeHandle type2 = *it2;
1724 TypeHandle type3 = *it3;
1725 TypeHandle intersect13 = T.Intersect(type1, type3);
1726 TypeHandle intersect23 = T.Intersect(type2, type3);
1727 CHECK(!type1->Is(type2) || intersect13->Is(intersect23));
1728 }
1729 }
1730 }
1731 */
1732
1733 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001734 // This does NOT hold. For example:
1735 // Class(..stringy..) <= Class(..stringy..)
1736 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..)
1737 // Constant(..string..) </= Class(..stringy..)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001738 /*
1739 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1740 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1741 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1742 TypeHandle type1 = *it1;
1743 TypeHandle type2 = *it2;
1744 TypeHandle type3 = *it3;
1745 TypeHandle intersect12 = T.Intersect(type1, type2);
1746 CHECK(!(type1->Is(type3) || type2->Is(type3)) ||
1747 intersect12->Is(type3));
1748 }
1749 }
1750 }
1751 */
1752
1753 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001754 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001755 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1757 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1758 TypeHandle type1 = *it1;
1759 TypeHandle type2 = *it2;
1760 TypeHandle type3 = *it3;
1761 TypeHandle intersect23 = T.Intersect(type2, type3);
1762 CHECK(!(type1->Is(type2) && type1->Is(type3)) ||
1763 type1->Is(intersect23));
1764 }
1765 }
1766 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001767
1768 // Bitset-class
1769 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001770 CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.Number)), T.None);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001771
1772 // Bitset-array
1773 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001774 CheckEqual(T.Semantic(T.Intersect(T.AnyArray, T.Proxy)), T.None);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001775
1776 // Bitset-function
1777 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001778 CheckEqual(T.Semantic(T.Intersect(T.NumberFunction1, T.Proxy)), T.None);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001779
1780 // Bitset-union
1781 CheckEqual(
1782 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
1783 T.Union(T.ObjectConstant1, T.ObjectClass));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001784 CheckEqual(T.Semantic(T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1),
1785 T.Number)),
1786 T.None);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001787
1788 // Class-constant
1789 CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); // !!!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001790 CHECK(T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001791
1792 // Array-union
1793 CheckEqual(
1794 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)),
1795 T.NumberArray);
1796 CheckEqual(
1797 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
1798 T.AnyArray);
1799 CHECK(
1800 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray)
1801 ->IsInhabited());
1802
1803 // Function-union
1804 CheckEqual(
1805 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
1806 T.MethodFunction);
1807 CheckEqual(
1808 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
1809 T.NumberFunction1);
1810 CHECK(
1811 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
1812 ->IsInhabited());
1813
1814 // Class-union
1815 CheckEqual(
1816 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)),
1817 T.ArrayClass);
1818 CheckEqual(
1819 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
1820 T.ArrayClass);
1821 CHECK(
1822 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
1823 ->IsInhabited()); // !!!
1824
1825 // Constant-union
1826 CheckEqual(
1827 T.Intersect(
1828 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1829 T.ObjectConstant1);
1830 CheckEqual(
1831 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
1832 T.SmiConstant);
1833 CHECK(
1834 T.Intersect(
1835 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
1836 ->IsInhabited()); // !!!
1837
1838 // Union-union
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001839 CheckEqual(T.Intersect(T.Union(T.Number, T.ArrayClass),
1840 T.Union(T.SignedSmall, T.Receiver)),
1841 T.Union(T.SignedSmall, T.ArrayClass));
1842 CheckEqual(T.Intersect(T.Union(T.Number, T.ObjectClass),
1843 T.Union(T.Signed32, T.OtherObject)),
1844 T.Union(T.Signed32, T.ObjectClass));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001845 CheckEqual(
1846 T.Intersect(
1847 T.Union(T.ObjectConstant2, T.ObjectConstant1),
1848 T.Union(T.ObjectConstant1, T.ObjectConstant2)),
1849 T.Union(T.ObjectConstant2, T.ObjectConstant1));
1850 CheckEqual(
1851 T.Intersect(
1852 T.Union(
1853 T.ArrayClass,
1854 T.Union(T.ObjectConstant2, T.ObjectConstant1)),
1855 T.Union(
1856 T.ObjectConstant1,
1857 T.Union(T.ArrayConstant, T.ObjectConstant2))),
1858 T.Union(
1859 T.ArrayConstant,
1860 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!!
1861 }
1862
1863 void Distributivity() {
1864 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001865 // This does NOT hold. For example:
1866 // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged)
1867 // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) =
1868 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
1869 // because Untagged <= Untagged \/ Class(../Tagged)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001870 /*
1871 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1872 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1873 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1874 TypeHandle type1 = *it1;
1875 TypeHandle type2 = *it2;
1876 TypeHandle type3 = *it3;
1877 TypeHandle union12 = T.Union(type1, type2);
1878 TypeHandle union13 = T.Union(type1, type3);
1879 TypeHandle intersect23 = T.Intersect(type2, type3);
1880 TypeHandle union1_23 = T.Union(type1, intersect23);
1881 TypeHandle intersect12_13 = T.Intersect(union12, union13);
1882 CHECK(Equal(union1_23, intersect12_13));
1883 }
1884 }
1885 }
1886 */
1887
1888 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001889 // This does NOT hold. For example:
1890 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
1891 // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) =
1892 // Untagged \/ Class(../Tagged)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001893 /*
1894 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1895 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1896 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
1897 TypeHandle type1 = *it1;
1898 TypeHandle type2 = *it2;
1899 TypeHandle type3 = *it3;
1900 TypeHandle intersect12 = T.Intersect(type1, type2);
1901 TypeHandle intersect13 = T.Intersect(type1, type3);
1902 TypeHandle union23 = T.Union(type2, type3);
1903 TypeHandle intersect1_23 = T.Intersect(type1, union23);
1904 TypeHandle union12_13 = T.Union(intersect12, intersect13);
1905 CHECK(Equal(intersect1_23, union12_13));
1906 }
1907 }
1908 }
1909 */
1910 }
1911
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001912 void GetRange() {
1913 // GetRange(Range(a, b)) = Range(a, b).
1914 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1915 TypeHandle type1 = *it1;
1916 if (type1->IsRange()) {
1917 typename Type::RangeType* range = type1->GetRange();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001918 CHECK(type1->Min() == range->Min());
1919 CHECK(type1->Max() == range->Max());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001920 }
1921 }
1922
1923 // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max).
1924 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1925 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1926 TypeHandle type1 = *it1;
1927 TypeHandle type2 = *it2;
1928 if (type1->IsConstant() && type2->IsRange()) {
1929 TypeHandle u = T.Union(type1, type2);
1930
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001931 CHECK(type2->Min() == u->GetRange()->Min());
1932 CHECK(type2->Max() == u->GetRange()->Max());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001933 }
1934 }
1935 }
1936 }
1937
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001938 template<class Type2, class TypeHandle2, class Region2, class Rep2>
1939 void Convert() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001940 Types<Type2, TypeHandle2, Region2> T2(Rep2::ToRegion(&zone, isolate),
1941 isolate,
1942 isolate->random_number_generator());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001943 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
1944 TypeHandle type1 = *it;
1945 TypeHandle2 type2 = T2.template Convert<Type>(type1);
1946 TypeHandle type3 = T.template Convert<Type2>(type2);
1947 CheckEqual(type1, type3);
1948 }
1949 }
1950
1951 void HTypeFromType() {
1952 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
1953 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
1954 TypeHandle type1 = *it1;
1955 TypeHandle type2 = *it2;
1956 HType htype1 = HType::FromType<Type>(type1);
1957 HType htype2 = HType::FromType<Type>(type2);
1958 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2));
1959 }
1960 }
1961 }
1962};
1963
1964typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
1965typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
1966
1967
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001968TEST(IsSomeType_zone) { ZoneTests().IsSomeType(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001969
1970
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001971TEST(IsSomeType_heap) { HeapTests().IsSomeType(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001972
1973
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001974TEST(PointwiseRepresentation_zone) { ZoneTests().PointwiseRepresentation(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001975
1976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001977TEST(PointwiseRepresentation_heap) { HeapTests().PointwiseRepresentation(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001978
1979
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001980TEST(BitsetType_zone) { ZoneTests().Bitset(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001981
1982
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001983TEST(BitsetType_heap) { HeapTests().Bitset(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001984
1985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001986TEST(ClassType_zone) { ZoneTests().Class(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001987
1988
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001989TEST(ClassType_heap) { HeapTests().Class(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001990
1991
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001992TEST(ConstantType_zone) { ZoneTests().Constant(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001993
1994
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001995TEST(ConstantType_heap) { HeapTests().Constant(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001996
1997
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001998TEST(RangeType_zone) { ZoneTests().Range(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001999
2000
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002001TEST(RangeType_heap) { HeapTests().Range(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002002
2003
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002004TEST(ArrayType_zone) { ZoneTests().Array(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002005
2006
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002007TEST(ArrayType_heap) { HeapTests().Array(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002008
2009
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002010TEST(FunctionType_zone) { ZoneTests().Function(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002011
2012
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002013TEST(FunctionType_heap) { HeapTests().Function(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002014
2015
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002016TEST(Of_zone) { ZoneTests().Of(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002017
2018
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002019TEST(Of_heap) { HeapTests().Of(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002020
2021
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002022TEST(NowOf_zone) { ZoneTests().NowOf(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002023
2024
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002025TEST(NowOf_heap) { HeapTests().NowOf(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002026
2027
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002028TEST(MinMax_zone) { ZoneTests().MinMax(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002029
2030
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002031TEST(MinMax_heap) { HeapTests().MinMax(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002032
2033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002034TEST(BitsetGlb_zone) { ZoneTests().BitsetGlb(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002035
2036
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002037TEST(BitsetGlb_heap) { HeapTests().BitsetGlb(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002038
2039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002040TEST(BitsetLub_zone) { ZoneTests().BitsetLub(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002041
2042
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002043TEST(BitsetLub_heap) { HeapTests().BitsetLub(); }
2044
2045
2046TEST(Is1_zone) { ZoneTests().Is1(); }
2047
2048
2049TEST(Is1_heap) { HeapTests().Is1(); }
2050
2051
2052TEST(Is2_zone) { ZoneTests().Is2(); }
2053
2054
2055TEST(Is2_heap) { HeapTests().Is2(); }
2056
2057
2058TEST(NowIs_zone) { ZoneTests().NowIs(); }
2059
2060
2061TEST(NowIs_heap) { HeapTests().NowIs(); }
2062
2063
2064TEST(Contains_zone) { ZoneTests().Contains(); }
2065
2066
2067TEST(Contains_heap) { HeapTests().Contains(); }
2068
2069
2070TEST(NowContains_zone) { ZoneTests().NowContains(); }
2071
2072
2073TEST(NowContains_heap) { HeapTests().NowContains(); }
2074
2075
2076TEST(Maybe_zone) { ZoneTests().Maybe(); }
2077
2078
2079TEST(Maybe_heap) { HeapTests().Maybe(); }
2080
2081
2082TEST(Union1_zone) { ZoneTests().Union1(); }
2083
2084
2085TEST(Union1_heap) { HeapTests().Union1(); }
2086
2087
2088TEST(Union2_zone) { ZoneTests().Union2(); }
2089
2090
2091TEST(Union2_heap) { HeapTests().Union2(); }
2092
2093
2094TEST(Union3_zone) { ZoneTests().Union3(); }
2095
2096
2097TEST(Union3_heap) { HeapTests().Union3(); }
2098
2099
2100TEST(Union4_zone) { ZoneTests().Union4(); }
2101
2102
2103TEST(Union4_heap) { HeapTests().Union4(); }
2104
2105
2106TEST(Intersect_zone) { ZoneTests().Intersect(); }
2107
2108
2109TEST(Intersect_heap) { HeapTests().Intersect(); }
2110
2111
2112TEST(Distributivity_zone) { ZoneTests().Distributivity(); }
2113
2114
2115TEST(Distributivity_heap) { HeapTests().Distributivity(); }
2116
2117
2118TEST(GetRange_zone) { ZoneTests().GetRange(); }
2119
2120
2121TEST(GetRange_heap) { HeapTests().GetRange(); }
2122
2123
2124TEST(Convert_zone) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002125 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002126}
2127
2128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002129TEST(Convert_heap) { HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); }
2130
2131
2132TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
2133
2134
2135TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }