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       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