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 | |
95 template<class Type, class TypeHandle, class Region> | 36 template<class Type, class TypeHandle, class Region> |
96 class Types { | 37 class Types { |
97 public: | 38 public: |
98 Types(Region* region, Isolate* isolate) : region_(region) { | 39 Types(Region* region, Isolate* isolate) : region_(region) { |
| 40 static const size_t kMaxTypes = 300; |
| 41 types.reserve(kMaxTypes); |
| 42 |
99 #define DECLARE_TYPE(name, value) \ | 43 #define DECLARE_TYPE(name, value) \ |
100 name = Type::name(region); \ | 44 name = Type::name(region); \ |
101 types.push_back(name); | 45 types.push_back(name); |
102 BITSET_TYPE_LIST(DECLARE_TYPE) | 46 BITSET_TYPE_LIST(DECLARE_TYPE) |
103 #undef DECLARE_TYPE | 47 #undef DECLARE_TYPE |
104 | 48 |
105 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); | 49 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); |
106 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); | 50 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); |
107 uninitialized_map = isolate->factory()->uninitialized_map(); | 51 uninitialized_map = isolate->factory()->uninitialized_map(); |
108 ObjectClass = Type::Class(object_map, region); | 52 ObjectClass = Type::Class(object_map, region); |
(...skipping 23 matching lines...) Expand all Loading... |
132 values.push_back(smi); | 76 values.push_back(smi); |
133 values.push_back(signed32); | 77 values.push_back(signed32); |
134 values.push_back(object1); | 78 values.push_back(object1); |
135 values.push_back(object2); | 79 values.push_back(object2); |
136 values.push_back(array); | 80 values.push_back(array); |
137 values.push_back(uninitialized); | 81 values.push_back(uninitialized); |
138 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { | 82 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { |
139 types.push_back(Type::Constant(*it, region)); | 83 types.push_back(Type::Constant(*it, region)); |
140 } | 84 } |
141 | 85 |
142 while (types.size() < 300) { | 86 while (types.size() < kMaxTypes) { |
143 types.push_back(Fuzz()); | 87 size_t i = rng.NextInt(static_cast<int>(types.size())); |
| 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)); |
144 } | 90 } |
145 } | 91 } |
146 | 92 |
| 93 RandomNumberGenerator rng; |
| 94 |
147 #define DECLARE_TYPE(name, value) TypeHandle name; | 95 #define DECLARE_TYPE(name, value) TypeHandle name; |
148 BITSET_TYPE_LIST(DECLARE_TYPE) | 96 BITSET_TYPE_LIST(DECLARE_TYPE) |
149 #undef DECLARE_TYPE | 97 #undef DECLARE_TYPE |
150 | 98 |
151 TypeHandle ObjectClass; | 99 TypeHandle ObjectClass; |
152 TypeHandle ArrayClass; | 100 TypeHandle ArrayClass; |
153 TypeHandle UninitializedClass; | 101 TypeHandle UninitializedClass; |
154 | 102 |
155 TypeHandle SmiConstant; | 103 TypeHandle SmiConstant; |
156 TypeHandle Signed32Constant; | 104 TypeHandle Signed32Constant; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 146 } |
199 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { | 147 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { |
200 return Type::Intersect(t1, t2, region_); | 148 return Type::Intersect(t1, t2, region_); |
201 } | 149 } |
202 | 150 |
203 template<class Type2, class TypeHandle2> | 151 template<class Type2, class TypeHandle2> |
204 TypeHandle Convert(TypeHandle2 t) { | 152 TypeHandle Convert(TypeHandle2 t) { |
205 return Type::template Convert<Type2>(t, region_); | 153 return Type::template Convert<Type2>(t, region_); |
206 } | 154 } |
207 | 155 |
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 | |
243 private: | 156 private: |
244 Region* region_; | 157 Region* region_; |
245 RandomNumberGenerator rng_; | |
246 }; | 158 }; |
247 | 159 |
248 | 160 |
| 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 |
249 template<class Type, class TypeHandle, class Region, class Rep> | 220 template<class Type, class TypeHandle, class Region, class Rep> |
250 struct Tests : Rep { | 221 struct Tests : Rep { |
251 typedef Types<Type, TypeHandle, Region> TypesInstance; | 222 typedef Types<Type, TypeHandle, Region> TypesInstance; |
252 typedef typename TypesInstance::TypeVector::iterator TypeIterator; | 223 typedef typename TypesInstance::TypeVector::iterator TypeIterator; |
253 typedef typename TypesInstance::MapVector::iterator MapIterator; | 224 typedef typename TypesInstance::MapVector::iterator MapIterator; |
254 typedef typename TypesInstance::ValueVector::iterator ValueIterator; | 225 typedef typename TypesInstance::ValueVector::iterator ValueIterator; |
255 | 226 |
256 Isolate* isolate; | 227 Isolate* isolate; |
257 HandleScope scope; | 228 HandleScope scope; |
258 Zone zone; | 229 Zone zone; |
259 TypesInstance T; | 230 TypesInstance T; |
260 | 231 |
261 Tests() : | 232 Tests() : |
262 isolate(CcTest::i_isolate()), | 233 isolate(CcTest::i_isolate()), |
263 scope(isolate), | 234 scope(isolate), |
264 zone(isolate), | 235 zone(isolate), |
265 T(Rep::ToRegion(&zone, isolate), isolate) { | 236 T(Rep::ToRegion(&zone, isolate), isolate) { |
266 } | 237 } |
267 | 238 |
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 | |
287 void CheckEqual(TypeHandle type1, TypeHandle type2) { | 239 void CheckEqual(TypeHandle type1, TypeHandle type2) { |
288 CHECK(Equal(type1, type2)); | 240 CHECK_EQ(Rep::IsBitset(type1), Rep::IsBitset(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)); |
289 } | 258 } |
290 | 259 |
291 void CheckSub(TypeHandle type1, TypeHandle type2) { | 260 void CheckSub(TypeHandle type1, TypeHandle type2) { |
292 CHECK(type1->Is(type2)); | 261 CHECK(type1->Is(type2)); |
293 CHECK(!type2->Is(type1)); | 262 CHECK(!type2->Is(type1)); |
294 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { | 263 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { |
295 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); | 264 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); |
296 } | 265 } |
297 } | 266 } |
298 | 267 |
(...skipping 26 matching lines...) Expand all Loading... |
325 } | 294 } |
326 | 295 |
327 void Bitset() { | 296 void Bitset() { |
328 // None and Any are bitsets. | 297 // None and Any are bitsets. |
329 CHECK(this->IsBitset(T.None)); | 298 CHECK(this->IsBitset(T.None)); |
330 CHECK(this->IsBitset(T.Any)); | 299 CHECK(this->IsBitset(T.Any)); |
331 | 300 |
332 CHECK_EQ(0, this->AsBitset(T.None)); | 301 CHECK_EQ(0, this->AsBitset(T.None)); |
333 CHECK_EQ(-1, this->AsBitset(T.Any)); | 302 CHECK_EQ(-1, this->AsBitset(T.Any)); |
334 | 303 |
335 // Union(T1, T2) is bitset for bitsets T1,T2 | 304 // Union(T1, T2) is a bitset for all bitsets T1,T2 |
336 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 305 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
337 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 306 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
338 TypeHandle type1 = *it1; | 307 TypeHandle type1 = *it1; |
339 TypeHandle type2 = *it2; | 308 TypeHandle type2 = *it2; |
340 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || | 309 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
341 this->IsBitset(T.Union(type1, type2))); | 310 this->IsBitset(T.Union(type1, type2))); |
342 } | 311 } |
343 } | 312 } |
344 | 313 |
345 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) | 314 // Union(T1, T2) is a bitset if T2 is a bitset and T1->Is(T2) |
| 315 // (and vice versa). |
346 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 316 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
347 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 317 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
348 TypeHandle type1 = *it1; | 318 TypeHandle type1 = *it1; |
349 TypeHandle type2 = *it2; | 319 TypeHandle type2 = *it2; |
350 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || | 320 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || |
351 this->IsBitset(T.Union(type1, type2))); | 321 this->IsBitset(T.Union(type1, type2))); |
| 322 CHECK(!(this->IsBitset(type1) && type2->Is(type1)) || |
| 323 this->IsBitset(T.Union(type1, type2))); |
352 } | 324 } |
353 } | 325 } |
354 | 326 |
355 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 | 327 // Union(T1, T2) is bitwise disjunction for all bitsets T1,T2 |
356 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 328 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
357 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 329 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
358 TypeHandle type1 = *it1; | 330 TypeHandle type1 = *it1; |
359 TypeHandle type2 = *it2; | 331 TypeHandle type2 = *it2; |
360 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 332 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
361 CHECK_EQ( | 333 CHECK_EQ( |
362 this->AsBitset(type1) | this->AsBitset(type2), | 334 this->AsBitset(type1) | this->AsBitset(type2), |
363 this->AsBitset(T.Union(type1, type2))); | 335 this->AsBitset(T.Union(type1, type2))); |
364 } | 336 } |
365 } | 337 } |
366 } | 338 } |
367 | 339 |
368 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 | 340 // Intersect(T1, T2) is bitwise conjunction for all bitsets T1,T2 |
369 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 341 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
370 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 342 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
371 TypeHandle type1 = *it1; | 343 TypeHandle type1 = *it1; |
372 TypeHandle type2 = *it2; | 344 TypeHandle type2 = *it2; |
373 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 345 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
374 CHECK_EQ( | 346 CHECK_EQ( |
375 this->AsBitset(type1) & this->AsBitset(type2), | 347 this->AsBitset(type1) & this->AsBitset(type2), |
376 this->AsBitset(T.Intersect(type1, type2))); | 348 this->AsBitset(T.Intersect(type1, type2))); |
377 } | 349 } |
378 } | 350 } |
379 } | 351 } |
380 } | 352 } |
381 | 353 |
382 void Class() { | 354 void Class() { |
383 // Constructor | 355 // Constructor |
384 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 356 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
385 Handle<i::Map> map = *mt; | 357 Handle<i::Map> map = *mt; |
386 CHECK(this->IsClass(T.Class(map))); | 358 CHECK(this->IsClass(T.Class(map))); |
387 } | 359 } |
388 | 360 |
389 // Map attribute | 361 // Map attribute |
390 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 362 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
391 Handle<i::Map> map = *mt; | 363 Handle<i::Map> map = *mt; |
392 CHECK(*map == *T.Class(map)->AsClass()); | 364 CHECK(*map == *T.Class(map)->AsClass()); |
393 } | 365 } |
394 | 366 |
395 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 | 367 // Functionality & Injectivity |
396 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 368 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
397 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 369 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
398 Handle<i::Map> map1 = *mt1; | 370 Handle<i::Map> map1 = *mt1; |
399 Handle<i::Map> map2 = *mt2; | 371 Handle<i::Map> map2 = *mt2; |
400 CHECK(Equal(T.Class(map1), T.Class(map2)) == (*map1 == *map2)); | 372 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); |
401 } | 373 } |
402 } | 374 } |
403 } | 375 } |
404 | 376 |
405 void Constant() { | 377 void Constant() { |
406 // Constructor | 378 // Constructor |
407 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 379 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
408 Handle<i::Object> value = *vt; | 380 Handle<i::Object> value = *vt; |
409 CHECK(this->IsConstant(T.Constant(value))); | 381 CHECK(this->IsConstant(T.Constant(value))); |
410 } | 382 } |
411 | 383 |
412 // Value attribute | 384 // Value attribute |
413 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 385 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
414 Handle<i::Object> value = *vt; | 386 Handle<i::Object> value = *vt; |
415 CHECK(*value == *T.Constant(value)->AsConstant()); | 387 CHECK(*value == *T.Constant(value)->AsConstant()); |
416 } | 388 } |
417 | 389 |
418 // Functionality & Injectivity: Constant(V1) = Constant(v2) iff V1 = V2 | 390 // Functionality & Injectivity |
419 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 391 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
420 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 392 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
421 Handle<i::Object> val1 = *vt1; | 393 Handle<i::Object> val1 = *vt1; |
422 Handle<i::Object> val2 = *vt2; | 394 Handle<i::Object> val2 = *vt2; |
423 CHECK(Equal(T.Constant(val1), T.Constant(val2)) == (*val1 == *val2)); | 395 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); |
424 } | 396 } |
425 } | 397 } |
426 } | 398 } |
427 | 399 |
428 void Of() { | 400 void Of() { |
429 // Constant(V)->Is(Of(V)) | 401 // Constant(V)->Is(Of(V)) for all V |
430 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 402 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
431 Handle<i::Object> value = *vt; | 403 Handle<i::Object> value = *vt; |
432 CHECK(T.Constant(value)->Is(T.Of(value))); | 404 CHECK(T.Constant(value)->Is(T.Of(value))); |
433 } | 405 } |
434 | 406 |
435 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V)) | 407 // Constant(V)->Is(T) implies Of(V)->Is(T) or T->Maybe(Constant(V)) |
436 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 408 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
437 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 409 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
438 Handle<i::Object> value = *vt; | 410 Handle<i::Object> value = *vt; |
439 TypeHandle type = *it; | 411 TypeHandle type = *it; |
440 CHECK(T.Constant(value)->Is(type) == | 412 CHECK(!T.Constant(value)->Is(type) || |
441 (T.Of(value)->Is(type) || type->Maybe(T.Constant(value)))); | 413 T.Of(value)->Is(type) || type->Maybe(T.Constant(value))); |
442 } | 414 } |
443 } | 415 } |
444 } | 416 } |
445 | 417 |
446 void NowOf() { | 418 void NowOf() { |
447 // Constant(V)->NowIs(NowOf(V)) | 419 // Constant(V)->NowIs(NowOf(V)) for all V |
448 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 420 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
449 Handle<i::Object> value = *vt; | 421 Handle<i::Object> value = *vt; |
450 CHECK(T.Constant(value)->NowIs(T.NowOf(value))); | 422 CHECK(T.Constant(value)->NowIs(T.NowOf(value))); |
451 } | 423 } |
452 | 424 |
453 // NowOf(V)->Is(Of(V)) | 425 // NowOf(V)->Is(Of(V)) for all V |
454 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 426 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
455 Handle<i::Object> value = *vt; | 427 Handle<i::Object> value = *vt; |
456 CHECK(T.NowOf(value)->Is(T.Of(value))); | 428 CHECK(T.NowOf(value)->Is(T.Of(value))); |
457 } | 429 } |
458 | 430 |
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 | |
469 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) | 431 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) |
470 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 432 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
471 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 433 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
472 Handle<i::Object> value = *vt; | 434 Handle<i::Object> value = *vt; |
473 TypeHandle type = *it; | 435 TypeHandle type = *it; |
474 CHECK(!T.Constant(value)->Is(type) || | 436 CHECK(!T.Constant(value)->Is(type) || |
475 (T.NowOf(value)->Is(type) || type->Maybe(T.Constant(value)))); | 437 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))); |
476 } | 448 } |
477 } | 449 } |
478 } | 450 } |
479 | 451 |
480 void Is() { | 452 void Is() { |
481 // Least Element (Bottom): None->Is(T) | 453 // T->Is(None) implies T = None for all T |
| 454 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 455 TypeHandle type = *it; |
| 456 if (type->Is(T.None)) CheckEqual(type, T.None); |
| 457 } |
| 458 |
| 459 // None->Is(T) for all T |
482 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 460 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
483 TypeHandle type = *it; | 461 TypeHandle type = *it; |
484 CHECK(T.None->Is(type)); | 462 CHECK(T.None->Is(type)); |
485 } | 463 } |
486 | 464 |
487 // Greatest Element (Top): T->Is(Any) | 465 // Any->Is(T) implies T = Any for all T |
| 466 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 467 TypeHandle type = *it; |
| 468 if (T.Any->Is(type)) CheckEqual(type, T.Any); |
| 469 } |
| 470 |
| 471 // T->Is(Any) for all T |
488 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 472 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
489 TypeHandle type = *it; | 473 TypeHandle type = *it; |
490 CHECK(type->Is(T.Any)); | 474 CHECK(type->Is(T.Any)); |
491 } | 475 } |
492 | 476 |
493 // Bottom Uniqueness: T->Is(None) implies T = None | 477 // Reflexivity |
494 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
495 TypeHandle type = *it; | |
496 if (type->Is(T.None)) CheckEqual(type, T.None); | |
497 } | |
498 | |
499 // Top Uniqueness: Any->Is(T) implies T = Any | |
500 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
501 TypeHandle type = *it; | |
502 if (T.Any->Is(type)) CheckEqual(type, T.Any); | |
503 } | |
504 | |
505 // Reflexivity: T->Is(T) | |
506 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 478 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
507 TypeHandle type = *it; | 479 TypeHandle type = *it; |
508 CHECK(type->Is(type)); | 480 CHECK(type->Is(type)); |
509 } | 481 } |
510 | 482 |
511 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) | 483 // Transitivity |
512 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 484 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
513 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 485 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
514 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 486 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
515 TypeHandle type1 = *it1; | 487 TypeHandle type1 = *it1; |
516 TypeHandle type2 = *it2; | 488 TypeHandle type2 = *it2; |
517 TypeHandle type3 = *it3; | 489 TypeHandle type3 = *it3; |
518 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); | 490 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); |
519 } | 491 } |
520 } | 492 } |
521 } | 493 } |
522 | 494 |
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 | |
532 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | 495 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
533 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 496 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
534 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 497 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
535 Handle<i::Object> val1 = *vt1; | 498 Handle<i::Object> val1 = *vt1; |
536 Handle<i::Object> val2 = *vt2; | 499 Handle<i::Object> val2 = *vt2; |
537 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); | 500 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); |
538 } | 501 } |
539 } | 502 } |
540 | 503 |
541 // Class(M1)->Is(Class(M2)) iff M1 = M2 | 504 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
542 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 505 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
543 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 506 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
544 Handle<i::Map> map1 = *mt1; | 507 Handle<i::Map> map1 = *mt1; |
545 Handle<i::Map> map2 = *mt2; | 508 Handle<i::Map> map2 = *mt2; |
546 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); | 509 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); |
547 } | 510 } |
548 } | 511 } |
549 | 512 |
550 // Constant(V)->Is(Class(M)) never | 513 // Constant(V)->Is(Class(M)) for no V,M |
551 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 514 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
552 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 515 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
553 Handle<i::Map> map = *mt; | 516 Handle<i::Map> map = *mt; |
554 Handle<i::Object> value = *vt; | 517 Handle<i::Object> value = *vt; |
555 CHECK(!T.Constant(value)->Is(T.Class(map))); | 518 CHECK(!T.Constant(value)->Is(T.Class(map))); |
556 } | 519 } |
557 } | 520 } |
558 | 521 |
559 // Class(M)->Is(Constant(V)) never | 522 // Class(M)->Is(Constant(V)) for no V,M |
560 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 523 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
561 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 524 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
562 Handle<i::Map> map = *mt; | 525 Handle<i::Map> map = *mt; |
563 Handle<i::Object> value = *vt; | 526 Handle<i::Object> value = *vt; |
564 CHECK(!T.Class(map)->Is(T.Constant(value))); | 527 CHECK(!T.Class(map)->Is(T.Constant(value))); |
565 } | 528 } |
566 } | 529 } |
567 | 530 |
568 // Basic types | 531 // Basic types |
569 CheckUnordered(T.Boolean, T.Null); | 532 CheckUnordered(T.Boolean, T.Null); |
(...skipping 18 matching lines...) Expand all Loading... |
588 CheckUnordered(T.String, T.Symbol); | 551 CheckUnordered(T.String, T.Symbol); |
589 CheckUnordered(T.InternalizedString, T.Symbol); | 552 CheckUnordered(T.InternalizedString, T.Symbol); |
590 | 553 |
591 CheckSub(T.Object, T.Receiver); | 554 CheckSub(T.Object, T.Receiver); |
592 CheckSub(T.Array, T.Object); | 555 CheckSub(T.Array, T.Object); |
593 CheckSub(T.Function, T.Object); | 556 CheckSub(T.Function, T.Object); |
594 CheckSub(T.Proxy, T.Receiver); | 557 CheckSub(T.Proxy, T.Receiver); |
595 CheckUnordered(T.Object, T.Proxy); | 558 CheckUnordered(T.Object, T.Proxy); |
596 CheckUnordered(T.Array, T.Function); | 559 CheckUnordered(T.Array, T.Function); |
597 | 560 |
| 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 |
598 // Structural types | 568 // Structural types |
599 CheckSub(T.ObjectClass, T.Object); | 569 CheckSub(T.ObjectClass, T.Object); |
600 CheckSub(T.ArrayClass, T.Object); | 570 CheckSub(T.ArrayClass, T.Object); |
601 CheckSub(T.UninitializedClass, T.Internal); | |
602 CheckUnordered(T.ObjectClass, T.ArrayClass); | 571 CheckUnordered(T.ObjectClass, T.ArrayClass); |
603 CheckUnordered(T.UninitializedClass, T.Null); | |
604 CheckUnordered(T.UninitializedClass, T.Undefined); | |
605 | 572 |
606 CheckSub(T.SmiConstant, T.SignedSmall); | 573 CheckSub(T.SmiConstant, T.SignedSmall); |
607 CheckSub(T.SmiConstant, T.Signed32); | 574 CheckSub(T.SmiConstant, T.Signed32); |
608 CheckSub(T.SmiConstant, T.Number); | 575 CheckSub(T.SmiConstant, T.Number); |
609 CheckSub(T.ObjectConstant1, T.Object); | 576 CheckSub(T.ObjectConstant1, T.Object); |
610 CheckSub(T.ObjectConstant2, T.Object); | 577 CheckSub(T.ObjectConstant2, T.Object); |
611 CheckSub(T.ArrayConstant, T.Object); | 578 CheckSub(T.ArrayConstant, T.Object); |
612 CheckSub(T.ArrayConstant, T.Array); | 579 CheckSub(T.ArrayConstant, T.Array); |
613 CheckSub(T.UninitializedConstant, T.Internal); | |
614 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); | 580 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); |
615 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); | 581 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); |
616 CheckUnordered(T.UninitializedConstant, T.Null); | |
617 CheckUnordered(T.UninitializedConstant, T.Undefined); | |
618 | 582 |
619 CheckUnordered(T.ObjectConstant1, T.ObjectClass); | 583 CheckUnordered(T.ObjectConstant1, T.ObjectClass); |
620 CheckUnordered(T.ObjectConstant2, T.ObjectClass); | 584 CheckUnordered(T.ObjectConstant2, T.ObjectClass); |
621 CheckUnordered(T.ObjectConstant1, T.ArrayClass); | 585 CheckUnordered(T.ObjectConstant1, T.ArrayClass); |
622 CheckUnordered(T.ObjectConstant2, T.ArrayClass); | 586 CheckUnordered(T.ObjectConstant2, T.ArrayClass); |
623 CheckUnordered(T.ArrayConstant, T.ObjectClass); | 587 CheckUnordered(T.ArrayConstant, T.ObjectClass); |
624 } | 588 } |
625 | 589 |
626 void NowIs() { | 590 void NowIs() { |
627 // Least Element (Bottom): None->NowIs(T) | 591 // T->NowIs(None) implies T = None for all T |
| 592 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 593 TypeHandle type = *it; |
| 594 if (type->NowIs(T.None)) CheckEqual(type, T.None); |
| 595 } |
| 596 |
| 597 // None->NowIs(T) for all T |
628 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 598 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
629 TypeHandle type = *it; | 599 TypeHandle type = *it; |
630 CHECK(T.None->NowIs(type)); | 600 CHECK(T.None->NowIs(type)); |
631 } | 601 } |
632 | 602 |
633 // Greatest Element (Top): T->NowIs(Any) | 603 // Any->NowIs(T) implies T = Any for all T |
| 604 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 605 TypeHandle type = *it; |
| 606 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); |
| 607 } |
| 608 |
| 609 // T->NowIs(Any) for all T |
634 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 610 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
635 TypeHandle type = *it; | 611 TypeHandle type = *it; |
636 CHECK(type->NowIs(T.Any)); | 612 CHECK(type->NowIs(T.Any)); |
637 } | 613 } |
638 | 614 |
639 // Bottom Uniqueness: T->NowIs(None) implies T = None | 615 // Reflexivity |
640 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
641 TypeHandle type = *it; | |
642 if (type->NowIs(T.None)) CheckEqual(type, T.None); | |
643 } | |
644 | |
645 // Top Uniqueness: Any->NowIs(T) implies T = Any | |
646 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | |
647 TypeHandle type = *it; | |
648 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); | |
649 } | |
650 | |
651 // Reflexivity: T->NowIs(T) | |
652 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 616 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
653 TypeHandle type = *it; | 617 TypeHandle type = *it; |
654 CHECK(type->NowIs(type)); | 618 CHECK(type->NowIs(type)); |
655 } | 619 } |
656 | 620 |
657 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) | 621 // Transitivity |
658 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 622 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
659 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 623 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
660 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 624 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
661 TypeHandle type1 = *it1; | 625 TypeHandle type1 = *it1; |
662 TypeHandle type2 = *it2; | 626 TypeHandle type2 = *it2; |
663 TypeHandle type3 = *it3; | 627 TypeHandle type3 = *it3; |
664 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || | 628 CHECK(!type1->NowIs(type2) || |
| 629 !type2->NowIs(type3) || |
665 type1->NowIs(type3)); | 630 type1->NowIs(type3)); |
666 } | 631 } |
667 } | 632 } |
668 } | 633 } |
669 | 634 |
670 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 | 635 // T1->Is(T2) implies T1->NowIs(T2) for all T1,T2 |
671 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 636 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
672 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 637 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
673 TypeHandle type1 = *it1; | 638 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; | |
684 TypeHandle type2 = *it2; | 639 TypeHandle type2 = *it2; |
685 CHECK(!type1->Is(type2) || type1->NowIs(type2)); | 640 CHECK(!type1->Is(type2) || type1->NowIs(type2)); |
686 } | 641 } |
687 } | 642 } |
688 | 643 |
689 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 | 644 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 |
690 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 645 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
691 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 646 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
692 Handle<i::Object> val1 = *vt1; | 647 Handle<i::Object> val1 = *vt1; |
693 Handle<i::Object> val2 = *vt2; | 648 Handle<i::Object> val2 = *vt2; |
(...skipping 14 matching lines...) Expand all Loading... |
708 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 663 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
709 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 664 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
710 Handle<i::Map> map = *mt; | 665 Handle<i::Map> map = *mt; |
711 Handle<i::Object> value = *vt; | 666 Handle<i::Object> value = *vt; |
712 CHECK((value->IsHeapObject() && | 667 CHECK((value->IsHeapObject() && |
713 i::HeapObject::cast(*value)->map() == *map) | 668 i::HeapObject::cast(*value)->map() == *map) |
714 == T.Constant(value)->NowIs(T.Class(map))); | 669 == T.Constant(value)->NowIs(T.Class(map))); |
715 } | 670 } |
716 } | 671 } |
717 | 672 |
718 // Class(M)->NowIs(Constant(V)) never | 673 // Class(M)->NowIs(Constant(V)) for no V,M |
719 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 674 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
720 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 675 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
721 Handle<i::Map> map = *mt; | 676 Handle<i::Map> map = *mt; |
722 Handle<i::Object> value = *vt; | 677 Handle<i::Object> value = *vt; |
723 CHECK(!T.Class(map)->NowIs(T.Constant(value))); | 678 CHECK(!T.Class(map)->NowIs(T.Constant(value))); |
724 } | 679 } |
725 } | 680 } |
726 } | 681 } |
727 | 682 |
728 void Contains() { | 683 void Contains() { |
729 // T->Contains(V) iff Constant(V)->Is(T) | 684 // T->Contains(V) iff Constant(V)->Is(T) for all T,V |
730 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 685 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
731 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 686 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
732 TypeHandle type = *it; | 687 TypeHandle type = *it; |
733 Handle<i::Object> value = *vt; | 688 Handle<i::Object> value = *vt; |
734 CHECK(type->Contains(value) == T.Constant(value)->Is(type)); | 689 CHECK(type->Contains(value) == T.Constant(value)->Is(type)); |
735 } | 690 } |
736 } | 691 } |
737 | 692 |
738 // Of(V)->Is(T) implies T->Contains(V) | 693 // Of(V)->Is(T) implies T->Contains(V) for all T,V |
739 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 694 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
740 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 695 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
741 TypeHandle type = *it; | 696 TypeHandle type = *it; |
742 Handle<i::Object> value = *vt; | 697 Handle<i::Object> value = *vt; |
743 CHECK(!T.Of(value)->Is(type) || type->Contains(value)); | 698 CHECK(!T.Of(value)->Is(type) || type->Contains(value)); |
744 } | 699 } |
745 } | 700 } |
746 } | 701 } |
747 | 702 |
748 void NowContains() { | 703 void NowContains() { |
749 // T->NowContains(V) iff Constant(V)->NowIs(T) | 704 // T->NowContains(V) iff Constant(V)->NowIs(T) for all T,V |
750 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 705 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
751 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 706 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
752 TypeHandle type = *it; | 707 TypeHandle type = *it; |
753 Handle<i::Object> value = *vt; | 708 Handle<i::Object> value = *vt; |
754 CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type)); | 709 CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type)); |
755 } | 710 } |
756 } | 711 } |
757 | 712 |
758 // T->Contains(V) implies T->NowContains(V) | 713 // T->Contains(V) implies T->NowContains(V) for all T,V |
759 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 714 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
760 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 715 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
761 TypeHandle type = *it; | 716 TypeHandle type = *it; |
762 Handle<i::Object> value = *vt; | 717 Handle<i::Object> value = *vt; |
763 CHECK(!type->Contains(value) || type->NowContains(value)); | 718 CHECK(!type->Contains(value) || type->NowContains(value)); |
764 } | 719 } |
765 } | 720 } |
766 | 721 |
767 // NowOf(V)->Is(T) implies T->NowContains(V) | 722 // NowOf(V)->Is(T) implies T->NowContains(V) for all T,V |
768 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 723 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
769 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 724 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
770 TypeHandle type = *it; | 725 TypeHandle type = *it; |
771 Handle<i::Object> value = *vt; | 726 Handle<i::Object> value = *vt; |
772 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 727 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); |
773 } | 728 } |
774 } | 729 } |
775 | 730 |
776 // NowOf(V)->NowIs(T) implies T->NowContains(V) | 731 // NowOf(V)->NowIs(T) implies T->NowContains(V) for all T,V |
777 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 732 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
778 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 733 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
779 TypeHandle type = *it; | 734 TypeHandle type = *it; |
780 Handle<i::Object> value = *vt; | 735 Handle<i::Object> value = *vt; |
781 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 736 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); |
782 } | 737 } |
783 } | 738 } |
784 } | 739 } |
785 | 740 |
786 void Maybe() { | 741 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 |
787 // T->Maybe(Any) iff T inhabited | 748 // T->Maybe(Any) iff T inhabited |
788 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 749 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
789 TypeHandle type = *it; | 750 TypeHandle type = *it; |
790 CHECK(type->Maybe(T.Any) == type->IsInhabited()); | 751 CHECK(type->Maybe(T.Any) == type->IsInhabited()); |
791 } | 752 } |
792 | 753 |
793 // T->Maybe(None) never | 754 // T->Maybe(None) never |
794 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 755 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
795 TypeHandle type = *it; | 756 TypeHandle type = *it; |
796 CHECK(!type->Maybe(T.None)); | 757 CHECK(!type->Maybe(T.None)); |
797 } | 758 } |
798 | 759 |
799 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited | 760 // Symmetry |
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) | |
806 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 761 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
807 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 762 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
808 TypeHandle type1 = *it1; | 763 TypeHandle type1 = *it1; |
809 TypeHandle type2 = *it2; | 764 TypeHandle type2 = *it2; |
810 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); | 765 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
811 } | 766 } |
812 } | 767 } |
813 | 768 |
814 // T1->Maybe(T2) implies T1, T2 inhabited | 769 // T1->Maybe(T2) only if T1, T2 inhabited |
815 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 770 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
816 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 771 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
817 TypeHandle type1 = *it1; | 772 TypeHandle type1 = *it1; |
818 TypeHandle type2 = *it2; | 773 TypeHandle type2 = *it2; |
819 CHECK(!type1->Maybe(type2) || | 774 CHECK(!type1->Maybe(type2) || |
820 (type1->IsInhabited() && type2->IsInhabited())); | 775 (type1->IsInhabited() && type2->IsInhabited())); |
821 } | 776 } |
822 } | 777 } |
823 | 778 |
824 // T1->Maybe(T2) iff Intersect(T1, T2) inhabited | 779 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) for all T1,T2 |
825 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 780 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
826 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 781 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
827 TypeHandle type1 = *it1; | 782 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; | |
837 TypeHandle type2 = *it2; | 783 TypeHandle type2 = *it2; |
838 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || | 784 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || |
839 type1->Maybe(type2)); | 785 type1->Maybe(type2)); |
840 } | 786 } |
841 } | 787 } |
842 | 788 |
843 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 | 789 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
844 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 790 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
845 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 791 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
846 Handle<i::Object> val1 = *vt1; | 792 Handle<i::Object> val1 = *vt1; |
847 Handle<i::Object> val2 = *vt2; | 793 Handle<i::Object> val2 = *vt2; |
848 CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2)); | 794 CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2)); |
849 } | 795 } |
850 } | 796 } |
851 | 797 |
852 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 | 798 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 |
853 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 799 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
854 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 800 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
855 Handle<i::Map> map1 = *mt1; | 801 Handle<i::Map> map1 = *mt1; |
856 Handle<i::Map> map2 = *mt2; | 802 Handle<i::Map> map2 = *mt2; |
857 CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2)); | 803 CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2)); |
858 } | 804 } |
859 } | 805 } |
860 | 806 |
861 // Constant(V)->Maybe(Class(M)) never | 807 // Constant(V)->Maybe(Class(M)) for no V,M |
862 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 808 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
863 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 809 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
864 Handle<i::Map> map = *mt; | 810 Handle<i::Map> map = *mt; |
865 Handle<i::Object> value = *vt; | 811 Handle<i::Object> value = *vt; |
866 CHECK(!T.Constant(value)->Maybe(T.Class(map))); | 812 CHECK(!T.Constant(value)->Maybe(T.Class(map))); |
867 } | 813 } |
868 } | 814 } |
869 | 815 |
870 // Class(M)->Maybe(Constant(V)) never | 816 // Class(M)->Maybe(Constant(V)) for no V,M |
871 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 817 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
872 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 818 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
873 Handle<i::Map> map = *mt; | 819 Handle<i::Map> map = *mt; |
874 Handle<i::Object> value = *vt; | 820 Handle<i::Object> value = *vt; |
875 CHECK(!T.Class(map)->Maybe(T.Constant(value))); | 821 CHECK(!T.Class(map)->Maybe(T.Constant(value))); |
876 } | 822 } |
877 } | 823 } |
878 | 824 |
879 // Basic types | 825 // Basic types |
880 CheckDisjoint(T.Boolean, T.Null, T.Semantic); | 826 CheckDisjoint(T.Boolean, T.Null, T.Semantic); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); | 869 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); |
924 | 870 |
925 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); | 871 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); |
926 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); | 872 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); |
927 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); | 873 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); |
928 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); | 874 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); |
929 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); | 875 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); |
930 } | 876 } |
931 | 877 |
932 void Union() { | 878 void Union() { |
933 // Identity: Union(T, None) = T | 879 // Bitset-bitset |
934 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 880 CHECK(this->IsBitset(T.Union(T.Object, T.Number))); |
935 TypeHandle type = *it; | 881 CHECK(this->IsBitset(T.Union(T.Object, T.Object))); |
936 CheckEqual(T.Union(type, T.None), type); | 882 CHECK(this->IsBitset(T.Union(T.Any, T.None))); |
937 } | |
938 | 883 |
939 // Domination: Union(T, Any) = Any | 884 CheckEqual(T.Union(T.None, T.Number), T.Number); |
940 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 885 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); |
941 TypeHandle type = *it; | 886 CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); |
942 CheckEqual(T.Union(type, T.Any), T.Any); | 887 CheckSub(T.Union(T.Number, T.String), 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 } | |
1031 | 888 |
1032 // Class-class | 889 // 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)); |
1033 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); | 898 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); |
1034 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); | 899 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); |
1035 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); | 900 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); |
1036 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); | 901 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); |
1037 | 902 |
1038 // Constant-constant | 903 // 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)); |
1039 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); | 916 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); |
1040 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); | |
1041 CheckUnordered( | 917 CheckUnordered( |
1042 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); | 918 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); |
| 919 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); |
1043 CheckOverlap( | 920 CheckOverlap( |
1044 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); | 921 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); |
1045 CheckDisjoint( | 922 CheckDisjoint( |
1046 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); | 923 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); |
1047 CheckDisjoint( | 924 CheckDisjoint( |
1048 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); | 925 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, |
| 926 T.Semantic); |
1049 | 927 |
1050 // Bitset-class | 928 // 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); |
1051 CheckSub( | 935 CheckSub( |
1052 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); | 936 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); |
1053 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); | 937 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); |
1054 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); | 938 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); |
1055 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); | 939 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); |
1056 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); | 940 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); |
1057 | 941 |
1058 // Bitset-constant | 942 // 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); |
1059 CheckSub( | 951 CheckSub( |
1060 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); | 952 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); |
1061 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); | 953 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); |
1062 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); | 954 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); |
1063 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); | 955 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); |
1064 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); | 956 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); |
| 957 CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); |
1065 | 958 |
1066 // Class-constant | 959 // 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); |
1067 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); | 965 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)); |
1068 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); | 968 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); |
1069 CheckSub( | 969 CheckSub( |
1070 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); | 970 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); |
1071 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); | 971 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); |
1072 CheckDisjoint( | 972 CheckDisjoint( |
1073 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, | 973 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, |
1074 T.Semantic); | 974 T.Semantic); |
1075 CheckDisjoint( | 975 CheckDisjoint( |
1076 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); | 976 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); |
1077 | 977 |
1078 // Bitset-union | 978 // 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))); |
1079 CheckSub( | 990 CheckSub( |
1080 T.Float, | 991 T.Float, |
1081 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); | 992 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); |
1082 CheckSub( | 993 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( |
1083 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), | 1003 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), |
1084 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | 1004 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); |
1085 | 1005 |
1086 // Class-union | 1006 // 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); |
1087 CheckSub( | 1021 CheckSub( |
1088 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1022 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1089 T.Object); | 1023 T.Object); |
1090 CheckEqual( | 1024 CheckEqual( |
1091 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), | 1025 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), |
1092 T.Union(T.ArrayClass, T.ObjectConstant2)); | 1026 T.Union(T.ArrayClass, T.ObjectConstant2)); |
1093 | 1027 |
1094 // Constant-union | 1028 // 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 |
1095 CheckEqual( | 1036 CheckEqual( |
1096 T.Union( | 1037 T.Union( |
1097 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1038 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1098 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1039 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1099 CheckEqual( | 1040 CheckEqual( |
1100 T.Union( | 1041 T.Union( |
1101 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), | 1042 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), |
1102 T.Union( | 1043 T.Union( |
1103 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); | 1044 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); |
1104 | 1045 |
1105 // Union-union | 1046 // 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 |
1106 CheckEqual( | 1054 CheckEqual( |
1107 T.Union( | 1055 T.Union( |
1108 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1056 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
1109 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1057 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1110 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1058 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1111 CheckEqual( | 1059 CheckEqual( |
1112 T.Union( | 1060 T.Union( |
1113 T.Union(T.Number, T.ArrayClass), | 1061 T.Union(T.Number, T.ArrayClass), |
1114 T.Union(T.SignedSmall, T.Array)), | 1062 T.Union(T.SignedSmall, T.Array)), |
1115 T.Union(T.Number, T.Array)); | 1063 T.Union(T.Number, T.Array)); |
1116 } | 1064 } |
1117 | 1065 |
1118 void Intersect() { | 1066 void Intersect() { |
1119 // Identity: Intersect(T, Any) = T | 1067 // Bitset-bitset |
1120 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1068 CHECK(this->IsBitset(T.Intersect(T.Object, T.Number))); |
1121 TypeHandle type = *it; | 1069 CHECK(this->IsBitset(T.Intersect(T.Object, T.Object))); |
1122 CheckEqual(T.Intersect(type, T.Any), type); | 1070 CHECK(this->IsBitset(T.Intersect(T.Any, T.None))); |
1123 } | |
1124 | 1071 |
1125 // Domination: Intersect(T, None) = None | 1072 CheckEqual(T.Intersect(T.None, T.Number), T.None); |
1126 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1073 CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation); |
1127 TypeHandle type = *it; | 1074 CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); |
1128 CheckEqual(T.Intersect(type, T.None), T.None); | 1075 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); |
1129 } | |
1130 | 1076 |
1131 // Idempotence: Intersect(T, T) = T | 1077 // Class-class |
1132 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1078 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); |
1133 TypeHandle type = *it; | 1079 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); |
1134 CheckEqual(T.Intersect(type, type), type); | |
1135 } | |
1136 | 1080 |
1137 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) | 1081 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); |
1138 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1082 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); |
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 } | |
1145 | 1083 |
1146 // Associativity: | 1084 // Constant-constant |
1147 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) | 1085 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); |
1148 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1086 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); |
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 } | |
1160 | 1087 |
1161 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) | 1088 CheckEqual( |
1162 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 1089 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); |
1163 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 1090 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); |
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 } | |
1231 | 1091 |
1232 // Bitset-class | 1092 // Bitset-class |
| 1093 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object))); |
| 1094 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number))); |
| 1095 |
1233 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 1096 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
1234 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); | 1097 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); |
1235 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); | 1098 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); |
1236 | 1099 |
| 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 |
1237 // Class-constant | 1109 // Class-constant |
| 1110 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectClass))); |
| 1111 CHECK(this->IsBitset(T.Intersect(T.ArrayClass, T.ObjectConstant2))); |
| 1112 |
1238 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); | 1113 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); |
1239 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); | 1114 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); |
1240 | 1115 |
1241 // Bitset-union | 1116 // 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 |
1242 CheckEqual( | 1122 CheckEqual( |
1243 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1123 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1244 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1124 T.Union(T.ObjectConstant1, T.ObjectClass)); |
1245 CheckEqual( | 1125 CheckEqual( |
1246 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | 1126 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), |
1247 T.None); | 1127 T.None); |
1248 | 1128 |
1249 // Class-union | 1129 // 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 |
1250 CheckEqual( | 1137 CheckEqual( |
1251 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1138 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
1252 T.ArrayClass); | 1139 T.ArrayClass); |
1253 CheckEqual( | 1140 CheckEqual( |
1254 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1141 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
1255 T.ArrayClass); | 1142 T.ArrayClass); |
1256 CheckEqual( | 1143 CheckEqual( |
1257 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), | 1144 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), |
1258 T.None); | 1145 T.None); |
1259 | 1146 |
1260 // Constant-union | 1147 // 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 |
1261 CheckEqual( | 1155 CheckEqual( |
1262 T.Intersect( | 1156 T.Intersect( |
1263 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1157 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1264 T.ObjectConstant1); | 1158 T.ObjectConstant1); |
1265 CheckEqual( | 1159 CheckEqual( |
1266 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | 1160 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
1267 T.SmiConstant); | 1161 T.SmiConstant); |
1268 CheckEqual( | 1162 CheckEqual( |
1269 T.Intersect( | 1163 T.Intersect( |
1270 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), | 1164 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), |
1271 T.None); | 1165 T.None); |
1272 | 1166 |
1273 // Union-union | 1167 // 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 |
1274 CheckEqual( | 1173 CheckEqual( |
1275 T.Intersect( | 1174 T.Intersect( |
1276 T.Union(T.Number, T.ArrayClass), | 1175 T.Union(T.Number, T.ArrayClass), |
1277 T.Union(T.SignedSmall, T.Array)), | 1176 T.Union(T.SignedSmall, T.Array)), |
1278 T.Union(T.SignedSmall, T.ArrayClass)); | 1177 T.Union(T.SignedSmall, T.ArrayClass)); |
1279 CheckEqual( | 1178 CheckEqual( |
1280 T.Intersect( | 1179 T.Intersect( |
1281 T.Union(T.Number, T.ObjectClass), | 1180 T.Union(T.Number, T.ObjectClass), |
1282 T.Union(T.Signed32, T.Array)), | 1181 T.Union(T.Signed32, T.Array)), |
1283 T.Signed32); | 1182 T.Signed32); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 ZoneTests().Intersect(); | 1293 ZoneTests().Intersect(); |
1395 HeapTests().Intersect(); | 1294 HeapTests().Intersect(); |
1396 } | 1295 } |
1397 | 1296 |
1398 | 1297 |
1399 TEST(Convert) { | 1298 TEST(Convert) { |
1400 CcTest::InitializeVM(); | 1299 CcTest::InitializeVM(); |
1401 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1300 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
1402 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1301 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
1403 } | 1302 } |
OLD | NEW |