Revision: 22535
Author: [email protected]
Date: Tue Jul 22 17:33:22 2014 UTC
Log: Add constructor for range types.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/409543004
http://code.google.com/p/v8/source/detail?r=22535
Modified:
/branches/bleeding_edge/src/types-inl.h
/branches/bleeding_edge/src/types.cc
/branches/bleeding_edge/src/types.h
/branches/bleeding_edge/test/cctest/test-types.cc
=======================================
--- /branches/bleeding_edge/src/types-inl.h Tue Jun 3 08:12:43 2014 UTC
+++ /branches/bleeding_edge/src/types-inl.h Tue Jul 22 17:33:22 2014 UTC
@@ -19,7 +19,7 @@
template<class Config>
TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
TypeImpl* t = static_cast<TypeImpl*>(object);
- ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() ||
+ ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() |
|
t->IsUnion() || t->IsArray() || t->IsFunction() ||
t->IsContext());
return t;
}
=======================================
--- /branches/bleeding_edge/src/types.cc Thu Jul 10 12:37:08 2014 UTC
+++ /branches/bleeding_edge/src/types.cc Tue Jul 22 17:33:22 2014 UTC
@@ -911,6 +911,11 @@
<< " : ";
BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
os << ")";
+ } else if (this->IsRange()) {
+ os << "Range(" << this->AsRange()->Min()
+ << ".." << this->AsRange()->Max() << " : ";
+ BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
+ os << ")";
} else if (this->IsContext()) {
os << "Context(";
this->AsContext()->Outer()->PrintTo(os, dim);
=======================================
--- /branches/bleeding_edge/src/types.h Thu Jul 3 07:18:30 2014 UTC
+++ /branches/bleeding_edge/src/types.h Tue Jul 22 17:33:22 2014 UTC
@@ -5,6 +5,7 @@
#ifndef V8_TYPES_H_
#define V8_TYPES_H_
+#include "src/factory.h"
#include "src/handles.h"
#include "src/ostreams.h"
@@ -254,6 +255,7 @@
class ClassType;
class ConstantType;
+ class RangeType;
class ContextType;
class ArrayType;
class FunctionType;
@@ -261,6 +263,7 @@
typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
typedef typename Config::template Handle<ClassType>::type ClassHandle;
typedef typename Config::template Handle<ConstantType>::type
ConstantHandle;
+ typedef typename Config::template Handle<RangeType>::type RangeHandle;
typedef typename Config::template Handle<ContextType>::type
ContextHandle;
typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
typedef typename Config::template Handle<FunctionType>::type
FunctionHandle;
@@ -281,8 +284,12 @@
return ClassType::New(map, region);
}
static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
+ // TODO(neis): return RangeType for numerical values
return ConstantType::New(value, region);
}
+ static TypeHandle Range(double min, double max, Region* region) {
+ return RangeType::New(min, max, region);
+ }
static TypeHandle Context(TypeHandle outer, Region* region) {
return ContextType::New(outer, region);
}
@@ -375,6 +382,9 @@
bool IsConstant() {
return Config::is_struct(this, StructuralType::kConstantTag);
}
+ bool IsRange() {
+ return Config::is_struct(this, StructuralType::kRangeTag);
+ }
bool IsContext() {
return Config::is_struct(this, StructuralType::kContextTag);
}
@@ -387,6 +397,7 @@
ClassType* AsClass() { return ClassType::cast(this); }
ConstantType* AsConstant() { return ConstantType::cast(this); }
+ RangeType* AsRange() { return RangeType::cast(this); }
ContextType* AsContext() { return ContextType::cast(this); }
ArrayType* AsArray() { return ArrayType::cast(this); }
FunctionType* AsFunction() { return FunctionType::cast(this); }
@@ -520,6 +531,7 @@
enum Tag {
kClassTag,
kConstantTag,
+ kRangeTag,
kContextTag,
kArrayTag,
kFunctionTag,
@@ -655,6 +667,42 @@
};
+//
-----------------------------------------------------------------------------
+// Range types.
+
+template<class Config>
+class TypeImpl<Config>::RangeType : public StructuralType {
+ public:
+ TypeHandle Bound() { return this->Get(0); }
+ double Min() { return this->template
GetValue<i::HeapNumber>(1)->value(); }
+ double Max() { return this->template
GetValue<i::HeapNumber>(2)->value(); }
+
+ static RangeHandle New(
+ double min, double max, TypeHandle bound, Region* region) {
+ ASSERT(SEMANTIC(bound->AsBitset() | BitsetType::kNumber)
+ == SEMANTIC(BitsetType::kNumber));
+ ASSERT(!std::isnan(min) && !std::isnan(max) && min <= max);
+ RangeHandle type = Config::template cast<RangeType>(
+ StructuralType::New(StructuralType::kRangeTag, 3, region));
+ type->Set(0, bound);
+ Factory* factory = Config::isolate(region)->factory();
+ type->SetValue(1, factory->NewHeapNumber(min));
+ type->SetValue(2, factory->NewHeapNumber(max));
+ return type;
+ }
+
+ static RangeHandle New(double min, double max, Region* region) {
+ TypeHandle bound = BitsetType::New(BitsetType::kNumber, region);
+ return New(min, max, bound, region);
+ }
+
+ static RangeType* cast(TypeImpl* type) {
+ ASSERT(type->IsRange());
+ return static_cast<RangeType*>(type);
+ }
+};
+
+
//
-----------------------------------------------------------------------------
// Context types.
@@ -790,6 +838,11 @@
typedef void* Struct;
typedef i::Zone Region;
template<class T> struct Handle { typedef T* type; };
+
+ // TODO(neis): This will be removed again once we have
struct_get_double().
+ static inline i::Isolate* isolate(Region* region) {
+ return region->isolate();
+ }
template<class T> static inline T* handle(T* type);
template<class T> static inline T* cast(Type* type);
@@ -832,6 +885,11 @@
typedef i::FixedArray Struct;
typedef i::Isolate Region;
template<class T> struct Handle { typedef i::Handle<T> type; };
+
+ // TODO(neis): This will be removed again once we have
struct_get_double().
+ static inline i::Isolate* isolate(Region* region) {
+ return region;
+ }
template<class T> static inline i::Handle<T> handle(T* type);
template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
=======================================
--- /branches/bleeding_edge/test/cctest/test-types.cc Mon Jul 7 07:04:16
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-types.cc Tue Jul 22 17:33:22
2014 UTC
@@ -21,10 +21,11 @@
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);
@@ -70,10 +71,11 @@
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();
}
@@ -148,6 +150,15 @@
for (ValueVector::iterator it = values.begin(); it != values.end();
++it) {
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 < 10; ++i) {
+ doubles.push_back(rng_->NextInt());
+ doubles.push_back(rng_->NextDouble() * rng_->NextInt());
+ }
NumberArray = Type::Array(Number, region);
StringArray = Type::Array(String, region);
@@ -201,9 +212,12 @@
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_);
@@ -216,6 +230,10 @@
TypeHandle Constant(Handle<i::Object> value) {
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 +345,7 @@
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 +365,7 @@
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) &&
@@ -358,8 +378,11 @@
Rep::AsClass(type1) == Rep::AsClass(type2)) &&
(!Rep::IsConstant(type1) ||
Rep::AsConstant(type1) == Rep::AsConstant(type2)) &&
+ (!Rep::IsRange(type1) ||
+ (type1->AsRange()->Min() == type2->AsRange()->Min() &&
+ type1->AsRange()->Max() == type2->AsRange()->Max())) &&
// TODO(rossberg): Check details of arrays, functions, bounds.
- (!Rep::IsUnion(type1) ||
+ (!Rep::IsUnion(type1) ||
Rep::Length(Rep::AsUnion(type1)) ==
Rep::Length(Rep::AsUnion(type2)));
}
@@ -565,6 +588,50 @@
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 = std::min(*i, *j);
+ double max = std::max(*i, *j);
+ 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 = std::min(*i, *j);
+ double max = std::max(*i, *j);
+ TypeHandle type = T.Range(min, 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 = std::min(*i1, *j1);
+// double max1 = std::max(*i1, *j1);
+// double min2 = std::min(*i2, *j2);
+// double max2 = std::max(*i2, *j2);
+// TypeHandle type1 = T.Range(min1, max1);
+// TypeHandle type2 = T.Range(min2, max2);
+// CHECK(Equal(type1, type2) == (min1 == min2 && max1 == max2));
+// }
+// }
+// }
+// }
+ }
void Array() {
// Constructor
@@ -1792,6 +1859,13 @@
ZoneTests().Constant();
HeapTests().Constant();
}
+
+
+TEST(RangeType) {
+ CcTest::InitializeVM();
+ ZoneTests().Range();
+ HeapTests().Range();
+}
TEST(ArrayType) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.