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 "cctest.h" 29 #include "types.h" 30 31 using namespace v8::internal; 32 33 // Testing auxiliaries (breaking the Type abstraction). 34 static bool IsBitset(Type* type) { return type->IsSmi(); } 35 static bool IsClass(Type* type) { return type->IsMap(); } 36 static bool IsConstant(Type* type) { return type->IsBox(); } 37 static bool IsUnion(Type* type) { return type->IsFixedArray(); } 38 39 static int AsBitset(Type* type) { return Smi::cast(type)->value(); } 40 static Map* AsClass(Type* type) { return Map::cast(type); } 41 static Object* AsConstant(Type* type) { return Box::cast(type)->value(); } 42 static FixedArray* AsUnion(Type* type) { return FixedArray::cast(type); } 43 44 45 static void CheckEqual(Handle<Type> type1, Handle<Type> type2) { 46 CHECK_EQ(IsBitset(*type1), IsBitset(*type2)); 47 CHECK_EQ(IsClass(*type1), IsClass(*type2)); 48 CHECK_EQ(IsConstant(*type1), IsConstant(*type2)); 49 CHECK_EQ(IsUnion(*type1), IsUnion(*type2)); 50 CHECK_EQ(type1->NumClasses(), type2->NumClasses()); 51 CHECK_EQ(type1->NumConstants(), type2->NumConstants()); 52 if (IsBitset(*type1)) { 53 CHECK_EQ(AsBitset(*type1), AsBitset(*type2)); 54 } else if (IsClass(*type1)) { 55 CHECK_EQ(AsClass(*type1), AsClass(*type2)); 56 } else if (IsConstant(*type1)) { 57 CHECK_EQ(AsConstant(*type1), AsConstant(*type2)); 58 } else if (IsUnion(*type1)) { 59 CHECK_EQ(AsUnion(*type1)->length(), AsUnion(*type2)->length()); 60 } 61 CHECK(type1->Is(type2)); 62 CHECK(type2->Is(type1)); 63 } 64 65 66 static void CheckSub(Handle<Type> type1, Handle<Type> type2) { 67 CHECK(type1->Is(type2)); 68 CHECK(!type2->Is(type1)); 69 if (IsBitset(*type1) && IsBitset(*type2)) { 70 CHECK_NE(AsBitset(*type1), AsBitset(*type2)); 71 } 72 } 73 74 75 static void CheckUnordered(Handle<Type> type1, Handle<Type> type2) { 76 CHECK(!type1->Is(type2)); 77 CHECK(!type2->Is(type1)); 78 if (IsBitset(*type1) && IsBitset(*type2)) { 79 CHECK_NE(AsBitset(*type1), AsBitset(*type2)); 80 } 81 } 82 83 84 static void CheckOverlap(Handle<Type> type1, Handle<Type> type2) { 85 CHECK(type1->Maybe(type2)); 86 CHECK(type2->Maybe(type1)); 87 if (IsBitset(*type1) && IsBitset(*type2)) { 88 CHECK_NE(0, AsBitset(*type1) & AsBitset(*type2)); 89 } 90 } 91 92 93 static void CheckDisjoint(Handle<Type> type1, Handle<Type> type2) { 94 CHECK(!type1->Is(type2)); 95 CHECK(!type2->Is(type1)); 96 CHECK(!type1->Maybe(type2)); 97 CHECK(!type2->Maybe(type1)); 98 if (IsBitset(*type1) && IsBitset(*type2)) { 99 CHECK_EQ(0, AsBitset(*type1) & AsBitset(*type2)); 100 } 101 } 102 103 104 class HandlifiedTypes { 105 public: 106 explicit HandlifiedTypes(Isolate* isolate) : 107 None(Type::None(), isolate), 108 Any(Type::Any(), isolate), 109 Oddball(Type::Oddball(), isolate), 110 Boolean(Type::Boolean(), isolate), 111 Null(Type::Null(), isolate), 112 Undefined(Type::Undefined(), isolate), 113 Number(Type::Number(), isolate), 114 Integer31(Type::Smi(), isolate), 115 Integer32(Type::Signed32(), isolate), 116 Double(Type::Double(), isolate), 117 Name(Type::Name(), isolate), 118 UniqueName(Type::UniqueName(), isolate), 119 String(Type::String(), isolate), 120 InternalizedString(Type::InternalizedString(), isolate), 121 Symbol(Type::Symbol(), isolate), 122 Receiver(Type::Receiver(), isolate), 123 Object(Type::Object(), isolate), 124 Array(Type::Array(), isolate), 125 Function(Type::Function(), isolate), 126 Proxy(Type::Proxy(), isolate), 127 object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)), 128 array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)), 129 isolate_(isolate) { 130 smi = handle(Smi::FromInt(666), isolate); 131 object1 = isolate->factory()->NewJSObjectFromMap(object_map); 132 object2 = isolate->factory()->NewJSObjectFromMap(object_map); 133 array = isolate->factory()->NewJSArray(20); 134 ObjectClass = handle(Type::Class(object_map), isolate); 135 ArrayClass = handle(Type::Class(array_map), isolate); 136 Integer31Constant = handle(Type::Constant(smi, isolate), isolate); 137 ObjectConstant1 = handle(Type::Constant(object1), isolate); 138 ObjectConstant2 = handle(Type::Constant(object2), isolate); 139 ArrayConstant1 = handle(Type::Constant(array), isolate); 140 ArrayConstant2 = handle(Type::Constant(array), isolate); 141 } 142 143 Handle<Type> None; 144 Handle<Type> Any; 145 Handle<Type> Oddball; 146 Handle<Type> Boolean; 147 Handle<Type> Null; 148 Handle<Type> Undefined; 149 Handle<Type> Number; 150 Handle<Type> Integer31; 151 Handle<Type> Integer32; 152 Handle<Type> Double; 153 Handle<Type> Name; 154 Handle<Type> UniqueName; 155 Handle<Type> String; 156 Handle<Type> InternalizedString; 157 Handle<Type> Symbol; 158 Handle<Type> Receiver; 159 Handle<Type> Object; 160 Handle<Type> Array; 161 Handle<Type> Function; 162 Handle<Type> Proxy; 163 164 Handle<Type> ObjectClass; 165 Handle<Type> ArrayClass; 166 167 Handle<Type> Integer31Constant; 168 Handle<Type> ObjectConstant1; 169 Handle<Type> ObjectConstant2; 170 Handle<Type> ArrayConstant1; 171 Handle<Type> ArrayConstant2; 172 173 Handle<Map> object_map; 174 Handle<Map> array_map; 175 176 Handle<v8::internal::Smi> smi; 177 Handle<JSObject> object1; 178 Handle<JSObject> object2; 179 Handle<JSArray> array; 180 181 Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) { 182 return handle(Type::Union(type1, type2), isolate_); 183 } 184 Handle<Type> Intersect(Handle<Type> type1, Handle<Type> type2) { 185 return handle(Type::Intersect(type1, type2), isolate_); 186 } 187 188 private: 189 Isolate* isolate_; 190 }; 191 192 193 TEST(Bitset) { 194 CcTest::InitializeVM(); 195 Isolate* isolate = Isolate::Current(); 196 HandleScope scope(isolate); 197 HandlifiedTypes T(isolate); 198 199 CHECK(IsBitset(*T.None)); 200 CHECK(IsBitset(*T.Any)); 201 CHECK(IsBitset(*T.String)); 202 CHECK(IsBitset(*T.Object)); 203 204 CHECK(IsBitset(Type::Union(T.String, T.Number))); 205 CHECK(IsBitset(Type::Union(T.String, T.Receiver))); 206 CHECK(IsBitset(Type::Optional(T.Object))); 207 208 CHECK_EQ(0, AsBitset(*T.None)); 209 CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String), 210 AsBitset(Type::Union(T.String, T.Number))); 211 CHECK_EQ(AsBitset(*T.Receiver), 212 AsBitset(Type::Union(T.Receiver, T.Object))); 213 CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined), 214 AsBitset(Type::Optional(T.String))); 215 } 216 217 218 TEST(Class) { 219 CcTest::InitializeVM(); 220 Isolate* isolate = Isolate::Current(); 221 HandleScope scope(isolate); 222 HandlifiedTypes T(isolate); 223 224 CHECK(IsClass(*T.ObjectClass)); 225 CHECK(IsClass(*T.ArrayClass)); 226 227 CHECK(*T.object_map == AsClass(*T.ObjectClass)); 228 CHECK(*T.array_map == AsClass(*T.ArrayClass)); 229 } 230 231 232 TEST(Constant) { 233 CcTest::InitializeVM(); 234 Isolate* isolate = Isolate::Current(); 235 HandleScope scope(isolate); 236 HandlifiedTypes T(isolate); 237 238 CHECK(IsConstant(*T.Integer31Constant)); 239 CHECK(IsConstant(*T.ObjectConstant1)); 240 CHECK(IsConstant(*T.ObjectConstant2)); 241 CHECK(IsConstant(*T.ArrayConstant1)); 242 CHECK(IsConstant(*T.ArrayConstant2)); 243 244 CHECK(*T.smi == AsConstant(*T.Integer31Constant)); 245 CHECK(*T.object1 == AsConstant(*T.ObjectConstant1)); 246 CHECK(*T.object2 == AsConstant(*T.ObjectConstant2)); 247 CHECK(*T.object1 != AsConstant(*T.ObjectConstant2)); 248 CHECK(*T.array == AsConstant(*T.ArrayConstant1)); 249 CHECK(*T.array == AsConstant(*T.ArrayConstant2)); 250 } 251 252 253 TEST(Is) { 254 CcTest::InitializeVM(); 255 Isolate* isolate = Isolate::Current(); 256 HandleScope scope(isolate); 257 HandlifiedTypes T(isolate); 258 259 // Reflexivity 260 CHECK(T.None->Is(T.None)); 261 CHECK(T.Any->Is(T.Any)); 262 CHECK(T.Object->Is(T.Object)); 263 264 CHECK(T.ObjectClass->Is(T.ObjectClass)); 265 CHECK(T.ObjectConstant1->Is(T.ObjectConstant1)); 266 CHECK(T.ArrayConstant1->Is(T.ArrayConstant2)); 267 268 // Symmetry and Transitivity 269 CheckSub(T.None, T.Number); 270 CheckSub(T.None, T.Any); 271 272 CheckSub(T.Oddball, T.Any); 273 CheckSub(T.Boolean, T.Oddball); 274 CheckSub(T.Null, T.Oddball); 275 CheckSub(T.Undefined, T.Oddball); 276 CheckUnordered(T.Boolean, T.Null); 277 CheckUnordered(T.Undefined, T.Null); 278 CheckUnordered(T.Boolean, T.Undefined); 279 280 CheckSub(T.Number, T.Any); 281 CheckSub(T.Integer31, T.Number); 282 CheckSub(T.Integer32, T.Number); 283 CheckSub(T.Double, T.Number); 284 CheckSub(T.Integer31, T.Integer32); 285 CheckUnordered(T.Integer31, T.Double); 286 CheckUnordered(T.Integer32, T.Double); 287 288 CheckSub(T.Name, T.Any); 289 CheckSub(T.UniqueName, T.Any); 290 CheckSub(T.UniqueName, T.Name); 291 CheckSub(T.String, T.Name); 292 CheckSub(T.InternalizedString, T.String); 293 CheckSub(T.InternalizedString, T.UniqueName); 294 CheckSub(T.InternalizedString, T.Name); 295 CheckSub(T.Symbol, T.UniqueName); 296 CheckSub(T.Symbol, T.Name); 297 CheckUnordered(T.String, T.UniqueName); 298 CheckUnordered(T.String, T.Symbol); 299 CheckUnordered(T.InternalizedString, T.Symbol); 300 301 CheckSub(T.Receiver, T.Any); 302 CheckSub(T.Object, T.Any); 303 CheckSub(T.Object, T.Receiver); 304 CheckSub(T.Array, T.Object); 305 CheckSub(T.Function, T.Object); 306 CheckSub(T.Proxy, T.Receiver); 307 CheckUnordered(T.Object, T.Proxy); 308 CheckUnordered(T.Array, T.Function); 309 310 // Structured subtyping 311 CheckSub(T.ObjectClass, T.Object); 312 CheckSub(T.ArrayClass, T.Object); 313 CheckUnordered(T.ObjectClass, T.ArrayClass); 314 315 CheckSub(T.Integer31Constant, T.Integer31); 316 CheckSub(T.Integer31Constant, T.Integer32); 317 CheckSub(T.Integer31Constant, T.Number); 318 CheckSub(T.ObjectConstant1, T.Object); 319 CheckSub(T.ObjectConstant2, T.Object); 320 CheckSub(T.ArrayConstant1, T.Object); 321 CheckSub(T.ArrayConstant1, T.Array); 322 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); 323 CheckUnordered(T.ObjectConstant1, T.ArrayConstant1); 324 325 CheckUnordered(T.ObjectConstant1, T.ObjectClass); 326 CheckUnordered(T.ObjectConstant2, T.ObjectClass); 327 CheckUnordered(T.ObjectConstant1, T.ArrayClass); 328 CheckUnordered(T.ObjectConstant2, T.ArrayClass); 329 CheckUnordered(T.ArrayConstant1, T.ObjectClass); 330 } 331 332 333 TEST(Maybe) { 334 CcTest::InitializeVM(); 335 Isolate* isolate = Isolate::Current(); 336 HandleScope scope(isolate); 337 HandlifiedTypes T(isolate); 338 339 CheckOverlap(T.Any, T.Any); 340 CheckOverlap(T.Object, T.Object); 341 342 CheckOverlap(T.Oddball, T.Any); 343 CheckOverlap(T.Boolean, T.Oddball); 344 CheckOverlap(T.Null, T.Oddball); 345 CheckOverlap(T.Undefined, T.Oddball); 346 CheckDisjoint(T.Boolean, T.Null); 347 CheckDisjoint(T.Undefined, T.Null); 348 CheckDisjoint(T.Boolean, T.Undefined); 349 350 CheckOverlap(T.Number, T.Any); 351 CheckOverlap(T.Integer31, T.Number); 352 CheckOverlap(T.Double, T.Number); 353 CheckDisjoint(T.Integer32, T.Double); 354 355 CheckOverlap(T.Name, T.Any); 356 CheckOverlap(T.UniqueName, T.Any); 357 CheckOverlap(T.UniqueName, T.Name); 358 CheckOverlap(T.String, T.Name); 359 CheckOverlap(T.InternalizedString, T.String); 360 CheckOverlap(T.InternalizedString, T.UniqueName); 361 CheckOverlap(T.InternalizedString, T.Name); 362 CheckOverlap(T.Symbol, T.UniqueName); 363 CheckOverlap(T.Symbol, T.Name); 364 CheckOverlap(T.String, T.UniqueName); 365 CheckDisjoint(T.String, T.Symbol); 366 CheckDisjoint(T.InternalizedString, T.Symbol); 367 368 CheckOverlap(T.Receiver, T.Any); 369 CheckOverlap(T.Object, T.Any); 370 CheckOverlap(T.Object, T.Receiver); 371 CheckOverlap(T.Array, T.Object); 372 CheckOverlap(T.Function, T.Object); 373 CheckOverlap(T.Proxy, T.Receiver); 374 CheckDisjoint(T.Object, T.Proxy); 375 CheckDisjoint(T.Array, T.Function); 376 377 CheckOverlap(T.ObjectClass, T.Object); 378 CheckOverlap(T.ArrayClass, T.Object); 379 CheckOverlap(T.ObjectClass, T.ObjectClass); 380 CheckOverlap(T.ArrayClass, T.ArrayClass); 381 CheckDisjoint(T.ObjectClass, T.ArrayClass); 382 383 CheckOverlap(T.Integer31Constant, T.Integer31); 384 CheckOverlap(T.Integer31Constant, T.Integer32); 385 CheckOverlap(T.Integer31Constant, T.Number); 386 CheckDisjoint(T.Integer31Constant, T.Double); 387 CheckOverlap(T.ObjectConstant1, T.Object); 388 CheckOverlap(T.ObjectConstant2, T.Object); 389 CheckOverlap(T.ArrayConstant1, T.Object); 390 CheckOverlap(T.ArrayConstant1, T.Array); 391 CheckOverlap(T.ArrayConstant1, T.ArrayConstant2); 392 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1); 393 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2); 394 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1); 395 396 CheckDisjoint(T.ObjectConstant1, T.ObjectClass); 397 CheckDisjoint(T.ObjectConstant2, T.ObjectClass); 398 CheckDisjoint(T.ObjectConstant1, T.ArrayClass); 399 CheckDisjoint(T.ObjectConstant2, T.ArrayClass); 400 CheckDisjoint(T.ArrayConstant1, T.ObjectClass); 401 } 402 403 404 TEST(Union) { 405 CcTest::InitializeVM(); 406 Isolate* isolate = Isolate::Current(); 407 HandleScope scope(isolate); 408 HandlifiedTypes T(isolate); 409 410 // Bitset-bitset 411 CHECK(IsBitset(Type::Union(T.Object, T.Number))); 412 CHECK(IsBitset(Type::Union(T.Object, T.Object))); 413 CHECK(IsBitset(Type::Union(T.Any, T.None))); 414 415 CheckEqual(T.Union(T.None, T.Number), T.Number); 416 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); 417 CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); 418 CheckSub(T.Union(T.Number, T.String), T.Any); 419 420 // Class-class 421 CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass))); 422 CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass))); 423 424 CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); 425 CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); 426 CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); 427 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); 428 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); 429 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array); 430 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); 431 432 // Constant-constant 433 CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1))); 434 CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1))); 435 CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2))); 436 437 CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); 438 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); 439 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); 440 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); 441 CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); 442 CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); 443 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); 444 CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); 445 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); 446 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); 447 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2); 448 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number); 449 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass); 450 451 // Bitset-class 452 CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object))); 453 CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number))); 454 455 CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); 456 CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); 457 CheckSub(T.Union(T.ObjectClass, T.Integer31), T.Union(T.Object, T.Number)); 458 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); 459 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); 460 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); 461 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); 462 463 // Bitset-constant 464 CHECK(IsBitset(Type::Union(T.Integer31Constant, T.Number))); 465 CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object))); 466 CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number))); 467 468 CheckEqual(T.Union(T.Integer31Constant, T.Number), T.Number); 469 CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); 470 CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); 471 CheckSub( 472 T.Union(T.ObjectConstant1, T.Integer32), T.Union(T.Object, T.Number)); 473 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); 474 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); 475 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); 476 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); 477 478 // Class-constant 479 CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass))); 480 CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2))); 481 482 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); 483 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); 484 CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 485 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 486 CheckSub( 487 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); 488 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1); 489 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); 490 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); 491 492 // Bitset-union 493 CHECK(IsBitset( 494 Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); 495 CHECK(IsUnion( 496 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); 497 498 CheckEqual( 499 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 500 T.Object); 501 CheckEqual( 502 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), 503 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 504 CheckSub( 505 T.Double, 506 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); 507 CheckSub( 508 T.ObjectConstant1, 509 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); 510 CheckSub( 511 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), 512 T.Any); 513 CheckSub( 514 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), 515 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 516 517 // Class-union 518 CHECK(IsUnion( 519 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); 520 CHECK(IsUnion( 521 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); 522 523 CheckEqual( 524 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 525 T.Union(T.ObjectClass, T.ObjectConstant1)); 526 CheckSub( 527 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 528 T.Object); 529 CheckEqual( 530 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), 531 T.Union(T.ArrayClass, T.ObjectConstant2)); 532 533 // Constant-union 534 CHECK(IsUnion(Type::Union( 535 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); 536 CHECK(IsUnion(Type::Union( 537 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); 538 CHECK(IsUnion(Type::Union( 539 T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); 540 541 CheckEqual( 542 T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 543 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 544 CheckEqual( 545 T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1), 546 T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); 547 548 // Union-union 549 CHECK(IsBitset(Type::Union( 550 T.Union(T.Number, T.ArrayClass), T.Union(T.Integer32, T.Array)))); 551 CHECK(IsUnion(Type::Union( 552 T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass)))); 553 554 CheckEqual( 555 T.Union( 556 T.Union(T.ObjectConstant2, T.ObjectConstant1), 557 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 558 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 559 CheckEqual( 560 T.Union( 561 T.Union(T.ObjectConstant2, T.ArrayConstant1), 562 T.Union(T.ObjectConstant1, T.ArrayConstant2)), 563 T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1)); 564 CheckEqual( 565 T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Integer31, T.Array)), 566 T.Union(T.Number, T.Array)); 567 } 568 569 570 TEST(Intersect) { 571 CcTest::InitializeVM(); 572 Isolate* isolate = Isolate::Current(); 573 HandleScope scope(isolate); 574 HandlifiedTypes T(isolate); 575 576 // Bitset-bitset 577 CHECK(IsBitset(Type::Intersect(T.Object, T.Number))); 578 CHECK(IsBitset(Type::Intersect(T.Object, T.Object))); 579 CHECK(IsBitset(Type::Intersect(T.Any, T.None))); 580 581 CheckEqual(T.Intersect(T.None, T.Number), T.None); 582 CheckEqual(T.Intersect(T.Object, T.Proxy), T.None); 583 CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); 584 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); 585 586 // Class-class 587 CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass))); 588 CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass))); 589 590 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); 591 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); 592 593 // Constant-constant 594 CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1))); 595 CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2))); 596 CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2))); 597 598 CheckEqual( 599 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); 600 CheckEqual( 601 T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1); 602 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); 603 604 // Bitset-class 605 CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object))); 606 CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number))); 607 608 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); 609 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); 610 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); 611 612 // Bitset-constant 613 CHECK(IsBitset(Type::Intersect(T.Integer31, T.Number))); 614 CHECK(IsConstant(Type::Intersect(T.Integer31Constant, T.Number))); 615 CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object))); 616 617 CheckEqual(T.Intersect(T.Integer31, T.Number), T.Integer31); 618 CheckEqual(T.Intersect(T.Integer31Constant, T.Number), T.Integer31Constant); 619 CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); 620 621 // Class-constant 622 CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectClass))); 623 CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2))); 624 625 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); 626 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); 627 628 // Bitset-union 629 CHECK(IsUnion( 630 Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); 631 CHECK(IsBitset( 632 Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); 633 634 CheckEqual( 635 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 636 T.Union(T.ObjectConstant1, T.ObjectClass)); 637 CheckEqual( 638 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), 639 T.None); 640 641 // Class-union 642 CHECK(IsClass( 643 Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); 644 CHECK(IsClass( 645 Type::Intersect(T.Union(T.Object, T.Integer31Constant), T.ArrayClass))); 646 CHECK(IsBitset( 647 Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); 648 649 CheckEqual( 650 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), 651 T.ArrayClass); 652 CheckEqual( 653 T.Intersect(T.ArrayClass, T.Union(T.Object, T.Integer31Constant)), 654 T.ArrayClass); 655 CheckEqual( 656 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), 657 T.None); 658 659 // Constant-union 660 CHECK(IsConstant(Type::Intersect( 661 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); 662 CHECK(IsConstant(Type::Intersect( 663 T.Union(T.Number, T.ObjectClass), T.Integer31Constant))); 664 CHECK(IsBitset(Type::Intersect( 665 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); 666 667 CheckEqual( 668 T.Intersect( 669 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 670 T.ObjectConstant1); 671 CheckEqual( 672 T.Intersect(T.Integer31Constant, T.Union(T.Number, T.ObjectConstant2)), 673 T.Integer31Constant); 674 CheckEqual( 675 T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), 676 T.None); 677 678 // Union-union 679 CHECK(IsUnion(Type::Intersect( 680 T.Union(T.Number, T.ArrayClass), T.Union(T.Integer32, T.Array)))); 681 CHECK(IsBitset(Type::Intersect( 682 T.Union(T.Number, T.ObjectClass), T.Union(T.Integer32, T.Array)))); 683 684 CheckEqual( 685 T.Intersect( 686 T.Union(T.Number, T.ArrayClass), 687 T.Union(T.Integer31, T.Array)), 688 T.Union(T.Integer31, T.ArrayClass)); 689 CheckEqual( 690 T.Intersect( 691 T.Union(T.Number, T.ObjectClass), 692 T.Union(T.Integer32, T.Array)), 693 T.Integer32); 694 CheckEqual( 695 T.Intersect( 696 T.Union(T.ObjectConstant2, T.ObjectConstant1), 697 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 698 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 699 CheckEqual( 700 T.Intersect( 701 T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), 702 T.Union( 703 T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))), 704 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 705 CheckEqual( 706 T.Intersect( 707 T.Union(T.ObjectConstant2, T.ArrayConstant1), 708 T.Union(T.ObjectConstant1, T.ArrayConstant2)), 709 T.ArrayConstant1); 710 } 711