1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include <vector> 29 30 #include "src/hydrogen-types.h" 31 #include "src/types.h" 32 #include "src/utils/random-number-generator.h" 33 #include "test/cctest/cctest.h" 34 35 using namespace v8::internal; 36 37 // Testing auxiliaries (breaking the Type abstraction). 38 struct ZoneRep { 39 typedef void* Struct; 40 41 static bool IsStruct(Type* t, int tag) { 42 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; 43 } 44 static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } 45 static bool IsClass(Type* t) { return IsStruct(t, 0); } 46 static bool IsConstant(Type* t) { return IsStruct(t, 1); } 47 static bool IsContext(Type* t) { return IsStruct(t, 2); } 48 static bool IsArray(Type* t) { return IsStruct(t, 3); } 49 static bool IsFunction(Type* t) { return IsStruct(t, 4); } 50 static bool IsUnion(Type* t) { return IsStruct(t, 5); } 51 52 static Struct* AsStruct(Type* t) { 53 return reinterpret_cast<Struct*>(t); 54 } 55 static int AsBitset(Type* t) { 56 return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); 57 } 58 static Map* AsClass(Type* t) { 59 return *static_cast<Map**>(AsStruct(t)[3]); 60 } 61 static Object* AsConstant(Type* t) { 62 return *static_cast<Object**>(AsStruct(t)[3]); 63 } 64 static Type* AsContext(Type* t) { 65 return *static_cast<Type**>(AsStruct(t)[2]); 66 } 67 static Struct* AsUnion(Type* t) { 68 return AsStruct(t); 69 } 70 static int Length(Struct* structured) { 71 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); 72 } 73 74 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } 75 76 struct BitsetType : Type::BitsetType { 77 using Type::BitsetType::New; 78 using Type::BitsetType::Glb; 79 using Type::BitsetType::Lub; 80 using Type::BitsetType::InherentLub; 81 }; 82 }; 83 84 85 struct HeapRep { 86 typedef FixedArray Struct; 87 88 static bool IsStruct(Handle<HeapType> t, int tag) { 89 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; 90 } 91 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } 92 static bool IsClass(Handle<HeapType> t) { 93 return t->IsMap() || IsStruct(t, 0); 94 } 95 static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); } 96 static bool IsContext(Handle<HeapType> t) { return IsStruct(t, 2); } 97 static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 3); } 98 static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 4); } 99 static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 5); } 100 101 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } 102 static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } 103 static Map* AsClass(Handle<HeapType> t) { 104 return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2)); 105 } 106 static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); } 107 static HeapType* AsContext(Handle<HeapType> t) { 108 return HeapType::cast(AsStruct(t)->get(1)); 109 } 110 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } 111 static int Length(Struct* structured) { return structured->length() - 1; } 112 113 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } 114 115 struct BitsetType : HeapType::BitsetType { 116 using HeapType::BitsetType::New; 117 using HeapType::BitsetType::Glb; 118 using HeapType::BitsetType::Lub; 119 using HeapType::BitsetType::InherentLub; 120 static int Glb(Handle<HeapType> type) { return Glb(*type); } 121 static int Lub(Handle<HeapType> type) { return Lub(*type); } 122 static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); } 123 }; 124 }; 125 126 127 template<class Type, class TypeHandle, class Region> 128 class Types { 129 public: 130 Types(Region* region, Isolate* isolate) : region_(region) { 131 #define DECLARE_TYPE(name, value) \ 132 name = Type::name(region); \ 133 types.push_back(name); 134 BITSET_TYPE_LIST(DECLARE_TYPE) 135 #undef DECLARE_TYPE 136 137 object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize); 138 array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize); 139 uninitialized_map = isolate->factory()->uninitialized_map(); 140 ObjectClass = Type::Class(object_map, region); 141 ArrayClass = Type::Class(array_map, region); 142 UninitializedClass = Type::Class(uninitialized_map, region); 143 144 maps.push_back(object_map); 145 maps.push_back(array_map); 146 maps.push_back(uninitialized_map); 147 for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) { 148 types.push_back(Type::Class(*it, region)); 149 } 150 151 smi = handle(Smi::FromInt(666), isolate); 152 signed32 = isolate->factory()->NewHeapNumber(0x40000000); 153 object1 = isolate->factory()->NewJSObjectFromMap(object_map); 154 object2 = isolate->factory()->NewJSObjectFromMap(object_map); 155 array = isolate->factory()->NewJSArray(20); 156 uninitialized = isolate->factory()->uninitialized_value(); 157 SmiConstant = Type::Constant(smi, region); 158 Signed32Constant = Type::Constant(signed32, region); 159 ObjectConstant1 = Type::Constant(object1, region); 160 ObjectConstant2 = Type::Constant(object2, region); 161 ArrayConstant = Type::Constant(array, region); 162 UninitializedConstant = Type::Constant(uninitialized, region); 163 164 values.push_back(smi); 165 values.push_back(signed32); 166 values.push_back(object1); 167 values.push_back(object2); 168 values.push_back(array); 169 values.push_back(uninitialized); 170 for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) { 171 types.push_back(Type::Constant(*it, region)); 172 } 173 174 NumberArray = Type::Array(Number, region); 175 StringArray = Type::Array(String, region); 176 AnyArray = Type::Array(Any, region); 177 178 SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region); 179 NumberFunction1 = Type::Function(Number, Number, region); 180 NumberFunction2 = Type::Function(Number, Number, Number, region); 181 MethodFunction = Type::Function(String, Object, 0, region); 182 183 for (int i = 0; i < 50; ++i) { 184 types.push_back(Fuzz()); 185 } 186 } 187 188 Handle<i::Map> object_map; 189 Handle<i::Map> array_map; 190 Handle<i::Map> uninitialized_map; 191 192 Handle<i::Smi> smi; 193 Handle<i::HeapNumber> signed32; 194 Handle<i::JSObject> object1; 195 Handle<i::JSObject> object2; 196 Handle<i::JSArray> array; 197 Handle<i::Oddball> uninitialized; 198 199 #define DECLARE_TYPE(name, value) TypeHandle name; 200 BITSET_TYPE_LIST(DECLARE_TYPE) 201 #undef DECLARE_TYPE 202 203 TypeHandle ObjectClass; 204 TypeHandle ArrayClass; 205 TypeHandle UninitializedClass; 206 207 TypeHandle SmiConstant; 208 TypeHandle Signed32Constant; 209 TypeHandle ObjectConstant1; 210 TypeHandle ObjectConstant2; 211 TypeHandle ArrayConstant; 212 TypeHandle UninitializedConstant; 213 214 TypeHandle NumberArray; 215 TypeHandle StringArray; 216 TypeHandle AnyArray; 217 218 TypeHandle SignedFunction1; 219 TypeHandle NumberFunction1; 220 TypeHandle NumberFunction2; 221 TypeHandle MethodFunction; 222 223 typedef std::vector<TypeHandle> TypeVector; 224 typedef std::vector<Handle<i::Map> > MapVector; 225 typedef std::vector<Handle<i::Object> > ValueVector; 226 TypeVector types; 227 MapVector maps; 228 ValueVector values; 229 230 TypeHandle Of(Handle<i::Object> value) { 231 return Type::Of(value, region_); 232 } 233 234 TypeHandle NowOf(Handle<i::Object> value) { 235 return Type::NowOf(value, region_); 236 } 237 238 TypeHandle Constant(Handle<i::Object> value) { 239 return Type::Constant(value, region_); 240 } 241 242 TypeHandle Class(Handle<i::Map> map) { 243 return Type::Class(map, region_); 244 } 245 246 TypeHandle Array1(TypeHandle element) { 247 return Type::Array(element, region_); 248 } 249 250 TypeHandle Function0(TypeHandle result, TypeHandle receiver) { 251 return Type::Function(result, receiver, 0, region_); 252 } 253 254 TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) { 255 TypeHandle type = Type::Function(result, receiver, 1, region_); 256 type->AsFunction()->InitParameter(0, arg); 257 return type; 258 } 259 260 TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) { 261 return Type::Function(result, arg1, arg2, region_); 262 } 263 264 TypeHandle Union(TypeHandle t1, TypeHandle t2) { 265 return Type::Union(t1, t2, region_); 266 } 267 TypeHandle Intersect(TypeHandle t1, TypeHandle t2) { 268 return Type::Intersect(t1, t2, region_); 269 } 270 271 template<class Type2, class TypeHandle2> 272 TypeHandle Convert(TypeHandle2 t) { 273 return Type::template Convert<Type2>(t, region_); 274 } 275 276 TypeHandle Random() { 277 return types[rng_.NextInt(static_cast<int>(types.size()))]; 278 } 279 280 TypeHandle Fuzz(int depth = 5) { 281 switch (rng_.NextInt(depth == 0 ? 3 : 20)) { 282 case 0: { // bitset 283 int n = 0 284 #define COUNT_BITSET_TYPES(type, value) + 1 285 BITSET_TYPE_LIST(COUNT_BITSET_TYPES) 286 #undef COUNT_BITSET_TYPES 287 ; 288 int i = rng_.NextInt(n); 289 #define PICK_BITSET_TYPE(type, value) \ 290 if (i-- == 0) return Type::type(region_); 291 BITSET_TYPE_LIST(PICK_BITSET_TYPE) 292 #undef PICK_BITSET_TYPE 293 UNREACHABLE(); 294 } 295 case 1: { // class 296 int i = rng_.NextInt(static_cast<int>(maps.size())); 297 return Type::Class(maps[i], region_); 298 } 299 case 2: { // constant 300 int i = rng_.NextInt(static_cast<int>(values.size())); 301 return Type::Constant(values[i], region_); 302 } 303 case 3: { // context 304 int depth = rng_.NextInt(3); 305 TypeHandle type = Type::Internal(region_); 306 for (int i = 0; i < depth; ++i) type = Type::Context(type, region_); 307 return type; 308 } 309 case 4: { // array 310 TypeHandle element = Fuzz(depth / 2); 311 return Type::Array(element, region_); 312 } 313 case 5: 314 case 6: 315 case 7: { // function 316 TypeHandle result = Fuzz(depth / 2); 317 TypeHandle receiver = Fuzz(depth / 2); 318 int arity = rng_.NextInt(3); 319 TypeHandle type = Type::Function(result, receiver, arity, region_); 320 for (int i = 0; i < type->AsFunction()->Arity(); ++i) { 321 TypeHandle parameter = Fuzz(depth - 1); 322 type->AsFunction()->InitParameter(i, parameter); 323 } 324 } 325 default: { // union 326 int n = rng_.NextInt(10); 327 TypeHandle type = None; 328 for (int i = 0; i < n; ++i) { 329 TypeHandle operand = Fuzz(depth - 1); 330 type = Type::Union(type, operand, region_); 331 } 332 return type; 333 } 334 } 335 UNREACHABLE(); 336 } 337 338 Region* region() { return region_; } 339 340 private: 341 Region* region_; 342 RandomNumberGenerator rng_; 343 }; 344 345 346 template<class Type, class TypeHandle, class Region, class Rep> 347 struct Tests : Rep { 348 typedef Types<Type, TypeHandle, Region> TypesInstance; 349 typedef typename TypesInstance::TypeVector::iterator TypeIterator; 350 typedef typename TypesInstance::MapVector::iterator MapIterator; 351 typedef typename TypesInstance::ValueVector::iterator ValueIterator; 352 353 Isolate* isolate; 354 HandleScope scope; 355 Zone zone; 356 TypesInstance T; 357 358 Tests() : 359 isolate(CcTest::i_isolate()), 360 scope(isolate), 361 zone(isolate), 362 T(Rep::ToRegion(&zone, isolate), isolate) { 363 } 364 365 bool Equal(TypeHandle type1, TypeHandle type2) { 366 return 367 type1->Is(type2) && type2->Is(type1) && 368 Rep::IsBitset(type1) == Rep::IsBitset(type2) && 369 Rep::IsClass(type1) == Rep::IsClass(type2) && 370 Rep::IsConstant(type1) == Rep::IsConstant(type2) && 371 Rep::IsContext(type1) == Rep::IsContext(type2) && 372 Rep::IsArray(type1) == Rep::IsArray(type2) && 373 Rep::IsFunction(type1) == Rep::IsFunction(type2) && 374 Rep::IsUnion(type1) == Rep::IsUnion(type2) && 375 type1->NumClasses() == type2->NumClasses() && 376 type1->NumConstants() == type2->NumConstants() && 377 (!Rep::IsBitset(type1) || 378 Rep::AsBitset(type1) == Rep::AsBitset(type2)) && 379 (!Rep::IsClass(type1) || 380 Rep::AsClass(type1) == Rep::AsClass(type2)) && 381 (!Rep::IsConstant(type1) || 382 Rep::AsConstant(type1) == Rep::AsConstant(type2)) && 383 // TODO(rossberg): Check details of arrays, functions, bounds. 384 (!Rep::IsUnion(type1) || 385 Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); 386 } 387 388 void CheckEqual(TypeHandle type1, TypeHandle type2) { 389 CHECK(Equal(type1, type2)); 390 } 391 392 void CheckSub(TypeHandle type1, TypeHandle type2) { 393 CHECK(type1->Is(type2)); 394 CHECK(!type2->Is(type1)); 395 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 396 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); 397 } 398 } 399 400 void CheckUnordered(TypeHandle type1, TypeHandle type2) { 401 CHECK(!type1->Is(type2)); 402 CHECK(!type2->Is(type1)); 403 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 404 CHECK_NE(Rep::AsBitset(type1), Rep::AsBitset(type2)); 405 } 406 } 407 408 void CheckOverlap(TypeHandle type1, TypeHandle type2, TypeHandle mask) { 409 CHECK(type1->Maybe(type2)); 410 CHECK(type2->Maybe(type1)); 411 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 412 CHECK_NE(0, 413 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); 414 } 415 } 416 417 void CheckDisjoint(TypeHandle type1, TypeHandle type2, TypeHandle mask) { 418 CHECK(!type1->Is(type2)); 419 CHECK(!type2->Is(type1)); 420 CHECK(!type1->Maybe(type2)); 421 CHECK(!type2->Maybe(type1)); 422 if (Rep::IsBitset(type1) && Rep::IsBitset(type2)) { 423 CHECK_EQ(0, 424 Rep::AsBitset(type1) & Rep::AsBitset(type2) & Rep::AsBitset(mask)); 425 } 426 } 427 428 void Bitset() { 429 // None and Any are bitsets. 430 CHECK(this->IsBitset(T.None)); 431 CHECK(this->IsBitset(T.Any)); 432 433 CHECK_EQ(0, this->AsBitset(T.None)); 434 CHECK_EQ(-1, this->AsBitset(T.Any)); 435 436 // Union(T1, T2) is bitset for bitsets T1,T2 437 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 438 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 439 TypeHandle type1 = *it1; 440 TypeHandle type2 = *it2; 441 TypeHandle union12 = T.Union(type1, type2); 442 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || 443 this->IsBitset(union12)); 444 } 445 } 446 447 // Intersect(T1, T2) is bitset for bitsets T1,T2 448 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 449 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 450 TypeHandle type1 = *it1; 451 TypeHandle type2 = *it2; 452 TypeHandle intersect12 = T.Intersect(type1, type2); 453 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || 454 this->IsBitset(intersect12)); 455 } 456 } 457 458 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) 459 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 460 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 461 TypeHandle type1 = *it1; 462 TypeHandle type2 = *it2; 463 TypeHandle union12 = T.Union(type1, type2); 464 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || 465 this->IsBitset(union12)); 466 } 467 } 468 469 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 470 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 471 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 472 TypeHandle type1 = *it1; 473 TypeHandle type2 = *it2; 474 TypeHandle union12 = T.Union(type1, type2); 475 if (this->IsBitset(type1) && this->IsBitset(type2)) { 476 CHECK_EQ( 477 this->AsBitset(type1) | this->AsBitset(type2), 478 this->AsBitset(union12)); 479 } 480 } 481 } 482 483 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 484 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 485 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 486 TypeHandle type1 = *it1; 487 TypeHandle type2 = *it2; 488 TypeHandle intersect12 = T.Intersect(type1, type2); 489 if (this->IsBitset(type1) && this->IsBitset(type2)) { 490 CHECK_EQ( 491 this->AsBitset(type1) & this->AsBitset(type2), 492 this->AsBitset(intersect12)); 493 } 494 } 495 } 496 } 497 498 void Class() { 499 // Constructor 500 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 501 Handle<i::Map> map = *mt; 502 TypeHandle type = T.Class(map); 503 CHECK(this->IsClass(type)); 504 } 505 506 // Map attribute 507 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 508 Handle<i::Map> map = *mt; 509 TypeHandle type = T.Class(map); 510 CHECK(*map == *type->AsClass()->Map()); 511 } 512 513 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 514 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 515 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 516 Handle<i::Map> map1 = *mt1; 517 Handle<i::Map> map2 = *mt2; 518 TypeHandle type1 = T.Class(map1); 519 TypeHandle type2 = T.Class(map2); 520 CHECK(Equal(type1, type2) == (*map1 == *map2)); 521 } 522 } 523 } 524 525 void Constant() { 526 // Constructor 527 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 528 Handle<i::Object> value = *vt; 529 TypeHandle type = T.Constant(value); 530 CHECK(this->IsConstant(type)); 531 } 532 533 // Value attribute 534 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 535 Handle<i::Object> value = *vt; 536 TypeHandle type = T.Constant(value); 537 CHECK(*value == *type->AsConstant()->Value()); 538 } 539 540 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 541 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 542 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 543 Handle<i::Object> value1 = *vt1; 544 Handle<i::Object> value2 = *vt2; 545 TypeHandle type1 = T.Constant(value1); 546 TypeHandle type2 = T.Constant(value2); 547 CHECK(Equal(type1, type2) == (*value1 == *value2)); 548 } 549 } 550 551 // Typing of numbers 552 Factory* fac = isolate->factory(); 553 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); 554 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); 555 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); 556 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall)); 557 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall)); 558 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall)); 559 if (SmiValuesAre31Bits()) { 560 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); 561 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31)); 562 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32)); 563 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32)); 564 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32)); 565 } else { 566 CHECK(SmiValuesAre32Bits()); 567 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); 568 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); 569 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); 570 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31)); 571 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall)); 572 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall)); 573 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall)); 574 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32)); 575 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32)); 576 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32)); 577 } 578 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32)); 579 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32)); 580 CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber)); 581 CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber)); 582 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber)); 583 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber)); 584 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber)); 585 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero)); 586 CHECK(T.Constant(fac->NewNumber(OS::nan_value()))->Is(T.NaN)); 587 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber)); 588 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber)); 589 } 590 591 void Array() { 592 // Constructor 593 for (int i = 0; i < 20; ++i) { 594 TypeHandle type = T.Random(); 595 TypeHandle array = T.Array1(type); 596 CHECK(this->IsArray(array)); 597 } 598 599 // Attributes 600 for (int i = 0; i < 20; ++i) { 601 TypeHandle type = T.Random(); 602 TypeHandle array = T.Array1(type); 603 CheckEqual(type, array->AsArray()->Element()); 604 } 605 606 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 607 for (int i = 0; i < 20; ++i) { 608 for (int j = 0; j < 20; ++j) { 609 TypeHandle type1 = T.Random(); 610 TypeHandle type2 = T.Random(); 611 TypeHandle array1 = T.Array1(type1); 612 TypeHandle array2 = T.Array1(type2); 613 CHECK(Equal(array1, array2) == Equal(type1, type2)); 614 } 615 } 616 } 617 618 void Function() { 619 // Constructors 620 for (int i = 0; i < 20; ++i) { 621 for (int j = 0; j < 20; ++j) { 622 for (int k = 0; k < 20; ++k) { 623 TypeHandle type1 = T.Random(); 624 TypeHandle type2 = T.Random(); 625 TypeHandle type3 = T.Random(); 626 TypeHandle function0 = T.Function0(type1, type2); 627 TypeHandle function1 = T.Function1(type1, type2, type3); 628 TypeHandle function2 = T.Function2(type1, type2, type3); 629 CHECK(function0->IsFunction()); 630 CHECK(function1->IsFunction()); 631 CHECK(function2->IsFunction()); 632 } 633 } 634 } 635 636 // Attributes 637 for (int i = 0; i < 20; ++i) { 638 for (int j = 0; j < 20; ++j) { 639 for (int k = 0; k < 20; ++k) { 640 TypeHandle type1 = T.Random(); 641 TypeHandle type2 = T.Random(); 642 TypeHandle type3 = T.Random(); 643 TypeHandle function0 = T.Function0(type1, type2); 644 TypeHandle function1 = T.Function1(type1, type2, type3); 645 TypeHandle function2 = T.Function2(type1, type2, type3); 646 CHECK_EQ(0, function0->AsFunction()->Arity()); 647 CHECK_EQ(1, function1->AsFunction()->Arity()); 648 CHECK_EQ(2, function2->AsFunction()->Arity()); 649 CheckEqual(type1, function0->AsFunction()->Result()); 650 CheckEqual(type1, function1->AsFunction()->Result()); 651 CheckEqual(type1, function2->AsFunction()->Result()); 652 CheckEqual(type2, function0->AsFunction()->Receiver()); 653 CheckEqual(type2, function1->AsFunction()->Receiver()); 654 CheckEqual(T.Any, function2->AsFunction()->Receiver()); 655 CheckEqual(type3, function1->AsFunction()->Parameter(0)); 656 CheckEqual(type2, function2->AsFunction()->Parameter(0)); 657 CheckEqual(type3, function2->AsFunction()->Parameter(1)); 658 } 659 } 660 } 661 662 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2 663 for (int i = 0; i < 20; ++i) { 664 for (int j = 0; j < 20; ++j) { 665 for (int k = 0; k < 20; ++k) { 666 TypeHandle type1 = T.Random(); 667 TypeHandle type2 = T.Random(); 668 TypeHandle type3 = T.Random(); 669 TypeHandle function01 = T.Function0(type1, type2); 670 TypeHandle function02 = T.Function0(type1, type3); 671 TypeHandle function03 = T.Function0(type3, type2); 672 TypeHandle function11 = T.Function1(type1, type2, type2); 673 TypeHandle function12 = T.Function1(type1, type2, type3); 674 TypeHandle function21 = T.Function2(type1, type2, type2); 675 TypeHandle function22 = T.Function2(type1, type2, type3); 676 TypeHandle function23 = T.Function2(type1, type3, type2); 677 CHECK(Equal(function01, function02) == Equal(type2, type3)); 678 CHECK(Equal(function01, function03) == Equal(type1, type3)); 679 CHECK(Equal(function11, function12) == Equal(type2, type3)); 680 CHECK(Equal(function21, function22) == Equal(type2, type3)); 681 CHECK(Equal(function21, function23) == Equal(type2, type3)); 682 } 683 } 684 } 685 } 686 687 void Of() { 688 // Constant(V)->Is(Of(V)) 689 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 690 Handle<i::Object> value = *vt; 691 TypeHandle const_type = T.Constant(value); 692 TypeHandle of_type = T.Of(value); 693 CHECK(const_type->Is(of_type)); 694 } 695 696 // Constant(V)->Is(T) iff Of(V)->Is(T) or T->Maybe(Constant(V)) 697 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 698 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 699 Handle<i::Object> value = *vt; 700 TypeHandle type = *it; 701 TypeHandle const_type = T.Constant(value); 702 TypeHandle of_type = T.Of(value); 703 CHECK(const_type->Is(type) == 704 (of_type->Is(type) || type->Maybe(const_type))); 705 } 706 } 707 } 708 709 void NowOf() { 710 // Constant(V)->NowIs(NowOf(V)) 711 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 712 Handle<i::Object> value = *vt; 713 TypeHandle const_type = T.Constant(value); 714 TypeHandle nowof_type = T.NowOf(value); 715 CHECK(const_type->NowIs(nowof_type)); 716 } 717 718 // NowOf(V)->Is(Of(V)) 719 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 720 Handle<i::Object> value = *vt; 721 TypeHandle nowof_type = T.NowOf(value); 722 TypeHandle of_type = T.Of(value); 723 CHECK(nowof_type->Is(of_type)); 724 } 725 726 // Constant(V)->NowIs(T) iff NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) 727 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 728 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 729 Handle<i::Object> value = *vt; 730 TypeHandle type = *it; 731 TypeHandle const_type = T.Constant(value); 732 TypeHandle nowof_type = T.NowOf(value); 733 CHECK(const_type->NowIs(type) == 734 (nowof_type->NowIs(type) || type->Maybe(const_type))); 735 } 736 } 737 738 // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V)) 739 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 740 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 741 Handle<i::Object> value = *vt; 742 TypeHandle type = *it; 743 TypeHandle const_type = T.Constant(value); 744 TypeHandle nowof_type = T.NowOf(value); 745 CHECK(!const_type->Is(type) || 746 (nowof_type->Is(type) || type->Maybe(const_type))); 747 } 748 } 749 } 750 751 void Bounds() { 752 // Ordering: (T->BitsetGlb())->Is(T->BitsetLub()) 753 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 754 TypeHandle type = *it; 755 TypeHandle glb = 756 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); 757 TypeHandle lub = 758 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); 759 CHECK(glb->Is(lub)); 760 } 761 762 // Lower bound: (T->BitsetGlb())->Is(T) 763 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 764 TypeHandle type = *it; 765 TypeHandle glb = 766 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); 767 CHECK(glb->Is(type)); 768 } 769 770 // Upper bound: T->Is(T->BitsetLub()) 771 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 772 TypeHandle type = *it; 773 TypeHandle lub = 774 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); 775 CHECK(type->Is(lub)); 776 } 777 778 // Inherent bound: (T->BitsetLub())->Is(T->InherentBitsetLub()) 779 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 780 TypeHandle type = *it; 781 TypeHandle lub = 782 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); 783 TypeHandle inherent = 784 Rep::BitsetType::New(Rep::BitsetType::InherentLub(type), T.region()); 785 CHECK(lub->Is(inherent)); 786 } 787 } 788 789 void Is() { 790 // Least Element (Bottom): None->Is(T) 791 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 792 TypeHandle type = *it; 793 CHECK(T.None->Is(type)); 794 } 795 796 // Greatest Element (Top): T->Is(Any) 797 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 798 TypeHandle type = *it; 799 CHECK(type->Is(T.Any)); 800 } 801 802 // Bottom Uniqueness: T->Is(None) implies T = None 803 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 804 TypeHandle type = *it; 805 if (type->Is(T.None)) CheckEqual(type, T.None); 806 } 807 808 // Top Uniqueness: Any->Is(T) implies T = Any 809 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 810 TypeHandle type = *it; 811 if (T.Any->Is(type)) CheckEqual(type, T.Any); 812 } 813 814 // Reflexivity: T->Is(T) 815 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 816 TypeHandle type = *it; 817 CHECK(type->Is(type)); 818 } 819 820 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) 821 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 822 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 823 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 824 TypeHandle type1 = *it1; 825 TypeHandle type2 = *it2; 826 TypeHandle type3 = *it3; 827 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); 828 } 829 } 830 } 831 832 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 833 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 834 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 835 TypeHandle type1 = *it1; 836 TypeHandle type2 = *it2; 837 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); 838 } 839 } 840 841 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 842 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 843 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 844 Handle<i::Object> value1 = *vt1; 845 Handle<i::Object> value2 = *vt2; 846 TypeHandle const_type1 = T.Constant(value1); 847 TypeHandle const_type2 = T.Constant(value2); 848 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); 849 } 850 } 851 852 // Class(M1)->Is(Class(M2)) iff M1 = M2 853 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 854 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 855 Handle<i::Map> map1 = *mt1; 856 Handle<i::Map> map2 = *mt2; 857 TypeHandle class_type1 = T.Class(map1); 858 TypeHandle class_type2 = T.Class(map2); 859 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); 860 } 861 } 862 863 // Constant(V)->Is(Class(M)) never 864 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 865 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 866 Handle<i::Map> map = *mt; 867 Handle<i::Object> value = *vt; 868 TypeHandle constant_type = T.Constant(value); 869 TypeHandle class_type = T.Class(map); 870 CHECK(!constant_type->Is(class_type)); 871 } 872 } 873 874 // Class(M)->Is(Constant(V)) never 875 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 876 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 877 Handle<i::Map> map = *mt; 878 Handle<i::Object> value = *vt; 879 TypeHandle constant_type = T.Constant(value); 880 TypeHandle class_type = T.Class(map); 881 CHECK(!class_type->Is(constant_type)); 882 } 883 } 884 885 // Basic types 886 CheckUnordered(T.Boolean, T.Null); 887 CheckUnordered(T.Undefined, T.Null); 888 CheckUnordered(T.Boolean, T.Undefined); 889 890 CheckSub(T.SignedSmall, T.Number); 891 CheckSub(T.Signed32, T.Number); 892 CheckSub(T.SignedSmall, T.Signed32); 893 CheckUnordered(T.SignedSmall, T.MinusZero); 894 CheckUnordered(T.Signed32, T.Unsigned32); 895 896 CheckSub(T.UniqueName, T.Name); 897 CheckSub(T.String, T.Name); 898 CheckSub(T.InternalizedString, T.String); 899 CheckSub(T.InternalizedString, T.UniqueName); 900 CheckSub(T.InternalizedString, T.Name); 901 CheckSub(T.Symbol, T.UniqueName); 902 CheckSub(T.Symbol, T.Name); 903 CheckUnordered(T.String, T.UniqueName); 904 CheckUnordered(T.String, T.Symbol); 905 CheckUnordered(T.InternalizedString, T.Symbol); 906 907 CheckSub(T.Object, T.Receiver); 908 CheckSub(T.Array, T.Object); 909 CheckSub(T.Function, T.Object); 910 CheckSub(T.Proxy, T.Receiver); 911 CheckUnordered(T.Object, T.Proxy); 912 CheckUnordered(T.Array, T.Function); 913 914 // Structural types 915 CheckSub(T.ObjectClass, T.Object); 916 CheckSub(T.ArrayClass, T.Object); 917 CheckSub(T.ArrayClass, T.Array); 918 CheckSub(T.UninitializedClass, T.Internal); 919 CheckUnordered(T.ObjectClass, T.ArrayClass); 920 CheckUnordered(T.UninitializedClass, T.Null); 921 CheckUnordered(T.UninitializedClass, T.Undefined); 922 923 CheckSub(T.SmiConstant, T.SignedSmall); 924 CheckSub(T.SmiConstant, T.Signed32); 925 CheckSub(T.SmiConstant, T.Number); 926 CheckSub(T.ObjectConstant1, T.Object); 927 CheckSub(T.ObjectConstant2, T.Object); 928 CheckSub(T.ArrayConstant, T.Object); 929 CheckSub(T.ArrayConstant, T.Array); 930 CheckSub(T.UninitializedConstant, T.Internal); 931 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); 932 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); 933 CheckUnordered(T.UninitializedConstant, T.Null); 934 CheckUnordered(T.UninitializedConstant, T.Undefined); 935 936 CheckUnordered(T.ObjectConstant1, T.ObjectClass); 937 CheckUnordered(T.ObjectConstant2, T.ObjectClass); 938 CheckUnordered(T.ObjectConstant1, T.ArrayClass); 939 CheckUnordered(T.ObjectConstant2, T.ArrayClass); 940 CheckUnordered(T.ArrayConstant, T.ObjectClass); 941 942 CheckSub(T.NumberArray, T.Array); 943 CheckSub(T.NumberArray, T.Object); 944 CheckUnordered(T.StringArray, T.AnyArray); 945 946 CheckSub(T.MethodFunction, T.Function); 947 CheckSub(T.NumberFunction1, T.Object); 948 CheckUnordered(T.SignedFunction1, T.NumberFunction1); 949 CheckUnordered(T.NumberFunction1, T.NumberFunction2); 950 } 951 952 void NowIs() { 953 // Least Element (Bottom): None->NowIs(T) 954 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 955 TypeHandle type = *it; 956 CHECK(T.None->NowIs(type)); 957 } 958 959 // Greatest Element (Top): T->NowIs(Any) 960 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 961 TypeHandle type = *it; 962 CHECK(type->NowIs(T.Any)); 963 } 964 965 // Bottom Uniqueness: T->NowIs(None) implies T = None 966 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 967 TypeHandle type = *it; 968 if (type->NowIs(T.None)) CheckEqual(type, T.None); 969 } 970 971 // Top Uniqueness: Any->NowIs(T) implies T = Any 972 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 973 TypeHandle type = *it; 974 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); 975 } 976 977 // Reflexivity: T->NowIs(T) 978 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 979 TypeHandle type = *it; 980 CHECK(type->NowIs(type)); 981 } 982 983 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) 984 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 985 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 986 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 987 TypeHandle type1 = *it1; 988 TypeHandle type2 = *it2; 989 TypeHandle type3 = *it3; 990 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || 991 type1->NowIs(type3)); 992 } 993 } 994 } 995 996 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 997 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 998 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 999 TypeHandle type1 = *it1; 1000 TypeHandle type2 = *it2; 1001 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == 1002 Equal(type1, type2)); 1003 } 1004 } 1005 1006 // T1->Is(T2) implies T1->NowIs(T2) 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 TypeHandle type1 = *it1; 1010 TypeHandle type2 = *it2; 1011 CHECK(!type1->Is(type2) || type1->NowIs(type2)); 1012 } 1013 } 1014 1015 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 1016 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 1017 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 1018 Handle<i::Object> value1 = *vt1; 1019 Handle<i::Object> value2 = *vt2; 1020 TypeHandle const_type1 = T.Constant(value1); 1021 TypeHandle const_type2 = T.Constant(value2); 1022 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2)); 1023 } 1024 } 1025 1026 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 1027 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 1028 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 1029 Handle<i::Map> map1 = *mt1; 1030 Handle<i::Map> map2 = *mt2; 1031 TypeHandle class_type1 = T.Class(map1); 1032 TypeHandle class_type2 = T.Class(map2); 1033 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2)); 1034 } 1035 } 1036 1037 // Constant(V)->NowIs(Class(M)) iff V has map M 1038 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1039 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1040 Handle<i::Map> map = *mt; 1041 Handle<i::Object> value = *vt; 1042 TypeHandle const_type = T.Constant(value); 1043 TypeHandle class_type = T.Class(map); 1044 CHECK((value->IsHeapObject() && 1045 i::HeapObject::cast(*value)->map() == *map) 1046 == const_type->NowIs(class_type)); 1047 } 1048 } 1049 1050 // Class(M)->NowIs(Constant(V)) never 1051 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1052 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1053 Handle<i::Map> map = *mt; 1054 Handle<i::Object> value = *vt; 1055 TypeHandle const_type = T.Constant(value); 1056 TypeHandle class_type = T.Class(map); 1057 CHECK(!class_type->NowIs(const_type)); 1058 } 1059 } 1060 } 1061 1062 void Contains() { 1063 // T->Contains(V) iff Constant(V)->Is(T) 1064 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1065 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1066 TypeHandle type = *it; 1067 Handle<i::Object> value = *vt; 1068 TypeHandle const_type = T.Constant(value); 1069 CHECK(type->Contains(value) == const_type->Is(type)); 1070 } 1071 } 1072 1073 // Of(V)->Is(T) implies T->Contains(V) 1074 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1075 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1076 TypeHandle type = *it; 1077 Handle<i::Object> value = *vt; 1078 TypeHandle of_type = T.Of(value); 1079 CHECK(!of_type->Is(type) || type->Contains(value)); 1080 } 1081 } 1082 } 1083 1084 void NowContains() { 1085 // T->NowContains(V) iff Constant(V)->NowIs(T) 1086 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1087 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1088 TypeHandle type = *it; 1089 Handle<i::Object> value = *vt; 1090 TypeHandle const_type = T.Constant(value); 1091 CHECK(type->NowContains(value) == const_type->NowIs(type)); 1092 } 1093 } 1094 1095 // T->Contains(V) implies T->NowContains(V) 1096 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1097 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1098 TypeHandle type = *it; 1099 Handle<i::Object> value = *vt; 1100 CHECK(!type->Contains(value) || type->NowContains(value)); 1101 } 1102 } 1103 1104 // NowOf(V)->Is(T) implies T->NowContains(V) 1105 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1106 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1107 TypeHandle type = *it; 1108 Handle<i::Object> value = *vt; 1109 TypeHandle nowof_type = T.Of(value); 1110 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); 1111 } 1112 } 1113 1114 // NowOf(V)->NowIs(T) implies T->NowContains(V) 1115 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1116 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1117 TypeHandle type = *it; 1118 Handle<i::Object> value = *vt; 1119 TypeHandle nowof_type = T.Of(value); 1120 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); 1121 } 1122 } 1123 } 1124 1125 void Maybe() { 1126 // T->Maybe(Any) iff T inhabited 1127 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1128 TypeHandle type = *it; 1129 CHECK(type->Maybe(T.Any) == type->IsInhabited()); 1130 } 1131 1132 // T->Maybe(None) never 1133 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1134 TypeHandle type = *it; 1135 CHECK(!type->Maybe(T.None)); 1136 } 1137 1138 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited 1139 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1140 TypeHandle type = *it; 1141 CHECK(type->Maybe(type) == type->IsInhabited()); 1142 } 1143 1144 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) 1145 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1146 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1147 TypeHandle type1 = *it1; 1148 TypeHandle type2 = *it2; 1149 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); 1150 } 1151 } 1152 1153 // T1->Maybe(T2) implies T1, T2 inhabited 1154 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1155 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1156 TypeHandle type1 = *it1; 1157 TypeHandle type2 = *it2; 1158 CHECK(!type1->Maybe(type2) || 1159 (type1->IsInhabited() && type2->IsInhabited())); 1160 } 1161 } 1162 1163 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited 1164 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1165 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1166 TypeHandle type1 = *it1; 1167 TypeHandle type2 = *it2; 1168 TypeHandle intersect12 = T.Intersect(type1, type2); 1169 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited()); 1170 } 1171 } 1172 1173 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) 1174 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1175 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1176 TypeHandle type1 = *it1; 1177 TypeHandle type2 = *it2; 1178 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || 1179 type1->Maybe(type2)); 1180 } 1181 } 1182 1183 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 1184 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 1185 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 1186 Handle<i::Object> value1 = *vt1; 1187 Handle<i::Object> value2 = *vt2; 1188 TypeHandle const_type1 = T.Constant(value1); 1189 TypeHandle const_type2 = T.Constant(value2); 1190 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); 1191 } 1192 } 1193 1194 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 1195 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 1196 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 1197 Handle<i::Map> map1 = *mt1; 1198 Handle<i::Map> map2 = *mt2; 1199 TypeHandle class_type1 = T.Class(map1); 1200 TypeHandle class_type2 = T.Class(map2); 1201 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); 1202 } 1203 } 1204 1205 // Constant(V)->Maybe(Class(M)) never 1206 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1207 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1208 Handle<i::Map> map = *mt; 1209 Handle<i::Object> value = *vt; 1210 TypeHandle const_type = T.Constant(value); 1211 TypeHandle class_type = T.Class(map); 1212 CHECK(!const_type->Maybe(class_type)); 1213 } 1214 } 1215 1216 // Class(M)->Maybe(Constant(V)) never 1217 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1218 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1219 Handle<i::Map> map = *mt; 1220 Handle<i::Object> value = *vt; 1221 TypeHandle const_type = T.Constant(value); 1222 TypeHandle class_type = T.Class(map); 1223 CHECK(!class_type->Maybe(const_type)); 1224 } 1225 } 1226 1227 // Basic types 1228 CheckDisjoint(T.Boolean, T.Null, T.Semantic); 1229 CheckDisjoint(T.Undefined, T.Null, T.Semantic); 1230 CheckDisjoint(T.Boolean, T.Undefined, T.Semantic); 1231 1232 CheckOverlap(T.SignedSmall, T.Number, T.Semantic); 1233 CheckOverlap(T.NaN, T.Number, T.Semantic); 1234 CheckDisjoint(T.Signed32, T.NaN, T.Semantic); 1235 1236 CheckOverlap(T.UniqueName, T.Name, T.Semantic); 1237 CheckOverlap(T.String, T.Name, T.Semantic); 1238 CheckOverlap(T.InternalizedString, T.String, T.Semantic); 1239 CheckOverlap(T.InternalizedString, T.UniqueName, T.Semantic); 1240 CheckOverlap(T.InternalizedString, T.Name, T.Semantic); 1241 CheckOverlap(T.Symbol, T.UniqueName, T.Semantic); 1242 CheckOverlap(T.Symbol, T.Name, T.Semantic); 1243 CheckOverlap(T.String, T.UniqueName, T.Semantic); 1244 CheckDisjoint(T.String, T.Symbol, T.Semantic); 1245 CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic); 1246 1247 CheckOverlap(T.Object, T.Receiver, T.Semantic); 1248 CheckOverlap(T.Array, T.Object, T.Semantic); 1249 CheckOverlap(T.Function, T.Object, T.Semantic); 1250 CheckOverlap(T.Proxy, T.Receiver, T.Semantic); 1251 CheckDisjoint(T.Object, T.Proxy, T.Semantic); 1252 CheckDisjoint(T.Array, T.Function, T.Semantic); 1253 1254 // Structural types 1255 CheckOverlap(T.ObjectClass, T.Object, T.Semantic); 1256 CheckOverlap(T.ArrayClass, T.Object, T.Semantic); 1257 CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic); 1258 CheckOverlap(T.ArrayClass, T.ArrayClass, T.Semantic); 1259 CheckDisjoint(T.ObjectClass, T.ArrayClass, T.Semantic); 1260 1261 CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic); 1262 CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic); 1263 CheckOverlap(T.SmiConstant, T.Number, T.Semantic); 1264 CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic); 1265 CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic); 1266 CheckOverlap(T.ArrayConstant, T.Object, T.Semantic); 1267 CheckOverlap(T.ArrayConstant, T.Array, T.Semantic); 1268 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1, T.Semantic); 1269 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2, T.Semantic); 1270 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant, T.Semantic); 1271 1272 CheckDisjoint(T.ObjectConstant1, T.ObjectClass, T.Semantic); 1273 CheckDisjoint(T.ObjectConstant2, T.ObjectClass, T.Semantic); 1274 CheckDisjoint(T.ObjectConstant1, T.ArrayClass, T.Semantic); 1275 CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); 1276 CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); 1277 1278 CheckOverlap(T.NumberArray, T.Array, T.Semantic); 1279 CheckDisjoint(T.NumberArray, T.AnyArray, T.Semantic); 1280 CheckDisjoint(T.NumberArray, T.StringArray, T.Semantic); 1281 1282 CheckOverlap(T.MethodFunction, T.Function, T.Semantic); 1283 CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic); 1284 CheckDisjoint(T.SignedFunction1, T.NumberFunction2, T.Semantic); 1285 CheckDisjoint(T.NumberFunction1, T.NumberFunction2, T.Semantic); 1286 CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic); 1287 } 1288 1289 void Union1() { 1290 // Identity: Union(T, None) = T 1291 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1292 TypeHandle type = *it; 1293 TypeHandle union_type = T.Union(type, T.None); 1294 CheckEqual(union_type, type); 1295 } 1296 1297 // Domination: Union(T, Any) = Any 1298 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1299 TypeHandle type = *it; 1300 TypeHandle union_type = T.Union(type, T.Any); 1301 CheckEqual(union_type, T.Any); 1302 } 1303 1304 // Idempotence: Union(T, T) = T 1305 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1306 TypeHandle type = *it; 1307 TypeHandle union_type = T.Union(type, type); 1308 CheckEqual(union_type, type); 1309 } 1310 1311 // Commutativity: Union(T1, T2) = Union(T2, T1) 1312 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1313 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1314 TypeHandle type1 = *it1; 1315 TypeHandle type2 = *it2; 1316 TypeHandle union12 = T.Union(type1, type2); 1317 TypeHandle union21 = T.Union(type2, type1); 1318 CheckEqual(union12, union21); 1319 } 1320 } 1321 1322 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) 1323 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1324 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1325 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1326 TypeHandle type1 = *it1; 1327 TypeHandle type2 = *it2; 1328 TypeHandle type3 = *it3; 1329 TypeHandle union12 = T.Union(type1, type2); 1330 TypeHandle union23 = T.Union(type2, type3); 1331 TypeHandle union1_23 = T.Union(type1, union23); 1332 TypeHandle union12_3 = T.Union(union12, type3); 1333 CheckEqual(union1_23, union12_3); 1334 } 1335 } 1336 } 1337 1338 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) 1339 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1340 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1341 TypeHandle type1 = *it1; 1342 TypeHandle type2 = *it2; 1343 TypeHandle union12 = T.Union(type1, type2); 1344 CHECK(type1->Is(union12)); 1345 CHECK(type2->Is(union12)); 1346 } 1347 } 1348 1349 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 1350 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1351 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1352 TypeHandle type1 = *it1; 1353 TypeHandle type2 = *it2; 1354 TypeHandle union12 = T.Union(type1, type2); 1355 if (type1->Is(type2)) CheckEqual(union12, type2); 1356 } 1357 } 1358 } 1359 1360 void Union2() { 1361 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) 1362 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1363 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1364 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1365 TypeHandle type1 = *it1; 1366 TypeHandle type2 = *it2; 1367 TypeHandle type3 = *it3; 1368 TypeHandle union13 = T.Union(type1, type3); 1369 TypeHandle union23 = T.Union(type2, type3); 1370 CHECK(!type1->Is(type2) || union13->Is(union23)); 1371 } 1372 } 1373 } 1374 1375 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) 1376 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1377 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1378 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1379 TypeHandle type1 = *it1; 1380 TypeHandle type2 = *it2; 1381 TypeHandle type3 = *it3; 1382 TypeHandle union12 = T.Union(type1, type2); 1383 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); 1384 } 1385 } 1386 } 1387 1388 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) 1389 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1390 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1391 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1392 TypeHandle type1 = *it1; 1393 TypeHandle type2 = *it2; 1394 TypeHandle type3 = *it3; 1395 TypeHandle union23 = T.Union(type2, type3); 1396 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); 1397 } 1398 } 1399 } 1400 1401 // Class-class 1402 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); 1403 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); 1404 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array, T.Semantic); 1405 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number, T.Semantic); 1406 1407 // Constant-constant 1408 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); 1409 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array); 1410 CheckUnordered( 1411 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); 1412 CheckOverlap( 1413 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Array, T.Semantic); 1414 CheckDisjoint( 1415 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number, T.Semantic); 1416 CheckDisjoint( 1417 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass, T.Semantic); 1418 1419 // Bitset-array 1420 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array))); 1421 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number))); 1422 1423 CheckEqual(T.Union(T.AnyArray, T.Array), T.Array); 1424 CheckUnordered(T.Union(T.AnyArray, T.String), T.Array); 1425 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object, T.Semantic); 1426 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number, T.Semantic); 1427 1428 // Bitset-function 1429 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function))); 1430 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number))); 1431 1432 CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function); 1433 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function); 1434 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic); 1435 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic); 1436 1437 // Bitset-class 1438 CheckSub( 1439 T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); 1440 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); 1441 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); 1442 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object, T.Semantic); 1443 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number, T.Semantic); 1444 1445 // Bitset-constant 1446 CheckSub( 1447 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); 1448 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); 1449 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); 1450 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object, T.Semantic); 1451 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number, T.Semantic); 1452 1453 // Class-constant 1454 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); 1455 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 1456 CheckSub( 1457 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); 1458 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); 1459 CheckDisjoint( 1460 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2, 1461 T.Semantic); 1462 CheckDisjoint( 1463 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass, T.Semantic); 1464 1465 // Bitset-union 1466 CheckSub( 1467 T.NaN, 1468 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); 1469 CheckSub( 1470 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32), 1471 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 1472 1473 // Class-union 1474 CheckSub( 1475 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 1476 T.Object); 1477 CheckEqual( 1478 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), 1479 T.Union(T.ArrayClass, T.ObjectConstant2)); 1480 1481 // Constant-union 1482 CheckEqual( 1483 T.Union( 1484 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1485 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1486 CheckEqual( 1487 T.Union( 1488 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), 1489 T.Union( 1490 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); 1491 1492 // Array-union 1493 CheckEqual( 1494 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)), 1495 T.Union(T.AnyArray, T.NumberArray)); 1496 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array); 1497 1498 // Function-union 1499 CheckEqual( 1500 T.Union(T.NumberFunction1, T.NumberFunction2), 1501 T.Union(T.NumberFunction2, T.NumberFunction1)); 1502 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function); 1503 1504 // Union-union 1505 CheckEqual( 1506 T.Union( 1507 T.Union(T.ObjectConstant2, T.ObjectConstant1), 1508 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1509 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1510 CheckEqual( 1511 T.Union( 1512 T.Union(T.Number, T.ArrayClass), 1513 T.Union(T.SignedSmall, T.Array)), 1514 T.Union(T.Number, T.Array)); 1515 } 1516 1517 void Intersect1() { 1518 // Identity: Intersect(T, Any) = T 1519 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1520 TypeHandle type = *it; 1521 TypeHandle intersect_type = T.Intersect(type, T.Any); 1522 CheckEqual(intersect_type, type); 1523 } 1524 1525 // Domination: Intersect(T, None) = None 1526 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1527 TypeHandle type = *it; 1528 TypeHandle intersect_type = T.Intersect(type, T.None); 1529 CheckEqual(intersect_type, T.None); 1530 } 1531 1532 // Idempotence: Intersect(T, T) = T 1533 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1534 TypeHandle type = *it; 1535 TypeHandle intersect_type = T.Intersect(type, type); 1536 CheckEqual(intersect_type, type); 1537 } 1538 1539 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) 1540 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1541 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1542 TypeHandle type1 = *it1; 1543 TypeHandle type2 = *it2; 1544 TypeHandle intersect12 = T.Intersect(type1, type2); 1545 TypeHandle intersect21 = T.Intersect(type2, type1); 1546 CheckEqual(intersect12, intersect21); 1547 } 1548 } 1549 1550 // Associativity: 1551 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) 1552 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1553 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1554 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1555 TypeHandle type1 = *it1; 1556 TypeHandle type2 = *it2; 1557 TypeHandle type3 = *it3; 1558 TypeHandle intersect12 = T.Intersect(type1, type2); 1559 TypeHandle intersect23 = T.Intersect(type2, type3); 1560 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); 1561 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); 1562 CheckEqual(intersect1_23, intersect12_3); 1563 } 1564 } 1565 } 1566 1567 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) 1568 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1569 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1570 TypeHandle type1 = *it1; 1571 TypeHandle type2 = *it2; 1572 TypeHandle intersect12 = T.Intersect(type1, type2); 1573 CHECK(intersect12->Is(type1)); 1574 CHECK(intersect12->Is(type2)); 1575 } 1576 } 1577 1578 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 1579 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1580 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1581 TypeHandle type1 = *it1; 1582 TypeHandle type2 = *it2; 1583 TypeHandle intersect12 = T.Intersect(type1, type2); 1584 if (type1->Is(type2)) CheckEqual(intersect12, type1); 1585 } 1586 } 1587 } 1588 1589 void Intersect2() { 1590 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) 1591 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1592 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1593 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1594 TypeHandle type1 = *it1; 1595 TypeHandle type2 = *it2; 1596 TypeHandle type3 = *it3; 1597 TypeHandle intersect13 = T.Intersect(type1, type3); 1598 TypeHandle intersect23 = T.Intersect(type2, type3); 1599 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); 1600 } 1601 } 1602 } 1603 1604 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) 1605 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1606 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1607 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1608 TypeHandle type1 = *it1; 1609 TypeHandle type2 = *it2; 1610 TypeHandle type3 = *it3; 1611 TypeHandle intersect12 = T.Intersect(type1, type2); 1612 CHECK(!(type1->Is(type3) || type2->Is(type3)) || 1613 intersect12->Is(type3)); 1614 } 1615 } 1616 } 1617 1618 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) 1619 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1620 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1621 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1622 TypeHandle type1 = *it1; 1623 TypeHandle type2 = *it2; 1624 TypeHandle type3 = *it3; 1625 TypeHandle intersect23 = T.Intersect(type2, type3); 1626 CHECK(!(type1->Is(type2) && type1->Is(type3)) || 1627 type1->Is(intersect23)); 1628 } 1629 } 1630 } 1631 1632 // Bitset-class 1633 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); 1634 CheckSub(T.Intersect(T.ObjectClass, T.Array), T.Representation); 1635 CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); 1636 1637 // Bitset-array 1638 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); 1639 CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation); 1640 1641 // Bitset-function 1642 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); 1643 CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation); 1644 1645 // Bitset-union 1646 CheckEqual( 1647 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 1648 T.Union(T.ObjectConstant1, T.ObjectClass)); 1649 CHECK( 1650 !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number) 1651 ->IsInhabited()); 1652 1653 // Class-constant 1654 CHECK(!T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); 1655 CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited()); 1656 1657 // Array-union 1658 CheckEqual( 1659 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)), 1660 T.NumberArray); 1661 CheckEqual( 1662 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), 1663 T.AnyArray); 1664 CHECK( 1665 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray) 1666 ->IsInhabited()); 1667 1668 // Function-union 1669 CheckEqual( 1670 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), 1671 T.MethodFunction); 1672 CheckEqual( 1673 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), 1674 T.NumberFunction1); 1675 CHECK( 1676 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) 1677 ->IsInhabited()); 1678 1679 // Class-union 1680 CheckEqual( 1681 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), 1682 T.ArrayClass); 1683 CheckEqual( 1684 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), 1685 T.ArrayClass); 1686 CHECK( 1687 !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) 1688 ->IsInhabited()); 1689 1690 // Constant-union 1691 CheckEqual( 1692 T.Intersect( 1693 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1694 T.ObjectConstant1); 1695 CheckEqual( 1696 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), 1697 T.SmiConstant); 1698 CHECK( 1699 !T.Intersect( 1700 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) 1701 ->IsInhabited()); 1702 1703 // Union-union 1704 CheckEqual( 1705 T.Intersect( 1706 T.Union(T.Number, T.ArrayClass), 1707 T.Union(T.SignedSmall, T.Array)), 1708 T.Union(T.SignedSmall, T.ArrayClass)); 1709 CheckEqual( 1710 T.Intersect( 1711 T.Union(T.Number, T.ObjectClass), 1712 T.Union(T.Signed32, T.Array)), 1713 T.Signed32); 1714 CheckEqual( 1715 T.Intersect( 1716 T.Union(T.ObjectConstant2, T.ObjectConstant1), 1717 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1718 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1719 CheckEqual( 1720 T.Intersect( 1721 T.Union( 1722 T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), 1723 T.Union( 1724 T.ObjectConstant1, 1725 T.Union(T.ArrayConstant, T.ObjectConstant2))), 1726 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1727 } 1728 1729 void Distributivity1() { 1730 // Distributivity: 1731 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) 1732 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1733 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1734 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1735 TypeHandle type1 = *it1; 1736 TypeHandle type2 = *it2; 1737 TypeHandle type3 = *it3; 1738 TypeHandle union12 = T.Union(type1, type2); 1739 TypeHandle union13 = T.Union(type1, type3); 1740 TypeHandle intersect23 = T.Intersect(type2, type3); 1741 TypeHandle union1_23 = T.Union(type1, intersect23); 1742 TypeHandle intersect12_13 = T.Intersect(union12, union13); 1743 CHECK(Equal(union1_23, intersect12_13)); 1744 } 1745 } 1746 } 1747 } 1748 1749 void Distributivity2() { 1750 // Distributivity: 1751 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) 1752 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1753 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1754 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1755 TypeHandle type1 = *it1; 1756 TypeHandle type2 = *it2; 1757 TypeHandle type3 = *it3; 1758 TypeHandle intersect12 = T.Intersect(type1, type2); 1759 TypeHandle intersect13 = T.Intersect(type1, type3); 1760 TypeHandle union23 = T.Union(type2, type3); 1761 TypeHandle intersect1_23 = T.Intersect(type1, union23); 1762 TypeHandle union12_13 = T.Union(intersect12, intersect13); 1763 CHECK(Equal(intersect1_23, union12_13)); 1764 } 1765 } 1766 } 1767 } 1768 1769 template<class Type2, class TypeHandle2, class Region2, class Rep2> 1770 void Convert() { 1771 Types<Type2, TypeHandle2, Region2> T2( 1772 Rep2::ToRegion(&zone, isolate), isolate); 1773 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1774 TypeHandle type1 = *it; 1775 TypeHandle2 type2 = T2.template Convert<Type>(type1); 1776 TypeHandle type3 = T.template Convert<Type2>(type2); 1777 CheckEqual(type1, type3); 1778 } 1779 } 1780 1781 void HTypeFromType() { 1782 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1783 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1784 TypeHandle type1 = *it1; 1785 TypeHandle type2 = *it2; 1786 HType htype1 = HType::FromType<Type>(type1); 1787 HType htype2 = HType::FromType<Type>(type2); 1788 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2)); 1789 } 1790 } 1791 } 1792 }; 1793 1794 typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; 1795 typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; 1796 1797 1798 TEST(BitsetType) { 1799 CcTest::InitializeVM(); 1800 ZoneTests().Bitset(); 1801 HeapTests().Bitset(); 1802 } 1803 1804 1805 TEST(ClassType) { 1806 CcTest::InitializeVM(); 1807 ZoneTests().Class(); 1808 HeapTests().Class(); 1809 } 1810 1811 1812 TEST(ConstantType) { 1813 CcTest::InitializeVM(); 1814 ZoneTests().Constant(); 1815 HeapTests().Constant(); 1816 } 1817 1818 1819 TEST(ArrayType) { 1820 CcTest::InitializeVM(); 1821 ZoneTests().Array(); 1822 HeapTests().Array(); 1823 } 1824 1825 1826 TEST(FunctionType) { 1827 CcTest::InitializeVM(); 1828 ZoneTests().Function(); 1829 HeapTests().Function(); 1830 } 1831 1832 1833 TEST(Of) { 1834 CcTest::InitializeVM(); 1835 ZoneTests().Of(); 1836 HeapTests().Of(); 1837 } 1838 1839 1840 TEST(NowOf) { 1841 CcTest::InitializeVM(); 1842 ZoneTests().NowOf(); 1843 HeapTests().NowOf(); 1844 } 1845 1846 1847 TEST(Bounds) { 1848 CcTest::InitializeVM(); 1849 ZoneTests().Bounds(); 1850 HeapTests().Bounds(); 1851 } 1852 1853 1854 TEST(Is) { 1855 CcTest::InitializeVM(); 1856 ZoneTests().Is(); 1857 HeapTests().Is(); 1858 } 1859 1860 1861 TEST(NowIs) { 1862 CcTest::InitializeVM(); 1863 ZoneTests().NowIs(); 1864 HeapTests().NowIs(); 1865 } 1866 1867 1868 TEST(Contains) { 1869 CcTest::InitializeVM(); 1870 ZoneTests().Contains(); 1871 HeapTests().Contains(); 1872 } 1873 1874 1875 TEST(NowContains) { 1876 CcTest::InitializeVM(); 1877 ZoneTests().NowContains(); 1878 HeapTests().NowContains(); 1879 } 1880 1881 1882 TEST(Maybe) { 1883 CcTest::InitializeVM(); 1884 ZoneTests().Maybe(); 1885 HeapTests().Maybe(); 1886 } 1887 1888 1889 TEST(Union1) { 1890 CcTest::InitializeVM(); 1891 ZoneTests().Union1(); 1892 HeapTests().Union1(); 1893 } 1894 1895 1896 TEST(Union2) { 1897 CcTest::InitializeVM(); 1898 ZoneTests().Union2(); 1899 HeapTests().Union2(); 1900 } 1901 1902 1903 TEST(Intersect1) { 1904 CcTest::InitializeVM(); 1905 ZoneTests().Intersect1(); 1906 HeapTests().Intersect1(); 1907 } 1908 1909 1910 TEST(Intersect2) { 1911 CcTest::InitializeVM(); 1912 ZoneTests().Intersect2(); 1913 HeapTests().Intersect2(); 1914 } 1915 1916 1917 TEST(Distributivity1) { 1918 CcTest::InitializeVM(); 1919 ZoneTests().Distributivity1(); 1920 HeapTests().Distributivity1(); 1921 } 1922 1923 1924 TEST(Distributivity2) { 1925 CcTest::InitializeVM(); 1926 ZoneTests().Distributivity2(); 1927 HeapTests().Distributivity2(); 1928 } 1929 1930 1931 TEST(Convert) { 1932 CcTest::InitializeVM(); 1933 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); 1934 HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); 1935 } 1936 1937 1938 TEST(HTypeFromType) { 1939 CcTest::InitializeVM(); 1940 ZoneTests().HTypeFromType(); 1941 HeapTests().HTypeFromType(); 1942 } 1943