| 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 |