| Index: test/cctest/test-types.cc
|
| diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc
|
| index 47868f6484b3e09fee9bf69d5fd9613296f74dff..d43aac3e3eb1acc8a8ac009017b9e2a0590e390a 100644
|
| --- a/test/cctest/test-types.cc
|
| +++ b/test/cctest/test-types.cc
|
| @@ -77,18 +77,20 @@ struct HeapRep {
|
| return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag;
|
| }
|
| static bool IsBitset(Handle<HeapType> t) { return t->IsSmi(); }
|
| - static bool IsClass(Handle<HeapType> t) { return t->IsMap(); }
|
| - static bool IsConstant(Handle<HeapType> t) { return t->IsBox(); }
|
| + static bool IsClass(Handle<HeapType> t) {
|
| + return t->IsMap() || IsStruct(t, 0);
|
| + }
|
| + static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); }
|
| static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 2); }
|
| static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 3); }
|
| static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 4); }
|
|
|
| static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); }
|
| static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); }
|
| - static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); }
|
| - static Object* AsConstant(Handle<HeapType> t) {
|
| - return Box::cast(*t)->value();
|
| + static Map* AsClass(Handle<HeapType> t) {
|
| + return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2));
|
| }
|
| + static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); }
|
| static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); }
|
| static int Length(Struct* structured) { return structured->length() - 1; }
|
|
|
| @@ -152,7 +154,7 @@ class Types {
|
| NumberFunction2 = Type::Function(Number, Number, Number, region);
|
| MethodFunction = Type::Function(String, Object, 0, region);
|
|
|
| - for (int i = 0; i < 50; ++i) {
|
| + for (int i = 0; i < 500; ++i) {
|
| types.push_back(Fuzz());
|
| }
|
| }
|
| @@ -332,6 +334,8 @@ struct Tests : Rep {
|
| Rep::IsBitset(type1) == Rep::IsBitset(type2) &&
|
| Rep::IsClass(type1) == Rep::IsClass(type2) &&
|
| Rep::IsConstant(type1) == Rep::IsConstant(type2) &&
|
| + Rep::IsArray(type1) == Rep::IsArray(type2) &&
|
| + Rep::IsFunction(type1) == Rep::IsFunction(type2) &&
|
| Rep::IsUnion(type1) == Rep::IsUnion(type2) &&
|
| type1->NumClasses() == type2->NumClasses() &&
|
| type1->NumConstants() == type2->NumConstants() &&
|
| @@ -341,7 +345,8 @@ struct Tests : Rep {
|
| Rep::AsClass(type1) == Rep::AsClass(type2)) &&
|
| (!Rep::IsConstant(type1) ||
|
| Rep::AsConstant(type1) == Rep::AsConstant(type2)) &&
|
| - (!Rep::IsUnion(type1) ||
|
| +// TODO(rossberg): Check details of arrays, functions, bounds.
|
| + (!Rep::IsUnion(type1) ||
|
| Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2)));
|
| }
|
|
|
| @@ -1535,9 +1540,9 @@ struct Tests : Rep {
|
| CheckEqual(
|
| T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)),
|
| T.Union(T.ObjectConstant1, T.ObjectClass));
|
| - CheckEqual(
|
| - T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
|
| - T.None);
|
| + CHECK(
|
| + !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)
|
| + ->IsInhabited());
|
|
|
| // Class-constant
|
| CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None);
|
| @@ -1550,9 +1555,9 @@ struct Tests : Rep {
|
| CheckEqual(
|
| T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
|
| T.AnyArray);
|
| - CheckEqual(
|
| - T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray),
|
| - T.None);
|
| + CHECK(
|
| + !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray)
|
| + ->IsInhabited());
|
|
|
| // Function-union
|
| CheckEqual(
|
| @@ -1561,9 +1566,9 @@ struct Tests : Rep {
|
| CheckEqual(
|
| T.Intersect(T.NumberFunction1, T.Union(T.Object, T.SmiConstant)),
|
| T.NumberFunction1);
|
| - CheckEqual(
|
| - T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2),
|
| - T.None);
|
| + CHECK(
|
| + !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2)
|
| + ->IsInhabited());
|
|
|
| // Class-union
|
| CheckEqual(
|
| @@ -1572,9 +1577,9 @@ struct Tests : Rep {
|
| CheckEqual(
|
| T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)),
|
| T.ArrayClass);
|
| - CheckEqual(
|
| - T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass),
|
| - T.None);
|
| + CHECK(
|
| + !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass)
|
| + ->IsInhabited());
|
|
|
| // Constant-union
|
| CheckEqual(
|
| @@ -1584,10 +1589,10 @@ struct Tests : Rep {
|
| CheckEqual(
|
| T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)),
|
| T.SmiConstant);
|
| - CheckEqual(
|
| - T.Intersect(
|
| - T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1),
|
| - T.None);
|
| + CHECK(
|
| + !T.Intersect(
|
| + T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1)
|
| + ->IsInhabited());
|
|
|
| // Union-union
|
| CheckEqual(
|
| @@ -1615,6 +1620,44 @@ struct Tests : Rep {
|
| T.Union(T.ObjectConstant2, T.ObjectConstant1));
|
| }
|
|
|
| + void Distributivity() {
|
| + // Distributivity:
|
| + // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
|
| + for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
|
| + for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
|
| + for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
|
| + TypeHandle type1 = *it1;
|
| + TypeHandle type2 = *it2;
|
| + TypeHandle type3 = *it3;
|
| + TypeHandle union12 = T.Union(type1, type2);
|
| + TypeHandle union13 = T.Union(type1, type3);
|
| + TypeHandle intersect23 = T.Intersect(type2, type3);
|
| + TypeHandle union1_23 = T.Union(type1, intersect23);
|
| + TypeHandle intersect12_13 = T.Intersect(union12, union13);
|
| + CHECK(Equal(union1_23, intersect12_13));
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Distributivity:
|
| + // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
|
| + for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
|
| + for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
|
| + for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
|
| + TypeHandle type1 = *it1;
|
| + TypeHandle type2 = *it2;
|
| + TypeHandle type3 = *it3;
|
| + TypeHandle intersect12 = T.Intersect(type1, type2);
|
| + TypeHandle intersect13 = T.Intersect(type1, type3);
|
| + TypeHandle union23 = T.Union(type2, type3);
|
| + TypeHandle intersect1_23 = T.Intersect(type1, union23);
|
| + TypeHandle union12_13 = T.Union(intersect12, intersect13);
|
| + CHECK(Equal(intersect1_23, union12_13));
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| template<class Type2, class TypeHandle2, class Region2, class Rep2>
|
| void Convert() {
|
| Types<Type2, TypeHandle2, Region2> T2(
|
| @@ -1744,6 +1787,13 @@ TEST(Intersect2) {
|
| }
|
|
|
|
|
| +TEST(Distributivity) {
|
| + CcTest::InitializeVM();
|
| + ZoneTests().Distributivity();
|
| + HeapTests().Distributivity();
|
| +}
|
| +
|
| +
|
| TEST(Convert) {
|
| CcTest::InitializeVM();
|
| ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>();
|
|
|