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; |
| 340 TypeHandle union12 = T.Union(type1, type2); |
309 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || | 341 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
310 this->IsBitset(T.Union(type1, type2))); | 342 this->IsBitset(union12)); |
311 } | 343 } |
312 } | 344 } |
313 | 345 |
314 // Union(T1, T2) is a bitset if T2 is a bitset and T1->Is(T2) | 346 // Intersect(T1, T2) is bitset for bitsets T1,T2 |
315 // (and vice versa). | |
316 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 347 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
317 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 348 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
318 TypeHandle type1 = *it1; | 349 TypeHandle type1 = *it1; |
319 TypeHandle type2 = *it2; | 350 TypeHandle type2 = *it2; |
320 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || | 351 TypeHandle intersect12 = T.Intersect(type1, type2); |
321 this->IsBitset(T.Union(type1, type2))); | 352 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || |
322 CHECK(!(this->IsBitset(type1) && type2->Is(type1)) || | 353 this->IsBitset(intersect12)); |
323 this->IsBitset(T.Union(type1, type2))); | |
324 } | 354 } |
325 } | 355 } |
326 | 356 |
327 // Union(T1, T2) is bitwise disjunction for all bitsets T1,T2 | 357 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) |
328 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 358 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
329 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 359 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
330 TypeHandle type1 = *it1; | 360 TypeHandle type1 = *it1; |
331 TypeHandle type2 = *it2; | 361 TypeHandle type2 = *it2; |
| 362 TypeHandle union12 = T.Union(type1, type2); |
| 363 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || |
| 364 this->IsBitset(union12)); |
| 365 } |
| 366 } |
| 367 |
| 368 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 |
| 369 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 370 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 371 TypeHandle type1 = *it1; |
| 372 TypeHandle type2 = *it2; |
| 373 TypeHandle union12 = T.Union(type1, type2); |
332 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 374 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
333 CHECK_EQ( | 375 CHECK_EQ( |
334 this->AsBitset(type1) | this->AsBitset(type2), | 376 this->AsBitset(type1) | this->AsBitset(type2), |
335 this->AsBitset(T.Union(type1, type2))); | 377 this->AsBitset(union12)); |
336 } | 378 } |
337 } | 379 } |
338 } | 380 } |
339 | 381 |
340 // Intersect(T1, T2) is bitwise conjunction for all bitsets T1,T2 | 382 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 |
341 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 383 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
342 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 384 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
343 TypeHandle type1 = *it1; | 385 TypeHandle type1 = *it1; |
344 TypeHandle type2 = *it2; | 386 TypeHandle type2 = *it2; |
| 387 TypeHandle intersect12 = T.Intersect(type1, type2); |
345 if (this->IsBitset(type1) && this->IsBitset(type2)) { | 388 if (this->IsBitset(type1) && this->IsBitset(type2)) { |
346 CHECK_EQ( | 389 CHECK_EQ( |
347 this->AsBitset(type1) & this->AsBitset(type2), | 390 this->AsBitset(type1) & this->AsBitset(type2), |
348 this->AsBitset(T.Intersect(type1, type2))); | 391 this->AsBitset(intersect12)); |
349 } | 392 } |
350 } | 393 } |
351 } | 394 } |
352 } | 395 } |
353 | 396 |
354 void Class() { | 397 void Class() { |
355 // Constructor | 398 // Constructor |
356 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 399 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
357 Handle<i::Map> map = *mt; | 400 Handle<i::Map> map = *mt; |
358 CHECK(this->IsClass(T.Class(map))); | 401 TypeHandle type = T.Class(map); |
| 402 CHECK(this->IsClass(type)); |
359 } | 403 } |
360 | 404 |
361 // Map attribute | 405 // Map attribute |
362 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 406 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
363 Handle<i::Map> map = *mt; | 407 Handle<i::Map> map = *mt; |
364 CHECK(*map == *T.Class(map)->AsClass()); | 408 TypeHandle type = T.Class(map); |
| 409 CHECK(*map == *type->AsClass()); |
365 } | 410 } |
366 | 411 |
367 // Functionality & Injectivity | 412 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 |
368 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 413 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
369 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 414 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
370 Handle<i::Map> map1 = *mt1; | 415 Handle<i::Map> map1 = *mt1; |
371 Handle<i::Map> map2 = *mt2; | 416 Handle<i::Map> map2 = *mt2; |
372 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); | 417 TypeHandle type1 = T.Class(map1); |
| 418 TypeHandle type2 = T.Class(map2); |
| 419 CHECK(Equal(type1, type2) == (*map1 == *map2)); |
373 } | 420 } |
374 } | 421 } |
375 } | 422 } |
376 | 423 |
377 void Constant() { | 424 void Constant() { |
378 // Constructor | 425 // Constructor |
379 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 426 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
380 Handle<i::Object> value = *vt; | 427 Handle<i::Object> value = *vt; |
381 CHECK(this->IsConstant(T.Constant(value))); | 428 TypeHandle type = T.Constant(value); |
| 429 CHECK(this->IsConstant(type)); |
382 } | 430 } |
383 | 431 |
384 // Value attribute | 432 // Value attribute |
385 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 433 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
386 Handle<i::Object> value = *vt; | 434 Handle<i::Object> value = *vt; |
387 CHECK(*value == *T.Constant(value)->AsConstant()); | 435 TypeHandle type = T.Constant(value); |
| 436 CHECK(*value == *type->AsConstant()); |
388 } | 437 } |
389 | 438 |
390 // Functionality & Injectivity | 439 // Functionality & Injectivity: Constant(V1) = Constant(v2) iff V1 = V2 |
391 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 440 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
392 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 441 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
393 Handle<i::Object> val1 = *vt1; | 442 Handle<i::Object> value1 = *vt1; |
394 Handle<i::Object> val2 = *vt2; | 443 Handle<i::Object> value2 = *vt2; |
395 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); | 444 TypeHandle type1 = T.Constant(value1); |
| 445 TypeHandle type2 = T.Constant(value2); |
| 446 CHECK(Equal(type1, type2) == (*value1 == *value2)); |
396 } | 447 } |
397 } | 448 } |
398 } | 449 } |
399 | 450 |
400 void Of() { | 451 void Of() { |
401 // Constant(V)->Is(Of(V)) for all V | 452 // Constant(V)->Is(Of(V)) |
402 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 453 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
403 Handle<i::Object> value = *vt; | 454 Handle<i::Object> value = *vt; |
404 CHECK(T.Constant(value)->Is(T.Of(value))); | 455 TypeHandle const_type = T.Constant(value); |
| 456 TypeHandle of_type = T.Of(value); |
| 457 CHECK(const_type->Is(of_type)); |
405 } | 458 } |
406 | 459 |
407 // Constant(V)->Is(T) implies Of(V)->Is(T) or T->Maybe(Constant(V)) | 460 // 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) { | 461 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
409 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 462 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
410 Handle<i::Object> value = *vt; | 463 Handle<i::Object> value = *vt; |
411 TypeHandle type = *it; | 464 TypeHandle type = *it; |
412 CHECK(!T.Constant(value)->Is(type) || | 465 TypeHandle const_type = T.Constant(value); |
413 T.Of(value)->Is(type) || type->Maybe(T.Constant(value))); | 466 TypeHandle of_type = T.Of(value); |
| 467 CHECK(const_type->Is(type) == |
| 468 (of_type->Is(type) || type->Maybe(const_type))); |
414 } | 469 } |
415 } | 470 } |
416 } | 471 } |
417 | 472 |
418 void NowOf() { | 473 void NowOf() { |
419 // Constant(V)->NowIs(NowOf(V)) for all V | 474 // Constant(V)->NowIs(NowOf(V)) |
420 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 475 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
421 Handle<i::Object> value = *vt; | 476 Handle<i::Object> value = *vt; |
422 CHECK(T.Constant(value)->NowIs(T.NowOf(value))); | 477 TypeHandle const_type = T.Constant(value); |
| 478 TypeHandle nowof_type = T.NowOf(value); |
| 479 CHECK(const_type->NowIs(nowof_type)); |
423 } | 480 } |
424 | 481 |
425 // NowOf(V)->Is(Of(V)) for all V | 482 // NowOf(V)->Is(Of(V)) |
426 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 483 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
427 Handle<i::Object> value = *vt; | 484 Handle<i::Object> value = *vt; |
428 CHECK(T.NowOf(value)->Is(T.Of(value))); | 485 TypeHandle nowof_type = T.NowOf(value); |
| 486 TypeHandle of_type = T.Of(value); |
| 487 CHECK(nowof_type->Is(of_type)); |
| 488 } |
| 489 |
| 490 // Constant(V)->NowIs(T) iff NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) |
| 491 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
| 492 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 493 Handle<i::Object> value = *vt; |
| 494 TypeHandle type = *it; |
| 495 TypeHandle const_type = T.Constant(value); |
| 496 TypeHandle nowof_type = T.NowOf(value); |
| 497 CHECK(const_type->NowIs(type) == |
| 498 (nowof_type->NowIs(type) || type->Maybe(const_type))); |
| 499 } |
429 } | 500 } |
430 | 501 |
431 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) | 502 // 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) { | 503 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
433 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 504 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
434 Handle<i::Object> value = *vt; | 505 Handle<i::Object> value = *vt; |
435 TypeHandle type = *it; | 506 TypeHandle type = *it; |
436 CHECK(!T.Constant(value)->Is(type) || | 507 TypeHandle const_type = T.Constant(value); |
437 T.NowOf(value)->Is(type) || type->Maybe(T.Constant(value))); | 508 TypeHandle nowof_type = T.NowOf(value); |
438 } | 509 CHECK(!const_type->Is(type) || |
439 } | 510 (nowof_type->Is(type) || type->Maybe(const_type))); |
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 } | 511 } |
449 } | 512 } |
450 } | 513 } |
451 | 514 |
452 void Is() { | 515 void Is() { |
453 // T->Is(None) implies T = None for all T | 516 // Least Element (Bottom): None->Is(T) |
| 517 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 518 TypeHandle type = *it; |
| 519 CHECK(T.None->Is(type)); |
| 520 } |
| 521 |
| 522 // Greatest Element (Top): T->Is(Any) |
| 523 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 524 TypeHandle type = *it; |
| 525 CHECK(type->Is(T.Any)); |
| 526 } |
| 527 |
| 528 // Bottom Uniqueness: T->Is(None) implies T = None |
454 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 529 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
455 TypeHandle type = *it; | 530 TypeHandle type = *it; |
456 if (type->Is(T.None)) CheckEqual(type, T.None); | 531 if (type->Is(T.None)) CheckEqual(type, T.None); |
457 } | 532 } |
458 | 533 |
459 // None->Is(T) for all T | 534 // 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) { | 535 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
467 TypeHandle type = *it; | 536 TypeHandle type = *it; |
468 if (T.Any->Is(type)) CheckEqual(type, T.Any); | 537 if (T.Any->Is(type)) CheckEqual(type, T.Any); |
469 } | 538 } |
470 | 539 |
471 // T->Is(Any) for all T | 540 // 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) { | 541 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
479 TypeHandle type = *it; | 542 TypeHandle type = *it; |
480 CHECK(type->Is(type)); | 543 CHECK(type->Is(type)); |
481 } | 544 } |
482 | 545 |
483 // Transitivity | 546 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) |
484 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 547 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
485 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 548 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
486 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 549 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
487 TypeHandle type1 = *it1; | 550 TypeHandle type1 = *it1; |
488 TypeHandle type2 = *it2; | 551 TypeHandle type2 = *it2; |
489 TypeHandle type3 = *it3; | 552 TypeHandle type3 = *it3; |
490 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); | 553 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); |
491 } | 554 } |
492 } | 555 } |
493 } | 556 } |
494 | 557 |
| 558 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 |
| 559 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 560 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 561 TypeHandle type1 = *it1; |
| 562 TypeHandle type2 = *it2; |
| 563 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); |
| 564 } |
| 565 } |
| 566 |
495 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 | 567 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 |
496 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 568 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
497 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 569 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
498 Handle<i::Object> val1 = *vt1; | 570 Handle<i::Object> value1 = *vt1; |
499 Handle<i::Object> val2 = *vt2; | 571 Handle<i::Object> value2 = *vt2; |
500 CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2)); | 572 TypeHandle const_type1 = T.Constant(value1); |
| 573 TypeHandle const_type2 = T.Constant(value2); |
| 574 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); |
501 } | 575 } |
502 } | 576 } |
503 | 577 |
504 // Class(M1)->Is(Class(M2)) iff M1 = M2 | 578 // Class(M1)->Is(Class(M2)) iff M1 = M2 |
505 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 579 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
506 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 580 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
507 Handle<i::Map> map1 = *mt1; | 581 Handle<i::Map> map1 = *mt1; |
508 Handle<i::Map> map2 = *mt2; | 582 Handle<i::Map> map2 = *mt2; |
509 CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2)); | 583 TypeHandle class_type1 = T.Class(map1); |
| 584 TypeHandle class_type2 = T.Class(map2); |
| 585 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); |
510 } | 586 } |
511 } | 587 } |
512 | 588 |
513 // Constant(V)->Is(Class(M)) for no V,M | 589 // Constant(V)->Is(Class(M)) never |
514 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 590 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
515 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 591 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
516 Handle<i::Map> map = *mt; | 592 Handle<i::Map> map = *mt; |
517 Handle<i::Object> value = *vt; | 593 Handle<i::Object> value = *vt; |
518 CHECK(!T.Constant(value)->Is(T.Class(map))); | 594 TypeHandle constant_type = T.Constant(value); |
| 595 TypeHandle class_type = T.Class(map); |
| 596 CHECK(!constant_type->Is(class_type)); |
519 } | 597 } |
520 } | 598 } |
521 | 599 |
522 // Class(M)->Is(Constant(V)) for no V,M | 600 // Class(M)->Is(Constant(V)) never |
523 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 601 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
524 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 602 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
525 Handle<i::Map> map = *mt; | 603 Handle<i::Map> map = *mt; |
526 Handle<i::Object> value = *vt; | 604 Handle<i::Object> value = *vt; |
527 CHECK(!T.Class(map)->Is(T.Constant(value))); | 605 TypeHandle constant_type = T.Constant(value); |
| 606 TypeHandle class_type = T.Class(map); |
| 607 CHECK(!class_type->Is(constant_type)); |
528 } | 608 } |
529 } | 609 } |
530 | 610 |
531 // Basic types | 611 // Basic types |
532 CheckUnordered(T.Boolean, T.Null); | 612 CheckUnordered(T.Boolean, T.Null); |
533 CheckUnordered(T.Undefined, T.Null); | 613 CheckUnordered(T.Undefined, T.Null); |
534 CheckUnordered(T.Boolean, T.Undefined); | 614 CheckUnordered(T.Boolean, T.Undefined); |
535 | 615 |
536 CheckSub(T.SignedSmall, T.Number); | 616 CheckSub(T.SignedSmall, T.Number); |
537 CheckSub(T.Signed32, T.Number); | 617 CheckSub(T.Signed32, T.Number); |
(...skipping 13 matching lines...) Expand all Loading... |
551 CheckUnordered(T.String, T.Symbol); | 631 CheckUnordered(T.String, T.Symbol); |
552 CheckUnordered(T.InternalizedString, T.Symbol); | 632 CheckUnordered(T.InternalizedString, T.Symbol); |
553 | 633 |
554 CheckSub(T.Object, T.Receiver); | 634 CheckSub(T.Object, T.Receiver); |
555 CheckSub(T.Array, T.Object); | 635 CheckSub(T.Array, T.Object); |
556 CheckSub(T.Function, T.Object); | 636 CheckSub(T.Function, T.Object); |
557 CheckSub(T.Proxy, T.Receiver); | 637 CheckSub(T.Proxy, T.Receiver); |
558 CheckUnordered(T.Object, T.Proxy); | 638 CheckUnordered(T.Object, T.Proxy); |
559 CheckUnordered(T.Array, T.Function); | 639 CheckUnordered(T.Array, T.Function); |
560 | 640 |
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 | 641 // Structural types |
569 CheckSub(T.ObjectClass, T.Object); | 642 CheckSub(T.ObjectClass, T.Object); |
570 CheckSub(T.ArrayClass, T.Object); | 643 CheckSub(T.ArrayClass, T.Object); |
| 644 CheckSub(T.UninitializedClass, T.Internal); |
571 CheckUnordered(T.ObjectClass, T.ArrayClass); | 645 CheckUnordered(T.ObjectClass, T.ArrayClass); |
| 646 CheckUnordered(T.UninitializedClass, T.Null); |
| 647 CheckUnordered(T.UninitializedClass, T.Undefined); |
572 | 648 |
573 CheckSub(T.SmiConstant, T.SignedSmall); | 649 CheckSub(T.SmiConstant, T.SignedSmall); |
574 CheckSub(T.SmiConstant, T.Signed32); | 650 CheckSub(T.SmiConstant, T.Signed32); |
575 CheckSub(T.SmiConstant, T.Number); | 651 CheckSub(T.SmiConstant, T.Number); |
576 CheckSub(T.ObjectConstant1, T.Object); | 652 CheckSub(T.ObjectConstant1, T.Object); |
577 CheckSub(T.ObjectConstant2, T.Object); | 653 CheckSub(T.ObjectConstant2, T.Object); |
578 CheckSub(T.ArrayConstant, T.Object); | 654 CheckSub(T.ArrayConstant, T.Object); |
579 CheckSub(T.ArrayConstant, T.Array); | 655 CheckSub(T.ArrayConstant, T.Array); |
| 656 CheckSub(T.UninitializedConstant, T.Internal); |
580 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); | 657 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); |
581 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); | 658 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); |
| 659 CheckUnordered(T.UninitializedConstant, T.Null); |
| 660 CheckUnordered(T.UninitializedConstant, T.Undefined); |
582 | 661 |
583 CheckUnordered(T.ObjectConstant1, T.ObjectClass); | 662 CheckUnordered(T.ObjectConstant1, T.ObjectClass); |
584 CheckUnordered(T.ObjectConstant2, T.ObjectClass); | 663 CheckUnordered(T.ObjectConstant2, T.ObjectClass); |
585 CheckUnordered(T.ObjectConstant1, T.ArrayClass); | 664 CheckUnordered(T.ObjectConstant1, T.ArrayClass); |
586 CheckUnordered(T.ObjectConstant2, T.ArrayClass); | 665 CheckUnordered(T.ObjectConstant2, T.ArrayClass); |
587 CheckUnordered(T.ArrayConstant, T.ObjectClass); | 666 CheckUnordered(T.ArrayConstant, T.ObjectClass); |
588 } | 667 } |
589 | 668 |
590 void NowIs() { | 669 void NowIs() { |
591 // T->NowIs(None) implies T = None for all T | 670 // Least Element (Bottom): None->NowIs(T) |
| 671 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 672 TypeHandle type = *it; |
| 673 CHECK(T.None->NowIs(type)); |
| 674 } |
| 675 |
| 676 // Greatest Element (Top): T->NowIs(Any) |
| 677 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 678 TypeHandle type = *it; |
| 679 CHECK(type->NowIs(T.Any)); |
| 680 } |
| 681 |
| 682 // Bottom Uniqueness: T->NowIs(None) implies T = None |
592 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 683 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
593 TypeHandle type = *it; | 684 TypeHandle type = *it; |
594 if (type->NowIs(T.None)) CheckEqual(type, T.None); | 685 if (type->NowIs(T.None)) CheckEqual(type, T.None); |
595 } | 686 } |
596 | 687 |
597 // None->NowIs(T) for all T | 688 // 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) { | 689 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
605 TypeHandle type = *it; | 690 TypeHandle type = *it; |
606 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); | 691 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); |
607 } | 692 } |
608 | 693 |
609 // T->NowIs(Any) for all T | 694 // 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) { | 695 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
617 TypeHandle type = *it; | 696 TypeHandle type = *it; |
618 CHECK(type->NowIs(type)); | 697 CHECK(type->NowIs(type)); |
619 } | 698 } |
620 | 699 |
621 // Transitivity | 700 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) |
622 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 701 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
623 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 702 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
624 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { | 703 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
625 TypeHandle type1 = *it1; | 704 TypeHandle type1 = *it1; |
626 TypeHandle type2 = *it2; | 705 TypeHandle type2 = *it2; |
627 TypeHandle type3 = *it3; | 706 TypeHandle type3 = *it3; |
628 CHECK(!type1->NowIs(type2) || | 707 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || |
629 !type2->NowIs(type3) || | |
630 type1->NowIs(type3)); | 708 type1->NowIs(type3)); |
631 } | 709 } |
632 } | 710 } |
633 } | 711 } |
634 | 712 |
635 // T1->Is(T2) implies T1->NowIs(T2) for all T1,T2 | 713 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 |
636 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 714 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
637 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 715 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
638 TypeHandle type1 = *it1; | 716 TypeHandle type1 = *it1; |
| 717 TypeHandle type2 = *it2; |
| 718 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == |
| 719 Equal(type1, type2)); |
| 720 } |
| 721 } |
| 722 |
| 723 // T1->Is(T2) implies T1->NowIs(T2) |
| 724 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 725 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 726 TypeHandle type1 = *it1; |
639 TypeHandle type2 = *it2; | 727 TypeHandle type2 = *it2; |
640 CHECK(!type1->Is(type2) || type1->NowIs(type2)); | 728 CHECK(!type1->Is(type2) || type1->NowIs(type2)); |
641 } | 729 } |
642 } | 730 } |
643 | 731 |
644 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 | 732 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 |
645 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 733 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
646 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 734 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
647 Handle<i::Object> val1 = *vt1; | 735 Handle<i::Object> value1 = *vt1; |
648 Handle<i::Object> val2 = *vt2; | 736 Handle<i::Object> value2 = *vt2; |
649 CHECK(T.Constant(val1)->NowIs(T.Constant(val2)) == (*val1 == *val2)); | 737 TypeHandle const_type1 = T.Constant(value1); |
| 738 TypeHandle const_type2 = T.Constant(value2); |
| 739 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2)); |
650 } | 740 } |
651 } | 741 } |
652 | 742 |
653 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 | 743 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 |
654 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 744 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
655 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 745 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
656 Handle<i::Map> map1 = *mt1; | 746 Handle<i::Map> map1 = *mt1; |
657 Handle<i::Map> map2 = *mt2; | 747 Handle<i::Map> map2 = *mt2; |
658 CHECK(T.Class(map1)->NowIs(T.Class(map2)) == (*map1 == *map2)); | 748 TypeHandle class_type1 = T.Class(map1); |
| 749 TypeHandle class_type2 = T.Class(map2); |
| 750 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2)); |
659 } | 751 } |
660 } | 752 } |
661 | 753 |
662 // Constant(V)->NowIs(Class(M)) iff V has map M | 754 // Constant(V)->NowIs(Class(M)) iff V has map M |
663 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 755 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
664 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 756 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
665 Handle<i::Map> map = *mt; | 757 Handle<i::Map> map = *mt; |
666 Handle<i::Object> value = *vt; | 758 Handle<i::Object> value = *vt; |
| 759 TypeHandle const_type = T.Constant(value); |
| 760 TypeHandle class_type = T.Class(map); |
667 CHECK((value->IsHeapObject() && | 761 CHECK((value->IsHeapObject() && |
668 i::HeapObject::cast(*value)->map() == *map) | 762 i::HeapObject::cast(*value)->map() == *map) |
669 == T.Constant(value)->NowIs(T.Class(map))); | 763 == const_type->NowIs(class_type)); |
670 } | 764 } |
671 } | 765 } |
672 | 766 |
673 // Class(M)->NowIs(Constant(V)) for no V,M | 767 // Class(M)->NowIs(Constant(V)) never |
674 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 768 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
675 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 769 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
676 Handle<i::Map> map = *mt; | 770 Handle<i::Map> map = *mt; |
677 Handle<i::Object> value = *vt; | 771 Handle<i::Object> value = *vt; |
678 CHECK(!T.Class(map)->NowIs(T.Constant(value))); | 772 TypeHandle const_type = T.Constant(value); |
| 773 TypeHandle class_type = T.Class(map); |
| 774 CHECK(!class_type->NowIs(const_type)); |
679 } | 775 } |
680 } | 776 } |
681 } | 777 } |
682 | 778 |
683 void Contains() { | 779 void Contains() { |
684 // T->Contains(V) iff Constant(V)->Is(T) for all T,V | 780 // T->Contains(V) iff Constant(V)->Is(T) |
685 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 781 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
686 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 782 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
687 TypeHandle type = *it; | 783 TypeHandle type = *it; |
688 Handle<i::Object> value = *vt; | 784 Handle<i::Object> value = *vt; |
689 CHECK(type->Contains(value) == T.Constant(value)->Is(type)); | 785 TypeHandle const_type = T.Constant(value); |
| 786 CHECK(type->Contains(value) == const_type->Is(type)); |
690 } | 787 } |
691 } | 788 } |
692 | 789 |
693 // Of(V)->Is(T) implies T->Contains(V) for all T,V | 790 // Of(V)->Is(T) implies T->Contains(V) |
694 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 791 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
695 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 792 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
696 TypeHandle type = *it; | 793 TypeHandle type = *it; |
697 Handle<i::Object> value = *vt; | 794 Handle<i::Object> value = *vt; |
698 CHECK(!T.Of(value)->Is(type) || type->Contains(value)); | 795 TypeHandle of_type = T.Of(value); |
| 796 CHECK(!of_type->Is(type) || type->Contains(value)); |
699 } | 797 } |
700 } | 798 } |
701 } | 799 } |
702 | 800 |
703 void NowContains() { | 801 void NowContains() { |
704 // T->NowContains(V) iff Constant(V)->NowIs(T) for all T,V | 802 // T->NowContains(V) iff Constant(V)->NowIs(T) |
705 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 803 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
706 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 804 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
707 TypeHandle type = *it; | 805 TypeHandle type = *it; |
708 Handle<i::Object> value = *vt; | 806 Handle<i::Object> value = *vt; |
709 CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type)); | 807 TypeHandle const_type = T.Constant(value); |
| 808 CHECK(type->NowContains(value) == const_type->NowIs(type)); |
710 } | 809 } |
711 } | 810 } |
712 | 811 |
713 // T->Contains(V) implies T->NowContains(V) for all T,V | 812 // T->Contains(V) implies T->NowContains(V) |
714 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 813 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
715 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 814 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
716 TypeHandle type = *it; | 815 TypeHandle type = *it; |
717 Handle<i::Object> value = *vt; | 816 Handle<i::Object> value = *vt; |
718 CHECK(!type->Contains(value) || type->NowContains(value)); | 817 CHECK(!type->Contains(value) || type->NowContains(value)); |
719 } | 818 } |
720 } | 819 } |
721 | 820 |
722 // NowOf(V)->Is(T) implies T->NowContains(V) for all T,V | 821 // NowOf(V)->Is(T) implies T->NowContains(V) |
723 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 822 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
724 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 823 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
725 TypeHandle type = *it; | 824 TypeHandle type = *it; |
726 Handle<i::Object> value = *vt; | 825 Handle<i::Object> value = *vt; |
727 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 826 TypeHandle nowof_type = T.Of(value); |
| 827 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); |
728 } | 828 } |
729 } | 829 } |
730 | 830 |
731 // NowOf(V)->NowIs(T) implies T->NowContains(V) for all T,V | 831 // NowOf(V)->NowIs(T) implies T->NowContains(V) |
732 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 832 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
733 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 833 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
734 TypeHandle type = *it; | 834 TypeHandle type = *it; |
735 Handle<i::Object> value = *vt; | 835 Handle<i::Object> value = *vt; |
736 CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value)); | 836 TypeHandle nowof_type = T.Of(value); |
| 837 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); |
737 } | 838 } |
738 } | 839 } |
739 } | 840 } |
740 | 841 |
741 void Maybe() { | 842 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 | 843 // T->Maybe(Any) iff T inhabited |
749 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 844 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
750 TypeHandle type = *it; | 845 TypeHandle type = *it; |
751 CHECK(type->Maybe(T.Any) == type->IsInhabited()); | 846 CHECK(type->Maybe(T.Any) == type->IsInhabited()); |
752 } | 847 } |
753 | 848 |
754 // T->Maybe(None) never | 849 // T->Maybe(None) never |
755 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 850 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
756 TypeHandle type = *it; | 851 TypeHandle type = *it; |
757 CHECK(!type->Maybe(T.None)); | 852 CHECK(!type->Maybe(T.None)); |
758 } | 853 } |
759 | 854 |
760 // Symmetry | 855 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited |
| 856 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 857 TypeHandle type = *it; |
| 858 CHECK(type->Maybe(type) == type->IsInhabited()); |
| 859 } |
| 860 |
| 861 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) |
761 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 862 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
762 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 863 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
763 TypeHandle type1 = *it1; | 864 TypeHandle type1 = *it1; |
764 TypeHandle type2 = *it2; | 865 TypeHandle type2 = *it2; |
765 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); | 866 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); |
766 } | 867 } |
767 } | 868 } |
768 | 869 |
769 // T1->Maybe(T2) only if T1, T2 inhabited | 870 // T1->Maybe(T2) implies T1, T2 inhabited |
770 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 871 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
771 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 872 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
772 TypeHandle type1 = *it1; | 873 TypeHandle type1 = *it1; |
773 TypeHandle type2 = *it2; | 874 TypeHandle type2 = *it2; |
774 CHECK(!type1->Maybe(type2) || | 875 CHECK(!type1->Maybe(type2) || |
775 (type1->IsInhabited() && type2->IsInhabited())); | 876 (type1->IsInhabited() && type2->IsInhabited())); |
776 } | 877 } |
777 } | 878 } |
778 | 879 |
779 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) for all T1,T2 | 880 // T1->Maybe(T2) iff Intersect(T1, T2) inhabited |
780 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 881 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
781 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 882 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
782 TypeHandle type1 = *it1; | 883 TypeHandle type1 = *it1; |
| 884 TypeHandle type2 = *it2; |
| 885 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 886 CHECK(type1->Maybe(type2) == intersect12->IsInhabited()); |
| 887 } |
| 888 } |
| 889 |
| 890 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) |
| 891 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 892 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 893 TypeHandle type1 = *it1; |
783 TypeHandle type2 = *it2; | 894 TypeHandle type2 = *it2; |
784 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || | 895 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || |
785 type1->Maybe(type2)); | 896 type1->Maybe(type2)); |
786 } | 897 } |
787 } | 898 } |
788 | 899 |
789 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 | 900 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 |
790 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { | 901 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { |
791 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { | 902 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { |
792 Handle<i::Object> val1 = *vt1; | 903 Handle<i::Object> value1 = *vt1; |
793 Handle<i::Object> val2 = *vt2; | 904 Handle<i::Object> value2 = *vt2; |
794 CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2)); | 905 TypeHandle const_type1 = T.Constant(value1); |
| 906 TypeHandle const_type2 = T.Constant(value2); |
| 907 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); |
795 } | 908 } |
796 } | 909 } |
797 | 910 |
798 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 | 911 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 |
799 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { | 912 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { |
800 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { | 913 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { |
801 Handle<i::Map> map1 = *mt1; | 914 Handle<i::Map> map1 = *mt1; |
802 Handle<i::Map> map2 = *mt2; | 915 Handle<i::Map> map2 = *mt2; |
803 CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2)); | 916 TypeHandle class_type1 = T.Class(map1); |
| 917 TypeHandle class_type2 = T.Class(map2); |
| 918 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); |
804 } | 919 } |
805 } | 920 } |
806 | 921 |
807 // Constant(V)->Maybe(Class(M)) for no V,M | 922 // Constant(V)->Maybe(Class(M)) never |
808 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 923 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
809 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 924 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
810 Handle<i::Map> map = *mt; | 925 Handle<i::Map> map = *mt; |
811 Handle<i::Object> value = *vt; | 926 Handle<i::Object> value = *vt; |
812 CHECK(!T.Constant(value)->Maybe(T.Class(map))); | 927 TypeHandle const_type = T.Constant(value); |
| 928 TypeHandle class_type = T.Class(map); |
| 929 CHECK(!const_type->Maybe(class_type)); |
813 } | 930 } |
814 } | 931 } |
815 | 932 |
816 // Class(M)->Maybe(Constant(V)) for no V,M | 933 // Class(M)->Maybe(Constant(V)) never |
817 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 934 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { |
818 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { | 935 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { |
819 Handle<i::Map> map = *mt; | 936 Handle<i::Map> map = *mt; |
820 Handle<i::Object> value = *vt; | 937 Handle<i::Object> value = *vt; |
821 CHECK(!T.Class(map)->Maybe(T.Constant(value))); | 938 TypeHandle const_type = T.Constant(value); |
| 939 TypeHandle class_type = T.Class(map); |
| 940 CHECK(!class_type->Maybe(const_type)); |
822 } | 941 } |
823 } | 942 } |
824 | 943 |
825 // Basic types | 944 // Basic types |
826 CheckDisjoint(T.Boolean, T.Null, T.Semantic); | 945 CheckDisjoint(T.Boolean, T.Null, T.Semantic); |
827 CheckDisjoint(T.Undefined, T.Null, T.Semantic); | 946 CheckDisjoint(T.Undefined, T.Null, T.Semantic); |
828 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic); | 947 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic); |
829 | 948 |
830 CheckOverlap(T.SignedSmall, T.Number, T.Semantic); | 949 CheckOverlap(T.SignedSmall, T.Number, T.Semantic); |
831 CheckOverlap(T.Float, T.Number, T.Semantic); | 950 CheckOverlap(T.Float, T.Number, T.Semantic); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); | 988 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); |
870 | 989 |
871 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); | 990 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); |
872 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); | 991 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); |
873 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); | 992 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); |
874 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); | 993 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); |
875 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); | 994 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); |
876 } | 995 } |
877 | 996 |
878 void Union() { | 997 void Union() { |
879 // Bitset-bitset | 998 // Identity: Union(T, None) = T |
880 CHECK(this->IsBitset(T.Union(T.Object, T.Number))); | 999 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
881 CHECK(this->IsBitset(T.Union(T.Object, T.Object))); | 1000 TypeHandle type = *it; |
882 CHECK(this->IsBitset(T.Union(T.Any, T.None))); | 1001 TypeHandle union_type = T.Union(type, T.None); |
| 1002 CheckEqual(union_type, type); |
| 1003 } |
883 | 1004 |
884 CheckEqual(T.Union(T.None, T.Number), T.Number); | 1005 // Domination: Union(T, Any) = Any |
885 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); | 1006 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)); | 1007 TypeHandle type = *it; |
887 CheckSub(T.Union(T.Number, T.String), T.Any); | 1008 TypeHandle union_type = T.Union(type, T.Any); |
| 1009 CheckEqual(union_type, T.Any); |
| 1010 } |
| 1011 |
| 1012 // Idempotence: Union(T, T) = T |
| 1013 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
| 1014 TypeHandle type = *it; |
| 1015 TypeHandle union_type = T.Union(type, type); |
| 1016 CheckEqual(union_type, type); |
| 1017 } |
| 1018 |
| 1019 // Commutativity: Union(T1, T2) = Union(T2, T1) |
| 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 TypeHandle type1 = *it1; |
| 1023 TypeHandle type2 = *it2; |
| 1024 TypeHandle union12 = T.Union(type1, type2); |
| 1025 TypeHandle union21 = T.Union(type2, type1); |
| 1026 CheckEqual(union12, union21); |
| 1027 } |
| 1028 } |
| 1029 |
| 1030 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) |
| 1031 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1032 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1033 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1034 TypeHandle type1 = *it1; |
| 1035 TypeHandle type2 = *it2; |
| 1036 TypeHandle type3 = *it3; |
| 1037 TypeHandle union12 = T.Union(type1, type2); |
| 1038 TypeHandle union23 = T.Union(type2, type3); |
| 1039 TypeHandle union1_23 = T.Union(type1, union23); |
| 1040 TypeHandle union12_3 = T.Union(union12, type3); |
| 1041 CheckEqual(union1_23, union12_3); |
| 1042 } |
| 1043 } |
| 1044 } |
| 1045 |
| 1046 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) |
| 1047 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1048 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1049 TypeHandle type1 = *it1; |
| 1050 TypeHandle type2 = *it2; |
| 1051 TypeHandle union12 = T.Union(type1, type2); |
| 1052 CHECK(type1->Is(union12)); |
| 1053 CHECK(type2->Is(union12)); |
| 1054 } |
| 1055 } |
| 1056 |
| 1057 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 |
| 1058 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1059 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1060 TypeHandle type1 = *it1; |
| 1061 TypeHandle type2 = *it2; |
| 1062 TypeHandle union12 = T.Union(type1, type2); |
| 1063 if (type1->Is(type2)) CheckEqual(union12, type2); |
| 1064 } |
| 1065 } |
| 1066 |
| 1067 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) |
| 1068 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1069 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1070 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1071 TypeHandle type1 = *it1; |
| 1072 TypeHandle type2 = *it2; |
| 1073 TypeHandle type3 = *it3; |
| 1074 TypeHandle union13 = T.Union(type1, type3); |
| 1075 TypeHandle union23 = T.Union(type2, type3); |
| 1076 CHECK(!type1->Is(type2) || union13->Is(union23)); |
| 1077 } |
| 1078 } |
| 1079 } |
| 1080 |
| 1081 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) |
| 1082 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1083 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1084 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1085 TypeHandle type1 = *it1; |
| 1086 TypeHandle type2 = *it2; |
| 1087 TypeHandle type3 = *it3; |
| 1088 TypeHandle union12 = T.Union(type1, type2); |
| 1089 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); |
| 1090 } |
| 1091 } |
| 1092 } |
| 1093 |
| 1094 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) |
| 1095 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1096 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1097 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1098 TypeHandle type1 = *it1; |
| 1099 TypeHandle type2 = *it2; |
| 1100 TypeHandle type3 = *it3; |
| 1101 TypeHandle union23 = T.Union(type2, type3); |
| 1102 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); |
| 1103 } |
| 1104 } |
| 1105 } |
888 | 1106 |
889 // Class-class | 1107 // 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); | 1108 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); |
899 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); | 1109 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); |
900 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); | 1110 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); |
901 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); | 1111 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); |
902 | 1112 |
903 // Constant-constant | 1113 // 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); | 1114 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); |
| 1115 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); |
917 CheckUnordered( | 1116 CheckUnordered( |
918 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); | 1117 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); |
919 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); | |
920 CheckOverlap( | 1118 CheckOverlap( |
921 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); | 1119 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); |
922 CheckDisjoint( | 1120 CheckDisjoint( |
923 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); | 1121 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); |
924 CheckDisjoint( | 1122 CheckDisjoint( |
925 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, | 1123 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); |
926 T.Semantic); | |
927 | 1124 |
928 // Bitset-class | 1125 // 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( | 1126 CheckSub( |
936 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); | 1127 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); |
937 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); | 1128 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); |
938 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); | 1129 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); |
939 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); | 1130 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); |
940 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); | 1131 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); |
941 | 1132 |
942 // Bitset-constant | 1133 // 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( | 1134 CheckSub( |
952 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); | 1135 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); |
953 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); | 1136 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); |
954 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); | 1137 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); |
955 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); | 1138 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); |
956 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); | 1139 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); |
957 CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); | |
958 | 1140 |
959 // Class-constant | 1141 // 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); | 1142 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)); | 1143 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); |
969 CheckSub( | 1144 CheckSub( |
970 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); | 1145 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); |
971 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); | 1146 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); |
972 CheckDisjoint( | 1147 CheckDisjoint( |
973 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, | 1148 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, |
974 T.Semantic); | 1149 T.Semantic); |
975 CheckDisjoint( | 1150 CheckDisjoint( |
976 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); | 1151 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); |
977 | 1152 |
978 // Bitset-union | 1153 // 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( | 1154 CheckSub( |
991 T.Float, | 1155 T.Float, |
992 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); | 1156 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); |
993 CheckSub( | 1157 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), | 1158 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), |
1004 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); | 1159 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); |
1005 | 1160 |
1006 // Class-union | 1161 // 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( | 1162 CheckSub( |
1022 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1163 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1023 T.Object); | 1164 T.Object); |
1024 CheckEqual( | 1165 CheckEqual( |
1025 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), | 1166 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), |
1026 T.Union(T.ArrayClass, T.ObjectConstant2)); | 1167 T.Union(T.ArrayClass, T.ObjectConstant2)); |
1027 | 1168 |
1028 // Constant-union | 1169 // 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( | 1170 CheckEqual( |
1037 T.Union( | 1171 T.Union( |
1038 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1172 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1039 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1173 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1040 CheckEqual( | 1174 CheckEqual( |
1041 T.Union( | 1175 T.Union( |
1042 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), | 1176 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), |
1043 T.Union( | 1177 T.Union( |
1044 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); | 1178 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); |
1045 | 1179 |
1046 // Union-union | 1180 // 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( | 1181 CheckEqual( |
1055 T.Union( | 1182 T.Union( |
1056 T.Union(T.ObjectConstant2, T.ObjectConstant1), | 1183 T.Union(T.ObjectConstant2, T.ObjectConstant1), |
1057 T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1184 T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1058 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1185 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1059 CheckEqual( | 1186 CheckEqual( |
1060 T.Union( | 1187 T.Union( |
1061 T.Union(T.Number, T.ArrayClass), | 1188 T.Union(T.Number, T.ArrayClass), |
1062 T.Union(T.SignedSmall, T.Array)), | 1189 T.Union(T.SignedSmall, T.Array)), |
1063 T.Union(T.Number, T.Array)); | 1190 T.Union(T.Number, T.Array)); |
1064 } | 1191 } |
1065 | 1192 |
1066 void Intersect() { | 1193 void Intersect() { |
1067 // Bitset-bitset | 1194 // Identity: Intersect(T, Any) = T |
1068 CHECK(this->IsBitset(T.Intersect(T.Object, T.Number))); | 1195 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1069 CHECK(this->IsBitset(T.Intersect(T.Object, T.Object))); | 1196 TypeHandle type = *it; |
1070 CHECK(this->IsBitset(T.Intersect(T.Any, T.None))); | 1197 TypeHandle intersect_type = T.Intersect(type, T.Any); |
| 1198 CheckEqual(intersect_type, type); |
| 1199 } |
1071 | 1200 |
1072 CheckEqual(T.Intersect(T.None, T.Number), T.None); | 1201 // Domination: Intersect(T, None) = None |
1073 CheckSub(T.Intersect(T.Object, T.Proxy), T.Representation); | 1202 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)); | 1203 TypeHandle type = *it; |
1075 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); | 1204 TypeHandle intersect_type = T.Intersect(type, T.None); |
| 1205 CheckEqual(intersect_type, T.None); |
| 1206 } |
1076 | 1207 |
1077 // Class-class | 1208 // Idempotence: Intersect(T, T) = T |
1078 CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.ObjectClass))); | 1209 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1079 CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.ArrayClass))); | 1210 TypeHandle type = *it; |
| 1211 TypeHandle intersect_type = T.Intersect(type, type); |
| 1212 CheckEqual(intersect_type, type); |
| 1213 } |
1080 | 1214 |
1081 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); | 1215 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) |
1082 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); | 1216 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1217 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1218 TypeHandle type1 = *it1; |
| 1219 TypeHandle type2 = *it2; |
| 1220 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1221 TypeHandle intersect21 = T.Intersect(type2, type1); |
| 1222 CheckEqual(intersect12, intersect21); |
| 1223 } |
| 1224 } |
1083 | 1225 |
1084 // Constant-constant | 1226 // Associativity: |
1085 CHECK(this->IsConstant(T.Intersect(T.ObjectConstant1, T.ObjectConstant1))); | 1227 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) |
1086 CHECK(this->IsBitset(T.Intersect(T.ObjectConstant1, T.ObjectConstant2))); | 1228 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1229 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1230 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1231 TypeHandle type1 = *it1; |
| 1232 TypeHandle type2 = *it2; |
| 1233 TypeHandle type3 = *it3; |
| 1234 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1235 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1236 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); |
| 1237 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); |
| 1238 CheckEqual(intersect1_23, intersect12_3); |
| 1239 } |
| 1240 } |
| 1241 } |
1087 | 1242 |
1088 CheckEqual( | 1243 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) |
1089 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); | 1244 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
1090 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); | 1245 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1246 TypeHandle type1 = *it1; |
| 1247 TypeHandle type2 = *it2; |
| 1248 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1249 CHECK(intersect12->Is(type1)); |
| 1250 CHECK(intersect12->Is(type2)); |
| 1251 } |
| 1252 } |
| 1253 |
| 1254 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 |
| 1255 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1256 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1257 TypeHandle type1 = *it1; |
| 1258 TypeHandle type2 = *it2; |
| 1259 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1260 if (type1->Is(type2)) CheckEqual(intersect12, type1); |
| 1261 } |
| 1262 } |
| 1263 |
| 1264 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) |
| 1265 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1266 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1267 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1268 TypeHandle type1 = *it1; |
| 1269 TypeHandle type2 = *it2; |
| 1270 TypeHandle type3 = *it3; |
| 1271 TypeHandle intersect13 = T.Intersect(type1, type3); |
| 1272 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1273 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); |
| 1274 } |
| 1275 } |
| 1276 } |
| 1277 |
| 1278 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) |
| 1279 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1280 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1281 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1282 TypeHandle type1 = *it1; |
| 1283 TypeHandle type2 = *it2; |
| 1284 TypeHandle type3 = *it3; |
| 1285 TypeHandle intersect12 = T.Intersect(type1, type2); |
| 1286 CHECK(!(type1->Is(type3) || type2->Is(type3)) || |
| 1287 intersect12->Is(type3)); |
| 1288 } |
| 1289 } |
| 1290 } |
| 1291 |
| 1292 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) |
| 1293 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { |
| 1294 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { |
| 1295 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { |
| 1296 TypeHandle type1 = *it1; |
| 1297 TypeHandle type2 = *it2; |
| 1298 TypeHandle type3 = *it3; |
| 1299 TypeHandle intersect23 = T.Intersect(type2, type3); |
| 1300 CHECK(!(type1->Is(type2) && type1->Is(type3)) || |
| 1301 type1->Is(intersect23)); |
| 1302 } |
| 1303 } |
| 1304 } |
1091 | 1305 |
1092 // Bitset-class | 1306 // 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); | 1307 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); |
1097 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); | 1308 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); |
1098 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); | 1309 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); |
1099 | 1310 |
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 | 1311 // 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); | 1312 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); |
1114 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); | 1313 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); |
1115 | 1314 |
1116 // Bitset-union | 1315 // 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( | 1316 CheckEqual( |
1123 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), | 1317 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), |
1124 T.Union(T.ObjectConstant1, T.ObjectClass)); | 1318 T.Union(T.ObjectConstant1, T.ObjectClass)); |
1125 CheckEqual( | 1319 CheckEqual( |
1126 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), | 1320 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), |
1127 T.None); | 1321 T.None); |
1128 | 1322 |
1129 // Class-union | 1323 // 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( | 1324 CheckEqual( |
1138 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), | 1325 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), |
1139 T.ArrayClass); | 1326 T.ArrayClass); |
1140 CheckEqual( | 1327 CheckEqual( |
1141 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), | 1328 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), |
1142 T.ArrayClass); | 1329 T.ArrayClass); |
1143 CheckEqual( | 1330 CheckEqual( |
1144 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), | 1331 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), |
1145 T.None); | 1332 T.None); |
1146 | 1333 |
1147 // Constant-union | 1334 // 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( | 1335 CheckEqual( |
1156 T.Intersect( | 1336 T.Intersect( |
1157 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), | 1337 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), |
1158 T.ObjectConstant1); | 1338 T.ObjectConstant1); |
1159 CheckEqual( | 1339 CheckEqual( |
1160 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), | 1340 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), |
1161 T.SmiConstant); | 1341 T.SmiConstant); |
1162 CheckEqual( | 1342 CheckEqual( |
1163 T.Intersect( | 1343 T.Intersect( |
1164 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), | 1344 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), |
1165 T.None); | 1345 T.None); |
1166 | 1346 |
1167 // Union-union | 1347 // 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( | 1348 CheckEqual( |
1174 T.Intersect( | 1349 T.Intersect( |
1175 T.Union(T.Number, T.ArrayClass), | 1350 T.Union(T.Number, T.ArrayClass), |
1176 T.Union(T.SignedSmall, T.Array)), | 1351 T.Union(T.SignedSmall, T.Array)), |
1177 T.Union(T.SignedSmall, T.ArrayClass)); | 1352 T.Union(T.SignedSmall, T.ArrayClass)); |
1178 CheckEqual( | 1353 CheckEqual( |
1179 T.Intersect( | 1354 T.Intersect( |
1180 T.Union(T.Number, T.ObjectClass), | 1355 T.Union(T.Number, T.ObjectClass), |
1181 T.Union(T.Signed32, T.Array)), | 1356 T.Union(T.Signed32, T.Array)), |
1182 T.Signed32); | 1357 T.Signed32); |
(...skipping 10 matching lines...) Expand all Loading... |
1193 T.ObjectConstant1, | 1368 T.ObjectConstant1, |
1194 T.Union(T.ArrayConstant, T.ObjectConstant2))), | 1369 T.Union(T.ArrayConstant, T.ObjectConstant2))), |
1195 T.Union(T.ObjectConstant2, T.ObjectConstant1)); | 1370 T.Union(T.ObjectConstant2, T.ObjectConstant1)); |
1196 } | 1371 } |
1197 | 1372 |
1198 template<class Type2, class TypeHandle2, class Region2, class Rep2> | 1373 template<class Type2, class TypeHandle2, class Region2, class Rep2> |
1199 void Convert() { | 1374 void Convert() { |
1200 Types<Type2, TypeHandle2, Region2> T2( | 1375 Types<Type2, TypeHandle2, Region2> T2( |
1201 Rep2::ToRegion(&zone, isolate), isolate); | 1376 Rep2::ToRegion(&zone, isolate), isolate); |
1202 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 1377 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { |
1203 TypeHandle type = *it; | 1378 TypeHandle type1 = *it; |
1204 CheckEqual(type, | 1379 TypeHandle2 type2 = T2.template Convert<Type>(type1); |
1205 T.template Convert<Type2>(T2.template Convert<Type>(type))); | 1380 TypeHandle type3 = T.template Convert<Type2>(type2); |
| 1381 CheckEqual(type1, type3); |
1206 } | 1382 } |
1207 } | 1383 } |
1208 }; | 1384 }; |
1209 | 1385 |
1210 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; | 1386 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; |
1211 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; | 1387 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; |
1212 | 1388 |
1213 | 1389 |
1214 TEST(Bitset) { | 1390 TEST(Bitset) { |
1215 CcTest::InitializeVM(); | 1391 CcTest::InitializeVM(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 ZoneTests().Intersect(); | 1469 ZoneTests().Intersect(); |
1294 HeapTests().Intersect(); | 1470 HeapTests().Intersect(); |
1295 } | 1471 } |
1296 | 1472 |
1297 | 1473 |
1298 TEST(Convert) { | 1474 TEST(Convert) { |
1299 CcTest::InitializeVM(); | 1475 CcTest::InitializeVM(); |
1300 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); | 1476 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); |
1301 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); | 1477 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); |
1302 } | 1478 } |
OLD | NEW |