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 Smi(Type::Smi(), isolate), 115 Signed32(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 signed32 = isolate->factory()->NewHeapNumber(0x40000000); 132 object1 = isolate->factory()->NewJSObjectFromMap(object_map); 133 object2 = isolate->factory()->NewJSObjectFromMap(object_map); 134 array = isolate->factory()->NewJSArray(20); 135 ObjectClass = Class(object_map); 136 ArrayClass = Class(array_map); 137 SmiConstant = Constant(smi); 138 Signed32Constant = Constant(signed32); 139 ObjectConstant1 = Constant(object1); 140 ObjectConstant2 = Constant(object2); 141 ArrayConstant1 = Constant(array); 142 ArrayConstant2 = Constant(array); 143 } 144 145 Handle<Type> None; 146 Handle<Type> Any; 147 Handle<Type> Oddball; 148 Handle<Type> Boolean; 149 Handle<Type> Null; 150 Handle<Type> Undefined; 151 Handle<Type> Number; 152 Handle<Type> Smi; 153 Handle<Type> Signed32; 154 Handle<Type> Double; 155 Handle<Type> Name; 156 Handle<Type> UniqueName; 157 Handle<Type> String; 158 Handle<Type> InternalizedString; 159 Handle<Type> Symbol; 160 Handle<Type> Receiver; 161 Handle<Type> Object; 162 Handle<Type> Array; 163 Handle<Type> Function; 164 Handle<Type> Proxy; 165 166 Handle<Type> ObjectClass; 167 Handle<Type> ArrayClass; 168 169 Handle<Type> SmiConstant; 170 Handle<Type> Signed32Constant; 171 Handle<Type> ObjectConstant1; 172 Handle<Type> ObjectConstant2; 173 Handle<Type> ArrayConstant1; 174 Handle<Type> ArrayConstant2; 175 176 Handle<Map> object_map; 177 Handle<Map> array_map; 178 179 Handle<i::Smi> smi; 180 Handle<HeapNumber> signed32; 181 Handle<JSObject> object1; 182 Handle<JSObject> object2; 183 Handle<JSArray> array; 184 185 Handle<Type> Class(Handle<Map> map) { 186 return handle(Type::Class(map), isolate_); 187 } 188 Handle<Type> Constant(Handle<i::Object> value) { 189 return handle(Type::Constant(value, isolate_), isolate_); 190 } 191 Handle<Type> Union(Handle<Type> type1, Handle<Type> type2) { 192 return handle(Type::Union(type1, type2), isolate_); 193 } 194 Handle<Type> Intersect(Handle<Type> type1, Handle<Type> type2) { 195 return handle(Type::Intersect(type1, type2), isolate_); 196 } 197 198 private: 199 Isolate* isolate_; 200 }; 201 202 203 TEST(Bitset) { 204 CcTest::InitializeVM(); 205 Isolate* isolate = CcTest::i_isolate(); 206 HandleScope scope(isolate); 207 HandlifiedTypes T(isolate); 208 209 CHECK(IsBitset(*T.None)); 210 CHECK(IsBitset(*T.Any)); 211 CHECK(IsBitset(*T.String)); 212 CHECK(IsBitset(*T.Object)); 213 214 CHECK(IsBitset(Type::Union(T.String, T.Number))); 215 CHECK(IsBitset(Type::Union(T.String, T.Receiver))); 216 CHECK(IsBitset(Type::Optional(T.Object))); 217 218 CHECK_EQ(0, AsBitset(*T.None)); 219 CHECK_EQ(AsBitset(*T.Number) | AsBitset(*T.String), 220 AsBitset(Type::Union(T.String, T.Number))); 221 CHECK_EQ(AsBitset(*T.Receiver), 222 AsBitset(Type::Union(T.Receiver, T.Object))); 223 CHECK_EQ(AsBitset(*T.String) | AsBitset(*T.Undefined), 224 AsBitset(Type::Optional(T.String))); 225 } 226 227 228 TEST(Class) { 229 CcTest::InitializeVM(); 230 Isolate* isolate = CcTest::i_isolate(); 231 HandleScope scope(isolate); 232 HandlifiedTypes T(isolate); 233 234 CHECK(IsClass(*T.ObjectClass)); 235 CHECK(IsClass(*T.ArrayClass)); 236 237 CHECK(*T.object_map == AsClass(*T.ObjectClass)); 238 CHECK(*T.array_map == AsClass(*T.ArrayClass)); 239 } 240 241 242 TEST(Constant) { 243 CcTest::InitializeVM(); 244 Isolate* isolate = CcTest::i_isolate(); 245 HandleScope scope(isolate); 246 HandlifiedTypes T(isolate); 247 248 CHECK(IsConstant(*T.SmiConstant)); 249 CHECK(IsConstant(*T.ObjectConstant1)); 250 CHECK(IsConstant(*T.ObjectConstant2)); 251 CHECK(IsConstant(*T.ArrayConstant1)); 252 CHECK(IsConstant(*T.ArrayConstant2)); 253 254 CHECK(*T.smi == AsConstant(*T.SmiConstant)); 255 CHECK(*T.object1 == AsConstant(*T.ObjectConstant1)); 256 CHECK(*T.object2 == AsConstant(*T.ObjectConstant2)); 257 CHECK(*T.object1 != AsConstant(*T.ObjectConstant2)); 258 CHECK(*T.array == AsConstant(*T.ArrayConstant1)); 259 CHECK(*T.array == AsConstant(*T.ArrayConstant2)); 260 } 261 262 263 TEST(Is) { 264 CcTest::InitializeVM(); 265 Isolate* isolate = CcTest::i_isolate(); 266 HandleScope scope(isolate); 267 HandlifiedTypes T(isolate); 268 269 // Reflexivity 270 CHECK(T.None->Is(T.None)); 271 CHECK(T.Any->Is(T.Any)); 272 CHECK(T.Object->Is(T.Object)); 273 274 CHECK(T.ObjectClass->Is(T.ObjectClass)); 275 CHECK(T.ObjectConstant1->Is(T.ObjectConstant1)); 276 CHECK(T.ArrayConstant1->Is(T.ArrayConstant2)); 277 278 // Symmetry and Transitivity 279 CheckSub(T.None, T.Number); 280 CheckSub(T.None, T.Any); 281 282 CheckSub(T.Oddball, T.Any); 283 CheckSub(T.Boolean, T.Oddball); 284 CheckSub(T.Null, T.Oddball); 285 CheckSub(T.Undefined, T.Oddball); 286 CheckUnordered(T.Boolean, T.Null); 287 CheckUnordered(T.Undefined, T.Null); 288 CheckUnordered(T.Boolean, T.Undefined); 289 290 CheckSub(T.Number, T.Any); 291 CheckSub(T.Smi, T.Number); 292 CheckSub(T.Signed32, T.Number); 293 CheckSub(T.Double, T.Number); 294 CheckSub(T.Smi, T.Signed32); 295 CheckUnordered(T.Smi, T.Double); 296 CheckUnordered(T.Signed32, T.Double); 297 298 CheckSub(T.Name, T.Any); 299 CheckSub(T.UniqueName, T.Any); 300 CheckSub(T.UniqueName, T.Name); 301 CheckSub(T.String, T.Name); 302 CheckSub(T.InternalizedString, T.String); 303 CheckSub(T.InternalizedString, T.UniqueName); 304 CheckSub(T.InternalizedString, T.Name); 305 CheckSub(T.Symbol, T.UniqueName); 306 CheckSub(T.Symbol, T.Name); 307 CheckUnordered(T.String, T.UniqueName); 308 CheckUnordered(T.String, T.Symbol); 309 CheckUnordered(T.InternalizedString, T.Symbol); 310 311 CheckSub(T.Receiver, T.Any); 312 CheckSub(T.Object, T.Any); 313 CheckSub(T.Object, T.Receiver); 314 CheckSub(T.Array, T.Object); 315 CheckSub(T.Function, T.Object); 316 CheckSub(T.Proxy, T.Receiver); 317 CheckUnordered(T.Object, T.Proxy); 318 CheckUnordered(T.Array, T.Function); 319 320 // Structured subtyping 321 CheckSub(T.None, T.ObjectClass); 322 CheckSub(T.None, T.ObjectConstant1); 323 CheckSub(T.ObjectClass, T.Any); 324 CheckSub(T.ObjectConstant1, T.Any); 325 326 CheckSub(T.ObjectClass, T.Object); 327 CheckSub(T.ArrayClass, T.Object); 328 CheckUnordered(T.ObjectClass, T.ArrayClass); 329 330 CheckSub(T.SmiConstant, T.Smi); 331 CheckSub(T.SmiConstant, T.Signed32); 332 CheckSub(T.SmiConstant, T.Number); 333 CheckSub(T.ObjectConstant1, T.Object); 334 CheckSub(T.ObjectConstant2, T.Object); 335 CheckSub(T.ArrayConstant1, T.Object); 336 CheckSub(T.ArrayConstant1, T.Array); 337 CheckUnordered(T.ObjectConstant1, T.ObjectConstant2); 338 CheckUnordered(T.ObjectConstant1, T.ArrayConstant1); 339 340 CheckUnordered(T.ObjectConstant1, T.ObjectClass); 341 CheckUnordered(T.ObjectConstant2, T.ObjectClass); 342 CheckUnordered(T.ObjectConstant1, T.ArrayClass); 343 CheckUnordered(T.ObjectConstant2, T.ArrayClass); 344 CheckUnordered(T.ArrayConstant1, T.ObjectClass); 345 } 346 347 348 TEST(Maybe) { 349 CcTest::InitializeVM(); 350 Isolate* isolate = CcTest::i_isolate(); 351 HandleScope scope(isolate); 352 HandlifiedTypes T(isolate); 353 354 CheckOverlap(T.Any, T.Any); 355 CheckOverlap(T.Object, T.Object); 356 357 CheckOverlap(T.Oddball, T.Any); 358 CheckOverlap(T.Boolean, T.Oddball); 359 CheckOverlap(T.Null, T.Oddball); 360 CheckOverlap(T.Undefined, T.Oddball); 361 CheckDisjoint(T.Boolean, T.Null); 362 CheckDisjoint(T.Undefined, T.Null); 363 CheckDisjoint(T.Boolean, T.Undefined); 364 365 CheckOverlap(T.Number, T.Any); 366 CheckOverlap(T.Smi, T.Number); 367 CheckOverlap(T.Double, T.Number); 368 CheckDisjoint(T.Signed32, T.Double); 369 370 CheckOverlap(T.Name, T.Any); 371 CheckOverlap(T.UniqueName, T.Any); 372 CheckOverlap(T.UniqueName, T.Name); 373 CheckOverlap(T.String, T.Name); 374 CheckOverlap(T.InternalizedString, T.String); 375 CheckOverlap(T.InternalizedString, T.UniqueName); 376 CheckOverlap(T.InternalizedString, T.Name); 377 CheckOverlap(T.Symbol, T.UniqueName); 378 CheckOverlap(T.Symbol, T.Name); 379 CheckOverlap(T.String, T.UniqueName); 380 CheckDisjoint(T.String, T.Symbol); 381 CheckDisjoint(T.InternalizedString, T.Symbol); 382 383 CheckOverlap(T.Receiver, T.Any); 384 CheckOverlap(T.Object, T.Any); 385 CheckOverlap(T.Object, T.Receiver); 386 CheckOverlap(T.Array, T.Object); 387 CheckOverlap(T.Function, T.Object); 388 CheckOverlap(T.Proxy, T.Receiver); 389 CheckDisjoint(T.Object, T.Proxy); 390 CheckDisjoint(T.Array, T.Function); 391 392 CheckOverlap(T.ObjectClass, T.Any); 393 CheckOverlap(T.ObjectConstant1, T.Any); 394 395 CheckOverlap(T.ObjectClass, T.Object); 396 CheckOverlap(T.ArrayClass, T.Object); 397 CheckOverlap(T.ObjectClass, T.ObjectClass); 398 CheckOverlap(T.ArrayClass, T.ArrayClass); 399 CheckDisjoint(T.ObjectClass, T.ArrayClass); 400 401 CheckOverlap(T.SmiConstant, T.Smi); 402 CheckOverlap(T.SmiConstant, T.Signed32); 403 CheckOverlap(T.SmiConstant, T.Number); 404 CheckDisjoint(T.SmiConstant, T.Double); 405 CheckOverlap(T.ObjectConstant1, T.Object); 406 CheckOverlap(T.ObjectConstant2, T.Object); 407 CheckOverlap(T.ArrayConstant1, T.Object); 408 CheckOverlap(T.ArrayConstant1, T.Array); 409 CheckOverlap(T.ArrayConstant1, T.ArrayConstant2); 410 CheckOverlap(T.ObjectConstant1, T.ObjectConstant1); 411 CheckDisjoint(T.ObjectConstant1, T.ObjectConstant2); 412 CheckDisjoint(T.ObjectConstant1, T.ArrayConstant1); 413 414 CheckDisjoint(T.ObjectConstant1, T.ObjectClass); 415 CheckDisjoint(T.ObjectConstant2, T.ObjectClass); 416 CheckDisjoint(T.ObjectConstant1, T.ArrayClass); 417 CheckDisjoint(T.ObjectConstant2, T.ArrayClass); 418 CheckDisjoint(T.ArrayConstant1, T.ObjectClass); 419 } 420 421 422 TEST(Union) { 423 CcTest::InitializeVM(); 424 Isolate* isolate = CcTest::i_isolate(); 425 HandleScope scope(isolate); 426 HandlifiedTypes T(isolate); 427 428 // Bitset-bitset 429 CHECK(IsBitset(Type::Union(T.Object, T.Number))); 430 CHECK(IsBitset(Type::Union(T.Object, T.Object))); 431 CHECK(IsBitset(Type::Union(T.Any, T.None))); 432 433 CheckEqual(T.Union(T.None, T.Number), T.Number); 434 CheckEqual(T.Union(T.Object, T.Proxy), T.Receiver); 435 CheckEqual(T.Union(T.Number, T.String), T.Union(T.String, T.Number)); 436 CheckSub(T.Union(T.Number, T.String), T.Any); 437 438 // Class-class 439 CHECK(IsClass(Type::Union(T.ObjectClass, T.ObjectClass))); 440 CHECK(IsUnion(Type::Union(T.ObjectClass, T.ArrayClass))); 441 442 CheckEqual(T.Union(T.ObjectClass, T.ObjectClass), T.ObjectClass); 443 CheckSub(T.None, T.Union(T.ObjectClass, T.ArrayClass)); 444 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Any); 445 CheckSub(T.ObjectClass, T.Union(T.ObjectClass, T.ArrayClass)); 446 CheckSub(T.ArrayClass, T.Union(T.ObjectClass, T.ArrayClass)); 447 CheckSub(T.Union(T.ObjectClass, T.ArrayClass), T.Object); 448 CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.Array); 449 CheckOverlap(T.Union(T.ObjectClass, T.ArrayClass), T.Array); 450 CheckDisjoint(T.Union(T.ObjectClass, T.ArrayClass), T.Number); 451 452 // Constant-constant 453 CHECK(IsConstant(Type::Union(T.ObjectConstant1, T.ObjectConstant1))); 454 CHECK(IsConstant(Type::Union(T.ArrayConstant1, T.ArrayConstant1))); 455 CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectConstant2))); 456 457 CheckEqual(T.Union(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); 458 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant1); 459 CheckEqual(T.Union(T.ArrayConstant1, T.ArrayConstant1), T.ArrayConstant2); 460 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ObjectConstant2)); 461 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Any); 462 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)); 463 CheckSub(T.ObjectConstant2, T.Union(T.ObjectConstant1, T.ObjectConstant2)); 464 CheckSub(T.ArrayConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant2)); 465 CheckSub(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.Object); 466 CheckUnordered(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ObjectClass); 467 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); 468 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Array); 469 CheckOverlap(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ArrayConstant2); 470 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.Number); 471 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass); 472 473 // Bitset-class 474 CHECK(IsBitset(Type::Union(T.ObjectClass, T.Object))); 475 CHECK(IsUnion(Type::Union(T.ObjectClass, T.Number))); 476 477 CheckEqual(T.Union(T.ObjectClass, T.Object), T.Object); 478 CheckSub(T.None, T.Union(T.ObjectClass, T.Number)); 479 CheckSub(T.Union(T.ObjectClass, T.Number), T.Any); 480 CheckSub(T.Union(T.ObjectClass, T.Smi), T.Union(T.Object, T.Number)); 481 CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); 482 CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); 483 CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); 484 CheckDisjoint(T.Union(T.ObjectClass, T.String), T.Number); 485 486 // Bitset-constant 487 CHECK(IsBitset(Type::Union(T.SmiConstant, T.Number))); 488 CHECK(IsBitset(Type::Union(T.ObjectConstant1, T.Object))); 489 CHECK(IsUnion(Type::Union(T.ObjectConstant2, T.Number))); 490 491 CheckEqual(T.Union(T.SmiConstant, T.Number), T.Number); 492 CheckEqual(T.Union(T.ObjectConstant1, T.Object), T.Object); 493 CheckSub(T.None, T.Union(T.ObjectConstant1, T.Number)); 494 CheckSub(T.Union(T.ObjectConstant1, T.Number), T.Any); 495 CheckSub(T.Union(T.ObjectConstant1, T.Signed32), T.Union(T.Object, T.Number)); 496 CheckSub(T.Union(T.ObjectConstant1, T.Array), T.Object); 497 CheckUnordered(T.Union(T.ObjectConstant1, T.String), T.Array); 498 CheckOverlap(T.Union(T.ObjectConstant1, T.String), T.Object); 499 CheckDisjoint(T.Union(T.ObjectConstant1, T.String), T.Number); 500 CheckEqual(T.Union(T.Signed32, T.Signed32Constant), T.Signed32); 501 502 // Class-constant 503 CHECK(IsUnion(Type::Union(T.ObjectConstant1, T.ObjectClass))); 504 CHECK(IsUnion(Type::Union(T.ArrayClass, T.ObjectConstant2))); 505 506 CheckSub(T.None, T.Union(T.ObjectConstant1, T.ArrayClass)); 507 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Any); 508 CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass), T.Object); 509 CheckSub(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ArrayClass)); 510 CheckSub(T.ArrayClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 511 CheckUnordered(T.ObjectClass, T.Union(T.ObjectConstant1, T.ArrayClass)); 512 CheckSub( 513 T.Union(T.ObjectConstant1, T.ArrayClass), T.Union(T.Array, T.Object)); 514 CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.ArrayConstant1); 515 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectConstant2); 516 CheckDisjoint(T.Union(T.ObjectConstant1, T.ArrayClass), T.ObjectClass); 517 518 // Bitset-union 519 CHECK(IsBitset( 520 Type::Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); 521 CHECK(IsUnion( 522 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); 523 524 CheckEqual( 525 T.Union(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 526 T.Object); 527 CheckEqual( 528 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), 529 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 530 CheckSub( 531 T.Double, 532 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); 533 CheckSub( 534 T.ObjectConstant1, 535 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); 536 CheckSub( 537 T.None, 538 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double)); 539 CheckSub( 540 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), 541 T.Any); 542 CheckSub( 543 T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Double), 544 T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); 545 546 // Class-union 547 CHECK(IsUnion( 548 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); 549 CHECK(IsUnion( 550 Type::Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ObjectClass))); 551 552 CheckEqual( 553 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 554 T.Union(T.ObjectClass, T.ObjectConstant1)); 555 CheckSub( 556 T.None, 557 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass))); 558 CheckSub( 559 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 560 T.Any); 561 CheckSub( 562 T.Union(T.ObjectClass, T.Union(T.ObjectConstant1, T.ObjectClass)), 563 T.Object); 564 CheckEqual( 565 T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass), 566 T.Union(T.ArrayClass, T.ObjectConstant2)); 567 568 // Constant-union 569 CHECK(IsUnion(Type::Union( 570 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); 571 CHECK(IsUnion(Type::Union( 572 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); 573 CHECK(IsUnion(Type::Union( 574 T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1))); 575 576 CheckEqual( 577 T.Union(T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 578 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 579 CheckEqual( 580 T.Union(T.Union(T.ArrayConstant1, T.ObjectConstant2), T.ObjectConstant1), 581 T.Union(T.ObjectConstant2, T.Union(T.ArrayConstant1, T.ObjectConstant1))); 582 583 // Union-union 584 CHECK(IsBitset(Type::Union( 585 T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); 586 CHECK(IsUnion(Type::Union( 587 T.Union(T.Number, T.ArrayClass), T.Union(T.ObjectClass, T.ArrayClass)))); 588 589 CheckEqual( 590 T.Union( 591 T.Union(T.ObjectConstant2, T.ObjectConstant1), 592 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 593 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 594 CheckEqual( 595 T.Union( 596 T.Union(T.ObjectConstant2, T.ArrayConstant1), 597 T.Union(T.ObjectConstant1, T.ArrayConstant2)), 598 T.Union(T.Union(T.ObjectConstant1, T.ObjectConstant2), T.ArrayConstant1)); 599 CheckEqual( 600 T.Union(T.Union(T.Number, T.ArrayClass), T.Union(T.Smi, T.Array)), 601 T.Union(T.Number, T.Array)); 602 } 603 604 605 TEST(Intersect) { 606 CcTest::InitializeVM(); 607 Isolate* isolate = CcTest::i_isolate(); 608 HandleScope scope(isolate); 609 HandlifiedTypes T(isolate); 610 611 // Bitset-bitset 612 CHECK(IsBitset(Type::Intersect(T.Object, T.Number))); 613 CHECK(IsBitset(Type::Intersect(T.Object, T.Object))); 614 CHECK(IsBitset(Type::Intersect(T.Any, T.None))); 615 616 CheckEqual(T.Intersect(T.None, T.Number), T.None); 617 CheckEqual(T.Intersect(T.Object, T.Proxy), T.None); 618 CheckEqual(T.Intersect(T.Name, T.String), T.Intersect(T.String, T.Name)); 619 CheckEqual(T.Intersect(T.UniqueName, T.String), T.InternalizedString); 620 621 // Class-class 622 CHECK(IsClass(Type::Intersect(T.ObjectClass, T.ObjectClass))); 623 CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.ArrayClass))); 624 625 CheckEqual(T.Intersect(T.ObjectClass, T.ObjectClass), T.ObjectClass); 626 CheckEqual(T.Intersect(T.ObjectClass, T.ArrayClass), T.None); 627 628 // Constant-constant 629 CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.ObjectConstant1))); 630 CHECK(IsConstant(Type::Intersect(T.ArrayConstant1, T.ArrayConstant2))); 631 CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectConstant2))); 632 633 CheckEqual( 634 T.Intersect(T.ObjectConstant1, T.ObjectConstant1), T.ObjectConstant1); 635 CheckEqual( 636 T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1); 637 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None); 638 639 // Bitset-class 640 CHECK(IsClass(Type::Intersect(T.ObjectClass, T.Object))); 641 CHECK(IsBitset(Type::Intersect(T.ObjectClass, T.Number))); 642 643 CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); 644 CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); 645 CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); 646 647 // Bitset-constant 648 CHECK(IsBitset(Type::Intersect(T.Smi, T.Number))); 649 CHECK(IsConstant(Type::Intersect(T.SmiConstant, T.Number))); 650 CHECK(IsConstant(Type::Intersect(T.ObjectConstant1, T.Object))); 651 652 CheckEqual(T.Intersect(T.Smi, T.Number), T.Smi); 653 CheckEqual(T.Intersect(T.SmiConstant, T.Number), T.SmiConstant); 654 CheckEqual(T.Intersect(T.ObjectConstant1, T.Object), T.ObjectConstant1); 655 656 // Class-constant 657 CHECK(IsBitset(Type::Intersect(T.ObjectConstant1, T.ObjectClass))); 658 CHECK(IsBitset(Type::Intersect(T.ArrayClass, T.ObjectConstant2))); 659 660 CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); 661 CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); 662 663 // Bitset-union 664 CHECK(IsUnion( 665 Type::Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)))); 666 CHECK(IsBitset( 667 Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.Number))); 668 669 CheckEqual( 670 T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), 671 T.Union(T.ObjectConstant1, T.ObjectClass)); 672 CheckEqual( 673 T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), 674 T.None); 675 676 // Class-union 677 CHECK(IsClass( 678 Type::Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass))); 679 CHECK(IsClass( 680 Type::Intersect(T.Union(T.Object, T.SmiConstant), T.ArrayClass))); 681 CHECK(IsBitset( 682 Type::Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass))); 683 684 CheckEqual( 685 T.Intersect(T.ArrayClass, T.Union(T.ObjectConstant2, T.ArrayClass)), 686 T.ArrayClass); 687 CheckEqual( 688 T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), 689 T.ArrayClass); 690 CheckEqual( 691 T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant1), T.ArrayClass), 692 T.None); 693 694 // Constant-union 695 CHECK(IsConstant(Type::Intersect( 696 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)))); 697 CHECK(IsConstant(Type::Intersect( 698 T.Union(T.Number, T.ObjectClass), T.SmiConstant))); 699 CHECK(IsBitset(Type::Intersect( 700 T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1))); 701 702 CheckEqual( 703 T.Intersect( 704 T.ObjectConstant1, T.Union(T.ObjectConstant1, T.ObjectConstant2)), 705 T.ObjectConstant1); 706 CheckEqual( 707 T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), 708 T.SmiConstant); 709 CheckEqual( 710 T.Intersect(T.Union(T.ArrayConstant1, T.ObjectClass), T.ObjectConstant1), 711 T.None); 712 713 // Union-union 714 CHECK(IsUnion(Type::Intersect( 715 T.Union(T.Number, T.ArrayClass), T.Union(T.Signed32, T.Array)))); 716 CHECK(IsBitset(Type::Intersect( 717 T.Union(T.Number, T.ObjectClass), T.Union(T.Signed32, T.Array)))); 718 719 CheckEqual( 720 T.Intersect( 721 T.Union(T.Number, T.ArrayClass), 722 T.Union(T.Smi, T.Array)), 723 T.Union(T.Smi, T.ArrayClass)); 724 CheckEqual( 725 T.Intersect( 726 T.Union(T.Number, T.ObjectClass), 727 T.Union(T.Signed32, T.Array)), 728 T.Signed32); 729 CheckEqual( 730 T.Intersect( 731 T.Union(T.ObjectConstant2, T.ObjectConstant1), 732 T.Union(T.ObjectConstant1, T.ObjectConstant2)), 733 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 734 CheckEqual( 735 T.Intersect( 736 T.Union(T.Union(T.ObjectConstant2, T.ObjectConstant1), T.ArrayClass), 737 T.Union( 738 T.ObjectConstant1, T.Union(T.ArrayConstant1, T.ObjectConstant2))), 739 T.Union(T.ObjectConstant2, T.ObjectConstant1)); 740 CheckEqual( 741 T.Intersect( 742 T.Union(T.ObjectConstant2, T.ArrayConstant1), 743 T.Union(T.ObjectConstant1, T.ArrayConstant2)), 744 T.ArrayConstant1); 745 } 746