diff options
Diffstat (limited to 'deps/v8/test/cctest/test-types.cc')
-rw-r--r-- | deps/v8/test/cctest/test-types.cc | 456 |
1 files changed, 337 insertions, 119 deletions
diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc index 47868f648..8c5e41ca1 100644 --- a/deps/v8/test/cctest/test-types.cc +++ b/deps/v8/test/cctest/test-types.cc @@ -1,35 +1,13 @@ // Copyright 2013 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #include <vector> -#include "cctest.h" -#include "types.h" -#include "utils/random-number-generator.h" +#include "src/hydrogen-types.h" +#include "src/isolate-inl.h" +#include "src/types.h" +#include "test/cctest/cctest.h" using namespace v8::internal; @@ -41,11 +19,7 @@ struct ZoneRep { return !IsBitset(t) && reinterpret_cast<intptr_t>(AsStruct(t)[0]) == tag; } 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 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 bool IsUnion(Type* t) { return IsStruct(t, 6); } static Struct* AsStruct(Type* t) { return reinterpret_cast<Struct*>(t); @@ -53,12 +27,6 @@ struct ZoneRep { static int AsBitset(Type* t) { return static_cast<int>(reinterpret_cast<intptr_t>(t) >> 1); } - static Map* AsClass(Type* t) { - return *static_cast<Map**>(AsStruct(t)[3]); - } - static Object* AsConstant(Type* t) { - return *static_cast<Object**>(AsStruct(t)[3]); - } static Struct* AsUnion(Type* t) { return AsStruct(t); } @@ -67,6 +35,13 @@ struct ZoneRep { } static Zone* ToRegion(Zone* zone, Isolate* isolate) { return zone; } + + struct BitsetType : Type::BitsetType { + using Type::BitsetType::New; + using Type::BitsetType::Glb; + using Type::BitsetType::Lub; + using Type::BitsetType::InherentLub; + }; }; @@ -77,29 +52,32 @@ struct HeapRep { return t->IsFixedArray() && Smi::cast(AsStruct(t)->get(0))->value() == tag; } 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 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 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(); } - static Map* AsClass(Handle<HeapType> t) { return Map::cast(*t); } - static Object* AsConstant(Handle<HeapType> t) { - return Box::cast(*t)->value(); - } static Struct* AsUnion(Handle<HeapType> t) { return AsStruct(t); } static int Length(Struct* structured) { return structured->length() - 1; } static Isolate* ToRegion(Zone* zone, Isolate* isolate) { return isolate; } + + struct BitsetType : HeapType::BitsetType { + using HeapType::BitsetType::New; + using HeapType::BitsetType::Glb; + using HeapType::BitsetType::Lub; + using HeapType::BitsetType::InherentLub; + static int Glb(Handle<HeapType> type) { return Glb(*type); } + static int Lub(Handle<HeapType> type) { return Lub(*type); } + static int InherentLub(Handle<HeapType> type) { return InherentLub(*type); } + }; }; template<class Type, class TypeHandle, class Region> class Types { public: - Types(Region* region, Isolate* isolate) : region_(region) { + Types(Region* region, Isolate* isolate) + : region_(region), rng_(isolate->random_number_generator()) { #define DECLARE_TYPE(name, value) \ name = Type::name(region); \ types.push_back(name); @@ -143,7 +121,16 @@ class Types { types.push_back(Type::Constant(*it, region)); } - FloatArray = Type::Array(Float, 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 < 10; ++i) { + doubles.push_back(rng_->NextInt()); + doubles.push_back(rng_->NextDouble() * rng_->NextInt()); + } + + NumberArray = Type::Array(Number, region); StringArray = Type::Array(String, region); AnyArray = Type::Array(Any, region); @@ -152,7 +139,7 @@ class Types { NumberFunction2 = Type::Function(Number, Number, Number, region); MethodFunction = Type::Function(String, Object, 0, region); - for (int i = 0; i < 50; ++i) { + for (int i = 0; i < 30; ++i) { types.push_back(Fuzz()); } } @@ -183,7 +170,7 @@ class Types { TypeHandle ArrayConstant; TypeHandle UninitializedConstant; - TypeHandle FloatArray; + TypeHandle NumberArray; TypeHandle StringArray; TypeHandle AnyArray; @@ -195,9 +182,27 @@ 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; // Some floating-point values, excluding NaN. + + // Range type helper functions, partially copied from types.cc. + // Note: dle(dmin(x,y), dmax(x,y)) holds iff neither x nor y is NaN. + bool dle(double x, double y) { + return x <= y && (x != 0 || IsMinusZero(x) || !IsMinusZero(y)); + } + bool deq(double x, double y) { + return dle(x, y) && dle(y, x); + } + double dmin(double x, double y) { + return dle(x, y) ? x : y; + } + double dmax(double x, double y) { + return dle(x, y) ? y : x; + } TypeHandle Of(Handle<i::Object> value) { return Type::Of(value, region_); @@ -211,6 +216,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_); } @@ -246,18 +255,18 @@ class Types { } TypeHandle Random() { - return types[rng_.NextInt(static_cast<int>(types.size()))]; + return types[rng_->NextInt(static_cast<int>(types.size()))]; } TypeHandle Fuzz(int depth = 5) { - switch (rng_.NextInt(depth == 0 ? 3 : 20)) { + switch (rng_->NextInt(depth == 0 ? 3 : 20)) { case 0: { // bitset int n = 0 #define COUNT_BITSET_TYPES(type, value) + 1 BITSET_TYPE_LIST(COUNT_BITSET_TYPES) #undef COUNT_BITSET_TYPES ; - int i = rng_.NextInt(n); + int i = rng_->NextInt(n); #define PICK_BITSET_TYPE(type, value) \ if (i-- == 0) return Type::type(region_); BITSET_TYPE_LIST(PICK_BITSET_TYPE) @@ -265,31 +274,37 @@ class Types { UNREACHABLE(); } case 1: { // class - int i = rng_.NextInt(static_cast<int>(maps.size())); + int i = rng_->NextInt(static_cast<int>(maps.size())); return Type::Class(maps[i], region_); } case 2: { // constant - int i = rng_.NextInt(static_cast<int>(values.size())); + int i = rng_->NextInt(static_cast<int>(values.size())); return Type::Constant(values[i], region_); } - case 3: { // array + case 3: { // context + int depth = rng_->NextInt(3); + TypeHandle type = Type::Internal(region_); + for (int i = 0; i < depth; ++i) type = Type::Context(type, region_); + return type; + } + case 4: { // array TypeHandle element = Fuzz(depth / 2); return Type::Array(element, region_); } - case 4: case 5: case 6: { // function TypeHandle result = Fuzz(depth / 2); TypeHandle receiver = Fuzz(depth / 2); - int arity = rng_.NextInt(3); + int arity = rng_->NextInt(3); TypeHandle type = Type::Function(result, receiver, arity, region_); for (int i = 0; i < type->AsFunction()->Arity(); ++i) { - TypeHandle parameter = Fuzz(depth - 1); + TypeHandle parameter = Fuzz(depth / 2); type->AsFunction()->InitParameter(i, parameter); } + return type; } default: { // union - int n = rng_.NextInt(10); + int n = rng_->NextInt(10); TypeHandle type = None; for (int i = 0; i < n; ++i) { TypeHandle operand = Fuzz(depth - 1); @@ -301,9 +316,11 @@ class Types { UNREACHABLE(); } + Region* region() { return region_; } + private: Region* region_; - RandomNumberGenerator rng_; + v8::base::RandomNumberGenerator* rng_; }; @@ -313,6 +330,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; @@ -328,19 +346,13 @@ struct Tests : Rep { bool Equal(TypeHandle type1, TypeHandle type2) { return - type1->Is(type2) && type2->Is(type1) && + type1->Equals(type2) && Rep::IsBitset(type1) == Rep::IsBitset(type2) && - Rep::IsClass(type1) == Rep::IsClass(type2) && - Rep::IsConstant(type1) == Rep::IsConstant(type2) && Rep::IsUnion(type1) == Rep::IsUnion(type2) && type1->NumClasses() == type2->NumClasses() && type1->NumConstants() == type2->NumConstants() && (!Rep::IsBitset(type1) || Rep::AsBitset(type1) == Rep::AsBitset(type2)) && - (!Rep::IsClass(type1) || - Rep::AsClass(type1) == Rep::AsClass(type2)) && - (!Rep::IsConstant(type1) || - Rep::AsConstant(type1) == Rep::AsConstant(type2)) && (!Rep::IsUnion(type1) || Rep::Length(Rep::AsUnion(type1)) == Rep::Length(Rep::AsUnion(type2))); } @@ -460,7 +472,7 @@ struct Tests : Rep { for (MapIterator mt = T.maps.begin(); mt != T.maps.end(); ++mt) { Handle<i::Map> map = *mt; TypeHandle type = T.Class(map); - CHECK(this->IsClass(type)); + CHECK(type->IsClass()); } // Map attribute @@ -487,7 +499,7 @@ struct Tests : Rep { for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) { Handle<i::Object> value = *vt; TypeHandle type = T.Constant(value); - CHECK(this->IsConstant(type)); + CHECK(type->IsConstant()); } // Value attribute @@ -507,6 +519,93 @@ struct Tests : Rep { CHECK(Equal(type1, type2) == (*value1 == *value2)); } } + + // Typing of numbers + Factory* fac = isolate->factory(); + CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); + CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); + CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); + CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall)); + if (SmiValuesAre31Bits()) { + CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); + CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31)); + CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32)); + } else { + CHECK(SmiValuesAre32Bits()); + CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); + CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); + CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31)); + CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31)); + CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall)); + CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32)); + CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32)); + CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32)); + } + CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32)); + CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32)); + CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber)); + CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber)); + CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber)); + CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber)); + CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero)); + CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN)); + CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber)); + 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 = T.dmin(*i, *j); + double max = T.dmax(*i, *j); + TypeHandle type = T.Range(min, max); + CHECK(type->IsRange()); + } + } + + // 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 = T.dmin(*i, *j); + double max = T.dmax(*i, *j); + printf("RangeType: min, max = %f, %f\n", min, max); + TypeHandle type = T.Range(min, max); + printf("RangeType: Min, Max = %f, %f\n", + type->AsRange()->Min(), type->AsRange()->Max()); + CHECK(min == type->AsRange()->Min()); + CHECK(max == type->AsRange()->Max()); + } + } + +// TODO(neis): enable once subtyping is updated. +// // Functionality & Injectivity: Range(min1, max1) = Range(min2, max2) <=> +// // min1 = min2 /\ max1 = max2 +// for (DoubleIterator i1 = T.doubles.begin(); i1 != T.doubles.end(); ++i1) { +// for (DoubleIterator j1 = T.doubles.begin(); j1 != T.doubles.end(); ++j1) { +// for (DoubleIterator i2 = T.doubles.begin(); +// i2 != T.doubles.end(); ++i2) { +// for (DoubleIterator j2 = T.doubles.begin(); +// j2 != T.doubles.end(); ++j2) { +// double min1 = T.dmin(*i1, *j1); +// double max1 = T.dmax(*i1, *j1); +// double min2 = T.dmin(*i2, *j2); +// double max2 = T.dmax(*i2, *j2); +// TypeHandle type1 = T.Range(min1, max1); +// TypeHandle type2 = T.Range(min2, max2); +// CHECK(Equal(type1, type2) == +// (T.deq(min1, min2) && T.deq(max1, max2))); +// } +// } +// } +// } } void Array() { @@ -514,7 +613,7 @@ struct Tests : Rep { for (int i = 0; i < 20; ++i) { TypeHandle type = T.Random(); TypeHandle array = T.Array1(type); - CHECK(this->IsArray(array)); + CHECK(array->IsArray()); } // Attributes @@ -669,6 +768,44 @@ struct Tests : Rep { } } + void Bounds() { + // Ordering: (T->BitsetGlb())->Is(T->BitsetLub()) + for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { + TypeHandle type = *it; + TypeHandle glb = + Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); + TypeHandle lub = + Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); + CHECK(glb->Is(lub)); + } + + // Lower bound: (T->BitsetGlb())->Is(T) + for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { + TypeHandle type = *it; + TypeHandle glb = + Rep::BitsetType::New(Rep::BitsetType::Glb(type), T.region()); + CHECK(glb->Is(type)); + } + + // Upper bound: T->Is(T->BitsetLub()) + for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { + TypeHandle type = *it; + TypeHandle lub = + Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); + CHECK(type->Is(lub)); + } + + // Inherent bound: (T->BitsetLub())->Is(T->InherentBitsetLub()) + for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { + TypeHandle type = *it; + TypeHandle lub = + Rep::BitsetType::New(Rep::BitsetType::Lub(type), T.region()); + TypeHandle inherent = + Rep::BitsetType::New(Rep::BitsetType::InherentLub(type), T.region()); + CHECK(lub->Is(inherent)); + } + } + void Is() { // Least Element (Bottom): None->Is(T) for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) { @@ -772,10 +909,9 @@ struct Tests : Rep { CheckSub(T.SignedSmall, T.Number); CheckSub(T.Signed32, T.Number); - CheckSub(T.Float, T.Number); CheckSub(T.SignedSmall, T.Signed32); - CheckUnordered(T.SignedSmall, T.Float); - CheckUnordered(T.Signed32, T.Float); + CheckUnordered(T.SignedSmall, T.MinusZero); + CheckUnordered(T.Signed32, T.Unsigned32); CheckSub(T.UniqueName, T.Name); CheckSub(T.String, T.Name); @@ -823,8 +959,8 @@ struct Tests : Rep { CheckUnordered(T.ObjectConstant2, T.ArrayClass); CheckUnordered(T.ArrayConstant, T.ObjectClass); - CheckSub(T.FloatArray, T.Array); - CheckSub(T.FloatArray, T.Object); + CheckSub(T.NumberArray, T.Array); + CheckSub(T.NumberArray, T.Object); CheckUnordered(T.StringArray, T.AnyArray); CheckSub(T.MethodFunction, T.Function); @@ -1044,13 +1180,13 @@ struct Tests : Rep { } } - // T1->Maybe(T2) iff Intersect(T1, T2) inhabited + // T1->Maybe(T2) implies Intersect(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; TypeHandle intersect12 = T.Intersect(type1, type2); - CHECK(type1->Maybe(type2) == intersect12->IsInhabited()); + CHECK(!type1->Maybe(type2) || intersect12->IsInhabited()); } } @@ -1114,8 +1250,8 @@ struct Tests : Rep { CheckDisjoint(T.Boolean, T.Undefined, 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.NaN, T.Number, T.Semantic); + CheckDisjoint(T.Signed32, T.NaN, T.Semantic); CheckOverlap(T.UniqueName, T.Name, T.Semantic); CheckOverlap(T.String, T.Name, T.Semantic); @@ -1145,7 +1281,6 @@ struct Tests : Rep { CheckOverlap(T.SmiConstant, T.SignedSmall, T.Semantic); CheckOverlap(T.SmiConstant, T.Signed32, T.Semantic); CheckOverlap(T.SmiConstant, T.Number, T.Semantic); - CheckDisjoint(T.SmiConstant, T.Float, T.Semantic); CheckOverlap(T.ObjectConstant1, T.Object, T.Semantic); CheckOverlap(T.ObjectConstant2, T.Object, T.Semantic); CheckOverlap(T.ArrayConstant, T.Object, T.Semantic); @@ -1160,9 +1295,9 @@ struct Tests : Rep { CheckDisjoint(T.ObjectConstant2, T.ArrayClass, T.Semantic); CheckDisjoint(T.ArrayConstant, T.ObjectClass, T.Semantic); - CheckOverlap(T.FloatArray, T.Array, T.Semantic); - CheckDisjoint(T.FloatArray, T.AnyArray, T.Semantic); - CheckDisjoint(T.FloatArray, T.StringArray, T.Semantic); + CheckOverlap(T.NumberArray, T.Array, T.Semantic); + CheckDisjoint(T.NumberArray, T.AnyArray, T.Semantic); + CheckDisjoint(T.NumberArray, T.StringArray, T.Semantic); CheckOverlap(T.MethodFunction, T.Function, T.Semantic); CheckDisjoint(T.SignedFunction1, T.NumberFunction1, T.Semantic); @@ -1303,22 +1438,18 @@ struct Tests : Rep { // Bitset-array CHECK(this->IsBitset(T.Union(T.AnyArray, T.Array))); - CHECK(this->IsUnion(T.Union(T.FloatArray, T.Number))); + CHECK(this->IsUnion(T.Union(T.NumberArray, 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); + CheckOverlap(T.Union(T.NumberArray, T.String), T.Object, T.Semantic); + CheckDisjoint(T.Union(T.NumberArray, 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); @@ -1353,10 +1484,10 @@ struct Tests : Rep { // Bitset-union CheckSub( - T.Float, + T.NaN, T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number)); CheckSub( - T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Float), + T.Union(T.Union(T.ArrayClass, T.ObjectConstant1), T.Signed32), T.Union(T.ObjectConstant1, T.Union(T.Number, T.ArrayClass))); // Class-union @@ -1380,9 +1511,9 @@ struct Tests : Rep { // Array-union CheckEqual( - T.Union(T.AnyArray, T.Union(T.FloatArray, T.AnyArray)), - T.Union(T.AnyArray, T.FloatArray)); - CheckSub(T.Union(T.AnyArray, T.FloatArray), T.Array); + T.Union(T.AnyArray, T.Union(T.NumberArray, T.AnyArray)), + T.Union(T.AnyArray, T.NumberArray)); + CheckSub(T.Union(T.AnyArray, T.NumberArray), T.Array); // Function-union CheckEqual( @@ -1524,7 +1655,7 @@ struct Tests : Rep { CheckSub(T.Intersect(T.ObjectClass, T.Number), T.Representation); // Bitset-array - CheckEqual(T.Intersect(T.FloatArray, T.Object), T.FloatArray); + CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray); CheckSub(T.Intersect(T.AnyArray, T.Function), T.Representation); // Bitset-function @@ -1535,24 +1666,24 @@ struct Tests : Rep { CheckEqual( T.Intersect(T.Object, T.Union(T.ObjectConstant1, T.ObjectClass)), T.Union(T.ObjectConstant1, T.ObjectClass)); - CheckEqual( - T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number), - T.None); + CHECK( + !T.Intersect(T.Union(T.ArrayClass, T.ObjectConstant1), T.Number) + ->IsInhabited()); // Class-constant - CheckEqual(T.Intersect(T.ObjectConstant1, T.ObjectClass), T.None); - CheckEqual(T.Intersect(T.ArrayClass, T.ObjectConstant2), T.None); + CHECK(!T.Intersect(T.ObjectConstant1, T.ObjectClass)->IsInhabited()); + CHECK(!T.Intersect(T.ArrayClass, T.ObjectConstant2)->IsInhabited()); // Array-union CheckEqual( - T.Intersect(T.FloatArray, T.Union(T.FloatArray, T.ArrayClass)), - T.FloatArray); + T.Intersect(T.NumberArray, T.Union(T.NumberArray, T.ArrayClass)), + T.NumberArray); CheckEqual( T.Intersect(T.AnyArray, T.Union(T.Object, T.SmiConstant)), T.AnyArray); - CheckEqual( - T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.FloatArray), - T.None); + CHECK( + !T.Intersect(T.Union(T.AnyArray, T.ArrayConstant), T.NumberArray) + ->IsInhabited()); // Function-union CheckEqual( @@ -1561,9 +1692,9 @@ struct Tests : Rep { 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); + CHECK( + !T.Intersect(T.Union(T.MethodFunction, T.Name), T.NumberFunction2) + ->IsInhabited()); // Class-union CheckEqual( @@ -1572,9 +1703,9 @@ struct Tests : Rep { CheckEqual( T.Intersect(T.ArrayClass, T.Union(T.Object, T.SmiConstant)), T.ArrayClass); - CheckEqual( - T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass), - T.None); + CHECK( + !T.Intersect(T.Union(T.ObjectClass, T.ArrayConstant), T.ArrayClass) + ->IsInhabited()); // Constant-union CheckEqual( @@ -1584,10 +1715,10 @@ struct Tests : Rep { CheckEqual( T.Intersect(T.SmiConstant, T.Union(T.Number, T.ObjectConstant2)), T.SmiConstant); - CheckEqual( - T.Intersect( - T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1), - T.None); + CHECK( + !T.Intersect( + T.Union(T.ArrayConstant, T.ObjectClass), T.ObjectConstant1) + ->IsInhabited()); // Union-union CheckEqual( @@ -1615,6 +1746,46 @@ struct Tests : Rep { T.Union(T.ObjectConstant2, T.ObjectConstant1)); } + void Distributivity1() { + // Distributivity: + // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3)) + for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { + for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { + for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { + TypeHandle type1 = *it1; + TypeHandle type2 = *it2; + TypeHandle type3 = *it3; + TypeHandle union12 = T.Union(type1, type2); + TypeHandle union13 = T.Union(type1, type3); + TypeHandle intersect23 = T.Intersect(type2, type3); + TypeHandle union1_23 = T.Union(type1, intersect23); + TypeHandle intersect12_13 = T.Intersect(union12, union13); + CHECK(Equal(union1_23, intersect12_13)); + } + } + } + } + + void Distributivity2() { + // Distributivity: + // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3)) + for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) { + for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) { + for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) { + TypeHandle type1 = *it1; + TypeHandle type2 = *it2; + TypeHandle type3 = *it3; + TypeHandle intersect12 = T.Intersect(type1, type2); + TypeHandle intersect13 = T.Intersect(type1, type3); + TypeHandle union23 = T.Union(type2, type3); + TypeHandle intersect1_23 = T.Intersect(type1, union23); + TypeHandle union12_13 = T.Union(intersect12, intersect13); + CHECK(Equal(intersect1_23, union12_13)); + } + } + } + } + template<class Type2, class TypeHandle2, class Region2, class Rep2> void Convert() { Types<Type2, TypeHandle2, Region2> T2( @@ -1626,6 +1797,18 @@ struct Tests : Rep { CheckEqual(type1, type3); } } + + void HTypeFromType() { + 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; + HType htype1 = HType::FromType<Type>(type1); + HType htype2 = HType::FromType<Type>(type2); + CHECK(!type1->Is(type2) || htype1.IsSubtypeOf(htype2)); + } + } + } }; typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests; @@ -1653,6 +1836,13 @@ TEST(ConstantType) { } +TEST(RangeType) { + CcTest::InitializeVM(); + ZoneTests().Range(); + HeapTests().Range(); +} + + TEST(ArrayType) { CcTest::InitializeVM(); ZoneTests().Array(); @@ -1681,6 +1871,13 @@ TEST(NowOf) { } +TEST(Bounds) { + CcTest::InitializeVM(); + ZoneTests().Bounds(); + HeapTests().Bounds(); +} + + TEST(Is) { CcTest::InitializeVM(); ZoneTests().Is(); @@ -1744,8 +1941,29 @@ TEST(Intersect2) { } +TEST(Distributivity1) { + CcTest::InitializeVM(); + ZoneTests().Distributivity1(); + HeapTests().Distributivity1(); +} + + +TEST(Distributivity2) { + CcTest::InitializeVM(); + ZoneTests().Distributivity2(); + HeapTests().Distributivity2(); +} + + TEST(Convert) { CcTest::InitializeVM(); ZoneTests().Convert<HeapType, Handle<HeapType>, Isolate, HeapRep>(); HeapTests().Convert<Type, Type*, Zone, ZoneRep>(); } + + +TEST(HTypeFromType) { + CcTest::InitializeVM(); + ZoneTests().HTypeFromType(); + HeapTests().HTypeFromType(); +} |