OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 15 matching lines...) Expand all Loading... |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <vector> | 28 #include <vector> |
29 | 29 |
30 #include "cctest.h" | 30 #include "cctest.h" |
31 #include "types.h" | 31 #include "types.h" |
32 #include "utils/random-number-generator.h" | 32 #include "utils/random-number-generator.h" |
33 | 33 |
34 using namespace v8::internal; | 34 using namespace v8::internal; |
35 | 35 |
| 36 // Testing auxiliaries (breaking the Type abstraction). |
| 37 struct ZoneRep { |
| 38 typedef void* Struct; |
| 39 |
| 40 static bool IsStruct(Type* t, int tag) { |
| 41 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; |
| 42 } |
| 43 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } |
| 44 static bool IsClass(Type* t) { return IsStruct(t, 0); } |
| 45 static bool IsConstant(Type* t) { return IsStruct(t, 1); } |
| 46 static bool IsUnion(Type* t) { return IsStruct(t, 2); } |
| 47 |
| 48 static Struct* AsStruct(Type* t) { |
| 49 return reinterpret_cast<Struct*>(t); |
| 50 } |
| 51 static int AsBitset(Type* t) { |
| 52 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); |
| 53 } |
| 54 static Map* AsClass(Type* t) { |
| 55 return *static_cast<Map**>(AsStruct(t)[3]); |
| 56 } |
| 57 static Object* AsConstant(Type* t) { |
| 58 return *static_cast<Object**>(AsStruct(t)[3]); |
| 59 } |
| 60 static Struct* AsUnion(Type* t) { |
| 61 return AsStruct(t); |
| 62 } |
| 63 static int Length(Struct* structured) { |
| 64 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); |
| 65 } |
| 66 |
| 67 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } |
| 68 }; |
| 69 |
| 70 |
| 71 struct HeapRep { |
| 72 typedef FixedArray Struct; |
| 73 |
| 74 static bool IsStruct(Handle<HeapType> t, int tag) { |
| 75 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; |
| 76 } |
| 77 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } |
| 78 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } |
| 79 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } |
| 80 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 2); } |
| 81 |
| 82 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } |
| 83 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } |
| 84 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } |
| 85 static Object* AsConstant(Handle<HeapType> t) { |
| 86 return Box::cast(*t)->value(); |
| 87 } |
| 88 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } |
| 89 static int Length(Struct* structured) { return structured->length() - 1; } |
| 90 |
| 91 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } |
| 92 }; |
| 93 |
| 94 |
36 template<class Type, class TypeHandle, class Region> | 95 template<class Type, class TypeHandle, class Region> |
37 class Types { | 96 class Types { |
38 public: | 97 public: |
39 Types(Region* region, Isolate* isolate) : region_(region) { | 98 Types(Region* region, Isolate* isolate) : region_(region) { |
40 static const size_t kMaxTypes = 300; | |
41 types.reserve(kMaxTypes); | |
42 | |
43 #define DECLARE_TYPE(name, value) \ | 99 #define DECLARE_TYPE(name, value) \ |
44 name = Type::name(region); \ | 100 name = Type::name(region); \ |
45 types.push_back(name); | 101 types.push_back(name); |
46 BITSET_TYPE_LIST(DECLARE_TYPE) | 102 BITSET_TYPE_LIST(DECLARE_TYPE) |
47 #undef DECLARE_TYPE | 103 #undef DECLARE_TYPE |
48 | 104 |
49 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); | 105 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); |
50 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); | 106 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); |
51 uninitialized_map = isolate->factory()->uninitialized_map(); | 107 uninitialized_map = isolate->factory()->uninitialized_map(); |
52 ObjectClass = Type::Class(object_map, region); | 108 ObjectClass = Type::Class(object_map, region); |
(...skipping 23 matching lines...) Expand all Loading... |
76 values.push_back(smi); | 132 values.push_back(smi); |
77 values.push_back(signed32); | 133 values.push_back(signed32); |
78 values.push_back(object1); | 134 values.push_back(object1); |
79 values.push_back(object2); | 135 values.push_back(object2); |
80 values.push_back(array); | 136 values.push_back(array); |
81 values.push_back(uninitialized); | 137 values.push_back(uninitialized); |
82 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { | 138 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { |
83 types.push_back(Type::Constant(*it, region)); | 139 types.push_back(Type::Constant(*it, region)); |
84 } | 140 } |
85 | 141 |
86 while (types.size() < kMaxTypes) { | 142 for (int i = 0; i < 100; ++i) { |
87 size_t i = rng.NextInt(static_cast<int>(types.size())); | 143 types.push_back(Fuzz()); |
88 size_t j = rng.NextInt(static_cast<int>(types.size())); | |
89 if (i != j) types.push_back(Type::Union(types[i], types[j], region)); | |
90 } | 144 } |
91 } | 145 } |
92 | 146 |
93 RandomNumberGenerator rng; | |
94 | |
95 #define DECLARE_TYPE(name, value) TypeHandle name; | 147 #define DECLARE_TYPE(name, value) TypeHandle name; |
96 BITSET_TYPE_LIST(DECLARE_TYPE) | 148 BITSET_TYPE_LIST(DECLARE_TYPE) |
97 #undef DECLARE_TYPE | 149 #undef DECLARE_TYPE |
98 | 150 |
99 TypeHandle ObjectClass; | 151 TypeHandle ObjectClass; |
100 TypeHandle ArrayClass; | 152 TypeHandle ArrayClass; |
101 TypeHandle UninitializedClass; | 153 TypeHandle UninitializedClass; |
102 | 154 |
103 TypeHandle SmiConstant; | 155 TypeHandle SmiConstant; |
104 TypeHandle Signed32Constant; | 156 TypeHandle Signed32Constant; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 } | 198 } |
147 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { | 199 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { |
148 return Type::Intersect(t1, t2, region_); | 200 return Type::Intersect(t1, t2, region_); |
149 } | 201 } |
150 | 202 |
151 template<class Type2, class TypeHandle2> | 203 template<class Type2, class TypeHandle2> |
152 TypeHandle Convert(TypeHandle2 t) { | 204 TypeHandle Convert(TypeHandle2 t) { |
153 return Type::template Convert<Type2>(t, region_); | 205 return Type::template Convert<Type2>(t, region_); |
154 } | 206 } |
155 | 207 |
| 208 TypeHandle Fuzz(int depth = 5) { |
| 209 switch (rng_.NextInt(depth == 0 ? 3 : 20)) { |
| 210 case 0: { // bitset |
| 211 int n = 0 |
| 212 #define COUNT_BITSET_TYPES(type, value) + 1 |
| 213 BITSET_TYPE_LIST(COUNT_BITSET_TYPES) |
| 214 #undef COUNT_BITSET_TYPES |
| 215 ; |
| 216 int i = rng_.NextInt(n); |
| 217 #define PICK_BITSET_TYPE(type, value) \ |
| 218 if (i-- == 0) return Type::type(region_); |
| 219 BITSET_TYPE_LIST(PICK_BITSET_TYPE) |
| 220 #undef PICK_BITSET_TYPE |
| 221 UNREACHABLE(); |
| 222 } |
| 223 case 1: { // class |
| 224 int i = rng_.NextInt(static_cast<int>(maps.size())); |
| 225 return Type::Class(maps[i], region_); |
| 226 } |
| 227 case 2: { // constant |
| 228 int i = rng_.NextInt(static_cast<int>(values.size())); |
| 229 return Type::Constant(values[i], region_); |
| 230 } |
| 231 default: { // union |
| 232 int n = rng_.NextInt(10); |
| 233 TypeHandle type = None; |
| 234 for (int i = 0; i < n; ++i) { |
| 235 type = Type::Union(type, Fuzz(depth - 1), region_); |
| 236 } |
| 237 return type; |
| 238 } |
| 239 } |
| 240 UNREACHABLE(); |
| 241 } |
| 242 |
156 private: | 243 private: |
157 Region* region_; | 244 Region* region_; |
| 245 RandomNumberGenerator rng_; |
158 }; | 246 }; |
159 | 247 |
160 | 248 |
161 // Testing auxiliaries (breaking the Type abstraction). | |
162 struct ZoneRep { | |
163 typedef void* Struct; | |
164 | |
165 static bool IsStruct(Type* t, int tag) { | |
166 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; | |
167 } | |
168 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } | |
169 static bool IsClass(Type* t) { return IsStruct(t, 0); } | |
170 static bool IsConstant(Type* t) { return IsStruct(t, 1); } | |
171 static bool IsUnion(Type* t) { return IsStruct(t, 2); } | |
172 | |
173 static Struct* AsStruct(Type* t) { | |
174 return reinterpret_cast<Struct*>(t); | |
175 } | |
176 static int AsBitset(Type* t) { | |
177 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); | |
178 } | |
179 static Map* AsClass(Type* t) { | |
180 return *static_cast<Map**>(AsStruct(t)[3]); | |
181 } | |
182 static Object* AsConstant(Type* t) { | |
183 return *static_cast<Object**>(AsStruct(t)[3]); | |
184 } | |
185 static Struct* AsUnion(Type* t) { | |
186 return AsStruct(t); | |
187 } | |
188 static int Length(Struct* structured) { | |
189 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); | |
190 } | |
191 | |
192 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } | |
193 }; | |
194 | |
195 | |
196 struct HeapRep { | |
197 typedef FixedArray Struct; | |
198 | |
199 static bool IsStruct(Handle<HeapType> t, int tag) { | |
200 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; | |
201 } | |
202 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } | |
203 static bool IsClass(Handle<HeapType> t) { return t->IsMap(); } | |
204 static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); } | |
205 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 2); } | |
206 | |
207 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } | |
208 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } | |
209 static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } | |
210 static Object* AsConstant(Handle<HeapType> t) { | |
211 return Box::cast(*t)->value(); | |
212 } | |
213 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } | |
214 static int Length(Struct* structured) { return structured->length() - 1; } | |
215 | |
216 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } | |
217 }; | |
218 | |
219 | |
220 template<class Type, class TypeHandle, class Region, class Rep> | 249 template<class Type, class TypeHandle, class Region, class Rep> |
221 struct Tests : Rep { | 250 struct Tests : Rep { |
222 typedef Types<Type, TypeHandle, Region> TypesInstance; | 251 typedef Types<Type, TypeHandle, Region> TypesInstance; |
223 typedef typename TypesInstance::TypeVector::iterator TypeIterator; | 252 typedef typename TypesInstance::TypeVector::iterator TypeIterator; |
224 typedef typename TypesInstance::MapVector::iterator MapIterator; | 253 typedef typename TypesInstance::MapVector::iterator MapIterator; |
225 typedef typename TypesInstance::ValueVector::iterator ValueIterator; | 254 typedef typename TypesInstance::ValueVector::iterator ValueIterator; |
226 | 255 |
227 Isolate* isolate; | 256 Isolate* isolate; |
228 HandleScope scope; | 257 HandleScope scope; |
229 Zone zone; | 258 Zone zone; |
230 TypesInstance T; | 259 TypesInstance T; |
231 | 260 |
232 Tests() : | 261 Tests() : |
233 isolate(CcTest::i_isolate()), | 262 isolate(CcTest::i_isolate()), |
234 scope(isolate), | 263 scope(isolate), |
235 zone(isolate), | 264 zone(isolate), |
236 T(Rep::ToRegion(&zone, isolate), isolate) { | 265 T(Rep::ToRegion(&zone, isolate), isolate) { |
237 } | 266 } |
238 | 267 |
| 268 bool Equal(TypeHandle type1, TypeHandle type2) { |
| 269 return |
| 270 type1->Is(type2) && type2->Is(type1) && |
| 271 Rep::IsBitset(type1) == Rep::IsBitset(type2) && |
| 272 Rep::IsClass(type1) == Rep::IsClass(type2) && |
| 273 Rep::IsConstant(type1) == Rep::IsConstant(type2) && |
| 274 Rep::IsUnion(type1) == Rep::IsUnion(type2) && |
| 275 type1->NumClasses() == type2->NumClasses() && |
| 276 type1->NumConstants() == type2->NumConstants() && |
| 277 (!Rep::IsBitset(type1) || |
| 278 Rep::AsBitset(type1) == Rep::AsBitset(type2)) && |
| 279 (!Rep::IsClass(type1) || |
| 280 Rep::AsClass(type1) == Rep::AsClass(type2)) && |
| 281 (!Rep::IsConstant(type1) || |
| 282 Rep::AsConstant(type1) == Rep::AsConstant(type2)) && |
| 283 (!Rep::IsUnion(type1) || |
| 284 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); |
| 285 } |
| 286 |
239 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 287 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
240 CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(type2)); | 288 CHECK(Equal(type1, type2)); |
241 CHECK_EQ(Rep::IsClass(type1), Rep::IsClass(type2)); | |
242 CHECK_EQ(Rep::IsConstant(type1), Rep::IsConstant(type2)); | |
243 CHECK_EQ(Rep::IsUnion(type1), Rep::IsUnion(type2)); | |
244 CHECK_EQ(type1->NumClasses(), type2->NumClasses()); | |
245 CHECK_EQ(type1->NumConstants(), type2->NumConstants()); | |
246 if (Rep::IsBitset(type1)) { | |
247 CHECK_EQ(Rep::AsBitset(type1), Rep::AsBitset(type2)); | |
248 } else if (Rep::IsClass(type1)) { | |
249 CHECK_EQ(Rep::AsClass(type1), Rep::AsClass(type2)); | |
250 } else if (Rep::IsConstant(type1)) { | |
251 CHECK_EQ(Rep::AsConstant(type1), Rep::AsConstant(type2)); | |
252 } else if (Rep::IsUnion(type1)) { | |
253 CHECK_EQ( | |
254 Rep::Length(Rep::AsUnion(type1)), Rep::Length(Rep::AsUnion(type2))); | |
255 } | |
256 CHECK(type1->Is(type2)); | |
257 CHECK(type2->Is(type1)); | |
258 } | 289 } |
259 | 290 |
260 void CheckSub(TypeHandle type1, TypeHandle type2) { | 291 void CheckSub(TypeHandle type1, TypeHandle type2) { |
261 CHECK(type1->Is(type2)); | 292 CHECK(type1->Is(type2)); |
262 CHECK(!type2->Is(type1)); | 293 CHECK(!type2->Is(type1)); |
263 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { | 294 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { |
264 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); | 295 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); |
265 } | 296 } |
266 } | 297 } |
267 | 298 |
(...skipping 26 matching lines...) Expand all Loading... |
294 } | 325 } |
295 | 326 |
296 void Bitset() { | 327 void Bitset() { |
297 // None and Any are bitsets. | 328 // None and Any are bitsets. |
298 CHECK(this->IsBitset(T.None)); | 329 CHECK(this->IsBitset(T.None)); |
299 CHECK(this->IsBitset(T.Any)); | 330 CHECK(this->IsBitset(T.Any)); |
300 | 331 |
301 CHECK_EQ(0, this->AsBitset(T.None)); | 332 CHECK_EQ(0, this->AsBitset(T.None)); |
302 CHECK_EQ(-1, this->AsBitset(T.Any)); | 333 CHECK_EQ(-1, this->AsBitset(T.Any)); |
303 | 334 |
304 // Union(T1, T2) is a bitset for all bitsets T1,T2 | 335 // Union(T1, T2) is bitset for bitsets T1,T2 |
305 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 336 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
306 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 337 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
307 TypeHandle type1 = *it1; | 338 TypeHandle type1 = *it1; |
308 TypeHandle type2 = *it2; | 339 TypeHandle type2 = *it2; |
309 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || | 340 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
310 this->IsBitset(T.Union(type1, type2))); | 341 this->IsBitset(T.Union(type1, type2))); |
311 } | 342 } |
312 } | 343 } |
313 | 344 |
314 // Union(T1, T2) is a bitset if T2 is a bitset and T1->Is(T2) | 345 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) |
315 // (and vice versa). | |
316 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 346 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
317 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 347 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
318 TypeHandle type1 = *it1; | 348 TypeHandle type1 = *it1; |
319 TypeHandle type2 = *it2; | 349 TypeHandle type2 = *it2; |
320 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || | 350 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || |
321 this->IsBitset(T.Union(type1, type2))); | 351 this->IsBitset(T.Union(type1, type2))); |
322 CHECK(!(this->IsBitset(type1) && type2->Is(type1)) || | |
323 this->IsBitset(T.Union(type1, type2))); | |
324 } | 352 } |
325 } | 353 } |
326 | 354 |
327 // Union(T1, T2) is bitwise disjunction for all bitsets T1,T2 | 355 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 |
328 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 356 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
329 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 357 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
330 TypeHandle type1 = *it1; | 358 TypeHandle type1 = *it1; |
331 TypeHandle type2 = *it2; | 359 TypeHandle type2 = *it2; |
332 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 360 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
333 CHECK_EQ( | 361 CHECK_EQ( |
334 this->AsBitset(type1) | this->AsBitset(type2), | 362 this->AsBitset(type1) | this->AsBitset(type2), |
335 this->AsBitset(T.Union(type1, type2))); | 363 this->AsBitset(T.Union(type1, type2))); |
336 } | 364 } |
337 } | 365 } |
338 } | 366 } |
339 | 367 |
340 // Intersect(T1, T2) is bitwise conjunction for all bitsets T1,T2 | 368 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 |
341 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 369 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
342 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 370 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
343 TypeHandle type1 = *it1; | 371 TypeHandle type1 = *it1; |
344 TypeHandle type2 = *it2; | 372 TypeHandle type2 = *it2; |
345 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 373 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
346 CHECK_EQ( | 374 CHECK_EQ( |
347 this->AsBitset(type1) & this->AsBitset(type2), | 375 this->AsBitset(type1) & this->AsBitset(type2), |
348 this->AsBitset(T.Intersect(type1, type2))); | 376 this->AsBitset(T.Intersect(type1, type2))); |
349 } | 377 } |
350 } | 378 } |
351 } | 379 } |
352 } | 380 } |
353 | 381 |
354 void Class() { | 382 void Class() { |
355 // Constructor | 383 // Constructor |
356 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 384 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
357 Handle<i::Map> map = *mt; | 385 Handle<i::Map> map = *mt; |
358 CHECK(this->IsClass(T.Class(map))); | 386 CHECK(this->IsClass(T.Class(map))); |
359 } | 387 } |
360 | 388 |
361 // Map attribute | 389 // Map attribute |
362 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 390 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
363 Handle<i::Map> map = *mt; | 391 Handle<i::Map> map = *mt; |
364 CHECK(*map == *T.Class(map)->AsClass()); | 392 CHECK(*map == *T.Class(map)->AsClass()); |
365 } | 393 } |
366 | 394 |
367 // Functionality & Injectivity | 395 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
368 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 396 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
369 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 397 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
370 Handle<i::Map> map1 = *mt1; | 398 Handle<i::Map> map1 = *mt1; |
371 Handle<i::Map> map2 = *mt2; | 399 Handle<i::Map> map2 = *mt2; |
372 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); | 400 CHECK(Equal(T.Class(map1), T.Class(map2)) == (*map1 == *map2)); |
373 } | 401 } |
374 } | 402 } |
375 } | 403 } |
376 | 404 |
377 void Constant() { | 405 void Constant() { |
378 // Constructor | 406 // Constructor |
379 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 407 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
380 Handle<i::Object> value = *vt; | 408 Handle<i::Object> value = *vt; |
381 CHECK(this->IsConstant(T.Constant(value))); | 409 CHECK(this->IsConstant(T.Constant(value))); |
382 } | 410 } |
383 | 411 |
384 // Value attribute | 412 // Value attribute |
385 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 413 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
386 Handle<i::Object> value = *vt; | 414 Handle<i::Object> value = *vt; |
387 CHECK(*value == *T.Constant(value)->AsConstant()); | 415 CHECK(*value == *T.Constant(value)->AsConstant()); |
388 } | 416 } |
389 | 417 |
390 // Functionality & Injectivity | 418 // Functionality & Injectivity: Constant(V1) = Constant(v2) iff V1 = V2 |
391 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 419 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
392 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 420 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
393 Handle<i::Object> val1 = *vt1; | 421 Handle<i::Object> val1 = *vt1; |
394 Handle<i::Object> val2 = *vt2; | 422 Handle<i::Object> val2 = *vt2; |
395 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); | 423 CHECK(Equal(T.Constant(val1), T.Constant(val2)) == (*val1 == *val2)); |
396 } | 424 } |
397 } | 425 } |
398 } | 426 } |
399 | 427 |
400 void Of() { | 428 void Of() { |
401 // Constant(V)->Is(Of(V)) for all V | 429 // Constant(V)->Is(Of(V)) |
402 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 430 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
403 Handle<i::Object> value = *vt; | 431 Handle<i::Object> value = *vt; |
404 CHECK(T.Constant(value)->Is(T.Of(value))); | 432 CHECK(T.Constant(value)->Is(T.Of(value))); |
405 } | 433 } |
406 | 434 |
407 // Constant(V)->Is(T) implies Of(V)->Is(T) or T->Maybe(Constant(V)) | 435 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V)) |
408 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 436 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
409 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 437 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
410 Handle<i::Object> value = *vt; | 438 Handle<i::Object> value = *vt; |
411 TypeHandle type = *it; | 439 TypeHandle type = *it; |
412 CHECK(!T.Constant(value)->Is(type) || | 440 CHECK(T.Constant(value)->Is(type) == |
413 T.Of(value)->Is(type) || type->Maybe(T.Constant(value))); | 441 (T.Of(value)->Is(type) || type->Maybe(T.Constant(value)))); |
414 } | 442 } |
415 } | 443 } |
416 } | 444 } |
417 | 445 |
418 void NowOf() { | 446 void NowOf() { |
419 // Constant(V)->NowIs(NowOf(V)) for all V | 447 // Constant(V)->NowIs(NowOf(V)) |
420 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 448 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
421 Handle<i::Object> value = *vt; | 449 Handle<i::Object> value = *vt; |
422 CHECK(T.Constant(value)->NowIs(T.NowOf(value))); | 450 CHECK(T.Constant(value)->NowIs(T.NowOf(value))); |
423 } | 451 } |
424 | 452 |
425 // NowOf(V)->Is(Of(V)) for all V | 453 // NowOf(V)->Is(Of(V)) |
426 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 454 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
427 Handle<i::Object> value = *vt; | 455 Handle<i::Object> value = *vt; |
428 CHECK(T.NowOf(value)->Is(T.Of(value))); | 456 CHECK(T.NowOf(value)->Is(T.Of(value))); |
429 } | 457 } |
430 | 458 |
| 459 // Constant(V)->NowIs(T) iff NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) |
| 460 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 461 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 462 Handle<i::Object> value = *vt; |
| 463 TypeHandle type = *it; |
| 464 CHECK(T.Constant(value)->NowIs(type) == |
| 465 (T.NowOf(value)->NowIs(type) || type->Maybe(T.Constant(value)))); |
| 466 } |
| 467 } |
| 468 |
431 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) | 469 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) |
432 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 470 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
433 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 471 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
434 Handle<i::Object> value = *vt; | 472 Handle<i::Object> value = *vt; |
435 TypeHandle type = *it; | 473 TypeHandle type = *it; |
436 CHECK(!T.Constant(value)->Is(type) || | 474 CHECK(!T.Constant(value)->Is(type) || |
437 T.NowOf(value)->Is(type) || type->Maybe(T.Constant(value))); | 475 (T.NowOf(value)->Is(type) || type->Maybe(T.Constant(value)))); |
438 } | |
439 } | |
440 | |
441 // Constant(V)->NowIs(T) implies NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) | |
442 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | |
443 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
444 Handle<i::Object> value = *vt; | |
445 TypeHandle type = *it; | |
446 CHECK(!T.Constant(value)->NowIs(type) || | |
447 T.NowOf(value)->NowIs(type) || type->Maybe(T.Constant(value))); | |
448 } | 476 } |
449 } | 477 } |
450 } | 478 } |
451 | 479 |
452 void Is() { | 480 void Is() { |
453 // T->Is(None) implies T = None for all T | 481 // Least Element (Bottom): None->Is(T) |
| 482 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 483 TypeHandle type = *it; |
| 484 CHECK(T.None->Is(type)); |
| 485 } |
| 486 |
| 487 // Greatest Element (Top): T->Is(Any) |
| 488 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 489 TypeHandle type = *it; |
| 490 CHECK(type->Is(T.Any)); |
| 491 } |
| 492 |
| 493 // Bottom Uniqueness: T->Is(None) implies T = None |
454 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 494 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
455 TypeHandle type = *it; | 495 TypeHandle type = *it; |
456 if (type->Is(T.None)) CheckEqual(type, T.None); | 496 if (type->Is(T.None)) CheckEqual(type, T.None); |
457 } | 497 } |
458 | 498 |
459 // None->Is(T) for all T | 499 // Top Uniqueness: Any->Is(T) implies T = Any |
460 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
461 TypeHandle type = *it; | |
462 CHECK(T.None->Is(type)); | |
463 } | |
464 | |
465 // Any->Is(T) implies T = Any for all T | |
466 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 500 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
467 TypeHandle type = *it; | 501 TypeHandle type = *it; |
468 if (T.Any->Is(type)) CheckEqual(type, T.Any); | 502 if (T.Any->Is(type)) CheckEqual(type, T.Any); |
469 } | 503 } |
470 | 504 |
471 // T->Is(Any) for all T | 505 // Reflexivity: T->Is(T) |
472 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
473 TypeHandle type = *it; | |
474 CHECK(type->Is(T.Any)); | |
475 } | |
476 | |
477 // Reflexivity | |
478 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 506 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
479 TypeHandle type = *it; | 507 TypeHandle type = *it; |
480 CHECK(type->Is(type)); | 508 CHECK(type->Is(type)); |
481 } | 509 } |
482 | 510 |
483 // Transitivity | 511 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) |
484 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 512 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
485 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 513 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
486 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 514 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
487 TypeHandle type1 = *it1; | 515 TypeHandle type1 = *it1; |
488 TypeHandle type2 = *it2; | 516 TypeHandle type2 = *it2; |
489 TypeHandle type3 = *it3; | 517 TypeHandle type3 = *it3; |
490 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); | 518 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); |
491 } | 519 } |
492 } | 520 } |
493 } | 521 } |
494 | 522 |
| 523 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 |
| 524 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 525 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 526 TypeHandle type1 = *it1; |
| 527 TypeHandle type2 = *it2; |
| 528 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); |
| 529 } |
| 530 } |
| 531 |
495 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | 532 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
496 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 533 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
497 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 534 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
498 Handle<i::Object> val1 = *vt1; | 535 Handle<i::Object> val1 = *vt1; |
499 Handle<i::Object> val2 = *vt2; | 536 Handle<i::Object> val2 = *vt2; |
500 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); | 537 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); |
501 } | 538 } |
502 } | 539 } |
503 | 540 |
504 // Class(M1)->Is(Class(M2)) iff M1 = M2 | 541 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
505 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 542 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
506 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 543 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
507 Handle<i::Map> map1 = *mt1; | 544 Handle<i::Map> map1 = *mt1; |
508 Handle<i::Map> map2 = *mt2; | 545 Handle<i::Map> map2 = *mt2; |
509 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); | 546 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); |
510 } | 547 } |
511 } | 548 } |
512 | 549 |
513 // Constant(V)->Is(Class(M)) for no V,M | 550 // Constant(V)->Is(Class(M)) never |
514 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 551 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
515 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 552 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
516 Handle<i::Map> map = *mt; | 553 Handle<i::Map> map = *mt; |
517 Handle<i::Object> value = *vt; | 554 Handle<i::Object> value = *vt; |
518 CHECK(!T.Constant(value)->Is(T.Class(map))); | 555 CHECK(!T.Constant(value)->Is(T.Class(map))); |
519 } | 556 } |
520 } | 557 } |
521 | 558 |
522 // Class(M)->Is(Constant(V)) for no V,M | 559 // Class(M)->Is(Constant(V)) never |
523 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 560 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
524 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 561 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
525 Handle<i::Map> map = *mt; | 562 Handle<i::Map> map = *mt; |
526 Handle<i::Object> value = *vt; | 563 Handle<i::Object> value = *vt; |
527 CHECK(!T.Class(map)->Is(T.Constant(value))); | 564 CHECK(!T.Class(map)->Is(T.Constant(value))); |
528 } | 565 } |
529 } | 566 } |
530 | 567 |
531 // Basic types | 568 // Basic types |
532 CheckUnordered(T.Boolean, T.Null); | 569 CheckUnordered(T.Boolean, T.Null); |
(...skipping 18 matching lines...) Expand all Loading... |
551 CheckUnordered(T.String, T.Symbol); | 588 CheckUnordered(T.String, T.Symbol); |
552 CheckUnordered(T.InternalizedString, T.Symbol); | 589 CheckUnordered(T.InternalizedString, T.Symbol); |
553 | 590 |
554 CheckSub(T.Object, T.Receiver); | 591 CheckSub(T.Object, T.Receiver); |
555 CheckSub(T.Array, T.Object); | 592 CheckSub(T.Array, T.Object); |
556 CheckSub(T.Function, T.Object); | 593 CheckSub(T.Function, T.Object); |
557 CheckSub(T.Proxy, T.Receiver); | 594 CheckSub(T.Proxy, T.Receiver); |
558 CheckUnordered(T.Object, T.Proxy); | 595 CheckUnordered(T.Object, T.Proxy); |
559 CheckUnordered(T.Array, T.Function); | 596 CheckUnordered(T.Array, T.Function); |
560 | 597 |
561 CheckSub(T.UninitializedClass, T.Internal); | |
562 CheckSub(T.UninitializedConstant, T.Internal); | |
563 CheckUnordered(T.UninitializedClass, T.Null); | |
564 CheckUnordered(T.UninitializedClass, T.Undefined); | |
565 CheckUnordered(T.UninitializedConstant, T.Null); | |
566 CheckUnordered(T.UninitializedConstant, T.Undefined); | |
567 | |
568 // Structural types | 598 // Structural types |
569 CheckSub(T.ObjectClass, T.Object); | 599 CheckSub(T.ObjectClass, T.Object); |
570 CheckSub(T.ArrayClass, T.Object); | 600 CheckSub(T.ArrayClass, T.Object); |
| 601 CheckSub(T.UninitializedClass, T.Internal); |
571 CheckUnordered(T.ObjectClass, T.ArrayClass); | 602 CheckUnordered(T.ObjectClass, T.ArrayClass); |
| 603 CheckUnordered(T.UninitializedClass, T.Null); |
| 604 CheckUnordered(T.UninitializedClass, T.Undefined); |
572 | 605 |
573 CheckSub(T.SmiConstant, T.SignedSmall); | 606 CheckSub(T.SmiConstant, T.SignedSmall); |
574 CheckSub(T.SmiConstant, T.Signed32); | 607 CheckSub(T.SmiConstant, T.Signed32); |
575 CheckSub(T.SmiConstant, T.Number); | 608 CheckSub(T.SmiConstant, T.Number); |
576 CheckSub(T.ObjectConstant1, T.Object); | 609 CheckSub(T.ObjectConstant1, T.Object); |
577 CheckSub(T.ObjectConstant2, T.Object); | 610 CheckSub(T.ObjectConstant2, T.Object); |
578 CheckSub(T.ArrayConstant, T.Object); | 611 CheckSub(T.ArrayConstant, T.Object); |
579 CheckSub(T.ArrayConstant, T.Array); | 612 CheckSub(T.ArrayConstant, T.Array); |
| 613 CheckSub(T.UninitializedConstant, T.Internal); |
580 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); | 614 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); |
581 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); | 615 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); |
| 616 CheckUnordered(T.UninitializedConstant, T.Null); |
| 617 CheckUnordered(T.UninitializedConstant, T.Undefined); |
582 | 618 |
583 CheckUnordered(T.ObjectConstant1, T.ObjectClass); | 619 CheckUnordered(T.ObjectConstant1, T.ObjectClass); |
584 CheckUnordered(T.ObjectConstant2, T.ObjectClass); | 620 CheckUnordered(T.ObjectConstant2, T.ObjectClass); |
585 CheckUnordered(T.ObjectConstant1, T.ArrayClass); | 621 CheckUnordered(T.ObjectConstant1, T.ArrayClass); |
586 CheckUnordered(T.ObjectConstant2, T.ArrayClass); | 622 CheckUnordered(T.ObjectConstant2, T.ArrayClass); |
587 CheckUnordered(T.ArrayConstant, T.ObjectClass); | 623 CheckUnordered(T.ArrayConstant, T.ObjectClass); |
588 } | 624 } |
589 | 625 |
590 void NowIs() { | 626 void NowIs() { |
591 // T->NowIs(None) implies T = None for all T | 627 // Least Element (Bottom): None->NowIs(T) |
| 628 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 629 TypeHandle type = *it; |
| 630 CHECK(T.None->NowIs(type)); |
| 631 } |
| 632 |
| 633 // Greatest Element (Top): T->NowIs(Any) |
| 634 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 635 TypeHandle type = *it; |
| 636 CHECK(type->NowIs(T.Any)); |
| 637 } |
| 638 |
| 639 // Bottom Uniqueness: T->NowIs(None) implies T = None |
592 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 640 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
593 TypeHandle type = *it; | 641 TypeHandle type = *it; |
594 if (type->NowIs(T.None)) CheckEqual(type, T.None); | 642 if (type->NowIs(T.None)) CheckEqual(type, T.None); |
595 } | 643 } |
596 | 644 |
597 // None->NowIs(T) for all T | 645 // Top Uniqueness: Any->NowIs(T) implies T = Any |
598 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
599 TypeHandle type = *it; | |
600 CHECK(T.None->NowIs(type)); | |
601 } | |
602 | |
603 // Any->NowIs(T) implies T = Any for all T | |
604 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 646 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
605 TypeHandle type = *it; | 647 TypeHandle type = *it; |
606 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); | 648 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); |
607 } | 649 } |
608 | 650 |
609 // T->NowIs(Any) for all T | 651 // Reflexivity: T->NowIs(T) |
610 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
611 TypeHandle type = *it; | |
612 CHECK(type->NowIs(T.Any)); | |
613 } | |
614 | |
615 // Reflexivity | |
616 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 652 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
617 TypeHandle type = *it; | 653 TypeHandle type = *it; |
618 CHECK(type->NowIs(type)); | 654 CHECK(type->NowIs(type)); |
619 } | 655 } |
620 | 656 |
621 // Transitivity | 657 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) |
622 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 658 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
623 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 659 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
624 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 660 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
625 TypeHandle type1 = *it1; | 661 TypeHandle type1 = *it1; |
626 TypeHandle type2 = *it2; | 662 TypeHandle type2 = *it2; |
627 TypeHandle type3 = *it3; | 663 TypeHandle type3 = *it3; |
628 CHECK(!type1->NowIs(type2) || | 664 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || |
629 !type2->NowIs(type3) || | |
630 type1->NowIs(type3)); | 665 type1->NowIs(type3)); |
631 } | 666 } |
632 } | 667 } |
633 } | 668 } |
634 | 669 |
635 // T1->Is(T2) implies T1->NowIs(T2) for all T1,T2 | 670 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 |
636 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 671 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
637 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 672 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
638 TypeHandle type1 = *it1; | 673 TypeHandle type1 = *it1; |
| 674 TypeHandle type2 = *it2; |
| 675 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == |
| 676 Equal(type1, type2)); |
| 677 } |
| 678 } |
| 679 |
| 680 // T1->Is(T2) implies T1->NowIs(T2) |
| 681 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 682 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 683 TypeHandle type1 = *it1; |
639 TypeHandle type2 = *it2; | 684 TypeHandle type2 = *it2; |
640 CHECK(!type1->Is(type2) || type1->NowIs(type2)); | 685 CHECK(!type1->Is(type2) || type1->NowIs(type2)); |
641 } | 686 } |
642 } | 687 } |
643 | 688 |
644 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 | 689 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 |
645 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 690 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
646 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 691 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
647 Handle<i::Object> val1 = *vt1; | 692 Handle<i::Object> val1 = *vt1; |
648 Handle<i::Object> val2 = *vt2; | 693 Handle<i::Object> val2 = *vt2; |
(...skipping 14 matching lines...) Expand all Loading... |
663 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 708 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
664 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 709 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
665 Handle<i::Map> map = *mt; | 710 Handle<i::Map> map = *mt; |
666 Handle<i::Object> value = *vt; | 711 Handle<i::Object> value = *vt; |
667 CHECK((value->IsHeapObject() && | 712 CHECK((value->IsHeapObject() && |
668 i::HeapObject::cast(*value)->map() == *map) | 713 i::HeapObject::cast(*value)->map() == *map) |
669 == T.Constant(value)->NowIs(T.Class(map))); | 714 == T.Constant(value)->NowIs(T.Class(map))); |
670 } | 715 } |
671 } | 716 } |
672 | 717 |
673 // Class(M)->NowIs(Constant(V)) for no V,M | 718 // Class(M)->NowIs(Constant(V)) never |
674 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 719 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
675 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 720 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
676 Handle<i::Map> map = *mt; | 721 Handle<i::Map> map = *mt; |
677 Handle<i::Object> value = *vt; | 722 Handle<i::Object> value = *vt; |
678 CHECK(!T.Class(map)->NowIs(T.Constant(value))); | 723 CHECK(!T.Class(map)->NowIs(T.Constant(value))); |
679 } | 724 } |
680 } | 725 } |
681 } | 726 } |
682 | 727 |
683 void Contains() { | 728 void Contains() { |
684 // T->Contains(V) iff Constant(V)->Is(T) for all T,V | 729 // T->Contains(V) iff Constant(V)->Is(T) |
685 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 730 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
686 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 731 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
687 TypeHandle type = *it; | 732 TypeHandle type = *it; |
688 Handle<i::Object> value = *vt; | 733 Handle<i::Object> value = *vt; |
689 CHECK(type->Contains(value) == T.Constant(value)->Is(type)); | 734 CHECK(type->Contains(value) == T.Constant(value)->Is(type)); |
690 } | 735 } |
691 } | 736 } |
692 | 737 |
693 // Of(V)->Is(T) implies T->Contains(V) for all T,V | 738 // Of(V)->Is(T) implies T->Contains(V) |
694 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 739 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
695 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 740 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
696 TypeHandle type = *it; | 741 TypeHandle type = *it; |
697 Handle<i::Object> value = *vt; | 742 Handle<i::Object> value = *vt; |
698 CHECK(!T.Of(value)->Is(type) || type->Contains(value)); | 743 CHECK(!T.Of(value)->Is(type) || type->Contains(value)); |
699 } | 744 } |
700 } | 745 } |
701 } | 746 } |
702 | 747 |
703 void NowContains() { | 748 void NowContains() { |
704 // T->NowContains(V) iff Constant(V)->NowIs(T) for all T,V | 749 // T->NowContains(V) iff Constant(V)->NowIs(T) |
705 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 750 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
706 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 751 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
707 TypeHandle type = *it; | 752 TypeHandle type = *it; |
708 Handle<i::Object> value = *vt; | 753 Handle<i::Object> value = *vt; |
709 CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type)); | 754 CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type)); |
710 } | 755 } |
711 } | 756 } |
712 | 757 |
713 // T->Contains(V) implies T->NowContains(V) for all T,V | 758 // T->Contains(V) implies T->NowContains(V) |
714 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 759 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
715 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 760 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
716 TypeHandle type = *it; | 761 TypeHandle type = *it; |
717 Handle<i::Object> value = *vt; | 762 Handle<i::Object> value = *vt; |
718 CHECK(!type->Contains(value) || type->NowContains(value)); | 763 CHECK(!type->Contains(value) || type->NowContains(value)); |
719 } | 764 } |
720 } | 765 } |
721 | 766 |
722 // NowOf(V)->Is(T) implies T->NowContains(V) for all T,V | 767 // NowOf(V)->Is(T) implies T->NowContains(V) |
723 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 768 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
724 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 769 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
725 TypeHandle type = *it; | 770 TypeHandle type = *it; |
726 Handle<i::Object> value = *vt; | 771 Handle<i::Object> value = *vt; |
727 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 772 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); |
728 } | 773 } |
729 } | 774 } |
730 | 775 |
731 // NowOf(V)->NowIs(T) implies T->NowContains(V) for all T,V | 776 // NowOf(V)->NowIs(T) implies T->NowContains(V) |
732 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 777 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
733 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 778 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
734 TypeHandle type = *it; | 779 TypeHandle type = *it; |
735 Handle<i::Object> value = *vt; | 780 Handle<i::Object> value = *vt; |
736 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 781 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); |
737 } | 782 } |
738 } | 783 } |
739 } | 784 } |
740 | 785 |
741 void Maybe() { | 786 void Maybe() { |
742 // T->Maybe(T) iff T inhabited | |
743 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
744 TypeHandle type = *it; | |
745 CHECK(type->Maybe(type) == type->IsInhabited()); | |
746 } | |
747 | |
748 // T->Maybe(Any) iff T inhabited | 787 // T->Maybe(Any) iff T inhabited |
749 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 788 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
750 TypeHandle type = *it; | 789 TypeHandle type = *it; |
751 CHECK(type->Maybe(T.Any) == type->IsInhabited()); | 790 CHECK(type->Maybe(T.Any) == type->IsInhabited()); |
752 } | 791 } |
753 | 792 |
754 // T->Maybe(None) never | 793 // T->Maybe(None) never |
755 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 794 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
756 TypeHandle type = *it; | 795 TypeHandle type = *it; |
757 CHECK(!type->Maybe(T.None)); | 796 CHECK(!type->Maybe(T.None)); |
758 } | 797 } |
759 | 798 |
760 // Symmetry | 799 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited |
| 800 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 801 TypeHandle type = *it; |
| 802 CHECK(type->Maybe(type) == type->IsInhabited()); |
| 803 } |
| 804 |
| 805 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) |
761 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 806 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
762 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 807 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
763 TypeHandle type1 = *it1; | 808 TypeHandle type1 = *it1; |
764 TypeHandle type2 = *it2; | 809 TypeHandle type2 = *it2; |
765 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); | 810 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
766 } | 811 } |
767 } | 812 } |
768 | 813 |
769 // T1->Maybe(T2) only if T1, T2 inhabited | 814 // T1->Maybe(T2) implies T1, T2 inhabited |
770 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 815 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
771 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 816 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
772 TypeHandle type1 = *it1; | 817 TypeHandle type1 = *it1; |
773 TypeHandle type2 = *it2; | 818 TypeHandle type2 = *it2; |
774 CHECK(!type1->Maybe(type2) || | 819 CHECK(!type1->Maybe(type2) || |
775 (type1->IsInhabited() && type2->IsInhabited())); | 820 (type1->IsInhabited() && type2->IsInhabited())); |
776 } | 821 } |
777 } | 822 } |
778 | 823 |
779 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) for all T1,T2 | 824 // T1->Maybe(T2) iff Intersect(T1, T2) inhabited |
780 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 825 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
781 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 826 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
782 TypeHandle type1 = *it1; | 827 TypeHandle type1 = *it1; |
| 828 TypeHandle type2 = *it2; |
| 829 CHECK(type1->Maybe(type2) == T.Intersect(type1, type2)->IsInhabited()); |
| 830 } |
| 831 } |
| 832 |
| 833 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) |
| 834 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 835 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 836 TypeHandle type1 = *it1; |
783 TypeHandle type2 = *it2; | 837 TypeHandle type2 = *it2; |
784 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || | 838 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || |
785 type1->Maybe(type2)); | 839 type1->Maybe(type2)); |
786 } | 840 } |
787 } | 841 } |
788 | 842 |
789 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 | 843 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
790 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 844 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
791 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 845 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
792 Handle<i::Object> val1 = *vt1; | 846 Handle<i::Object> val1 = *vt1; |
793 Handle<i::Object> val2 = *vt2; | 847 Handle<i::Object> val2 = *vt2; |
794 CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2)); | 848 CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2)); |
795 } | 849 } |
796 } | 850 } |
797 | 851 |
798 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 | 852 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 |
799 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 853 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
800 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 854 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
801 Handle<i::Map> map1 = *mt1; | 855 Handle<i::Map> map1 = *mt1; |
802 Handle<i::Map> map2 = *mt2; | 856 Handle<i::Map> map2 = *mt2; |
803 CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2)); | 857 CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2)); |
804 } | 858 } |
805 } | 859 } |
806 | 860 |
807 // Constant(V)->Maybe(Class(M)) for no V,M | 861 // Constant(V)->Maybe(Class(M)) never |
808 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 862 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
809 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 863 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
810 Handle<i::Map> map = *mt; | 864 Handle<i::Map> map = *mt; |
811 Handle<i::Object> value = *vt; | 865 Handle<i::Object> value = *vt; |
812 CHECK(!T.Constant(value)->Maybe(T.Class(map))); | 866 CHECK(!T.Constant(value)->Maybe(T.Class(map))); |
813 } | 867 } |
814 } | 868 } |
815 | 869 |
816 // Class(M)->Maybe(Constant(V)) for no V,M | 870 // Class(M)->Maybe(Constant(V)) never |
817 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 871 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
818 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 872 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
819 Handle<i::Map> map = *mt; | 873 Handle<i::Map> map = *mt; |
820 Handle<i::Object> value = *vt; | 874 Handle<i::Object> value = *vt; |
821 CHECK(!T.Class(map)->Maybe(T.Constant(value))); | 875 CHECK(!T.Class(map)->Maybe(T.Constant(value))); |
822 } | 876 } |
823 } | 877 } |
824 | 878 |
825 // Basic types | 879 // Basic types |
826 CheckDisjoint(T.Boolean, T.Null, T.Semantic); | 880 CheckDisjoint(T.Boolean, T.Null, T.Semantic); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); | 923 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); |
870 | 924 |
871 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); | 925 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); |
872 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); | 926 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); |
873 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); | 927 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); |
874 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); | 928 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); |
875 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); | 929 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); |
876 } | 930 } |
877 | 931 |
878 void Union() { | 932 void Union() { |
879 // Bitset-bitset | 933 // Identity: Union(T, None) = T |
880 CHECK(this->IsBitset(T.Union(T.Object, T.Number))); | 934 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
881 CHECK(this->IsBitset(T.Union(T.Object, T.Object))); | 935 TypeHandle type = *it; |
882 CHECK(this->IsBitset(T.Union(T.Any, T.None))); | 936 CheckEqual(T.Union(type, T.None), type); |
| 937 } |
883 | 938 |
884 CheckEqual(T.Union(T.None, T.Number), T.Number); | 939 // Domination: Union(T, Any) = Any |
885 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); | 940 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
886 CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); | 941 TypeHandle type = *it; |
887 CheckSub(T.Union(T.Number, T.String), T.Any); | 942 CheckEqual(T.Union(type, T.Any), T.Any); |
| 943 } |
| 944 |
| 945 // Idempotence: Union(T, T) = T |
| 946 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 947 TypeHandle type = *it; |
| 948 CheckEqual(T.Union(type, type), type); |
| 949 } |
| 950 |
| 951 // Commutativity: Union(T1, T2) = Union(T2, T1) |
| 952 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 953 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 954 TypeHandle type1 = *it1; |
| 955 TypeHandle type2 = *it2; |
| 956 CheckEqual(T.Union(type1, type2), T.Union(type2, type1)); |
| 957 } |
| 958 } |
| 959 |
| 960 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) |
| 961 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 962 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 963 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 964 TypeHandle type1 = *it1; |
| 965 TypeHandle type2 = *it2; |
| 966 TypeHandle type3 = *it3; |
| 967 CheckEqual( |
| 968 T.Union(type1, T.Union(type2, type3)), |
| 969 T.Union(T.Union(type1, type2), type3)); |
| 970 } |
| 971 } |
| 972 } |
| 973 |
| 974 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(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 type1 = *it1; |
| 978 TypeHandle type2 = *it2; |
| 979 CHECK(type1->Is(T.Union(type1, type2))); |
| 980 CHECK(type2->Is(T.Union(type1, type2))); |
| 981 } |
| 982 } |
| 983 |
| 984 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 |
| 985 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 986 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 987 TypeHandle type1 = *it1; |
| 988 TypeHandle type2 = *it2; |
| 989 if (type1->Is(type2)) CheckEqual(T.Union(type1, type2), type2); |
| 990 } |
| 991 } |
| 992 |
| 993 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) |
| 994 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 995 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 996 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 997 TypeHandle type1 = *it1; |
| 998 TypeHandle type2 = *it2; |
| 999 TypeHandle type3 = *it3; |
| 1000 CHECK(!type1->Is(type2) || |
| 1001 (T.Union(type1, type3)->Is(T.Union(type2, type3)))); |
| 1002 } |
| 1003 } |
| 1004 } |
| 1005 |
| 1006 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) |
| 1007 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1008 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1009 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1010 TypeHandle type1 = *it1; |
| 1011 TypeHandle type2 = *it2; |
| 1012 TypeHandle type3 = *it3; |
| 1013 CHECK(!(type1->Is(type3) && type2->Is(type3)) || |
| 1014 T.Union(type1, type2)->Is(type3)); |
| 1015 } |
| 1016 } |
| 1017 } |
| 1018 |
| 1019 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) |
| 1020 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1021 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1022 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1023 TypeHandle type1 = *it1; |
| 1024 TypeHandle type2 = *it2; |
| 1025 TypeHandle type3 = *it3; |
| 1026 CHECK(!(type1->Is(type2) || type1->Is(type3)) || |
| 1027 type1->Is(T.Union(type2, type3))); |
| 1028 } |
| 1029 } |
| 1030 } |
888 | 1031 |
889 // Class-class | 1032 // Class-class |
890 CHECK(this->IsClass(T.Union(T.ObjectClass, T.ObjectClass))); | |
891 CHECK(this->IsUnion(T.Union(T.ObjectClass, T.ArrayClass))); | |
892 | |
893 CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); | |
894 CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); | |
895 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); | |
896 CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); | |
897 CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); | |
898 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); | 1033 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); |
899 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); | 1034 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); |
900 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); | 1035 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); |
901 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); | 1036 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); |
902 | 1037 |
903 // Constant-constant | 1038 // Constant-constant |
904 CHECK(this->IsConstant(T.Union(T.ObjectConstant1, T.ObjectConstant1))); | |
905 CHECK(this->IsConstant(T.Union(T.ArrayConstant, T.ArrayConstant))); | |
906 CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectConstant2))); | |
907 | |
908 CheckEqual( | |
909 T.Union(T.ObjectConstant1, T.ObjectConstant1), | |
910 T.ObjectConstant1); | |
911 CheckEqual(T.Union(T.ArrayConstant, T.ArrayConstant), T.ArrayConstant); | |
912 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
913 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); | |
914 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
915 CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); | |
916 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); | 1039 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); |
| 1040 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); |
917 CheckUnordered( | 1041 CheckUnordered( |
918 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); | 1042 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); |
919 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); | |
920 CheckOverlap( | 1043 CheckOverlap( |
921 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); | 1044 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); |
922 CheckDisjoint( | 1045 CheckDisjoint( |
923 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); | 1046 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); |
924 CheckDisjoint( | 1047 CheckDisjoint( |
925 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, | 1048 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); |
926 T.Semantic); | |
927 | 1049 |
928 // Bitset-class | 1050 // Bitset-class |
929 CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object))); | |
930 CHECK(this->IsUnion(T.Union(T.ObjectClass, T.Number))); | |
931 | |
932 CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); | |
933 CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); | |
934 CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); | |
935 CheckSub( | 1051 CheckSub( |
936 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); | 1052 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); |
937 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); | 1053 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); |
938 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); | 1054 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); |
939 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); | 1055 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); |
940 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); | 1056 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); |
941 | 1057 |
942 // Bitset-constant | 1058 // Bitset-constant |
943 CHECK(this->IsBitset(T.Union(T.SmiConstant, T.Number))); | |
944 CHECK(this->IsBitset(T.Union(T.ObjectConstant1, T.Object))); | |
945 CHECK(this->IsUnion(T.Union(T.ObjectConstant2, T.Number))); | |
946 | |
947 CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); | |
948 CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); | |
949 CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); | |
950 CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); | |
951 CheckSub( | 1059 CheckSub( |
952 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); | 1060 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); |
953 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); | 1061 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); |
954 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); | 1062 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); |
955 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); | 1063 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); |
956 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); | 1064 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); |
957 CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); | |
958 | 1065 |
959 // Class-constant | 1066 // Class-constant |
960 CHECK(this->IsUnion(T.Union(T.ObjectConstant1, T.ObjectClass))); | |
961 CHECK(this->IsUnion(T.Union(T.ArrayClass, T.ObjectConstant2))); | |
962 | |
963 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
964 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); | |
965 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); | 1067 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); |
966 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
967 CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | |
968 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | 1068 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); |
969 CheckSub( | 1069 CheckSub( |
970 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); | 1070 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); |
971 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); | 1071 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); |
972 CheckDisjoint( | 1072 CheckDisjoint( |
973 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, | 1073 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, |
974 T.Semantic); | 1074 T.Semantic); |
975 CheckDisjoint( | 1075 CheckDisjoint( |
976 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); | 1076 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); |
977 | 1077 |
978 // Bitset-union | 1078 // Bitset-union |
979 CHECK(this->IsBitset( | |
980 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); | |
981 CHECK(this->IsUnion( | |
982 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); | |
983 | |
984 CheckEqual( | |
985 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
986 T.Object); | |
987 CheckEqual( | |
988 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | |
989 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | |
990 CheckSub( | 1079 CheckSub( |
991 T.Float, | 1080 T.Float, |
992 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); | 1081 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); |
993 CheckSub( | 1082 CheckSub( |
994 T.ObjectConstant1, | |
995 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float)); | |
996 CheckSub( | |
997 T.None, | |
998 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float)); | |
999 CheckSub( | |
1000 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), | |
1001 T.Any); | |
1002 CheckSub( | |
1003 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), | 1083 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), |
1004 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | 1084 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); |
1005 | 1085 |
1006 // Class-union | 1086 // Class-union |
1007 CHECK(this->IsUnion( | |
1008 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); | |
1009 CHECK(this->IsUnion( | |
1010 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); | |
1011 | |
1012 CheckEqual( | |
1013 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
1014 T.Union(T.ObjectClass, T.ObjectConstant1)); | |
1015 CheckSub( | |
1016 T.None, | |
1017 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); | |
1018 CheckSub( | |
1019 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | |
1020 T.Any); | |
1021 CheckSub( | 1087 CheckSub( |
1022 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1088 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1023 T.Object); | 1089 T.Object); |
1024 CheckEqual( | 1090 CheckEqual( |
1025 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), | 1091 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), |
1026 T.Union(T.ArrayClass, T.ObjectConstant2)); | 1092 T.Union(T.ArrayClass, T.ObjectConstant2)); |
1027 | 1093 |
1028 // Constant-union | 1094 // Constant-union |
1029 CHECK(this->IsUnion(T.Union( | |
1030 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); | |
1031 CHECK(this->IsUnion(T.Union( | |
1032 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1))); | |
1033 CHECK(this->IsUnion(T.Union( | |
1034 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1))); | |
1035 | |
1036 CheckEqual( | 1095 CheckEqual( |
1037 T.Union( | 1096 T.Union( |
1038 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1097 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1039 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1098 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1040 CheckEqual( | 1099 CheckEqual( |
1041 T.Union( | 1100 T.Union( |
1042 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), | 1101 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), |
1043 T.Union( | 1102 T.Union( |
1044 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); | 1103 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); |
1045 | 1104 |
1046 // Union-union | 1105 // Union-union |
1047 CHECK(this->IsBitset(T.Union( | |
1048 T.Union(T.Number, T.ArrayClass), | |
1049 T.Union(T.Signed32, T.Array)))); | |
1050 CHECK(this->IsUnion(T.Union( | |
1051 T.Union(T.Number, T.ArrayClass), | |
1052 T.Union(T.ObjectClass, T.ArrayClass)))); | |
1053 | |
1054 CheckEqual( | 1106 CheckEqual( |
1055 T.Union( | 1107 T.Union( |
1056 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1108 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
1057 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1109 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1058 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1110 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1059 CheckEqual( | 1111 CheckEqual( |
1060 T.Union( | 1112 T.Union( |
1061 T.Union(T.Number, T.ArrayClass), | 1113 T.Union(T.Number, T.ArrayClass), |
1062 T.Union(T.SignedSmall, T.Array)), | 1114 T.Union(T.SignedSmall, T.Array)), |
1063 T.Union(T.Number, T.Array)); | 1115 T.Union(T.Number, T.Array)); |
1064 } | 1116 } |
1065 | 1117 |
1066 void Intersect() { | 1118 void Intersect() { |
1067 // Bitset-bitset | 1119 // Identity: Intersect(T, Any) = T |
1068 CHECK(this->IsBitset(T.Intersect(T.Object, T.Number))); | 1120 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1069 CHECK(this->IsBitset(T.Intersect(T.Object, T.Object))); | 1121 TypeHandle type = *it; |
1070 CHECK(this->IsBitset(T.Intersect(T.Any, T.None))); | 1122 CheckEqual(T.Intersect(type, T.Any), type); |
| 1123 } |
1071 | 1124 |
1072 CheckEqual(T.Intersect(T.None, T.Number), T.None); | 1125 // Domination: Intersect(T, None) = None |
1073 CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation); | 1126 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1074 CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); | 1127 TypeHandle type = *it; |
1075 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); | 1128 CheckEqual(T.Intersect(type, T.None), T.None); |
| 1129 } |
1076 | 1130 |
1077 // Class-class | 1131 // Idempotence: Intersect(T, T) = T |
1078 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); | 1132 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1079 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); | 1133 TypeHandle type = *it; |
| 1134 CheckEqual(T.Intersect(type, type), type); |
| 1135 } |
1080 | 1136 |
1081 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); | 1137 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) |
1082 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); | 1138 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1139 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1140 TypeHandle type1 = *it1; |
| 1141 TypeHandle type2 = *it2; |
| 1142 CheckEqual(T.Intersect(type1, type2), T.Intersect(type2, type1)); |
| 1143 } |
| 1144 } |
1083 | 1145 |
1084 // Constant-constant | 1146 // Associativity: |
1085 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); | 1147 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) |
1086 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); | 1148 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1149 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1150 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1151 TypeHandle type1 = *it1; |
| 1152 TypeHandle type2 = *it2; |
| 1153 TypeHandle type3 = *it3; |
| 1154 CheckEqual( |
| 1155 T.Intersect(type1, T.Intersect(type2, type3)), |
| 1156 T.Intersect(T.Intersect(type1, type2), type3)); |
| 1157 } |
| 1158 } |
| 1159 } |
1087 | 1160 |
1088 CheckEqual( | 1161 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) |
1089 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); | 1162 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
1090 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); | 1163 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1164 TypeHandle type1 = *it1; |
| 1165 TypeHandle type2 = *it2; |
| 1166 CHECK(T.Intersect(type1, type2)->Is(type1)); |
| 1167 CHECK(T.Intersect(type1, type2)->Is(type2)); |
| 1168 } |
| 1169 } |
| 1170 |
| 1171 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 |
| 1172 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1173 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1174 TypeHandle type1 = *it1; |
| 1175 TypeHandle type2 = *it2; |
| 1176 if (type1->Is(type2)) CheckEqual(T.Intersect(type1, type2), type1); |
| 1177 } |
| 1178 } |
| 1179 |
| 1180 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 1181 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1182 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1183 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1184 TypeHandle type1 = *it1; |
| 1185 TypeHandle type2 = *it2; |
| 1186 TypeHandle type3 = *it3; |
| 1187 CHECK(!type1->Is(type2) || |
| 1188 (T.Intersect(type1, type3)->Is(T.Intersect(type2, type3)))); |
| 1189 } |
| 1190 } |
| 1191 } |
| 1192 |
| 1193 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 1194 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1195 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1196 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1197 TypeHandle type1 = *it1; |
| 1198 TypeHandle type2 = *it2; |
| 1199 TypeHandle type3 = *it3; |
| 1200 CHECK(!type1->Is(type2) || |
| 1201 (T.Intersect(type1, type3)->Is(T.Intersect(type2, type3)))); |
| 1202 } |
| 1203 } |
| 1204 } |
| 1205 |
| 1206 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) |
| 1207 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1208 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1209 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1210 TypeHandle type1 = *it1; |
| 1211 TypeHandle type2 = *it2; |
| 1212 TypeHandle type3 = *it3; |
| 1213 CHECK(!(type1->Is(type3) || type2->Is(type3)) || |
| 1214 T.Intersect(type1, type2)->Is(type3)); |
| 1215 } |
| 1216 } |
| 1217 } |
| 1218 |
| 1219 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) |
| 1220 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1221 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1222 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1223 TypeHandle type1 = *it1; |
| 1224 TypeHandle type2 = *it2; |
| 1225 TypeHandle type3 = *it3; |
| 1226 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1227 type1->Is(T.Intersect(type2, type3))); |
| 1228 } |
| 1229 } |
| 1230 } |
1091 | 1231 |
1092 // Bitset-class | 1232 // Bitset-class |
1093 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object))); | |
1094 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number))); | |
1095 | |
1096 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1233 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
1097 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); | 1234 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); |
1098 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); | 1235 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); |
1099 | 1236 |
1100 // Bitset-constant | |
1101 CHECK(this->IsBitset(T.Intersect(T.SignedSmall, T.Number))); | |
1102 CHECK(this->IsConstant(T.Intersect(T.SmiConstant, T.Number))); | |
1103 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.Object))); | |
1104 | |
1105 CheckEqual(T.Intersect(T.SignedSmall, T.Number), T.SignedSmall); | |
1106 CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); | |
1107 CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); | |
1108 | |
1109 // Class-constant | 1237 // Class-constant |
1110 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass))); | |
1111 CHECK(this->IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2))); | |
1112 | |
1113 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); | 1238 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); |
1114 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); | 1239 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); |
1115 | 1240 |
1116 // Bitset-union | 1241 // Bitset-union |
1117 CHECK(this->IsUnion( | |
1118 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); | |
1119 CHECK(this->IsBitset( | |
1120 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); | |
1121 | |
1122 CheckEqual( | 1242 CheckEqual( |
1123 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1243 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1124 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1244 T.Union(T.ObjectConstant1, T.ObjectClass)); |
1125 CheckEqual( | 1245 CheckEqual( |
1126 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | 1246 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), |
1127 T.None); | 1247 T.None); |
1128 | 1248 |
1129 // Class-union | 1249 // Class-union |
1130 CHECK(this->IsClass( | |
1131 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); | |
1132 CHECK(this->IsClass( | |
1133 T.Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); | |
1134 CHECK(this->IsBitset( | |
1135 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass))); | |
1136 | |
1137 CheckEqual( | 1250 CheckEqual( |
1138 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1251 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
1139 T.ArrayClass); | 1252 T.ArrayClass); |
1140 CheckEqual( | 1253 CheckEqual( |
1141 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1254 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
1142 T.ArrayClass); | 1255 T.ArrayClass); |
1143 CheckEqual( | 1256 CheckEqual( |
1144 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), | 1257 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), |
1145 T.None); | 1258 T.None); |
1146 | 1259 |
1147 // Constant-union | 1260 // Constant-union |
1148 CHECK(this->IsConstant(T.Intersect( | |
1149 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); | |
1150 CHECK(this->IsConstant(T.Intersect( | |
1151 T.Union(T.Number, T.ObjectClass), T.SmiConstant))); | |
1152 CHECK(this->IsBitset(T.Intersect( | |
1153 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1))); | |
1154 | |
1155 CheckEqual( | 1261 CheckEqual( |
1156 T.Intersect( | 1262 T.Intersect( |
1157 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1263 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1158 T.ObjectConstant1); | 1264 T.ObjectConstant1); |
1159 CheckEqual( | 1265 CheckEqual( |
1160 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | 1266 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
1161 T.SmiConstant); | 1267 T.SmiConstant); |
1162 CheckEqual( | 1268 CheckEqual( |
1163 T.Intersect( | 1269 T.Intersect( |
1164 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), | 1270 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), |
1165 T.None); | 1271 T.None); |
1166 | 1272 |
1167 // Union-union | 1273 // Union-union |
1168 CHECK(this->IsUnion(T.Intersect( | |
1169 T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); | |
1170 CHECK(this->IsBitset(T.Intersect( | |
1171 T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); | |
1172 | |
1173 CheckEqual( | 1274 CheckEqual( |
1174 T.Intersect( | 1275 T.Intersect( |
1175 T.Union(T.Number, T.ArrayClass), | 1276 T.Union(T.Number, T.ArrayClass), |
1176 T.Union(T.SignedSmall, T.Array)), | 1277 T.Union(T.SignedSmall, T.Array)), |
1177 T.Union(T.SignedSmall, T.ArrayClass)); | 1278 T.Union(T.SignedSmall, T.ArrayClass)); |
1178 CheckEqual( | 1279 CheckEqual( |
1179 T.Intersect( | 1280 T.Intersect( |
1180 T.Union(T.Number, T.ObjectClass), | 1281 T.Union(T.Number, T.ObjectClass), |
1181 T.Union(T.Signed32, T.Array)), | 1282 T.Union(T.Signed32, T.Array)), |
1182 T.Signed32); | 1283 T.Signed32); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 ZoneTests().Intersect(); | 1394 ZoneTests().Intersect(); |
1294 HeapTests().Intersect(); | 1395 HeapTests().Intersect(); |
1295 } | 1396 } |
1296 | 1397 |
1297 | 1398 |
1298 TEST(Convert) { | 1399 TEST(Convert) { |
1299 CcTest::InitializeVM(); | 1400 CcTest::InitializeVM(); |
1300 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1401 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
1301 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1402 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
1302 } | 1403 } |
OLD | NEW |