Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: src/types.cc

Issue 1343933002: Fix type Intersection and Maybe (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/types.cc
diff --git a/src/types.cc b/src/types.cc
index 868b073efaadd8c8faa854225467065b02a9448e..af1700254bb824370552ed2d884c844bb9f22322 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -152,7 +152,7 @@ TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
}
-// The smallest bitset subsuming this type.
+// The smallest bitset subsuming this type, possibly not a proper one.
template<class Config>
typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
@@ -168,13 +168,9 @@ TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
}
return bitset;
}
- if (type->IsClass()) {
- // Little hack to avoid the need for a region for handlification here...
- return Config::is_class(type) ? Lub(*Config::as_class(type)) :
- type->AsClass()->Bound(NULL)->AsBitset();
- }
- if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
- if (type->IsRange()) return type->AsRange()->Bound();
+ if (type->IsClass()) return type->AsClass()->Lub();
+ if (type->IsConstant()) return type->AsConstant()->Lub();
+ if (type->IsRange()) return type->AsRange()->Lub();
if (type->IsContext()) return kInternal & kTaggedPointer;
if (type->IsArray()) return kOtherObject;
if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction
@@ -341,22 +337,21 @@ TypeImpl<Config>::BitsetType::Lub(double value) {
if (i::IsMinusZero(value)) return kMinusZero;
if (std::isnan(value)) return kNaN;
if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
- return kPlainNumber;
+ return kOtherNumber;
}
-// Minimum values of regular numeric bitsets.
+// Minimum values of plain numeric bitsets.
template <class Config>
const typename TypeImpl<Config>::BitsetType::Boundary
- TypeImpl<Config>::BitsetType::BoundariesArray[] = {
- {kPlainNumber, -V8_INFINITY},
- {kNegative32, kMinInt},
- {kNegative31, -0x40000000},
- {kUnsigned30, 0},
- {kUnsigned31, 0x40000000},
- {kUnsigned32, 0x80000000},
- {kPlainNumber, static_cast<double>(kMaxUInt32) + 1}
-};
+TypeImpl<Config>::BitsetType::BoundariesArray[] = {
+ {kOtherNumber, kPlainNumber, -V8_INFINITY},
+ {kOtherSigned32, kNegative32, kMinInt},
+ {kNegative31, kNegative31, -0x40000000},
+ {kUnsigned30, kUnsigned30, 0},
+ {kOtherUnsigned31, kUnsigned31, 0x40000000},
+ {kOtherUnsigned32, kUnsigned32, 0x80000000},
+ {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
template <class Config>
@@ -374,6 +369,21 @@ size_t TypeImpl<Config>::BitsetType::BoundariesSize() {
}
+template <class Config>
+typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::ExpandInternals(
+ typename TypeImpl<Config>::bitset bits) {
+ DisallowHeapAllocation no_allocation;
+ if (!(bits & SEMANTIC(kPlainNumber))) return bits; // Shortcut.
+ const Boundary* boundaries = Boundaries();
+ for (size_t i = 0; i < BoundariesSize(); ++i) {
+ DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
+ if (bits & SEMANTIC(boundaries[i].internal))
+ bits |= SEMANTIC(boundaries[i].external);
+ }
+ return bits;
+}
+
+
template<class Config>
typename TypeImpl<Config>::bitset
TypeImpl<Config>::BitsetType::Lub(double min, double max) {
@@ -381,18 +391,13 @@ TypeImpl<Config>::BitsetType::Lub(double min, double max) {
int lub = kNone;
const Boundary* mins = Boundaries();
- // Make sure the min-max range touches 0, so we are guaranteed no holes
- // in unions of valid bitsets.
- if (max < -1) max = -1;
- if (min > 0) min = 0;
-
for (size_t i = 1; i < BoundariesSize(); ++i) {
if (min < mins[i].min) {
- lub |= mins[i-1].bits;
+ lub |= mins[i-1].internal;
if (max < mins[i].min) return lub;
}
}
- return lub |= mins[BoundariesSize() - 1].bits;
+ return lub | mins[BoundariesSize() - 1].internal;
}
@@ -404,16 +409,6 @@ typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::NumberBits(
template <class Config>
-void TypeImpl<Config>::BitsetType::CheckNumberBits(bitset bits) {
- // Check that the bitset does not contain any holes in number ranges.
- bitset number_bits = NumberBits(bits);
- if (number_bits != 0) {
- bitset lub = SEMANTIC(Lub(Min(number_bits), Max(number_bits)));
- CHECK(lub == number_bits);
- }
-}
-
-template <class Config>
typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
double min, double max) {
DisallowHeapAllocation no_allocation;
@@ -426,13 +421,11 @@ typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
if (min <= mins[i].min) {
if (max + 1 < mins[i + 1].min) break;
- glb |= mins[i].bits;
+ glb |= mins[i].external;
}
}
// OtherNumber also contains float numbers, so it can never be
- // in the greatest lower bound. (There is also the small trouble
- // of kOtherNumber having a range hole, which we can conveniently
- // ignore here.)
+ // in the greatest lower bound.
return glb & ~(SEMANTIC(kOtherNumber));
}
@@ -444,7 +437,7 @@ double TypeImpl<Config>::BitsetType::Min(bitset bits) {
const Boundary* mins = Boundaries();
bool mz = SEMANTIC(bits & kMinusZero);
for (size_t i = 0; i < BoundariesSize(); ++i) {
- if (Is(SEMANTIC(mins[i].bits), bits)) {
+ if (Is(SEMANTIC(mins[i].internal), bits)) {
return mz ? std::min(0.0, mins[i].min) : mins[i].min;
}
}
@@ -459,11 +452,11 @@ double TypeImpl<Config>::BitsetType::Max(bitset bits) {
DCHECK(Is(SEMANTIC(bits), kNumber));
const Boundary* mins = Boundaries();
bool mz = SEMANTIC(bits & kMinusZero);
- if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) {
+ if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].internal), bits)) {
return +V8_INFINITY;
}
for (size_t i = BoundariesSize() - 1; i-- > 0;) {
- if (Is(SEMANTIC(mins[i].bits), bits)) {
+ if (Is(SEMANTIC(mins[i].internal), bits)) {
return mz ?
std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1;
}
@@ -944,7 +937,7 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
// If the range is semantically contained within the bitset, return None and
// leave the bitset untouched.
bitset range_lub = SEMANTIC(range->BitsetLub());
- if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) {
+ if (BitsetType::Is(range_lub, *bits)) {
return None(region);
}
@@ -956,6 +949,8 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
double range_max = range->Max();
// Remove the number bits from the bitset, they would just confuse us now.
+ // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
+ // case we already returned after the subtype check above.
*bits &= ~number_bits;
if (range_min <= bitset_min && range_max >= bitset_max) {
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698