Home | History | Annotate | Download | only in cctest
      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