1// Copyright 2013 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <vector> 6 7#include "src/crankshaft/hydrogen-types.h" 8#include "src/types.h" 9#include "test/cctest/cctest.h" 10#include "test/cctest/types-fuzz.h" 11 12using namespace v8::internal; 13 14 15// Testing auxiliaries (breaking the Type abstraction). 16 17 18static bool IsInteger(double x) { 19 return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities. 20} 21 22 23static bool IsInteger(i::Object* x) { 24 return x->IsNumber() && IsInteger(x->Number()); 25} 26 27 28typedef uint32_t bitset; 29 30 31struct ZoneRep { 32 typedef void* Struct; 33 34 static bool IsStruct(Type* t, int tag) { 35 return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; 36 } 37 static bool IsBitset(Type* t) { return reinterpret_cast<uintptr_t>(t) & 1; } 38 // HACK: the number 5 below is the value of StructuralType::kUnionTag. 39 static bool IsUnion(Type* t) { return t->IsUnionForTesting(); } 40 41 static Struct* AsStruct(Type* t) { 42 return reinterpret_cast<Struct*>(t); 43 } 44 static bitset AsBitset(Type* t) { 45 return static_cast<bitset>(reinterpret_cast<uintptr_t>(t) ^ 1u); 46 } 47 static Struct* AsUnion(Type* t) { 48 return AsStruct(t); 49 } 50 static int Length(Struct* structured) { 51 return static_cast<int>(reinterpret_cast<intptr_t>(structured[1])); 52 } 53 54 static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } 55 56 struct BitsetType : Type::BitsetType { 57 using Type::BitsetType::New; 58 using Type::BitsetType::Glb; 59 using Type::BitsetType::Lub; 60 using Type::BitsetType::IsInhabited; 61 }; 62}; 63 64 65struct HeapRep { 66 typedef FixedArray Struct; 67 68 static bool IsStruct(Handle<HeapType> t, int tag) { 69 return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; 70 } 71 static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); } 72 // HACK: the number 5 below is the value of StructuralType::kUnionTag. 73 static bool IsUnion(Handle<HeapType> t) { return t->IsUnionForTesting(); } 74 75 static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } 76 static bitset AsBitset(Handle<HeapType> t) { 77 return static_cast<bitset>(reinterpret_cast<uintptr_t>(*t)); 78 } 79 static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } 80 static int Length(Struct* structured) { return structured->length() - 1; } 81 82 static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } 83 84 struct BitsetType : HeapType::BitsetType { 85 using HeapType::BitsetType::New; 86 using HeapType::BitsetType::Glb; 87 using HeapType::BitsetType::Lub; 88 using HeapType::BitsetType::IsInhabited; 89 static bitset Glb(Handle<HeapType> type) { return Glb(*type); } 90 static bitset Lub(Handle<HeapType> type) { return Lub(*type); } 91 }; 92}; 93 94 95template<class Type, class TypeHandle, class Region, class Rep> 96struct Tests : Rep { 97 typedef Types<Type, TypeHandle, Region> TypesInstance; 98 typedef typename TypesInstance::TypeVector::iterator TypeIterator; 99 typedef typename TypesInstance::MapVector::iterator MapIterator; 100 typedef typename TypesInstance::ValueVector::iterator ValueIterator; 101 102 Isolate* isolate; 103 HandleScope scope; 104 Zone zone; 105 TypesInstance T; 106 107 Tests() 108 : isolate(CcTest::InitIsolateOnce()), 109 scope(isolate), 110 zone(), 111 T(Rep::ToRegion(&zone, isolate), isolate, 112 isolate->random_number_generator()) {} 113 114 bool Equal(TypeHandle type1, TypeHandle type2) { 115 return 116 type1->Equals(type2) && 117 this->IsBitset(type1) == this->IsBitset(type2) && 118 this->IsUnion(type1) == this->IsUnion(type2) && 119 type1->NumClasses() == type2->NumClasses() && 120 type1->NumConstants() == type2->NumConstants() && 121 (!this->IsBitset(type1) || 122 this->AsBitset(type1) == this->AsBitset(type2)) && 123 (!this->IsUnion(type1) || 124 this->Length(this->AsUnion(type1)) == 125 this->Length(this->AsUnion(type2))); 126 } 127 128 void CheckEqual(TypeHandle type1, TypeHandle type2) { 129 CHECK(Equal(type1, type2)); 130 } 131 132 void CheckSub(TypeHandle type1, TypeHandle type2) { 133 CHECK(type1->Is(type2)); 134 CHECK(!type2->Is(type1)); 135 if (this->IsBitset(type1) && this->IsBitset(type2)) { 136 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); 137 } 138 } 139 140 void CheckSubOrEqual(TypeHandle type1, TypeHandle type2) { 141 CHECK(type1->Is(type2)); 142 if (this->IsBitset(type1) && this->IsBitset(type2)) { 143 CHECK((this->AsBitset(type1) | this->AsBitset(type2)) 144 == this->AsBitset(type2)); 145 } 146 } 147 148 void CheckUnordered(TypeHandle type1, TypeHandle type2) { 149 CHECK(!type1->Is(type2)); 150 CHECK(!type2->Is(type1)); 151 if (this->IsBitset(type1) && this->IsBitset(type2)) { 152 CHECK(this->AsBitset(type1) != this->AsBitset(type2)); 153 } 154 } 155 156 void CheckOverlap(TypeHandle type1, TypeHandle type2) { 157 CHECK(type1->Maybe(type2)); 158 CHECK(type2->Maybe(type1)); 159 } 160 161 void CheckDisjoint(TypeHandle type1, TypeHandle type2) { 162 CHECK(!type1->Is(type2)); 163 CHECK(!type2->Is(type1)); 164 CHECK(!type1->Maybe(type2)); 165 CHECK(!type2->Maybe(type1)); 166 } 167 168 void IsSomeType() { 169 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 170 TypeHandle t = *it; 171 CHECK(1 == 172 this->IsBitset(t) + t->IsClass() + t->IsConstant() + t->IsRange() + 173 this->IsUnion(t) + t->IsArray() + t->IsFunction() + t->IsContext()); 174 } 175 } 176 177 void Bitset() { 178 // None and Any are bitsets. 179 CHECK(this->IsBitset(T.None)); 180 CHECK(this->IsBitset(T.Any)); 181 182 CHECK(bitset(0) == this->AsBitset(T.None)); 183 CHECK(bitset(0xfffffffeu) == this->AsBitset(T.Any)); 184 185 // Union(T1, T2) is bitset for bitsets T1,T2 186 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 187 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 188 TypeHandle type1 = *it1; 189 TypeHandle type2 = *it2; 190 TypeHandle union12 = T.Union(type1, type2); 191 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || 192 this->IsBitset(union12)); 193 } 194 } 195 196 // Intersect(T1, T2) is bitset for bitsets T1,T2 197 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 198 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 199 TypeHandle type1 = *it1; 200 TypeHandle type2 = *it2; 201 TypeHandle intersect12 = T.Intersect(type1, type2); 202 CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) || 203 this->IsBitset(intersect12)); 204 } 205 } 206 207 // Union(T1, T2) is bitset if T2 is bitset and T1->Is(T2) 208 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 209 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 210 TypeHandle type1 = *it1; 211 TypeHandle type2 = *it2; 212 TypeHandle union12 = T.Union(type1, type2); 213 CHECK(!(this->IsBitset(type2) && type1->Is(type2)) || 214 this->IsBitset(union12)); 215 } 216 } 217 218 // Union(T1, T2) is bitwise disjunction for bitsets T1,T2 219 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 220 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 221 TypeHandle type1 = *it1; 222 TypeHandle type2 = *it2; 223 TypeHandle union12 = T.Union(type1, type2); 224 if (this->IsBitset(type1) && this->IsBitset(type2)) { 225 CHECK( 226 (this->AsBitset(type1) | this->AsBitset(type2)) == 227 this->AsBitset(union12)); 228 } 229 } 230 } 231 232 // Intersect(T1, T2) is bitwise conjunction for bitsets T1,T2 (modulo None) 233 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 234 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 235 TypeHandle type1 = *it1; 236 TypeHandle type2 = *it2; 237 if (this->IsBitset(type1) && this->IsBitset(type2)) { 238 TypeHandle intersect12 = T.Intersect(type1, type2); 239 bitset bits = this->AsBitset(type1) & this->AsBitset(type2); 240 CHECK(bits == this->AsBitset(intersect12)); 241 } 242 } 243 } 244 } 245 246 void PointwiseRepresentation() { 247 // Check we can decompose type into semantics and representation and 248 // then compose it back to get an equivalent type. 249 int counter = 0; 250 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 251 counter++; 252 printf("Counter: %i\n", counter); 253 fflush(stdout); 254 TypeHandle type1 = *it1; 255 TypeHandle representation = T.Representation(type1); 256 TypeHandle semantic = T.Semantic(type1); 257 TypeHandle composed = T.Union(representation, semantic); 258 CHECK(type1->Equals(composed)); 259 } 260 261 // Pointwiseness of Union. 262 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 263 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 264 TypeHandle type1 = *it1; 265 TypeHandle type2 = *it2; 266 TypeHandle representation1 = T.Representation(type1); 267 TypeHandle semantic1 = T.Semantic(type1); 268 TypeHandle representation2 = T.Representation(type2); 269 TypeHandle semantic2 = T.Semantic(type2); 270 TypeHandle direct_union = T.Union(type1, type2); 271 TypeHandle representation_union = 272 T.Union(representation1, representation2); 273 TypeHandle semantic_union = T.Union(semantic1, semantic2); 274 TypeHandle composed_union = 275 T.Union(representation_union, semantic_union); 276 CHECK(direct_union->Equals(composed_union)); 277 } 278 } 279 280 // Pointwiseness of Intersect. 281 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 282 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 283 TypeHandle type1 = *it1; 284 TypeHandle type2 = *it2; 285 TypeHandle representation1 = T.Representation(type1); 286 TypeHandle semantic1 = T.Semantic(type1); 287 TypeHandle representation2 = T.Representation(type2); 288 TypeHandle semantic2 = T.Semantic(type2); 289 TypeHandle direct_intersection = T.Intersect(type1, type2); 290 TypeHandle representation_intersection = 291 T.Intersect(representation1, representation2); 292 TypeHandle semantic_intersection = T.Intersect(semantic1, semantic2); 293 TypeHandle composed_intersection = 294 T.Union(representation_intersection, semantic_intersection); 295 CHECK(direct_intersection->Equals(composed_intersection)); 296 } 297 } 298 299 // Pointwiseness of Is. 300 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 301 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 302 TypeHandle type1 = *it1; 303 TypeHandle type2 = *it2; 304 TypeHandle representation1 = T.Representation(type1); 305 TypeHandle semantic1 = T.Semantic(type1); 306 TypeHandle representation2 = T.Representation(type2); 307 TypeHandle semantic2 = T.Semantic(type2); 308 bool representation_is = representation1->Is(representation2); 309 bool semantic_is = semantic1->Is(semantic2); 310 bool direct_is = type1->Is(type2); 311 CHECK(direct_is == (semantic_is && representation_is)); 312 } 313 } 314 } 315 316 void Class() { 317 // Constructor 318 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 319 Handle<i::Map> map = *mt; 320 TypeHandle type = T.Class(map); 321 CHECK(type->IsClass()); 322 } 323 324 // Map attribute 325 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 326 Handle<i::Map> map = *mt; 327 TypeHandle type = T.Class(map); 328 CHECK(*map == *type->AsClass()->Map()); 329 } 330 331 // Functionality & Injectivity: Class(M1) = Class(M2) iff M1 = M2 332 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 333 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 334 Handle<i::Map> map1 = *mt1; 335 Handle<i::Map> map2 = *mt2; 336 TypeHandle type1 = T.Class(map1); 337 TypeHandle type2 = T.Class(map2); 338 CHECK(Equal(type1, type2) == (*map1 == *map2)); 339 } 340 } 341 } 342 343 void Constant() { 344 // Constructor 345 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 346 Handle<i::Object> value = *vt; 347 TypeHandle type = T.Constant(value); 348 CHECK(type->IsConstant()); 349 } 350 351 // Value attribute 352 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 353 Handle<i::Object> value = *vt; 354 TypeHandle type = T.Constant(value); 355 CHECK(*value == *type->AsConstant()->Value()); 356 } 357 358 // Functionality & Injectivity: Constant(V1) = Constant(V2) iff V1 = V2 359 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 360 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 361 Handle<i::Object> value1 = *vt1; 362 Handle<i::Object> value2 = *vt2; 363 TypeHandle type1 = T.Constant(value1); 364 TypeHandle type2 = T.Constant(value2); 365 CHECK(Equal(type1, type2) == (*value1 == *value2)); 366 } 367 } 368 369 // Typing of numbers 370 Factory* fac = isolate->factory(); 371 CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); 372 CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); 373 CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); 374 CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31)); 375 CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.Negative31)); 376 CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.Negative31)); 377 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned31)); 378 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned30)); 379 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned31)); 380 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned30)); 381 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative32)); 382 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative31)); 383 CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.Negative32)); 384 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.Negative31)); 385 if (SmiValuesAre31Bits()) { 386 CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); 387 CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); 388 CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); 389 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); 390 } else { 391 CHECK(SmiValuesAre32Bits()); 392 CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); 393 CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); 394 CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); 395 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); 396 } 397 CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32)); 398 CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned31)); 399 CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32)); 400 CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned31)); 401 CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); 402 CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); 403 CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); 404 CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32)); 405 CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber)); 406 CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32)); 407 CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber)); 408 CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32)); 409 CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber)); 410 CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32)); 411 CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero)); 412 CHECK(T.Constant(fac->NewNumber(std::numeric_limits<double>::quiet_NaN())) 413 ->Is(T.NaN)); 414 CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber)); 415 CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32)); 416 CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber)); 417 CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32)); 418 } 419 420 void Range() { 421 // Constructor 422 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { 423 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { 424 double min = (*i)->Number(); 425 double max = (*j)->Number(); 426 if (min > max) std::swap(min, max); 427 TypeHandle type = T.Range(min, max); 428 CHECK(type->IsRange()); 429 } 430 } 431 432 // Range attributes 433 for (ValueIterator i = T.integers.begin(); i != T.integers.end(); ++i) { 434 for (ValueIterator j = T.integers.begin(); j != T.integers.end(); ++j) { 435 double min = (*i)->Number(); 436 double max = (*j)->Number(); 437 if (min > max) std::swap(min, max); 438 TypeHandle type = T.Range(min, max); 439 CHECK(min == type->AsRange()->Min()); 440 CHECK(max == type->AsRange()->Max()); 441 } 442 } 443 444 // Functionality & Injectivity: 445 // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2 446 for (ValueIterator i1 = T.integers.begin(); 447 i1 != T.integers.end(); ++i1) { 448 for (ValueIterator j1 = i1; 449 j1 != T.integers.end(); ++j1) { 450 for (ValueIterator i2 = T.integers.begin(); 451 i2 != T.integers.end(); ++i2) { 452 for (ValueIterator j2 = i2; 453 j2 != T.integers.end(); ++j2) { 454 double min1 = (*i1)->Number(); 455 double max1 = (*j1)->Number(); 456 double min2 = (*i2)->Number(); 457 double max2 = (*j2)->Number(); 458 if (min1 > max1) std::swap(min1, max1); 459 if (min2 > max2) std::swap(min2, max2); 460 TypeHandle type1 = T.Range(min1, max1); 461 TypeHandle type2 = T.Range(min2, max2); 462 CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2)); 463 } 464 } 465 } 466 } 467 } 468 469 void Context() { 470 // Constructor 471 for (int i = 0; i < 20; ++i) { 472 TypeHandle type = T.Random(); 473 TypeHandle context = T.Context(type); 474 CHECK(context->Iscontext()); 475 } 476 477 // Attributes 478 for (int i = 0; i < 20; ++i) { 479 TypeHandle type = T.Random(); 480 TypeHandle context = T.Context(type); 481 CheckEqual(type, context->AsContext()->Outer()); 482 } 483 484 // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2 485 for (int i = 0; i < 20; ++i) { 486 for (int j = 0; j < 20; ++j) { 487 TypeHandle type1 = T.Random(); 488 TypeHandle type2 = T.Random(); 489 TypeHandle context1 = T.Context(type1); 490 TypeHandle context2 = T.Context(type2); 491 CHECK(Equal(context1, context2) == Equal(type1, type2)); 492 } 493 } 494 } 495 496 void Array() { 497 // Constructor 498 for (int i = 0; i < 20; ++i) { 499 TypeHandle type = T.Random(); 500 TypeHandle array = T.Array1(type); 501 CHECK(array->IsArray()); 502 } 503 504 // Attributes 505 for (int i = 0; i < 20; ++i) { 506 TypeHandle type = T.Random(); 507 TypeHandle array = T.Array1(type); 508 CheckEqual(type, array->AsArray()->Element()); 509 } 510 511 // Functionality & Injectivity: Array(T1) = Array(T2) iff T1 = T2 512 for (int i = 0; i < 20; ++i) { 513 for (int j = 0; j < 20; ++j) { 514 TypeHandle type1 = T.Random(); 515 TypeHandle type2 = T.Random(); 516 TypeHandle array1 = T.Array1(type1); 517 TypeHandle array2 = T.Array1(type2); 518 CHECK(Equal(array1, array2) == Equal(type1, type2)); 519 } 520 } 521 } 522 523 void Function() { 524 // Constructors 525 for (int i = 0; i < 20; ++i) { 526 for (int j = 0; j < 20; ++j) { 527 for (int k = 0; k < 20; ++k) { 528 TypeHandle type1 = T.Random(); 529 TypeHandle type2 = T.Random(); 530 TypeHandle type3 = T.Random(); 531 TypeHandle function0 = T.Function0(type1, type2); 532 TypeHandle function1 = T.Function1(type1, type2, type3); 533 TypeHandle function2 = T.Function2(type1, type2, type3); 534 CHECK(function0->IsFunction()); 535 CHECK(function1->IsFunction()); 536 CHECK(function2->IsFunction()); 537 } 538 } 539 } 540 541 // Attributes 542 for (int i = 0; i < 20; ++i) { 543 for (int j = 0; j < 20; ++j) { 544 for (int k = 0; k < 20; ++k) { 545 TypeHandle type1 = T.Random(); 546 TypeHandle type2 = T.Random(); 547 TypeHandle type3 = T.Random(); 548 TypeHandle function0 = T.Function0(type1, type2); 549 TypeHandle function1 = T.Function1(type1, type2, type3); 550 TypeHandle function2 = T.Function2(type1, type2, type3); 551 CHECK_EQ(0, function0->AsFunction()->Arity()); 552 CHECK_EQ(1, function1->AsFunction()->Arity()); 553 CHECK_EQ(2, function2->AsFunction()->Arity()); 554 CheckEqual(type1, function0->AsFunction()->Result()); 555 CheckEqual(type1, function1->AsFunction()->Result()); 556 CheckEqual(type1, function2->AsFunction()->Result()); 557 CheckEqual(type2, function0->AsFunction()->Receiver()); 558 CheckEqual(type2, function1->AsFunction()->Receiver()); 559 CheckEqual(T.Any, function2->AsFunction()->Receiver()); 560 CheckEqual(type3, function1->AsFunction()->Parameter(0)); 561 CheckEqual(type2, function2->AsFunction()->Parameter(0)); 562 CheckEqual(type3, function2->AsFunction()->Parameter(1)); 563 } 564 } 565 } 566 567 // Functionality & Injectivity: Function(Ts1) = Function(Ts2) iff Ts1 = Ts2 568 for (int i = 0; i < 20; ++i) { 569 for (int j = 0; j < 20; ++j) { 570 for (int k = 0; k < 20; ++k) { 571 TypeHandle type1 = T.Random(); 572 TypeHandle type2 = T.Random(); 573 TypeHandle type3 = T.Random(); 574 TypeHandle function01 = T.Function0(type1, type2); 575 TypeHandle function02 = T.Function0(type1, type3); 576 TypeHandle function03 = T.Function0(type3, type2); 577 TypeHandle function11 = T.Function1(type1, type2, type2); 578 TypeHandle function12 = T.Function1(type1, type2, type3); 579 TypeHandle function21 = T.Function2(type1, type2, type2); 580 TypeHandle function22 = T.Function2(type1, type2, type3); 581 TypeHandle function23 = T.Function2(type1, type3, type2); 582 CHECK(Equal(function01, function02) == Equal(type2, type3)); 583 CHECK(Equal(function01, function03) == Equal(type1, type3)); 584 CHECK(Equal(function11, function12) == Equal(type2, type3)); 585 CHECK(Equal(function21, function22) == Equal(type2, type3)); 586 CHECK(Equal(function21, function23) == Equal(type2, type3)); 587 } 588 } 589 } 590 } 591 592 void Of() { 593 // Constant(V)->Is(Of(V)) 594 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 595 Handle<i::Object> value = *vt; 596 TypeHandle const_type = T.Constant(value); 597 TypeHandle of_type = T.Of(value); 598 CHECK(const_type->Is(of_type)); 599 } 600 601 // If Of(V)->Is(T), then Constant(V)->Is(T) 602 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 603 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 604 Handle<i::Object> value = *vt; 605 TypeHandle type = *it; 606 TypeHandle const_type = T.Constant(value); 607 TypeHandle of_type = T.Of(value); 608 CHECK(!of_type->Is(type) || const_type->Is(type)); 609 } 610 } 611 612 // If Constant(V)->Is(T), then Of(V)->Is(T) or T->Maybe(Constant(V)) 613 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 614 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 615 Handle<i::Object> value = *vt; 616 TypeHandle type = *it; 617 TypeHandle const_type = T.Constant(value); 618 TypeHandle of_type = T.Of(value); 619 CHECK(!const_type->Is(type) || 620 of_type->Is(type) || type->Maybe(const_type)); 621 } 622 } 623 } 624 625 void NowOf() { 626 // Constant(V)->NowIs(NowOf(V)) 627 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 628 Handle<i::Object> value = *vt; 629 TypeHandle const_type = T.Constant(value); 630 TypeHandle nowof_type = T.NowOf(value); 631 CHECK(const_type->NowIs(nowof_type)); 632 } 633 634 // NowOf(V)->Is(Of(V)) 635 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 636 Handle<i::Object> value = *vt; 637 TypeHandle nowof_type = T.NowOf(value); 638 TypeHandle of_type = T.Of(value); 639 CHECK(nowof_type->Is(of_type)); 640 } 641 642 // If NowOf(V)->NowIs(T), then Constant(V)->NowIs(T) 643 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 644 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 645 Handle<i::Object> value = *vt; 646 TypeHandle type = *it; 647 TypeHandle const_type = T.Constant(value); 648 TypeHandle nowof_type = T.NowOf(value); 649 CHECK(!nowof_type->NowIs(type) || const_type->NowIs(type)); 650 } 651 } 652 653 // If Constant(V)->NowIs(T), 654 // then NowOf(V)->NowIs(T) or T->Maybe(Constant(V)) 655 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 656 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 657 Handle<i::Object> value = *vt; 658 TypeHandle type = *it; 659 TypeHandle const_type = T.Constant(value); 660 TypeHandle nowof_type = T.NowOf(value); 661 CHECK(!const_type->NowIs(type) || 662 nowof_type->NowIs(type) || type->Maybe(const_type)); 663 } 664 } 665 666 // If Constant(V)->Is(T), 667 // then NowOf(V)->Is(T) or T->Maybe(Constant(V)) 668 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 669 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 670 Handle<i::Object> value = *vt; 671 TypeHandle type = *it; 672 TypeHandle const_type = T.Constant(value); 673 TypeHandle nowof_type = T.NowOf(value); 674 CHECK(!const_type->Is(type) || 675 nowof_type->Is(type) || type->Maybe(const_type)); 676 } 677 } 678 } 679 680 void MinMax() { 681 // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b). 682 // TODO(neis): Need to ignore representation for this to be true. 683 /* 684 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 685 TypeHandle type = *it; 686 if (this->IsBitset(type) && type->Is(T.Number) && 687 !type->Is(T.None) && !type->Is(T.NaN)) { 688 TypeHandle range = T.Range( 689 isolate->factory()->NewNumber(type->Min()), 690 isolate->factory()->NewNumber(type->Max())); 691 CHECK(range->Is(type)); 692 } 693 } 694 */ 695 696 // If b is regular numeric bitset, then b->Min() and b->Max() are integers. 697 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 698 TypeHandle type = *it; 699 if (this->IsBitset(type) && type->Is(T.Number) && !type->Is(T.NaN)) { 700 CHECK(IsInteger(type->Min()) && IsInteger(type->Max())); 701 } 702 } 703 704 // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then 705 // b1->Min() >= b2->Min() and b1->Max() <= b2->Max(). 706 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 707 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 708 TypeHandle type1 = *it1; 709 TypeHandle type2 = *it2; 710 if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) && 711 !type1->Is(T.NaN) && !type2->Is(T.NaN)) { 712 CHECK(type1->Min() >= type2->Min()); 713 CHECK(type1->Max() <= type2->Max()); 714 } 715 } 716 } 717 718 // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max() 719 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 720 TypeHandle type = *it; 721 if (type->IsRange()) { 722 TypeHandle lub = Rep::BitsetType::New( 723 Rep::BitsetType::Lub(type), T.region()); 724 CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max()); 725 } 726 } 727 728 // Rangification: If T->Is(Range(-inf,+inf)) and T is inhabited, then 729 // T->Is(Range(T->Min(), T->Max())). 730 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 731 TypeHandle type = *it; 732 CHECK(!type->Is(T.Integer) || !type->IsInhabited() || 733 type->Is(T.Range(type->Min(), type->Max()))); 734 } 735 } 736 737 void BitsetGlb() { 738 // Lower: (T->BitsetGlb())->Is(T) 739 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 740 TypeHandle type = *it; 741 TypeHandle glb = 742 Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); 743 CHECK(glb->Is(type)); 744 } 745 746 // Greatest: If T1->IsBitset() and T1->Is(T2), then T1->Is(T2->BitsetGlb()) 747 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 748 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 749 TypeHandle type1 = *it1; 750 TypeHandle type2 = *it2; 751 TypeHandle glb2 = 752 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region()); 753 CHECK(!this->IsBitset(type1) || !type1->Is(type2) || type1->Is(glb2)); 754 } 755 } 756 757 // Monotonicity: T1->Is(T2) implies (T1->BitsetGlb())->Is(T2->BitsetGlb()) 758 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 759 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 760 TypeHandle type1 = *it1; 761 TypeHandle type2 = *it2; 762 TypeHandle glb1 = 763 Rep::BitsetType::New(Rep::BitsetType::Glb(type1), T.region()); 764 TypeHandle glb2 = 765 Rep::BitsetType::New(Rep::BitsetType::Glb(type2), T.region()); 766 CHECK(!type1->Is(type2) || glb1->Is(glb2)); 767 } 768 } 769 } 770 771 void BitsetLub() { 772 // Upper: T->Is(T->BitsetLub()) 773 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 774 TypeHandle type = *it; 775 TypeHandle lub = 776 Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); 777 CHECK(type->Is(lub)); 778 } 779 780 // Least: If T2->IsBitset() and T1->Is(T2), then (T1->BitsetLub())->Is(T2) 781 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 782 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 783 TypeHandle type1 = *it1; 784 TypeHandle type2 = *it2; 785 TypeHandle lub1 = 786 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region()); 787 CHECK(!this->IsBitset(type2) || !type1->Is(type2) || lub1->Is(type2)); 788 } 789 } 790 791 // Monotonicity: T1->Is(T2) implies (T1->BitsetLub())->Is(T2->BitsetLub()) 792 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 793 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 794 TypeHandle type1 = *it1; 795 TypeHandle type2 = *it2; 796 TypeHandle lub1 = 797 Rep::BitsetType::New(Rep::BitsetType::Lub(type1), T.region()); 798 TypeHandle lub2 = 799 Rep::BitsetType::New(Rep::BitsetType::Lub(type2), T.region()); 800 CHECK(!type1->Is(type2) || lub1->Is(lub2)); 801 } 802 } 803 } 804 805 void Is1() { 806 // Least Element (Bottom): None->Is(T) 807 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 808 TypeHandle type = *it; 809 CHECK(T.None->Is(type)); 810 } 811 812 // Greatest Element (Top): T->Is(Any) 813 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 814 TypeHandle type = *it; 815 CHECK(type->Is(T.Any)); 816 } 817 818 // Bottom Uniqueness: T->Is(None) implies T = None 819 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 820 TypeHandle type = *it; 821 if (type->Is(T.None)) CheckEqual(type, T.None); 822 } 823 824 // Top Uniqueness: Any->Is(T) implies T = Any 825 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 826 TypeHandle type = *it; 827 if (T.Any->Is(type)) CheckEqual(type, T.Any); 828 } 829 830 // Reflexivity: T->Is(T) 831 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 832 TypeHandle type = *it; 833 CHECK(type->Is(type)); 834 } 835 836 // Transitivity: T1->Is(T2) and T2->Is(T3) implies T1->Is(T3) 837 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 838 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 839 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 840 TypeHandle type1 = *it1; 841 TypeHandle type2 = *it2; 842 TypeHandle type3 = *it3; 843 CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3)); 844 } 845 } 846 } 847 848 // Antisymmetry: T1->Is(T2) and T2->Is(T1) iff T1 = T2 849 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 850 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 851 TypeHandle type1 = *it1; 852 TypeHandle type2 = *it2; 853 CHECK((type1->Is(type2) && type2->Is(type1)) == Equal(type1, type2)); 854 } 855 } 856 857 // (In-)Compatibilities. 858 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { 859 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { 860 TypeHandle type1 = *i; 861 TypeHandle type2 = *j; 862 CHECK(!type1->Is(type2) || this->IsBitset(type2) || 863 this->IsUnion(type2) || this->IsUnion(type1) || 864 (type1->IsClass() && type2->IsClass()) || 865 (type1->IsConstant() && type2->IsConstant()) || 866 (type1->IsConstant() && type2->IsRange()) || 867 (this->IsBitset(type1) && type2->IsRange()) || 868 (type1->IsRange() && type2->IsRange()) || 869 (type1->IsContext() && type2->IsContext()) || 870 (type1->IsArray() && type2->IsArray()) || 871 (type1->IsFunction() && type2->IsFunction()) || 872 !type1->IsInhabited()); 873 } 874 } 875 } 876 877 void Is2() { 878 // Class(M1)->Is(Class(M2)) iff M1 = M2 879 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 880 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 881 Handle<i::Map> map1 = *mt1; 882 Handle<i::Map> map2 = *mt2; 883 TypeHandle class_type1 = T.Class(map1); 884 TypeHandle class_type2 = T.Class(map2); 885 CHECK(class_type1->Is(class_type2) == (*map1 == *map2)); 886 } 887 } 888 889 // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2 890 for (ValueIterator i1 = T.integers.begin(); 891 i1 != T.integers.end(); ++i1) { 892 for (ValueIterator j1 = i1; 893 j1 != T.integers.end(); ++j1) { 894 for (ValueIterator i2 = T.integers.begin(); 895 i2 != T.integers.end(); ++i2) { 896 for (ValueIterator j2 = i2; 897 j2 != T.integers.end(); ++j2) { 898 double min1 = (*i1)->Number(); 899 double max1 = (*j1)->Number(); 900 double min2 = (*i2)->Number(); 901 double max2 = (*j2)->Number(); 902 if (min1 > max1) std::swap(min1, max1); 903 if (min2 > max2) std::swap(min2, max2); 904 TypeHandle type1 = T.Range(min1, max1); 905 TypeHandle type2 = T.Range(min2, max2); 906 CHECK(type1->Is(type2) == (min1 >= min2 && max1 <= max2)); 907 } 908 } 909 } 910 } 911 912 // Constant(V1)->Is(Constant(V2)) iff V1 = V2 913 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 914 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 915 Handle<i::Object> value1 = *vt1; 916 Handle<i::Object> value2 = *vt2; 917 TypeHandle const_type1 = T.Constant(value1); 918 TypeHandle const_type2 = T.Constant(value2); 919 CHECK(const_type1->Is(const_type2) == (*value1 == *value2)); 920 } 921 } 922 923 // Context(T1)->Is(Context(T2)) iff T1 = T2 924 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 925 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 926 TypeHandle outer1 = *it1; 927 TypeHandle outer2 = *it2; 928 TypeHandle type1 = T.Context(outer1); 929 TypeHandle type2 = T.Context(outer2); 930 CHECK(type1->Is(type2) == outer1->Equals(outer2)); 931 } 932 } 933 934 // Array(T1)->Is(Array(T2)) iff T1 = T2 935 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 936 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 937 TypeHandle element1 = *it1; 938 TypeHandle element2 = *it2; 939 TypeHandle type1 = T.Array1(element1); 940 TypeHandle type2 = T.Array1(element2); 941 CHECK(type1->Is(type2) == element1->Equals(element2)); 942 } 943 } 944 945 // Function0(S1, T1)->Is(Function0(S2, T2)) iff S1 = S2 and T1 = T2 946 for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) { 947 for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) { 948 TypeHandle result1 = *i; 949 TypeHandle receiver1 = *j; 950 TypeHandle type1 = T.Function0(result1, receiver1); 951 TypeHandle result2 = T.Random(); 952 TypeHandle receiver2 = T.Random(); 953 TypeHandle type2 = T.Function0(result2, receiver2); 954 CHECK(type1->Is(type2) == 955 (result1->Equals(result2) && receiver1->Equals(receiver2))); 956 } 957 } 958 959 960 // Range-specific subtyping 961 962 // If IsInteger(v) then Constant(v)->Is(Range(v, v)). 963 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 964 TypeHandle type = *it; 965 if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) { 966 CHECK(type->Is(T.Range(type->AsConstant()->Value()->Number(), 967 type->AsConstant()->Value()->Number()))); 968 } 969 } 970 971 // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max. 972 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 973 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 974 TypeHandle type1 = *it1; 975 TypeHandle type2 = *it2; 976 if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) { 977 double x = type1->AsConstant()->Value()->Number(); 978 double min = type2->AsRange()->Min(); 979 double max = type2->AsRange()->Max(); 980 CHECK(IsInteger(x) && min <= x && x <= max); 981 } 982 } 983 } 984 985 // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber)) 986 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 987 TypeHandle type = *it; 988 if (type->IsRange()) { 989 TypeHandle lub = Rep::BitsetType::New( 990 Rep::BitsetType::Lub(type), T.region()); 991 CHECK(lub->Is(T.PlainNumber)); 992 } 993 } 994 995 996 // Subtyping between concrete basic types 997 998 CheckUnordered(T.Boolean, T.Null); 999 CheckUnordered(T.Undefined, T.Null); 1000 CheckUnordered(T.Boolean, T.Undefined); 1001 1002 CheckSub(T.SignedSmall, T.Number); 1003 CheckSub(T.Signed32, T.Number); 1004 CheckSubOrEqual(T.SignedSmall, T.Signed32); 1005 CheckUnordered(T.SignedSmall, T.MinusZero); 1006 CheckUnordered(T.Signed32, T.Unsigned32); 1007 1008 CheckSub(T.UniqueName, T.Name); 1009 CheckSub(T.String, T.Name); 1010 CheckSub(T.InternalizedString, T.String); 1011 CheckSub(T.InternalizedString, T.UniqueName); 1012 CheckSub(T.InternalizedString, T.Name); 1013 CheckSub(T.Symbol, T.UniqueName); 1014 CheckSub(T.Symbol, T.Name); 1015 CheckUnordered(T.String, T.UniqueName); 1016 CheckUnordered(T.String, T.Symbol); 1017 CheckUnordered(T.InternalizedString, T.Symbol); 1018 1019 CheckSub(T.Object, T.Receiver); 1020 CheckSub(T.Proxy, T.Receiver); 1021 CheckSub(T.OtherObject, T.Object); 1022 CheckSub(T.Undetectable, T.Object); 1023 CheckSub(T.OtherObject, T.Object); 1024 1025 CheckUnordered(T.Object, T.Proxy); 1026 CheckUnordered(T.OtherObject, T.Undetectable); 1027 1028 // Subtyping between concrete structural types 1029 1030 CheckSub(T.ObjectClass, T.Object); 1031 CheckSub(T.ArrayClass, T.OtherObject); 1032 CheckSub(T.UninitializedClass, T.Internal); 1033 CheckUnordered(T.ObjectClass, T.ArrayClass); 1034 CheckUnordered(T.UninitializedClass, T.Null); 1035 CheckUnordered(T.UninitializedClass, T.Undefined); 1036 1037 CheckSub(T.SmiConstant, T.SignedSmall); 1038 CheckSub(T.SmiConstant, T.Signed32); 1039 CheckSub(T.SmiConstant, T.Number); 1040 CheckSub(T.ObjectConstant1, T.Object); 1041 CheckSub(T.ObjectConstant2, T.Object); 1042 CheckSub(T.ArrayConstant, T.Object); 1043 CheckSub(T.ArrayConstant, T.OtherObject); 1044 CheckSub(T.ArrayConstant, T.Receiver); 1045 CheckSub(T.UninitializedConstant, T.Internal); 1046 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); 1047 CheckUnordered(T.ObjectConstant1, T.ArrayConstant); 1048 CheckUnordered(T.UninitializedConstant, T.Null); 1049 CheckUnordered(T.UninitializedConstant, T.Undefined); 1050 1051 CheckUnordered(T.ObjectConstant1, T.ObjectClass); 1052 CheckUnordered(T.ObjectConstant2, T.ObjectClass); 1053 CheckUnordered(T.ObjectConstant1, T.ArrayClass); 1054 CheckUnordered(T.ObjectConstant2, T.ArrayClass); 1055 CheckUnordered(T.ArrayConstant, T.ObjectClass); 1056 1057 CheckSub(T.NumberArray, T.OtherObject); 1058 CheckSub(T.NumberArray, T.Receiver); 1059 CheckSub(T.NumberArray, T.Object); 1060 CheckUnordered(T.StringArray, T.AnyArray); 1061 1062 CheckSub(T.MethodFunction, T.Object); 1063 CheckSub(T.NumberFunction1, T.Object); 1064 CheckUnordered(T.SignedFunction1, T.NumberFunction1); 1065 CheckUnordered(T.NumberFunction1, T.NumberFunction2); 1066 } 1067 1068 void NowIs() { 1069 // Least Element (Bottom): None->NowIs(T) 1070 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1071 TypeHandle type = *it; 1072 CHECK(T.None->NowIs(type)); 1073 } 1074 1075 // Greatest Element (Top): T->NowIs(Any) 1076 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1077 TypeHandle type = *it; 1078 CHECK(type->NowIs(T.Any)); 1079 } 1080 1081 // Bottom Uniqueness: T->NowIs(None) implies T = None 1082 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1083 TypeHandle type = *it; 1084 if (type->NowIs(T.None)) CheckEqual(type, T.None); 1085 } 1086 1087 // Top Uniqueness: Any->NowIs(T) implies T = Any 1088 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1089 TypeHandle type = *it; 1090 if (T.Any->NowIs(type)) CheckEqual(type, T.Any); 1091 } 1092 1093 // Reflexivity: T->NowIs(T) 1094 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1095 TypeHandle type = *it; 1096 CHECK(type->NowIs(type)); 1097 } 1098 1099 // Transitivity: T1->NowIs(T2) and T2->NowIs(T3) implies T1->NowIs(T3) 1100 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1101 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1102 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1103 TypeHandle type1 = *it1; 1104 TypeHandle type2 = *it2; 1105 TypeHandle type3 = *it3; 1106 CHECK(!(type1->NowIs(type2) && type2->NowIs(type3)) || 1107 type1->NowIs(type3)); 1108 } 1109 } 1110 } 1111 1112 // Antisymmetry: T1->NowIs(T2) and T2->NowIs(T1) iff T1 = T2 1113 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1114 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1115 TypeHandle type1 = *it1; 1116 TypeHandle type2 = *it2; 1117 CHECK((type1->NowIs(type2) && type2->NowIs(type1)) == 1118 Equal(type1, type2)); 1119 } 1120 } 1121 1122 // T1->Is(T2) implies T1->NowIs(T2) 1123 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1124 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1125 TypeHandle type1 = *it1; 1126 TypeHandle type2 = *it2; 1127 CHECK(!type1->Is(type2) || type1->NowIs(type2)); 1128 } 1129 } 1130 1131 // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2 1132 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 1133 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 1134 Handle<i::Object> value1 = *vt1; 1135 Handle<i::Object> value2 = *vt2; 1136 TypeHandle const_type1 = T.Constant(value1); 1137 TypeHandle const_type2 = T.Constant(value2); 1138 CHECK(const_type1->NowIs(const_type2) == (*value1 == *value2)); 1139 } 1140 } 1141 1142 // Class(M1)->NowIs(Class(M2)) iff M1 = M2 1143 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 1144 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 1145 Handle<i::Map> map1 = *mt1; 1146 Handle<i::Map> map2 = *mt2; 1147 TypeHandle class_type1 = T.Class(map1); 1148 TypeHandle class_type2 = T.Class(map2); 1149 CHECK(class_type1->NowIs(class_type2) == (*map1 == *map2)); 1150 } 1151 } 1152 1153 // Constant(V)->NowIs(Class(M)) iff V has map M 1154 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1155 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1156 Handle<i::Map> map = *mt; 1157 Handle<i::Object> value = *vt; 1158 TypeHandle const_type = T.Constant(value); 1159 TypeHandle class_type = T.Class(map); 1160 CHECK((value->IsHeapObject() && 1161 i::HeapObject::cast(*value)->map() == *map) 1162 == const_type->NowIs(class_type)); 1163 } 1164 } 1165 1166 // Class(M)->NowIs(Constant(V)) never 1167 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1168 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1169 Handle<i::Map> map = *mt; 1170 Handle<i::Object> value = *vt; 1171 TypeHandle const_type = T.Constant(value); 1172 TypeHandle class_type = T.Class(map); 1173 CHECK(!class_type->NowIs(const_type)); 1174 } 1175 } 1176 } 1177 1178 void Contains() { 1179 // T->Contains(V) iff Constant(V)->Is(T) 1180 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1181 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1182 TypeHandle type = *it; 1183 Handle<i::Object> value = *vt; 1184 TypeHandle const_type = T.Constant(value); 1185 CHECK(type->Contains(value) == const_type->Is(type)); 1186 } 1187 } 1188 } 1189 1190 void NowContains() { 1191 // T->NowContains(V) iff Constant(V)->NowIs(T) 1192 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1193 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1194 TypeHandle type = *it; 1195 Handle<i::Object> value = *vt; 1196 TypeHandle const_type = T.Constant(value); 1197 CHECK(type->NowContains(value) == const_type->NowIs(type)); 1198 } 1199 } 1200 1201 // T->Contains(V) implies T->NowContains(V) 1202 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1203 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1204 TypeHandle type = *it; 1205 Handle<i::Object> value = *vt; 1206 CHECK(!type->Contains(value) || type->NowContains(value)); 1207 } 1208 } 1209 1210 // NowOf(V)->Is(T) implies T->NowContains(V) 1211 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1212 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1213 TypeHandle type = *it; 1214 Handle<i::Object> value = *vt; 1215 TypeHandle nowof_type = T.Of(value); 1216 CHECK(!nowof_type->NowIs(type) || type->NowContains(value)); 1217 } 1218 } 1219 } 1220 1221 void Maybe() { 1222 // T->Maybe(Any) iff T inhabited 1223 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1224 TypeHandle type = *it; 1225 CHECK(type->Maybe(T.Any) == type->IsInhabited()); 1226 } 1227 1228 // T->Maybe(None) never 1229 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1230 TypeHandle type = *it; 1231 CHECK(!type->Maybe(T.None)); 1232 } 1233 1234 // Reflexivity upto Inhabitation: T->Maybe(T) iff T inhabited 1235 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1236 TypeHandle type = *it; 1237 CHECK(type->Maybe(type) == type->IsInhabited()); 1238 } 1239 1240 // Symmetry: T1->Maybe(T2) iff T2->Maybe(T1) 1241 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1242 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1243 TypeHandle type1 = *it1; 1244 TypeHandle type2 = *it2; 1245 CHECK(type1->Maybe(type2) == type2->Maybe(type1)); 1246 } 1247 } 1248 1249 // T1->Maybe(T2) implies T1, T2 inhabited 1250 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1251 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1252 TypeHandle type1 = *it1; 1253 TypeHandle type2 = *it2; 1254 CHECK(!type1->Maybe(type2) || 1255 (type1->IsInhabited() && type2->IsInhabited())); 1256 } 1257 } 1258 1259 // T1->Maybe(T2) implies Intersect(T1, T2) inhabited 1260 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1261 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1262 TypeHandle type1 = *it1; 1263 TypeHandle type2 = *it2; 1264 TypeHandle intersect12 = T.Intersect(type1, type2); 1265 CHECK(!type1->Maybe(type2) || intersect12->IsInhabited()); 1266 } 1267 } 1268 1269 // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) 1270 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1271 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1272 TypeHandle type1 = *it1; 1273 TypeHandle type2 = *it2; 1274 CHECK(!(type1->Is(type2) && type1->IsInhabited()) || 1275 type1->Maybe(type2)); 1276 } 1277 } 1278 1279 // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2 1280 for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) { 1281 for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) { 1282 Handle<i::Object> value1 = *vt1; 1283 Handle<i::Object> value2 = *vt2; 1284 TypeHandle const_type1 = T.Constant(value1); 1285 TypeHandle const_type2 = T.Constant(value2); 1286 CHECK(const_type1->Maybe(const_type2) == (*value1 == *value2)); 1287 } 1288 } 1289 1290 // Class(M1)->Maybe(Class(M2)) iff M1 = M2 1291 for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) { 1292 for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) { 1293 Handle<i::Map> map1 = *mt1; 1294 Handle<i::Map> map2 = *mt2; 1295 TypeHandle class_type1 = T.Class(map1); 1296 TypeHandle class_type2 = T.Class(map2); 1297 CHECK(class_type1->Maybe(class_type2) == (*map1 == *map2)); 1298 } 1299 } 1300 1301 // Constant(V)->Maybe(Class(M)) never 1302 // This does NOT hold! 1303 /* 1304 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1305 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1306 Handle<i::Map> map = *mt; 1307 Handle<i::Object> value = *vt; 1308 TypeHandle const_type = T.Constant(value); 1309 TypeHandle class_type = T.Class(map); 1310 CHECK(!const_type->Maybe(class_type)); 1311 } 1312 } 1313 */ 1314 1315 // Class(M)->Maybe(Constant(V)) never 1316 // This does NOT hold! 1317 /* 1318 for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { 1319 for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { 1320 Handle<i::Map> map = *mt; 1321 Handle<i::Object> value = *vt; 1322 TypeHandle const_type = T.Constant(value); 1323 TypeHandle class_type = T.Class(map); 1324 CHECK(!class_type->Maybe(const_type)); 1325 } 1326 } 1327 */ 1328 1329 // Basic types 1330 CheckDisjoint(T.Boolean, T.Null); 1331 CheckDisjoint(T.Undefined, T.Null); 1332 CheckDisjoint(T.Boolean, T.Undefined); 1333 CheckOverlap(T.SignedSmall, T.Number); 1334 CheckOverlap(T.NaN, T.Number); 1335 CheckDisjoint(T.Signed32, T.NaN); 1336 CheckOverlap(T.UniqueName, T.Name); 1337 CheckOverlap(T.String, T.Name); 1338 CheckOverlap(T.InternalizedString, T.String); 1339 CheckOverlap(T.InternalizedString, T.UniqueName); 1340 CheckOverlap(T.InternalizedString, T.Name); 1341 CheckOverlap(T.Symbol, T.UniqueName); 1342 CheckOverlap(T.Symbol, T.Name); 1343 CheckOverlap(T.String, T.UniqueName); 1344 CheckDisjoint(T.String, T.Symbol); 1345 CheckDisjoint(T.InternalizedString, T.Symbol); 1346 CheckOverlap(T.Object, T.Receiver); 1347 CheckOverlap(T.OtherObject, T.Object); 1348 CheckOverlap(T.Proxy, T.Receiver); 1349 CheckDisjoint(T.Object, T.Proxy); 1350 1351 // Structural types 1352 CheckOverlap(T.ObjectClass, T.Object); 1353 CheckOverlap(T.ArrayClass, T.Object); 1354 CheckOverlap(T.ObjectClass, T.ObjectClass); 1355 CheckOverlap(T.ArrayClass, T.ArrayClass); 1356 CheckDisjoint(T.ObjectClass, T.ArrayClass); 1357 CheckOverlap(T.SmiConstant, T.SignedSmall); 1358 CheckOverlap(T.SmiConstant, T.Signed32); 1359 CheckOverlap(T.SmiConstant, T.Number); 1360 CheckOverlap(T.ObjectConstant1, T.Object); 1361 CheckOverlap(T.ObjectConstant2, T.Object); 1362 CheckOverlap(T.ArrayConstant, T.Object); 1363 CheckOverlap(T.ArrayConstant, T.Receiver); 1364 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1); 1365 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2); 1366 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant); 1367 CheckOverlap(T.ObjectConstant1, T.ArrayClass); 1368 CheckOverlap(T.ObjectConstant2, T.ArrayClass); 1369 CheckOverlap(T.ArrayConstant, T.ObjectClass); 1370 CheckOverlap(T.NumberArray, T.Receiver); 1371 CheckDisjoint(T.NumberArray, T.AnyArray); 1372 CheckDisjoint(T.NumberArray, T.StringArray); 1373 CheckOverlap(T.MethodFunction, T.Object); 1374 CheckDisjoint(T.SignedFunction1, T.NumberFunction1); 1375 CheckDisjoint(T.SignedFunction1, T.NumberFunction2); 1376 CheckDisjoint(T.NumberFunction1, T.NumberFunction2); 1377 CheckDisjoint(T.SignedFunction1, T.MethodFunction); 1378 CheckOverlap(T.ObjectConstant1, T.ObjectClass); // !!! 1379 CheckOverlap(T.ObjectConstant2, T.ObjectClass); // !!! 1380 CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged)); // !!! 1381 } 1382 1383 void Union1() { 1384 // Identity: Union(T, None) = T 1385 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1386 TypeHandle type = *it; 1387 TypeHandle union_type = T.Union(type, T.None); 1388 CheckEqual(union_type, type); 1389 } 1390 1391 // Domination: Union(T, Any) = Any 1392 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1393 TypeHandle type = *it; 1394 TypeHandle union_type = T.Union(type, T.Any); 1395 CheckEqual(union_type, T.Any); 1396 } 1397 1398 // Idempotence: Union(T, T) = T 1399 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1400 TypeHandle type = *it; 1401 TypeHandle union_type = T.Union(type, type); 1402 CheckEqual(union_type, type); 1403 } 1404 1405 // Commutativity: Union(T1, T2) = Union(T2, T1) 1406 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1407 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1408 TypeHandle type1 = *it1; 1409 TypeHandle type2 = *it2; 1410 TypeHandle union12 = T.Union(type1, type2); 1411 TypeHandle union21 = T.Union(type2, type1); 1412 CheckEqual(union12, union21); 1413 } 1414 } 1415 1416 // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3) 1417 // This does NOT hold! For example: 1418 // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0) 1419 // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5) 1420 /* 1421 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1422 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1423 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1424 TypeHandle type1 = *it1; 1425 TypeHandle type2 = *it2; 1426 TypeHandle type3 = *it3; 1427 TypeHandle union12 = T.Union(type1, type2); 1428 TypeHandle union23 = T.Union(type2, type3); 1429 TypeHandle union1_23 = T.Union(type1, union23); 1430 TypeHandle union12_3 = T.Union(union12, type3); 1431 CheckEqual(union1_23, union12_3); 1432 } 1433 } 1434 } 1435 */ 1436 1437 // Meet: T1->Is(Union(T1, T2)) and T2->Is(Union(T1, T2)) 1438 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1439 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1440 TypeHandle type1 = *it1; 1441 TypeHandle type2 = *it2; 1442 TypeHandle union12 = T.Union(type1, type2); 1443 CHECK(type1->Is(union12)); 1444 CHECK(type2->Is(union12)); 1445 } 1446 } 1447 1448 // Upper Boundedness: T1->Is(T2) implies Union(T1, T2) = T2 1449 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1450 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1451 TypeHandle type1 = *it1; 1452 TypeHandle type2 = *it2; 1453 TypeHandle union12 = T.Union(type1, type2); 1454 if (type1->Is(type2)) CheckEqual(union12, type2); 1455 } 1456 } 1457 1458 // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3)) 1459 // This does NOT hold. For example: 1460 // Range(-5,-1) <= Signed32 1461 // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5) 1462 /* 1463 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1464 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1465 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1466 TypeHandle type1 = *it1; 1467 TypeHandle type2 = *it2; 1468 TypeHandle type3 = *it3; 1469 TypeHandle union13 = T.Union(type1, type3); 1470 TypeHandle union23 = T.Union(type2, type3); 1471 CHECK(!type1->Is(type2) || union13->Is(union23)); 1472 } 1473 } 1474 } 1475 */ 1476 } 1477 1478 void Union2() { 1479 // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3) 1480 // This does NOT hold. For example: 1481 // Range(-2^33, -2^33) <= OtherNumber 1482 // Range(2^33, 2^33) <= OtherNumber 1483 // Range(-2^33, 2^33) </= OtherNumber 1484 /* 1485 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1486 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1487 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1488 TypeHandle type1 = *it1; 1489 TypeHandle type2 = *it2; 1490 TypeHandle type3 = *it3; 1491 TypeHandle union12 = T.Union(type1, type2); 1492 CHECK(!(type1->Is(type3) && type2->Is(type3)) || union12->Is(type3)); 1493 } 1494 } 1495 } 1496 */ 1497 } 1498 1499 void Union3() { 1500 // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3)) 1501 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1502 HandleScope scope(isolate); 1503 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1504 for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) { 1505 TypeHandle type1 = *it1; 1506 TypeHandle type2 = *it2; 1507 TypeHandle type3 = *it3; 1508 TypeHandle union23 = T.Union(type2, type3); 1509 CHECK(!(type1->Is(type2) || type1->Is(type3)) || type1->Is(union23)); 1510 } 1511 } 1512 } 1513 } 1514 1515 void Union4() { 1516 // Class-class 1517 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); 1518 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.OtherObject); 1519 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Receiver); 1520 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); 1521 1522 // Constant-constant 1523 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); 1524 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); 1525 CheckUnordered( 1526 T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); 1527 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant), T.OtherObject); 1528 CheckDisjoint( 1529 T.Union(T.ObjectConstant1, T.ArrayConstant), T.Number); 1530 CheckOverlap( 1531 T.Union(T.ObjectConstant1, T.ArrayConstant), T.ObjectClass); // !!! 1532 1533 // Bitset-array 1534 CHECK(this->IsBitset(T.Union(T.AnyArray, T.Receiver))); 1535 CHECK(this->IsUnion(T.Union(T.NumberArray, T.Number))); 1536 1537 CheckEqual(T.Union(T.AnyArray, T.Receiver), T.Receiver); 1538 CheckEqual(T.Union(T.AnyArray, T.OtherObject), T.OtherObject); 1539 CheckUnordered(T.Union(T.AnyArray, T.String), T.Receiver); 1540 CheckOverlap(T.Union(T.NumberArray, T.String), T.Object); 1541 CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number); 1542 1543 // Bitset-function 1544 CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object))); 1545 CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number))); 1546 1547 CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object); 1548 CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object); 1549 CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object); 1550 CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number); 1551 1552 // Bitset-class 1553 CheckSub(T.Union(T.ObjectClass, T.SignedSmall), 1554 T.Union(T.Object, T.Number)); 1555 CheckSub(T.Union(T.ObjectClass, T.OtherObject), T.Object); 1556 CheckUnordered(T.Union(T.ObjectClass, T.String), T.OtherObject); 1557 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); 1558 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); 1559 1560 // Bitset-constant 1561 CheckSub( 1562 T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); 1563 CheckSub(T.Union(T.ObjectConstant1, T.OtherObject), T.Object); 1564 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.OtherObject); 1565 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); 1566 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); 1567 1568 // Class-constant 1569 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); 1570 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 1571 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), 1572 T.Union(T.Receiver, T.Object)); 1573 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant); 1574 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); 1575 CheckOverlap( 1576 T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); // !!! 1577 1578 // Bitset-union 1579 CheckSub( 1580 T.NaN, 1581 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); 1582 CheckSub( 1583 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32), 1584 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 1585 1586 // Class-union 1587 CheckSub( 1588 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 1589 T.Object); 1590 CheckEqual( 1591 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), 1592 T.Union(T.ArrayClass, T.ObjectConstant2)); 1593 1594 // Constant-union 1595 CheckEqual( 1596 T.Union( 1597 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1598 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1599 CheckEqual( 1600 T.Union( 1601 T.Union(T.ArrayConstant, T.ObjectConstant2), T.ObjectConstant1), 1602 T.Union( 1603 T.ObjectConstant2, T.Union(T.ArrayConstant, T.ObjectConstant1))); 1604 1605 // Array-union 1606 CheckEqual( 1607 T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)), 1608 T.Union(T.AnyArray, T.NumberArray)); 1609 CheckSub(T.Union(T.AnyArray, T.NumberArray), T.OtherObject); 1610 1611 // Function-union 1612 CheckEqual( 1613 T.Union(T.NumberFunction1, T.NumberFunction2), 1614 T.Union(T.NumberFunction2, T.NumberFunction1)); 1615 CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object); 1616 1617 // Union-union 1618 CheckEqual( 1619 T.Union( 1620 T.Union(T.ObjectConstant2, T.ObjectConstant1), 1621 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1622 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1623 CheckEqual(T.Union(T.Union(T.Number, T.ArrayClass), 1624 T.Union(T.SignedSmall, T.Receiver)), 1625 T.Union(T.Number, T.Receiver)); 1626 } 1627 1628 void Intersect() { 1629 // Identity: Intersect(T, Any) = T 1630 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1631 TypeHandle type = *it; 1632 TypeHandle intersect_type = T.Intersect(type, T.Any); 1633 CheckEqual(intersect_type, type); 1634 } 1635 1636 // Domination: Intersect(T, None) = None 1637 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1638 TypeHandle type = *it; 1639 TypeHandle intersect_type = T.Intersect(type, T.None); 1640 CheckEqual(intersect_type, T.None); 1641 } 1642 1643 // Idempotence: Intersect(T, T) = T 1644 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1645 TypeHandle type = *it; 1646 TypeHandle intersect_type = T.Intersect(type, type); 1647 CheckEqual(intersect_type, type); 1648 } 1649 1650 // Commutativity: Intersect(T1, T2) = Intersect(T2, T1) 1651 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1652 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1653 TypeHandle type1 = *it1; 1654 TypeHandle type2 = *it2; 1655 TypeHandle intersect12 = T.Intersect(type1, type2); 1656 TypeHandle intersect21 = T.Intersect(type2, type1); 1657 CheckEqual(intersect12, intersect21); 1658 } 1659 } 1660 1661 // Associativity: 1662 // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3) 1663 // This does NOT hold. For example: 1664 // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) = 1665 // None 1666 // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) = 1667 // Constant(..string..) 1668 /* 1669 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1670 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1671 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1672 TypeHandle type1 = *it1; 1673 TypeHandle type2 = *it2; 1674 TypeHandle type3 = *it3; 1675 TypeHandle intersect12 = T.Intersect(type1, type2); 1676 TypeHandle intersect23 = T.Intersect(type2, type3); 1677 TypeHandle intersect1_23 = T.Intersect(type1, intersect23); 1678 TypeHandle intersect12_3 = T.Intersect(intersect12, type3); 1679 CheckEqual(intersect1_23, intersect12_3); 1680 } 1681 } 1682 } 1683 */ 1684 1685 // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2) 1686 // This does NOT hold. For example: 1687 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) 1688 // Currently, not even the disjunction holds: 1689 // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) = 1690 // Class(Internal/TaggedPtr) \/ Context(..) 1691 /* 1692 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1693 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1694 TypeHandle type1 = *it1; 1695 TypeHandle type2 = *it2; 1696 TypeHandle intersect12 = T.Intersect(type1, type2); 1697 CHECK(intersect12->Is(type1)); 1698 CHECK(intersect12->Is(type2)); 1699 } 1700 } 1701 */ 1702 1703 // Lower Boundedness: T1->Is(T2) implies Intersect(T1, T2) = T1 1704 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1705 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1706 TypeHandle type1 = *it1; 1707 TypeHandle type2 = *it2; 1708 TypeHandle intersect12 = T.Intersect(type1, type2); 1709 if (type1->Is(type2)) CheckEqual(intersect12, type1); 1710 } 1711 } 1712 1713 // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3)) 1714 // This does NOT hold. For example: 1715 // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr 1716 // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..) 1717 // Any/TaggedPtr /\ Any/UntaggedInt1 = None 1718 /* 1719 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1720 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1721 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1722 TypeHandle type1 = *it1; 1723 TypeHandle type2 = *it2; 1724 TypeHandle type3 = *it3; 1725 TypeHandle intersect13 = T.Intersect(type1, type3); 1726 TypeHandle intersect23 = T.Intersect(type2, type3); 1727 CHECK(!type1->Is(type2) || intersect13->Is(intersect23)); 1728 } 1729 } 1730 } 1731 */ 1732 1733 // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3) 1734 // This does NOT hold. For example: 1735 // Class(..stringy..) <= Class(..stringy..) 1736 // Class(..stringy..) /\ Constant(..string..) = Constant(..string..) 1737 // Constant(..string..) </= Class(..stringy..) 1738 /* 1739 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1740 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1741 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1742 TypeHandle type1 = *it1; 1743 TypeHandle type2 = *it2; 1744 TypeHandle type3 = *it3; 1745 TypeHandle intersect12 = T.Intersect(type1, type2); 1746 CHECK(!(type1->Is(type3) || type2->Is(type3)) || 1747 intersect12->Is(type3)); 1748 } 1749 } 1750 } 1751 */ 1752 1753 // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3)) 1754 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1755 HandleScope scope(isolate); 1756 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1757 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1758 TypeHandle type1 = *it1; 1759 TypeHandle type2 = *it2; 1760 TypeHandle type3 = *it3; 1761 TypeHandle intersect23 = T.Intersect(type2, type3); 1762 CHECK(!(type1->Is(type2) && type1->Is(type3)) || 1763 type1->Is(intersect23)); 1764 } 1765 } 1766 } 1767 1768 // Bitset-class 1769 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); 1770 CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.Number)), T.None); 1771 1772 // Bitset-array 1773 CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); 1774 CheckEqual(T.Semantic(T.Intersect(T.AnyArray, T.Proxy)), T.None); 1775 1776 // Bitset-function 1777 CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); 1778 CheckEqual(T.Semantic(T.Intersect(T.NumberFunction1, T.Proxy)), T.None); 1779 1780 // Bitset-union 1781 CheckEqual( 1782 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 1783 T.Union(T.ObjectConstant1, T.ObjectClass)); 1784 CheckEqual(T.Semantic(T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), 1785 T.Number)), 1786 T.None); 1787 1788 // Class-constant 1789 CHECK(T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); // !!! 1790 CHECK(T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited()); 1791 1792 // Array-union 1793 CheckEqual( 1794 T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)), 1795 T.NumberArray); 1796 CheckEqual( 1797 T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), 1798 T.AnyArray); 1799 CHECK( 1800 !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray) 1801 ->IsInhabited()); 1802 1803 // Function-union 1804 CheckEqual( 1805 T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)), 1806 T.MethodFunction); 1807 CheckEqual( 1808 T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)), 1809 T.NumberFunction1); 1810 CHECK( 1811 !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) 1812 ->IsInhabited()); 1813 1814 // Class-union 1815 CheckEqual( 1816 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), 1817 T.ArrayClass); 1818 CheckEqual( 1819 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), 1820 T.ArrayClass); 1821 CHECK( 1822 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) 1823 ->IsInhabited()); // !!! 1824 1825 // Constant-union 1826 CheckEqual( 1827 T.Intersect( 1828 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1829 T.ObjectConstant1); 1830 CheckEqual( 1831 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), 1832 T.SmiConstant); 1833 CHECK( 1834 T.Intersect( 1835 T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) 1836 ->IsInhabited()); // !!! 1837 1838 // Union-union 1839 CheckEqual(T.Intersect(T.Union(T.Number, T.ArrayClass), 1840 T.Union(T.SignedSmall, T.Receiver)), 1841 T.Union(T.SignedSmall, T.ArrayClass)); 1842 CheckEqual(T.Intersect(T.Union(T.Number, T.ObjectClass), 1843 T.Union(T.Signed32, T.OtherObject)), 1844 T.Union(T.Signed32, T.ObjectClass)); 1845 CheckEqual( 1846 T.Intersect( 1847 T.Union(T.ObjectConstant2, T.ObjectConstant1), 1848 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 1849 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 1850 CheckEqual( 1851 T.Intersect( 1852 T.Union( 1853 T.ArrayClass, 1854 T.Union(T.ObjectConstant2, T.ObjectConstant1)), 1855 T.Union( 1856 T.ObjectConstant1, 1857 T.Union(T.ArrayConstant, T.ObjectConstant2))), 1858 T.Union( 1859 T.ArrayConstant, 1860 T.Union(T.ObjectConstant2, T.ObjectConstant1))); // !!! 1861 } 1862 1863 void Distributivity() { 1864 // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) 1865 // This does NOT hold. For example: 1866 // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged) 1867 // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) = 1868 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged 1869 // because Untagged <= Untagged \/ Class(../Tagged) 1870 /* 1871 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1872 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1873 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1874 TypeHandle type1 = *it1; 1875 TypeHandle type2 = *it2; 1876 TypeHandle type3 = *it3; 1877 TypeHandle union12 = T.Union(type1, type2); 1878 TypeHandle union13 = T.Union(type1, type3); 1879 TypeHandle intersect23 = T.Intersect(type2, type3); 1880 TypeHandle union1_23 = T.Union(type1, intersect23); 1881 TypeHandle intersect12_13 = T.Intersect(union12, union13); 1882 CHECK(Equal(union1_23, intersect12_13)); 1883 } 1884 } 1885 } 1886 */ 1887 1888 // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) 1889 // This does NOT hold. For example: 1890 // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged 1891 // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) = 1892 // Untagged \/ Class(../Tagged) 1893 /* 1894 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1895 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1896 for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { 1897 TypeHandle type1 = *it1; 1898 TypeHandle type2 = *it2; 1899 TypeHandle type3 = *it3; 1900 TypeHandle intersect12 = T.Intersect(type1, type2); 1901 TypeHandle intersect13 = T.Intersect(type1, type3); 1902 TypeHandle union23 = T.Union(type2, type3); 1903 TypeHandle intersect1_23 = T.Intersect(type1, union23); 1904 TypeHandle union12_13 = T.Union(intersect12, intersect13); 1905 CHECK(Equal(intersect1_23, union12_13)); 1906 } 1907 } 1908 } 1909 */ 1910 } 1911 1912 void GetRange() { 1913 // GetRange(Range(a, b)) = Range(a, b). 1914 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1915 TypeHandle type1 = *it1; 1916 if (type1->IsRange()) { 1917 typename Type::RangeType* range = type1->GetRange(); 1918 CHECK(type1->Min() == range->Min()); 1919 CHECK(type1->Max() == range->Max()); 1920 } 1921 } 1922 1923 // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max). 1924 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1925 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1926 TypeHandle type1 = *it1; 1927 TypeHandle type2 = *it2; 1928 if (type1->IsConstant() && type2->IsRange()) { 1929 TypeHandle u = T.Union(type1, type2); 1930 1931 CHECK(type2->Min() == u->GetRange()->Min()); 1932 CHECK(type2->Max() == u->GetRange()->Max()); 1933 } 1934 } 1935 } 1936 } 1937 1938 template<class Type2, class TypeHandle2, class Region2, class Rep2> 1939 void Convert() { 1940 Types<Type2, TypeHandle2, Region2> T2(Rep2::ToRegion(&zone, isolate), 1941 isolate, 1942 isolate->random_number_generator()); 1943 for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { 1944 TypeHandle type1 = *it; 1945 TypeHandle2 type2 = T2.template Convert<Type>(type1); 1946 TypeHandle type3 = T.template Convert<Type2>(type2); 1947 CheckEqual(type1, type3); 1948 } 1949 } 1950 1951 void HTypeFromType() { 1952 for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { 1953 for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { 1954 TypeHandle type1 = *it1; 1955 TypeHandle type2 = *it2; 1956 HType htype1 = HType::FromType<Type>(type1); 1957 HType htype2 = HType::FromType<Type>(type2); 1958 CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2)); 1959 } 1960 } 1961 } 1962}; 1963 1964typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; 1965typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests; 1966 1967 1968TEST(IsSomeType_zone) { ZoneTests().IsSomeType(); } 1969 1970 1971TEST(IsSomeType_heap) { HeapTests().IsSomeType(); } 1972 1973 1974TEST(PointwiseRepresentation_zone) { ZoneTests().PointwiseRepresentation(); } 1975 1976 1977TEST(PointwiseRepresentation_heap) { HeapTests().PointwiseRepresentation(); } 1978 1979 1980TEST(BitsetType_zone) { ZoneTests().Bitset(); } 1981 1982 1983TEST(BitsetType_heap) { HeapTests().Bitset(); } 1984 1985 1986TEST(ClassType_zone) { ZoneTests().Class(); } 1987 1988 1989TEST(ClassType_heap) { HeapTests().Class(); } 1990 1991 1992TEST(ConstantType_zone) { ZoneTests().Constant(); } 1993 1994 1995TEST(ConstantType_heap) { HeapTests().Constant(); } 1996 1997 1998TEST(RangeType_zone) { ZoneTests().Range(); } 1999 2000 2001TEST(RangeType_heap) { HeapTests().Range(); } 2002 2003 2004TEST(ArrayType_zone) { ZoneTests().Array(); } 2005 2006 2007TEST(ArrayType_heap) { HeapTests().Array(); } 2008 2009 2010TEST(FunctionType_zone) { ZoneTests().Function(); } 2011 2012 2013TEST(FunctionType_heap) { HeapTests().Function(); } 2014 2015 2016TEST(Of_zone) { ZoneTests().Of(); } 2017 2018 2019TEST(Of_heap) { HeapTests().Of(); } 2020 2021 2022TEST(NowOf_zone) { ZoneTests().NowOf(); } 2023 2024 2025TEST(NowOf_heap) { HeapTests().NowOf(); } 2026 2027 2028TEST(MinMax_zone) { ZoneTests().MinMax(); } 2029 2030 2031TEST(MinMax_heap) { HeapTests().MinMax(); } 2032 2033 2034TEST(BitsetGlb_zone) { ZoneTests().BitsetGlb(); } 2035 2036 2037TEST(BitsetGlb_heap) { HeapTests().BitsetGlb(); } 2038 2039 2040TEST(BitsetLub_zone) { ZoneTests().BitsetLub(); } 2041 2042 2043TEST(BitsetLub_heap) { HeapTests().BitsetLub(); } 2044 2045 2046TEST(Is1_zone) { ZoneTests().Is1(); } 2047 2048 2049TEST(Is1_heap) { HeapTests().Is1(); } 2050 2051 2052TEST(Is2_zone) { ZoneTests().Is2(); } 2053 2054 2055TEST(Is2_heap) { HeapTests().Is2(); } 2056 2057 2058TEST(NowIs_zone) { ZoneTests().NowIs(); } 2059 2060 2061TEST(NowIs_heap) { HeapTests().NowIs(); } 2062 2063 2064TEST(Contains_zone) { ZoneTests().Contains(); } 2065 2066 2067TEST(Contains_heap) { HeapTests().Contains(); } 2068 2069 2070TEST(NowContains_zone) { ZoneTests().NowContains(); } 2071 2072 2073TEST(NowContains_heap) { HeapTests().NowContains(); } 2074 2075 2076TEST(Maybe_zone) { ZoneTests().Maybe(); } 2077 2078 2079TEST(Maybe_heap) { HeapTests().Maybe(); } 2080 2081 2082TEST(Union1_zone) { ZoneTests().Union1(); } 2083 2084 2085TEST(Union1_heap) { HeapTests().Union1(); } 2086 2087 2088TEST(Union2_zone) { ZoneTests().Union2(); } 2089 2090 2091TEST(Union2_heap) { HeapTests().Union2(); } 2092 2093 2094TEST(Union3_zone) { ZoneTests().Union3(); } 2095 2096 2097TEST(Union3_heap) { HeapTests().Union3(); } 2098 2099 2100TEST(Union4_zone) { ZoneTests().Union4(); } 2101 2102 2103TEST(Union4_heap) { HeapTests().Union4(); } 2104 2105 2106TEST(Intersect_zone) { ZoneTests().Intersect(); } 2107 2108 2109TEST(Intersect_heap) { HeapTests().Intersect(); } 2110 2111 2112TEST(Distributivity_zone) { ZoneTests().Distributivity(); } 2113 2114 2115TEST(Distributivity_heap) { HeapTests().Distributivity(); } 2116 2117 2118TEST(GetRange_zone) { ZoneTests().GetRange(); } 2119 2120 2121TEST(GetRange_heap) { HeapTests().GetRange(); } 2122 2123 2124TEST(Convert_zone) { 2125 ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); 2126} 2127 2128 2129TEST(Convert_heap) { HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); } 2130 2131 2132TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); } 2133 2134 2135TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); } 2136