Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Unified Diff: test/cctest/test-types.cc

Issue 232843002: Yet more type system tests (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Doc Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/types.h ('K') | « src/types.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-types.cc
diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc
index 6cdd46c8665d042881a00feb014885826a2803ea..15af42567f88e2738c2ff8a40ee9b60f918e4dae 100644
--- a/test/cctest/test-types.cc
+++ b/test/cctest/test-types.cc
@@ -50,24 +50,29 @@ class Types {
array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize);
ObjectClass = Type::Class(object_map, region);
ArrayClass = Type::Class(array_map, region);
- types.push_back(ObjectClass);
- types.push_back(ArrayClass);
+
+ maps.push_back(object_map);
+ maps.push_back(array_map);
+ for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
+ types.push_back(Type::Class(*it, region));
+ }
smi = handle(Smi::FromInt(666), isolate);
signed32 = isolate->factory()->NewHeapNumber(0x40000000);
object1 = isolate->factory()->NewJSObjectFromMap(object_map);
object2 = isolate->factory()->NewJSObjectFromMap(object_map);
array = isolate->factory()->NewJSArray(20);
- values.push_back(smi);
- values.push_back(signed32);
- values.push_back(object1);
- values.push_back(object2);
- values.push_back(array);
SmiConstant = Type::Constant(smi, region);
Signed32Constant = Type::Constant(signed32, region);
ObjectConstant1 = Type::Constant(object1, region);
ObjectConstant2 = Type::Constant(object2, region);
ArrayConstant = Type::Constant(array, region);
+
+ values.push_back(smi);
+ values.push_back(signed32);
+ values.push_back(object1);
+ values.push_back(object2);
+ values.push_back(array);
for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
types.push_back(Type::Constant(*it, region));
}
@@ -104,21 +109,26 @@ class Types {
Handle<i::JSArray> array;
typedef std::vector<TypeHandle> TypeVector;
- TypeVector types;
-
+ typedef std::vector<Handle<i::Map> > MapVector;
typedef std::vector<Handle<i::Object> > ValueVector;
+ TypeVector types;
+ MapVector maps;
ValueVector values;
- TypeHandle Of(Handle<i::Object> obj) {
- return Type::Of(obj, region_);
+ TypeHandle Of(Handle<i::Object> value) {
+ return Type::Of(value, region_);
+ }
+
+ TypeHandle NowOf(Handle<i::Object> value) {
+ return Type::NowOf(value, region_);
}
- TypeHandle NowOf(Handle<i::Object> obj) {
- return Type::NowOf(obj, region_);
+ TypeHandle Constant(Handle<i::Object> value) {
+ return Type::Constant(value, region_);
}
- TypeHandle Constant(Handle<i::Object> obj) {
- return Type::Constant(obj, region_);
+ TypeHandle Class(Handle<i::Map> map) {
+ return Type::Class(map, region_);
}
TypeHandle Union(TypeHandle t1, TypeHandle t2) {
@@ -201,6 +211,7 @@ template<class Type, class TypeHandle, class Region, class Rep>
struct Tests : Rep {
typedef Types<Type, TypeHandle, Region> TypesInstance;
typedef typename TypesInstance::TypeVector::iterator TypeIterator;
+ typedef typename TypesInstance::MapVector::iterator MapIterator;
typedef typename TypesInstance::ValueVector::iterator ValueIterator;
Isolate* isolate;
@@ -273,64 +284,159 @@ struct Tests : Rep {
}
void Bitset() {
+ // None and Any are bitsets.
CHECK(this->IsBitset(T.None));
CHECK(this->IsBitset(T.Any));
- CHECK(this->IsBitset(T.String));
- CHECK(this->IsBitset(T.Object));
-
- CHECK(this->IsBitset(T.Union(T.String, T.Number)));
- CHECK(this->IsBitset(T.Union(T.String, T.Receiver)));
CHECK_EQ(0, this->AsBitset(T.None));
- CHECK_EQ(
- this->AsBitset(T.Number) | this->AsBitset(T.String),
- this->AsBitset(T.Union(T.String, T.Number)));
- CHECK_EQ(
- this->AsBitset(T.Receiver),
- this->AsBitset(T.Union(T.Receiver, T.Object)));
+ CHECK_EQ(-1, this->AsBitset(T.Any));
+
+ // Union(T1, T2) is a bitset for all bitsets T1,T2
+ 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;
+ CHECK(!(this->IsBitset(type1) && this->IsBitset(type2)) ||
+ this->IsBitset(T.Union(type1, type2)));
+ }
+ }
+
+ // Union(T1, T2) is a bitset if T2 is a bitset and T1->Is(T2)
+ // (and vice versa).
+ 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;
+ CHECK(!(this->IsBitset(type2) && type1->Is(type2)) ||
+ this->IsBitset(T.Union(type1, type2)));
+ CHECK(!(this->IsBitset(type1) && type2->Is(type1)) ||
+ this->IsBitset(T.Union(type1, type2)));
+ }
+ }
+
+ // Union(T1, T2) is bitwise disjunction for all bitsets T1,T2
+ 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;
+ if (this->IsBitset(type1) && this->IsBitset(type2)) {
+ CHECK_EQ(
+ this->AsBitset(type1) | this->AsBitset(type2),
+ this->AsBitset(T.Union(type1, type2)));
+ }
+ }
+ }
+
+ // Intersect(T1, T2) is bitwise conjunction for all bitsets T1,T2
+ 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;
+ if (this->IsBitset(type1) && this->IsBitset(type2)) {
+ CHECK_EQ(
+ this->AsBitset(type1) & this->AsBitset(type2),
+ this->AsBitset(T.Intersect(type1, type2)));
+ }
+ }
+ }
}
void Class() {
- CHECK(this->IsClass(T.ObjectClass));
- CHECK(this->IsClass(T.ArrayClass));
+ // Constructor
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ Handle<i::Map> map = *mt;
+ CHECK(this->IsClass(T.Class(map)));
+ }
- CHECK(*T.object_map == this->AsClass(T.ObjectClass));
- CHECK(*T.array_map == this->AsClass(T.ArrayClass));
+ // Map attribute
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ Handle<i::Map> map = *mt;
+ CHECK(*map == *T.Class(map)->AsClass());
+ }
+
+ // Functionality & Injectivity
+ for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
+ for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
+ Handle<i::Map> map1 = *mt1;
+ Handle<i::Map> map2 = *mt2;
+ CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2));
+ }
+ }
}
void Constant() {
- CHECK(this->IsConstant(T.SmiConstant));
- CHECK(this->IsConstant(T.ObjectConstant1));
- CHECK(this->IsConstant(T.ObjectConstant2));
- CHECK(this->IsConstant(T.ArrayConstant));
-
- CHECK(*T.smi == this->AsConstant(T.SmiConstant));
- CHECK(*T.object1 == this->AsConstant(T.ObjectConstant1));
- CHECK(*T.object2 == this->AsConstant(T.ObjectConstant2));
- CHECK(*T.object1 != this->AsConstant(T.ObjectConstant2));
- CHECK(*T.array == this->AsConstant(T.ArrayConstant));
+ // Constructor
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Object> value = *vt;
+ CHECK(this->IsConstant(T.Constant(value)));
+ }
+
+ // Value attribute
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Object> value = *vt;
+ CHECK(*value == *T.Constant(value)->AsConstant());
+ }
+
+ // Functionality & Injectivity
+ for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
+ for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
+ Handle<i::Object> val1 = *vt1;
+ Handle<i::Object> val2 = *vt2;
+ CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2));
+ }
+ }
}
void Of() {
- CHECK(T.Of(T.smi)->Is(T.SignedSmall));
- CHECK(T.Of(T.signed32)->Is(T.Signed32));
- CHECK(T.Of(T.object1)->Is(T.Object));
- CHECK(T.Of(T.object2)->Is(T.Object));
- CHECK(T.Of(T.array)->Is(T.Array));
+ // Constant(V)->Is(Of(V)) for all V
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Object> value = *vt;
+ CHECK(T.Constant(value)->Is(T.Of(value)));
+ }
+
+ // Constant(V)->Is(T) implies Of(V)->Is(T) or T->Maybe(Constant(V))
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ Handle<i::Object> value = *vt;
+ TypeHandle type = *it;
+ CHECK(!T.Constant(value)->Is(type) ||
+ T.Of(value)->Is(type) || type->Maybe(T.Constant(value)));
+ }
+ }
}
void NowOf() {
+ // Constant(V)->NowIs(NowOf(V)) for all V
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Object> value = *vt;
+ CHECK(T.Constant(value)->NowIs(T.NowOf(value)));
+ }
+
// NowOf(V)->Is(Of(V)) for all V
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
- Handle<i::Object> val = *vt;
- CHECK(T.NowOf(val)->Is(T.Of(val)));
+ Handle<i::Object> value = *vt;
+ CHECK(T.NowOf(value)->Is(T.Of(value)));
+ }
+
+ // Constant(V)->Is(T) implies NowOf(V)->Is(T) or T->Maybe(Constant(V))
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ Handle<i::Object> value = *vt;
+ TypeHandle type = *it;
+ CHECK(!T.Constant(value)->Is(type) ||
+ T.NowOf(value)->Is(type) || type->Maybe(T.Constant(value)));
+ }
}
- CHECK(T.NowOf(T.smi)->NowIs(T.SignedSmall));
- CHECK(T.NowOf(T.signed32)->NowIs(T.Signed32));
- CHECK(T.NowOf(T.object1)->NowIs(T.ObjectClass));
- CHECK(T.NowOf(T.object2)->NowIs(T.ObjectClass));
- CHECK(T.NowOf(T.array)->NowIs(T.Array));
+ // Constant(V)->NowIs(T) implies NowOf(V)->NowIs(T) or T->Maybe(Constant(V))
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ Handle<i::Object> value = *vt;
+ TypeHandle type = *it;
+ CHECK(!T.Constant(value)->NowIs(type) ||
+ T.NowOf(value)->NowIs(type) || type->Maybe(T.Constant(value)));
+ }
+ }
}
void Is() {
@@ -371,22 +477,52 @@ struct Tests : Rep {
TypeHandle type1 = *it1;
TypeHandle type2 = *it2;
TypeHandle type3 = *it3;
- CHECK(!type1->Is(type2) ||
- !type2->Is(type3) ||
- type1->Is(type3));
+ CHECK(!(type1->Is(type2) && type2->Is(type3)) || type1->Is(type3));
}
}
}
- // Symmetry and Transitivity
- CheckSub(T.None, T.Number);
- CheckSub(T.None, T.Any);
+ // Constant(V1)->Is(Constant(V2)) iff V1 = V2
+ for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
+ for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
+ Handle<i::Object> val1 = *vt1;
+ Handle<i::Object> val2 = *vt2;
+ CHECK(T.Constant(val1)->Is(T.Constant(val2)) == (*val1 == *val2));
+ }
+ }
+
+ // Class(M1)->Is(Class(M2)) iff M1 = M2
+ for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
+ for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
+ Handle<i::Map> map1 = *mt1;
+ Handle<i::Map> map2 = *mt2;
+ CHECK(T.Class(map1)->Is(T.Class(map2)) == (*map1 == *map2));
+ }
+ }
+
+ // Constant(V)->Is(Class(M)) for no V,M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Constant(value)->Is(T.Class(map)));
+ }
+ }
+
+ // Class(M)->Is(Constant(V)) for no V,M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Class(map)->Is(T.Constant(value)));
+ }
+ }
+ // Basic types
CheckUnordered(T.Boolean, T.Null);
CheckUnordered(T.Undefined, T.Null);
CheckUnordered(T.Boolean, T.Undefined);
- CheckSub(T.Number, T.Any);
CheckSub(T.SignedSmall, T.Number);
CheckSub(T.Signed32, T.Number);
CheckSub(T.Float, T.Number);
@@ -394,8 +530,6 @@ struct Tests : Rep {
CheckUnordered(T.SignedSmall, T.Float);
CheckUnordered(T.Signed32, T.Float);
- CheckSub(T.Name, T.Any);
- CheckSub(T.UniqueName, T.Any);
CheckSub(T.UniqueName, T.Name);
CheckSub(T.String, T.Name);
CheckSub(T.InternalizedString, T.String);
@@ -407,8 +541,6 @@ struct Tests : Rep {
CheckUnordered(T.String, T.Symbol);
CheckUnordered(T.InternalizedString, T.Symbol);
- CheckSub(T.Receiver, T.Any);
- CheckSub(T.Object, T.Any);
CheckSub(T.Object, T.Receiver);
CheckSub(T.Array, T.Object);
CheckSub(T.Function, T.Object);
@@ -416,12 +548,7 @@ struct Tests : Rep {
CheckUnordered(T.Object, T.Proxy);
CheckUnordered(T.Array, T.Function);
- // Structured subtyping
- CheckSub(T.None, T.ObjectClass);
- CheckSub(T.None, T.ObjectConstant1);
- CheckSub(T.ObjectClass, T.Any);
- CheckSub(T.ObjectConstant1, T.Any);
-
+ // Structural types
CheckSub(T.ObjectClass, T.Object);
CheckSub(T.ArrayClass, T.Object);
CheckUnordered(T.ObjectClass, T.ArrayClass);
@@ -497,8 +624,43 @@ struct Tests : Rep {
}
}
- CHECK(T.ObjectConstant1->NowIs(T.ObjectClass));
- CHECK(T.ObjectConstant2->NowIs(T.ObjectClass));
+ // Constant(V1)->NowIs(Constant(V2)) iff V1 = V2
+ for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
+ for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
+ Handle<i::Object> val1 = *vt1;
+ Handle<i::Object> val2 = *vt2;
+ CHECK(T.Constant(val1)->NowIs(T.Constant(val2)) == (*val1 == *val2));
+ }
+ }
+
+ // Class(M1)->NowIs(Class(M2)) iff M1 = M2
+ for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
+ for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
+ Handle<i::Map> map1 = *mt1;
+ Handle<i::Map> map2 = *mt2;
+ CHECK(T.Class(map1)->NowIs(T.Class(map2)) == (*map1 == *map2));
+ }
+ }
+
+ // Constant(V)->NowIs(Class(M)) iff V has map M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK((value->IsHeapObject() &&
+ i::HeapObject::cast(*value)->map() == *map)
+ == T.Constant(value)->NowIs(T.Class(map)));
+ }
+ }
+
+ // Class(M)->NowIs(Constant(V)) for no V,M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Class(map)->NowIs(T.Constant(value)));
+ }
+ }
}
void Contains() {
@@ -506,8 +668,8 @@ struct Tests : Rep {
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
- Handle<i::Object> val = *vt;
- CHECK(type->Contains(val) == T.Constant(val)->Is(type));
+ Handle<i::Object> value = *vt;
+ CHECK(type->Contains(value) == T.Constant(value)->Is(type));
}
}
@@ -515,8 +677,8 @@ struct Tests : Rep {
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
- Handle<i::Object> val = *vt;
- CHECK(!T.Of(val)->Is(type) || type->Contains(val));
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Of(value)->Is(type) || type->Contains(value));
}
}
}
@@ -526,44 +688,56 @@ struct Tests : Rep {
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
- Handle<i::Object> val = *vt;
- CHECK(type->NowContains(val) == T.Constant(val)->NowIs(type));
+ Handle<i::Object> value = *vt;
+ CHECK(type->NowContains(value) == T.Constant(value)->NowIs(type));
}
}
- // NowOf(V)->Is(T) implies T->NowContains(V) for all T,V
+ // T->Contains(V) implies T->NowContains(V) for all T,V
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
Handle<i::Object> value = *vt;
- CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value));
+ CHECK(!type->Contains(value) || type->NowContains(value));
}
}
- // NowOf(V)->NowIs(T) implies T->NowContains(V) for all T,V
+ // NowOf(V)->Is(T) implies T->NowContains(V) for all T,V
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
- Handle<i::Object> val = *vt;
- CHECK(!T.NowOf(val)->NowIs(type) || type->NowContains(val));
+ Handle<i::Object> value = *vt;
+ CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value));
}
}
- // T->Contains(V) implies T->NowContains(V) for all T,V
+ // NowOf(V)->NowIs(T) implies T->NowContains(V) for all T,V
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
TypeHandle type = *it;
- Handle<i::Object> val = *vt;
- CHECK(!type->Contains(val) || type->NowContains(val));
+ Handle<i::Object> value = *vt;
+ CHECK(!T.NowOf(value)->NowIs(type) || type->NowContains(value));
}
}
}
void Maybe() {
- // T->Maybe(T) for all inhabited T
+ // T->Maybe(T) iff T inhabited
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ CHECK(type->Maybe(type) == type->IsInhabited());
+ }
+
+ // T->Maybe(Any) iff T inhabited
+ for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+ TypeHandle type = *it;
+ CHECK(type->Maybe(T.Any) == type->IsInhabited());
+ }
+
+ // T->Maybe(None) never
for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
TypeHandle type = *it;
- CHECK(type->Maybe(type) || !type->IsInhabited());
+ CHECK(!type->Maybe(T.None));
}
// Symmetry
@@ -575,31 +749,71 @@ struct Tests : Rep {
}
}
- // T1->Is(T2) implies T1->Maybe(T2) or T1 is uninhabited for all T1,T2
+ // T1->Maybe(T2) only if T1, T2 inhabited
+ 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;
+ CHECK(!type1->Maybe(type2) ||
+ (type1->IsInhabited() && type2->IsInhabited()));
+ }
+ }
+
+ // T1->Is(T2) and T1 inhabited implies T1->Maybe(T2) for all T1,T2
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;
- CHECK(!type1->Is(type2) ||
- type1->Maybe(type2) ||
- !type1->IsInhabited());
+ CHECK(!(type1->Is(type2) && type1->IsInhabited()) ||
+ type1->Maybe(type2));
+ }
+ }
+
+ // Constant(V1)->Maybe(Constant(V2)) iff V1 = V2
+ for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
+ for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
+ Handle<i::Object> val1 = *vt1;
+ Handle<i::Object> val2 = *vt2;
+ CHECK(T.Constant(val1)->Maybe(T.Constant(val2)) == (*val1 == *val2));
+ }
+ }
+
+ // Class(M1)->Maybe(Class(M2)) iff M1 = M2
+ for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
+ for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
+ Handle<i::Map> map1 = *mt1;
+ Handle<i::Map> map2 = *mt2;
+ CHECK(T.Class(map1)->Maybe(T.Class(map2)) == (*map1 == *map2));
}
}
- CheckOverlap(T.Any, T.Any, T.Semantic);
- CheckOverlap(T.Object, T.Object, T.Semantic);
+ // Constant(V)->Maybe(Class(M)) for no V,M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Constant(value)->Maybe(T.Class(map)));
+ }
+ }
+
+ // Class(M)->Maybe(Constant(V)) for no V,M
+ for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) {
+ for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
+ Handle<i::Map> map = *mt;
+ Handle<i::Object> value = *vt;
+ CHECK(!T.Class(map)->Maybe(T.Constant(value)));
+ }
+ }
+ // Basic types
CheckDisjoint(T.Boolean, T.Null, T.Semantic);
CheckDisjoint(T.Undefined, T.Null, T.Semantic);
CheckDisjoint(T.Boolean, T.Undefined, T.Semantic);
- CheckOverlap(T.Number, T.Any, T.Semantic);
CheckOverlap(T.SignedSmall, T.Number, T.Semantic);
CheckOverlap(T.Float, T.Number, T.Semantic);
CheckDisjoint(T.Signed32, T.Float, T.Semantic);
- CheckOverlap(T.Name, T.Any, T.Semantic);
- CheckOverlap(T.UniqueName, T.Any, T.Semantic);
CheckOverlap(T.UniqueName, T.Name, T.Semantic);
CheckOverlap(T.String, T.Name, T.Semantic);
CheckOverlap(T.InternalizedString, T.String, T.Semantic);
@@ -611,8 +825,6 @@ struct Tests : Rep {
CheckDisjoint(T.String, T.Symbol, T.Semantic);
CheckDisjoint(T.InternalizedString, T.Symbol, T.Semantic);
- CheckOverlap(T.Receiver, T.Any, T.Semantic);
- CheckOverlap(T.Object, T.Any, T.Semantic);
CheckOverlap(T.Object, T.Receiver, T.Semantic);
CheckOverlap(T.Array, T.Object, T.Semantic);
CheckOverlap(T.Function, T.Object, T.Semantic);
@@ -620,9 +832,7 @@ struct Tests : Rep {
CheckDisjoint(T.Object, T.Proxy, T.Semantic);
CheckDisjoint(T.Array, T.Function, T.Semantic);
- CheckOverlap(T.ObjectClass, T.Any, T.Semantic);
- CheckOverlap(T.ObjectConstant1, T.Any, T.Semantic);
-
+ // Structural types
CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
« src/types.h ('K') | « src/types.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698