| Index: test/cctest/test-types.cc | 
| diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc | 
| index 34592d833607b39fab39c9682cef2f11bdf01382..8806f4b3f048d159d079b5ac8029bc6082ccb04e 100644 | 
| --- a/test/cctest/test-types.cc | 
| +++ b/test/cctest/test-types.cc | 
| @@ -234,17 +234,81 @@ struct Tests : Rep { | 
| for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 
| TypeHandle type1 = *it1; | 
| TypeHandle type2 = *it2; | 
| -        TypeHandle intersect12 = T.Intersect(type1, type2); | 
| if (this->IsBitset(type1) && this->IsBitset(type2)) { | 
| +          TypeHandle intersect12 = T.Intersect(type1, type2); | 
| bitset bits = this->AsBitset(type1) & this->AsBitset(type2); | 
| -          CHECK( | 
| -              (Rep::BitsetType::IsInhabited(bits) ? bits : 0) == | 
| -              this->AsBitset(intersect12)); | 
| +          CHECK(bits == this->AsBitset(intersect12)); | 
| } | 
| } | 
| } | 
| } | 
|  | 
| +  void PointwiseRepresentation() { | 
| +    // Check we can decompose type into semantics and representation and | 
| +    // then compose it back to get an equivalent type. | 
| +    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 
| +      TypeHandle type1 = *it1; | 
| +      TypeHandle representation = T.ProjectRepresentation(type1); | 
| +      TypeHandle semantic = T.ProjectSemantic(type1); | 
| +      TypeHandle composed = T.Union(representation, semantic); | 
| +      CHECK(type1->Equals(composed)); | 
| +    } | 
| + | 
| +    // Pointwiseness of Union. | 
| +    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 
| +      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 
| +        TypeHandle type1 = *it1; | 
| +        TypeHandle type2 = *it2; | 
| +        TypeHandle representation1 = T.ProjectRepresentation(type1); | 
| +        TypeHandle semantic1 = T.ProjectSemantic(type1); | 
| +        TypeHandle representation2 = T.ProjectRepresentation(type2); | 
| +        TypeHandle semantic2 = T.ProjectSemantic(type2); | 
| +        TypeHandle direct_union = T.Union(type1, type2); | 
| +        TypeHandle representation_union = | 
| +            T.Union(representation1, representation2); | 
| +        TypeHandle semantic_union = T.Union(semantic1, semantic2); | 
| +        TypeHandle composed_union = | 
| +            T.Union(representation_union, semantic_union); | 
| +        CHECK(direct_union->Equals(composed_union)); | 
| +      } | 
| +    } | 
| + | 
| +    // Pointwiseness of Intersect. | 
| +    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 
| +      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 
| +        TypeHandle type1 = *it1; | 
| +        TypeHandle type2 = *it2; | 
| +        TypeHandle representation1 = T.ProjectRepresentation(type1); | 
| +        TypeHandle semantic1 = T.ProjectSemantic(type1); | 
| +        TypeHandle representation2 = T.ProjectRepresentation(type2); | 
| +        TypeHandle semantic2 = T.ProjectSemantic(type2); | 
| +        TypeHandle direct_intersection = T.Intersect(type1, type2); | 
| +        TypeHandle representation_intersection = | 
| +            T.Intersect(representation1, representation2); | 
| +        TypeHandle semantic_intersection = T.Intersect(semantic1, semantic2); | 
| +        TypeHandle composed_intersection = | 
| +            T.Union(representation_intersection, semantic_intersection); | 
| +        CHECK(direct_intersection->Equals(composed_intersection)); | 
| +      } | 
| +    } | 
| + | 
| +    // Pointwiseness of Is. | 
| +    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { | 
| +      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { | 
| +        TypeHandle type1 = *it1; | 
| +        TypeHandle type2 = *it2; | 
| +        TypeHandle representation1 = T.ProjectRepresentation(type1); | 
| +        TypeHandle semantic1 = T.ProjectSemantic(type1); | 
| +        TypeHandle representation2 = T.ProjectRepresentation(type2); | 
| +        TypeHandle semantic2 = T.ProjectSemantic(type2); | 
| +        bool representation_is = representation1->Is(representation2); | 
| +        bool semantic_is = semantic1->Is(semantic2); | 
| +        bool direct_is = type1->Is(type2); | 
| +        CHECK(direct_is == (semantic_is && representation_is)); | 
| +      } | 
| +    } | 
| +  } | 
| + | 
| void Class() { | 
| // Constructor | 
| for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { | 
| @@ -661,7 +725,7 @@ struct Tests : Rep { | 
| // T->Is(Range(T->Min(), T->Max())). | 
| for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { | 
| TypeHandle type = *it; | 
| -      CHECK(!(type->Is(T.Integer) && !type->Is(T.None)) || | 
| +      CHECK(!type->Is(T.Integer) || !type->IsInhabited() || | 
| type->Is(T.Range(type->Min(), type->Max()))); | 
| } | 
| } | 
| @@ -801,7 +865,7 @@ struct Tests : Rep { | 
| (type1->IsContext() && type2->IsContext()) || | 
| (type1->IsArray() && type2->IsArray()) || | 
| (type1->IsFunction() && type2->IsFunction()) || | 
| -              type1->Equals(T.None)); | 
| +              !type1->IsInhabited()); | 
| } | 
| } | 
| } | 
| @@ -1305,7 +1369,7 @@ struct Tests : Rep { | 
| CheckDisjoint(T.SignedFunction1, T.MethodFunction); | 
| CheckOverlap(T.ObjectConstant1, T.ObjectClass);  // !!! | 
| CheckOverlap(T.ObjectConstant2, T.ObjectClass);  // !!! | 
| -    CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Untagged));  // !!! | 
| +    CheckOverlap(T.NumberClass, T.Intersect(T.Number, T.Tagged));  // !!! | 
| } | 
|  | 
| void Union1() { | 
| @@ -1694,16 +1758,16 @@ struct Tests : Rep { | 
|  | 
| // Bitset-class | 
| CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass); | 
| -    CheckEqual(T.Intersect(T.ObjectClass, T.Array), T.None); | 
| -    CheckEqual(T.Intersect(T.ObjectClass, T.Number), T.None); | 
| +    CHECK(!T.Intersect(T.ObjectClass, T.Array)->IsInhabited()); | 
| +    CHECK(!T.Intersect(T.ObjectClass, T.Number)->IsInhabited()); | 
|  | 
| // Bitset-array | 
| CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); | 
| -    CheckEqual(T.Intersect(T.AnyArray, T.Proxy), T.None); | 
| +    CHECK(!T.Intersect(T.AnyArray, T.Proxy)->IsInhabited()); | 
|  | 
| // Bitset-function | 
| CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction); | 
| -    CheckEqual(T.Intersect(T.NumberFunction1, T.Proxy), T.None); | 
| +    CHECK(!T.Intersect(T.NumberFunction1, T.Proxy)->IsInhabited()); | 
|  | 
| // Bitset-union | 
| CheckEqual( | 
| @@ -1901,6 +1965,13 @@ TEST(IsSomeType) { | 
| } | 
|  | 
|  | 
| +TEST(PointwiseRepresentation) { | 
| +  CcTest::InitializeVM(); | 
| +  ZoneTests().PointwiseRepresentation(); | 
| +  HeapTests().PointwiseRepresentation(); | 
| +} | 
| + | 
| + | 
| TEST(BitsetType) { | 
| CcTest::InitializeVM(); | 
| ZoneTests().Bitset(); | 
|  |