Index: src/types.h |
diff --git a/src/types.h b/src/types.h |
index f141712bb84f09c5e58124174517eadc7a2241f6..711d2eebb99a3b38d5ebfd41a9bfbd683af02f88 100644 |
--- a/src/types.h |
+++ b/src/types.h |
@@ -285,7 +285,7 @@ class TypeImpl : public Config::Base { |
return ClassType::New(map, region); |
} |
static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
- // TODO(neis): return RangeType for numerical values |
+ // TODO(neis): Return RangeType for numerical values. |
return ConstantType::New(value, region); |
} |
static TypeHandle Range(double min, double max, Region* region) { |
@@ -514,6 +514,7 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> { |
static int Lub(int32_t value); |
static int Lub(uint32_t value); |
static int Lub(i::Map* map); |
+ static int RangeLub(double min, double max, TypeHandle bound); |
rossberg
2014/08/05 14:49:15
Is this defined anywhere?
neis
2014/08/06 13:15:01
Oops, was a leftover.
|
static int InherentLub(TypeImpl* type); |
static const char* Name(int bitset); |
@@ -684,10 +685,37 @@ class TypeImpl<Config>::RangeType : public StructuralType { |
double Min() { return this->template GetValue<i::HeapNumber>(1)->value(); } |
double Max() { return this->template GetValue<i::HeapNumber>(2)->value(); } |
+ static bool le(double x, double y) { |
rossberg
2014/08/05 14:49:15
These are helpers that shouldn't pollute the publi
neis
2014/08/06 13:15:01
Done.
|
+ return x <= y && copysign(1, x) <= copysign(1, y); |
+ } |
+ static bool eq(double x, double y) { |
+ return le(x, y) && le(y, x); |
+ } |
+ static double min(double x, double y) { |
+ return le(x, y) ? x : y; |
+ } |
+ static double max(double x, double y) { |
+ return le(x, y) ? y : x; |
+ } |
+ |
+ static int InherentLub(double min, double max) { |
rossberg
2014/08/05 14:49:15
Rename/move this to BitsetType::Lub(double, double
neis
2014/08/06 13:15:01
Done.
|
+ DCHECK(le(min, max)); |
+ DisallowHeapAllocation no_allocation; |
+ if (min == max) { |
rossberg
2014/08/05 14:49:15
eq(min, max)
neis
2014/08/06 13:15:01
Done.
|
+ return BitsetType::Lub(min); // Singleton range. |
+ } |
+ int bitset = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN); |
+ if (le(0, min) || max < 0) |
+ bitset ^= SEMANTIC(BitsetType::kMinusZero); |
+ return bitset; |
+ // TODO(neis): Could refine this further by doing more checks on min/max. |
+ } |
+ |
static RangeHandle New( |
double min, double max, TypeHandle bound, Region* region) { |
- DCHECK(BitsetType::Is(bound->AsBitset(), BitsetType::kNumber)); |
- DCHECK(!std::isnan(min) && !std::isnan(max) && min <= max); |
+ DCHECK(le(min, max)); |
+ DCHECK(bound->IsBitset()); |
+ DCHECK(BitsetType::Is(bound->AsBitset(), InherentLub(min, max))); |
RangeHandle type = Config::template cast<RangeType>( |
StructuralType::New(StructuralType::kRangeTag, 3, region)); |
type->Set(0, bound); |
@@ -700,7 +728,7 @@ class TypeImpl<Config>::RangeType : public StructuralType { |
} |
static RangeHandle New(double min, double max, Region* region) { |
- TypeHandle bound = BitsetType::New(BitsetType::kNumber, region); |
+ TypeHandle bound = BitsetType::New(InherentLub(min, max), region); |
return New(min, max, bound, region); |
} |