Chromium Code Reviews| Index: test/cctest/test-types.cc |
| diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc |
| index 8120a6d94c39cdd014b637f7ab723c925c3d9aa1..262a1d3b33f8d3cd5be40a14669b394ccf72fd81 100644 |
| --- a/test/cctest/test-types.cc |
| +++ b/test/cctest/test-types.cc |
| @@ -21,10 +21,11 @@ struct ZoneRep { |
| static bool IsBitset(Type* t) { return reinterpret_cast<intptr_t>(t) & 1; } |
| static bool IsClass(Type* t) { return IsStruct(t, 0); } |
| static bool IsConstant(Type* t) { return IsStruct(t, 1); } |
| - static bool IsContext(Type* t) { return IsStruct(t, 2); } |
| - static bool IsArray(Type* t) { return IsStruct(t, 3); } |
| - static bool IsFunction(Type* t) { return IsStruct(t, 4); } |
| - static bool IsUnion(Type* t) { return IsStruct(t, 5); } |
| + static bool IsRange(Type* t) { return IsStruct(t, 2); } |
| + static bool IsContext(Type* t) { return IsStruct(t, 3); } |
| + static bool IsArray(Type* t) { return IsStruct(t, 4); } |
| + static bool IsFunction(Type* t) { return IsStruct(t, 5); } |
| + static bool IsUnion(Type* t) { return IsStruct(t, 6); } |
| static Struct* AsStruct(Type* t) { |
| return reinterpret_cast<Struct*>(t); |
| @@ -38,6 +39,9 @@ struct ZoneRep { |
| static Object* AsConstant(Type* t) { |
| return *static_cast<Object**>(AsStruct(t)[3]); |
| } |
| + static Type* AsRange(Type* t) { |
| + return *static_cast<Type**>(AsStruct(t)[2]); |
| + } |
|
neis
2014/07/21 17:47:15
This was bogus and I got rid of it.
|
| static Type* AsContext(Type* t) { |
| return *static_cast<Type**>(AsStruct(t)[2]); |
| } |
| @@ -70,10 +74,11 @@ struct HeapRep { |
| return t->IsMap() || IsStruct(t, 0); |
| } |
| static bool IsConstant(Handle<HeapType> t) { return IsStruct(t, 1); } |
| - static bool IsContext(Handle<HeapType> t) { return IsStruct(t, 2); } |
| - static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 3); } |
| - static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 4); } |
| - static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 5); } |
| + static bool IsRange(Handle<HeapType> t) { return IsStruct(t, 2); } |
| + static bool IsContext(Handle<HeapType> t) { return IsStruct(t, 3); } |
| + static bool IsArray(Handle<HeapType> t) { return IsStruct(t, 4); } |
| + static bool IsFunction(Handle<HeapType> t) { return IsStruct(t, 5); } |
| + static bool IsUnion(Handle<HeapType> t) { return IsStruct(t, 6); } |
| static Struct* AsStruct(Handle<HeapType> t) { return FixedArray::cast(*t); } |
| static int AsBitset(Handle<HeapType> t) { return Smi::cast(*t)->value(); } |
| @@ -81,6 +86,9 @@ struct HeapRep { |
| return t->IsMap() ? Map::cast(*t) : Map::cast(AsStruct(t)->get(2)); |
| } |
| static Object* AsConstant(Handle<HeapType> t) { return AsStruct(t)->get(2); } |
| + static HeapType* AsRange(Handle<HeapType> t) { |
| + return HeapType::cast(AsStruct(t)->get(1)); |
| + } |
| static HeapType* AsContext(Handle<HeapType> t) { |
| return HeapType::cast(AsStruct(t)->get(1)); |
| } |
| @@ -149,6 +157,14 @@ class Types { |
| types.push_back(Type::Constant(*it, region)); |
| } |
| + doubles.push_back(-0.0); |
| + doubles.push_back(+0.0); |
| + doubles.push_back(-std::numeric_limits<double>::infinity()); |
| + doubles.push_back(+std::numeric_limits<double>::infinity()); |
| + for (int i = 0; i < 40; ++i) { |
|
rossberg
2014/07/21 15:58:32
I suppose 10 to 20 is enough here, esp given that
neis
2014/07/21 17:47:15
Done.
|
| + doubles.push_back(rng_->NextDouble() * rng_->NextInt()); |
| + } |
| + |
| NumberArray = Type::Array(Number, region); |
| StringArray = Type::Array(String, region); |
| AnyArray = Type::Array(Any, region); |
| @@ -201,9 +217,12 @@ class Types { |
| typedef std::vector<TypeHandle> TypeVector; |
| typedef std::vector<Handle<i::Map> > MapVector; |
| typedef std::vector<Handle<i::Object> > ValueVector; |
| + typedef std::vector<double> DoubleVector; |
| + |
| TypeVector types; |
| MapVector maps; |
| ValueVector values; |
| + DoubleVector doubles; |
| TypeHandle Of(Handle<i::Object> value) { |
| return Type::Of(value, region_); |
| @@ -217,6 +236,10 @@ class Types { |
| return Type::Constant(value, region_); |
| } |
| + TypeHandle Range(double min, double max) { |
| + return Type::Range(min, max, region_); |
| + } |
| + |
| TypeHandle Class(Handle<i::Map> map) { |
| return Type::Class(map, region_); |
| } |
| @@ -327,6 +350,7 @@ struct Tests : Rep { |
| typedef typename TypesInstance::TypeVector::iterator TypeIterator; |
| typedef typename TypesInstance::MapVector::iterator MapIterator; |
| typedef typename TypesInstance::ValueVector::iterator ValueIterator; |
| + typedef typename TypesInstance::DoubleVector::iterator DoubleIterator; |
| Isolate* isolate; |
| HandleScope scope; |
| @@ -346,6 +370,7 @@ struct Tests : Rep { |
| Rep::IsBitset(type1) == Rep::IsBitset(type2) && |
| Rep::IsClass(type1) == Rep::IsClass(type2) && |
| Rep::IsConstant(type1) == Rep::IsConstant(type2) && |
| + Rep::IsRange(type1) == Rep::IsRange(type2) && |
| Rep::IsContext(type1) == Rep::IsContext(type2) && |
| Rep::IsArray(type1) == Rep::IsArray(type2) && |
| Rep::IsFunction(type1) == Rep::IsFunction(type2) && |
| @@ -359,7 +384,7 @@ struct Tests : Rep { |
| (!Rep::IsConstant(type1) || |
| Rep::AsConstant(type1) == Rep::AsConstant(type2)) && |
| // TODO(rossberg): Check details of arrays, functions, bounds. |
| - (!Rep::IsUnion(type1) || |
| + (!Rep::IsUnion(type1) || |
| Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); |
| } |
| @@ -566,6 +591,48 @@ struct Tests : Rep { |
| CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber)); |
| } |
| + void Range() { |
| + // Constructor |
| + for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { |
| + for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { |
| + double min = *i <= *j ? *i : *j; |
|
rossberg
2014/07/21 15:58:32
You can use the C++ min & max functions for these.
neis
2014/07/21 17:47:15
Done.
|
| + double max = *i <= *j ? *j : *i; |
| + TypeHandle type = T.Range(min, max); |
| + CHECK(this->IsRange(type)); |
| + } |
| + } |
| + |
| + // Range attributes |
| + for (DoubleIterator i = T.doubles.begin(); i != T.doubles.end(); ++i) { |
| + for (DoubleIterator j = T.doubles.begin(); j != T.doubles.end(); ++j) { |
| + double min = *i <= *j ? *i : *j; |
| + double max = *i <= *j ? *j : *i; |
| + TypeHandle type = T.Range(min, max); |
| + CHECK(min == type->AsRange()->Min()); |
| + CHECK(max == type->AsRange()->Max()); |
| + } |
| + } |
| + |
| + // Injectivity: Range(min1, max1) = Range(min2, max2) => |
|
rossberg
2014/07/21 15:58:32
I think that Functionality should hold as well.
neis
2014/07/21 17:47:15
Right. Actually, the changes to Equal were incomp
rossberg
2014/07/22 07:58:35
Might be worth including the test anyway for clari
neis
2014/07/22 08:34:46
Done.
|
| + // min1 = min2 /\ max1 = max2 |
| + typedef DoubleIterator DI; |
| + for (DI i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) { |
| + for (DI j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) { |
| + for (DI i2 = T.doubles.begin(); i2 != T.doubles.end(); ++i2) { |
| + for (DI j2 = T.doubles.begin(); j2 != T.doubles.end(); ++j2) { |
| + double min1 = *i1 <= *j1 ? *i1 : *j1; |
| + double max1 = *i1 <= *j1 ? *j1 : *i1; |
| + double min2 = *i2 <= *j2 ? *i2 : *j2; |
| + double max2 = *i2 <= *j2 ? *j2 : *i2; |
| + TypeHandle type1 = T.Range(min1, max1); |
| + TypeHandle type2 = T.Range(min2, max2); |
| + CHECK(!Equal(type1, type2) || (min1 == min2 && max1 == max2)); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + |
| void Array() { |
| // Constructor |
| for (int i = 0; i < 20; ++i) { |
| @@ -1794,6 +1861,13 @@ TEST(ConstantType) { |
| } |
| +TEST(RangeType) { |
| + CcTest::InitializeVM(); |
| + ZoneTests().Range(); |
| + HeapTests().Range(); |
| +} |
| + |
| + |
| TEST(ArrayType) { |
| CcTest::InitializeVM(); |
| ZoneTests().Array(); |