| Index: test/cctest/test-types.cc
|
| diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc
|
| index 445a9e1a7f63fcb495c4ae4a81e7a38d1d4d404f..7b9bbb18f107a113aba29fcb976735e2b2077277 100644
|
| --- a/test/cctest/test-types.cc
|
| +++ b/test/cctest/test-types.cc
|
| @@ -33,38 +33,48 @@ using namespace v8::internal;
|
| template<class Type, class TypeHandle, class Region>
|
| class Types {
|
| public:
|
| - Types(Region* region, Isolate* isolate) :
|
| - Representation(Type::Representation(region)),
|
| - Semantic(Type::Semantic(region)),
|
| - None(Type::None(region)),
|
| - Any(Type::Any(region)),
|
| - Boolean(Type::Boolean(region)),
|
| - Null(Type::Null(region)),
|
| - Undefined(Type::Undefined(region)),
|
| - Number(Type::Number(region)),
|
| - SignedSmall(Type::SignedSmall(region)),
|
| - Signed32(Type::Signed32(region)),
|
| - Float(Type::Float(region)),
|
| - Name(Type::Name(region)),
|
| - UniqueName(Type::UniqueName(region)),
|
| - String(Type::String(region)),
|
| - InternalizedString(Type::InternalizedString(region)),
|
| - Symbol(Type::Symbol(region)),
|
| - Receiver(Type::Receiver(region)),
|
| - Object(Type::Object(region)),
|
| - Array(Type::Array(region)),
|
| - Function(Type::Function(region)),
|
| - Proxy(Type::Proxy(region)),
|
| - object_map(isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize)),
|
| - array_map(isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize)),
|
| - region_(region) {
|
| + Types(Region* region, Isolate* isolate) : region_(region) {
|
| + Representation = Type::Representation(region);
|
| + Semantic = Type::Semantic(region);
|
| + None = Type::None(region);
|
| + Any = Type::Any(region);
|
| + Boolean = Type::Boolean(region);
|
| + Null = Type::Null(region);
|
| + Undefined = Type::Undefined(region);
|
| + Number = Type::Number(region);
|
| + SignedSmall = Type::SignedSmall(region);
|
| + Signed32 = Type::Signed32(region);
|
| + Float = Type::Float(region);
|
| + Name = Type::Name(region);
|
| + UniqueName = Type::UniqueName(region);
|
| + String = Type::String(region);
|
| + InternalizedString = Type::InternalizedString(region);
|
| + Symbol = Type::Symbol(region);
|
| + Receiver = Type::Receiver(region);
|
| + Object = Type::Object(region);
|
| + Array = Type::Array(region);
|
| + Function = Type::Function(region);
|
| + Proxy = Type::Proxy(region);
|
| +
|
| + FloatArray = Type::Array(Float, region);
|
| + StringArray = Type::Array(String, region);
|
| + AnyArray = Type::Array(Any, region);
|
| +
|
| + SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
|
| + NumberFunction1 = Type::Function(Number, Number, region);
|
| + NumberFunction2 = Type::Function(Number, Number, Number, region);
|
| + MethodFunction = Type::Function(String, Object, 0, region);
|
| +
|
| + object_map = isolate->factory()->NewMap(JS_OBJECT_TYPE, 3 * kPointerSize);
|
| + array_map = isolate->factory()->NewMap(JS_ARRAY_TYPE, 4 * kPointerSize);
|
| + ObjectClass = Type::Class(object_map, region);
|
| + ArrayClass = Type::Class(array_map, 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);
|
| - ObjectClass = Type::Class(object_map, region);
|
| - ArrayClass = Type::Class(array_map, region);
|
| SmiConstant = Type::Constant(smi, region);
|
| Signed32Constant = Type::Constant(signed32, region);
|
| ObjectConstant1 = Type::Constant(object1, region);
|
| @@ -95,6 +105,15 @@ class Types {
|
| TypeHandle Function;
|
| TypeHandle Proxy;
|
|
|
| + TypeHandle FloatArray;
|
| + TypeHandle StringArray;
|
| + TypeHandle AnyArray;
|
| +
|
| + TypeHandle SignedFunction1;
|
| + TypeHandle NumberFunction1;
|
| + TypeHandle NumberFunction2;
|
| + TypeHandle MethodFunction;
|
| +
|
| TypeHandle ObjectClass;
|
| TypeHandle ArrayClass;
|
|
|
| @@ -157,6 +176,17 @@ class Types {
|
| case 5: return ArrayConstant2;
|
| }
|
| UNREACHABLE();
|
| + case 3: // array
|
| + return Type::Array(Fuzz(depth / 2), region_);
|
| + case 4:
|
| + case 5:
|
| + case 6: { // function
|
| + TypeHandle type = Type::Function(
|
| + Fuzz(depth / 2), Fuzz(depth / 2), rand() % 3, region_);
|
| + for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
|
| + type->AsFunction()->InitParameter(i, Fuzz(depth - 1));
|
| + }
|
| + }
|
| default: { // union
|
| int n = rand() % 10;
|
| TypeHandle type = None;
|
| @@ -184,7 +214,9 @@ 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 IsUnion(Type* t) { return IsStruct(t, 2); }
|
| + static bool IsArray(Type* t) { return IsStruct(t, 2); }
|
| + static bool IsFunction(Type* t) { return IsStruct(t, 3); }
|
| + static bool IsUnion(Type* t) { return IsStruct(t, 4); }
|
|
|
| static Struct* AsStruct(Type* t) {
|
| return reinterpret_cast<Struct*>(t);
|
| @@ -218,7 +250,9 @@ struct HeapRep {
|
| 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 IsUnion(Handle<HeapType> t) { return IsStruct(t, 2); }
|
| + 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(); }
|
| @@ -322,6 +356,43 @@ struct Tests : Rep {
|
| this->AsBitset(T.Union(T.Receiver, T.Object)));
|
| }
|
|
|
| + void Array() {
|
| + CHECK(this->IsArray(T.FloatArray));
|
| + CHECK(this->IsArray(T.StringArray));
|
| + CHECK(this->IsArray(T.AnyArray));
|
| +
|
| + CheckEqual(T.Float, T.FloatArray->AsArray()->Element());
|
| + CheckEqual(T.String, T.StringArray->AsArray()->Element());
|
| + CheckEqual(T.Any, T.AnyArray->AsArray()->Element());
|
| + }
|
| +
|
| + void Function() {
|
| + CHECK(this->IsFunction(T.SignedFunction1));
|
| + CHECK(this->IsFunction(T.NumberFunction1));
|
| + CHECK(this->IsFunction(T.NumberFunction2));
|
| + CHECK(this->IsFunction(T.MethodFunction));
|
| +
|
| + CHECK(1 == T.SignedFunction1->AsFunction()->Arity());
|
| + CheckEqual(T.SignedSmall, T.SignedFunction1->AsFunction()->Result());
|
| + CheckEqual(T.Any, T.SignedFunction1->AsFunction()->Receiver());
|
| + CheckEqual(T.SignedSmall, T.SignedFunction1->AsFunction()->Parameter(0));
|
| +
|
| + CHECK(1 == T.NumberFunction1->AsFunction()->Arity());
|
| + CheckEqual(T.Number, T.NumberFunction1->AsFunction()->Result());
|
| + CheckEqual(T.Any, T.NumberFunction1->AsFunction()->Receiver());
|
| + CheckEqual(T.Number, T.NumberFunction1->AsFunction()->Parameter(0));
|
| +
|
| + CHECK(2 == T.NumberFunction2->AsFunction()->Arity());
|
| + CheckEqual(T.Number, T.NumberFunction2->AsFunction()->Result());
|
| + CheckEqual(T.Any, T.NumberFunction2->AsFunction()->Receiver());
|
| + CheckEqual(T.Number, T.NumberFunction2->AsFunction()->Parameter(0));
|
| + CheckEqual(T.Number, T.NumberFunction2->AsFunction()->Parameter(1));
|
| +
|
| + CHECK(0 == T.MethodFunction->AsFunction()->Arity());
|
| + CheckEqual(T.String, T.MethodFunction->AsFunction()->Result());
|
| + CheckEqual(T.Object, T.MethodFunction->AsFunction()->Receiver());
|
| + }
|
| +
|
| void Class() {
|
| CHECK(this->IsClass(T.ObjectClass));
|
| CHECK(this->IsClass(T.ArrayClass));
|
| @@ -394,13 +465,29 @@ struct Tests : Rep {
|
| CheckUnordered(T.Array, T.Function);
|
|
|
| // Structured subtyping
|
| + CheckSub(T.None, T.FloatArray);
|
| + CheckSub(T.None, T.MethodFunction);
|
| CheckSub(T.None, T.ObjectClass);
|
| CheckSub(T.None, T.ObjectConstant1);
|
| + CheckSub(T.FloatArray, T.Any);
|
| + CheckSub(T.NumberFunction1, T.Any);
|
| CheckSub(T.ObjectClass, T.Any);
|
| CheckSub(T.ObjectConstant1, T.Any);
|
|
|
| + CheckSub(T.FloatArray, T.Array);
|
| + CheckSub(T.AnyArray, T.Array);
|
| + CheckUnordered(T.FloatArray, T.AnyArray);
|
| + CheckUnordered(T.StringArray, T.AnyArray);
|
| +
|
| + CheckSub(T.SignedFunction1, T.Function);
|
| + CheckSub(T.NumberFunction2, T.Function);
|
| + CheckSub(T.MethodFunction, T.Function);
|
| + CheckUnordered(T.SignedFunction1, T.NumberFunction1);
|
| + CheckUnordered(T.NumberFunction1, T.NumberFunction2);
|
| +
|
| CheckSub(T.ObjectClass, T.Object);
|
| CheckSub(T.ArrayClass, T.Object);
|
| + CheckSub(T.ArrayClass, T.Array);
|
| CheckUnordered(T.ObjectClass, T.ArrayClass);
|
|
|
| CheckSub(T.SmiConstant, T.SignedSmall);
|
| @@ -455,9 +542,19 @@ struct Tests : Rep {
|
| CheckDisjoint(T.Object, T.Proxy, T.Semantic);
|
| CheckDisjoint(T.Array, T.Function, T.Semantic);
|
|
|
| + CheckOverlap(T.FloatArray, T.Any, T.Semantic);
|
| + CheckOverlap(T.MethodFunction, T.Any, T.Semantic);
|
| CheckOverlap(T.ObjectClass, T.Any, T.Semantic);
|
| CheckOverlap(T.ObjectConstant1, T.Any, T.Semantic);
|
|
|
| + CheckOverlap(T.FloatArray, T.AnyArray, T.Semantic);
|
| + CheckDisjoint(T.FloatArray, T.StringArray, T.Semantic);
|
| +
|
| + CheckOverlap(T.SignedFunction1, T.NumberFunction1, T.Semantic);
|
| + CheckOverlap(T.SignedFunction1, T.NumberFunction2, T.Semantic);
|
| + CheckOverlap(T.NumberFunction1, T.NumberFunction2, T.Semantic);
|
| + CheckDisjoint(T.SignedFunction1, T.MethodFunction, T.Semantic);
|
| +
|
| CheckOverlap(T.ObjectClass, T.Object, T.Semantic);
|
| CheckOverlap(T.ArrayClass, T.Object, T.Semantic);
|
| CheckOverlap(T.ObjectClass, T.ObjectClass, T.Semantic);
|
| @@ -539,6 +636,28 @@ struct Tests : Rep {
|
| T.Union(T.ObjectConstant1, T.ArrayConstant1), T.ObjectClass,
|
| T.Semantic);
|
|
|
| + // Bitset-array
|
| + CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array)));
|
| + CHECK(this->IsUnion(T.Union(T.FloatArray, T.Number)));
|
| +
|
| + CheckEqual(T.Union(T.AnyArray, T.Array), T.Array);
|
| + CheckSub(T.None, T.Union(T.FloatArray, T.Number));
|
| + CheckSub(T.Union(T.FloatArray, T.Number), T.Any);
|
| + CheckUnordered(T.Union(T.AnyArray, T.String), T.Array);
|
| + CheckOverlap(T.Union(T.FloatArray, T.String), T.Object, T.Semantic);
|
| + CheckDisjoint(T.Union(T.FloatArray, T.String), T.Number, T.Semantic);
|
| +
|
| + // Bitset-function
|
| + CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
|
| + CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
|
| +
|
| + CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
|
| + CheckSub(T.None, T.Union(T.MethodFunction, T.Number));
|
| + CheckSub(T.Union(T.MethodFunction, T.Number), T.Any);
|
| + CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
|
| + CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object, T.Semantic);
|
| + CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number, T.Semantic);
|
| +
|
| // Bitset-class
|
| CHECK(this->IsBitset(T.Union(T.ObjectClass, T.Object)));
|
| CHECK(this->IsUnion(T.Union(T.ObjectClass, T.Number)));
|
| @@ -617,6 +736,30 @@ struct Tests : Rep {
|
| T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float),
|
| T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass)));
|
|
|
| + // Array-union
|
| + CHECK(this->IsUnion(
|
| + T.Union(T.Union(T.AnyArray, T.FloatArray), T.ArrayClass)));
|
| + CHECK(this->IsUnion(
|
| + T.Union(T.Union(T.ArrayClass, T.AnyArray), T.FloatArray)));
|
| +
|
| + CheckEqual(
|
| + T.Union(T.AnyArray, T.Union(T.FloatArray, T.AnyArray)),
|
| + T.Union(T.AnyArray, T.FloatArray));
|
| + CheckSub(T.None, T.Union(T.AnyArray, T.FloatArray));
|
| + CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Any);
|
| + CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Array);
|
| +
|
| + // Funtion-union
|
| + CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.NumberFunction2)));
|
| + CHECK(this->IsUnion(T.Union(T.SignedFunction1, T.NumberFunction1)));
|
| +
|
| + CheckEqual(
|
| + T.Union(T.NumberFunction1, T.NumberFunction2),
|
| + T.Union(T.NumberFunction2, T.NumberFunction1));
|
| + CheckSub(T.None, T.Union(T.NumberFunction2, T.MethodFunction));
|
| + CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Any);
|
| + CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
|
| +
|
| // Class-union
|
| CHECK(this->IsUnion(
|
| T.Union(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
|
| @@ -713,6 +856,20 @@ struct Tests : Rep {
|
| T.Intersect(T.ArrayConstant1, T.ArrayConstant2), T.ArrayConstant1);
|
| CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectConstant2), T.None);
|
|
|
| + // Bitset-array
|
| + CHECK(this->IsArray(T.Intersect(T.FloatArray, T.Object)));
|
| + CHECK(this->IsBitset(T.Intersect(T.FloatArray, T.Number)));
|
| +
|
| + CheckEqual(T.Intersect(T.FloatArray, T.Object), T.FloatArray);
|
| + CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation);
|
| +
|
| + // Bitset-function
|
| + CHECK(this->IsFunction(T.Intersect(T.MethodFunction, T.Object)));
|
| + CHECK(this->IsBitset(T.Intersect(T.MethodFunction, T.Number)));
|
| +
|
| + CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
|
| + CheckSub(T.Intersect(T.NumberFunction1, T.Array), T.Representation);
|
| +
|
| // Bitset-class
|
| CHECK(this->IsClass(T.Intersect(T.ObjectClass, T.Object)));
|
| CHECK(this->IsBitset(T.Intersect(T.ObjectClass, T.Number)));
|
| @@ -750,6 +907,42 @@ struct Tests : Rep {
|
| T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number),
|
| T.None);
|
|
|
| + // Array-union
|
| + CHECK(this->IsArray(
|
| + T.Intersect(T.Union(T.FloatArray, T.ArrayClass), T.FloatArray)));
|
| + CHECK(this->IsArray(
|
| + T.Intersect(T.Union(T.Object, T.SmiConstant), T.AnyArray)));
|
| + CHECK(this->IsBitset(
|
| + T.Intersect(T.Union(T.AnyArray, T.ArrayConstant1), T.FloatArray)));
|
| +
|
| + CheckEqual(
|
| + T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)),
|
| + T.FloatArray);
|
| + CheckEqual(
|
| + T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)),
|
| + T.AnyArray);
|
| + CheckEqual(
|
| + T.Intersect(T.Union(T.AnyArray, T.ArrayConstant1), T.FloatArray),
|
| + T.None);
|
| +
|
| + // Function-union
|
| + CHECK(this->IsFunction(
|
| + T.Intersect(T.Union(T.MethodFunction, T.String), T.MethodFunction)));
|
| + CHECK(this->IsFunction(
|
| + T.Intersect(T.Union(T.Object, T.SmiConstant), T.NumberFunction1)));
|
| + CHECK(this->IsBitset(
|
| + T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction1)));
|
| +
|
| + CheckEqual(
|
| + T.Intersect(T.MethodFunction, T.Union(T.String, T.MethodFunction)),
|
| + T.MethodFunction);
|
| + 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);
|
| +
|
| // Class-union
|
| CHECK(this->IsClass(
|
| T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant2), T.ArrayClass)));
|
| @@ -840,27 +1033,41 @@ typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
|
| typedef Tests<HeapType, Handle<HeapType>, Isolate, HeapRep> HeapTests;
|
|
|
|
|
| -TEST(Bitset) {
|
| +TEST(BitsetType) {
|
| CcTest::InitializeVM();
|
| ZoneTests().Bitset();
|
| HeapTests().Bitset();
|
| }
|
|
|
|
|
| -TEST(Class) {
|
| +TEST(ClassType) {
|
| CcTest::InitializeVM();
|
| ZoneTests().Class();
|
| HeapTests().Class();
|
| }
|
|
|
|
|
| -TEST(Constant) {
|
| +TEST(ConstantType) {
|
| CcTest::InitializeVM();
|
| ZoneTests().Constant();
|
| HeapTests().Constant();
|
| }
|
|
|
|
|
| +TEST(ArrayType) {
|
| + CcTest::InitializeVM();
|
| + ZoneTests().Array();
|
| + HeapTests().Array();
|
| +}
|
| +
|
| +
|
| +TEST(FunctionType) {
|
| + CcTest::InitializeVM();
|
| + ZoneTests().Function();
|
| + HeapTests().Function();
|
| +}
|
| +
|
| +
|
| TEST(Is) {
|
| CcTest::InitializeVM();
|
| ZoneTests().Is();
|
|
|