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(); |