mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 915846 - IonMonkey: Rename things named "infinite" when they really mean to describe the presence or absence of an int32 bound value. r=nbp
This commit is contained in:
parent
3675a4e9fc
commit
6e024eb500
@ -7466,20 +7466,20 @@ bool
|
||||
CodeGenerator::emitAssertRangeD(const Range *r, FloatRegister input, FloatRegister temp)
|
||||
{
|
||||
// Check the lower bound.
|
||||
if (!r->isLowerInfinite()) {
|
||||
if (r->hasInt32LowerBound()) {
|
||||
Label success;
|
||||
masm.loadConstantDouble(r->lower(), temp);
|
||||
if (r->isUpperInfinite())
|
||||
if (!r->hasInt32UpperBound())
|
||||
masm.branchDouble(Assembler::DoubleUnordered, input, input, &success);
|
||||
masm.branchDouble(Assembler::DoubleGreaterThanOrEqual, input, temp, &success);
|
||||
masm.breakpoint();
|
||||
masm.bind(&success);
|
||||
}
|
||||
// Check the upper bound.
|
||||
if (!r->isUpperInfinite()) {
|
||||
if (r->hasInt32UpperBound()) {
|
||||
Label success;
|
||||
masm.loadConstantDouble(r->upper(), temp);
|
||||
if (r->isLowerInfinite())
|
||||
if (!r->hasInt32LowerBound())
|
||||
masm.branchDouble(Assembler::DoubleUnordered, input, input, &success);
|
||||
masm.branchDouble(Assembler::DoubleLessThanOrEqual, input, temp, &success);
|
||||
masm.breakpoint();
|
||||
|
@ -266,8 +266,8 @@ SymbolicBound::print(Sprinter &sp) const
|
||||
void
|
||||
Range::print(Sprinter &sp) const
|
||||
{
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
|
||||
// Floating-point or Integer subset.
|
||||
if (canHaveFractionalPart_)
|
||||
@ -277,8 +277,8 @@ Range::print(Sprinter &sp) const
|
||||
|
||||
sp.printf("[");
|
||||
|
||||
if (lower_infinite_)
|
||||
sp.printf("-inf");
|
||||
if (!hasInt32LowerBound_)
|
||||
sp.printf("?");
|
||||
else
|
||||
sp.printf("%d", lower_);
|
||||
if (symbolicLower_) {
|
||||
@ -289,8 +289,8 @@ Range::print(Sprinter &sp) const
|
||||
|
||||
sp.printf(", ");
|
||||
|
||||
if (upper_infinite_)
|
||||
sp.printf("inf");
|
||||
if (!hasInt32UpperBound_)
|
||||
sp.printf("?");
|
||||
else
|
||||
sp.printf("%d", upper_);
|
||||
if (symbolicUpper_) {
|
||||
@ -329,7 +329,7 @@ Range::intersect(const Range *lhs, const Range *rhs, bool *emptyRange)
|
||||
// }
|
||||
//
|
||||
// In this case, the block is dead. Right now, we just disregard this fact
|
||||
// and make the range infinite, rather than empty.
|
||||
// and make the range unbounded, rather than empty.
|
||||
//
|
||||
// Instead, we should use it to eliminate the dead block.
|
||||
// (Bug 765127)
|
||||
@ -343,8 +343,8 @@ Range::intersect(const Range *lhs, const Range *rhs, bool *emptyRange)
|
||||
lhs->canHaveFractionalPart_ && rhs->canHaveFractionalPart_,
|
||||
Min(lhs->max_exponent_, rhs->max_exponent_));
|
||||
|
||||
r->lower_infinite_ = lhs->lower_infinite_ && rhs->lower_infinite_;
|
||||
r->upper_infinite_ = lhs->upper_infinite_ && rhs->upper_infinite_;
|
||||
r->hasInt32LowerBound_ = lhs->hasInt32LowerBound_ || rhs->hasInt32LowerBound_;
|
||||
r->hasInt32UpperBound_ = lhs->hasInt32UpperBound_ || rhs->hasInt32UpperBound_;
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -355,13 +355,13 @@ Range::unionWith(const Range *other)
|
||||
bool canHaveFractionalPart = canHaveFractionalPart_ | other->canHaveFractionalPart_;
|
||||
uint16_t max_exponent = Max(max_exponent_, other->max_exponent_);
|
||||
|
||||
if (lower_infinite_ || other->lower_infinite_)
|
||||
makeLowerInfinite();
|
||||
if (!hasInt32LowerBound_ || !other->hasInt32LowerBound_)
|
||||
dropInt32LowerBound();
|
||||
else
|
||||
setLowerInit(Min(lower_, other->lower_));
|
||||
|
||||
if (upper_infinite_ || other->upper_infinite_)
|
||||
makeUpperInfinite();
|
||||
if (!hasInt32UpperBound_ || !other->hasInt32UpperBound_)
|
||||
dropInt32UpperBound();
|
||||
else
|
||||
setUpperInit(Max(upper_, other->upper_));
|
||||
|
||||
@ -369,9 +369,6 @@ Range::unionWith(const Range *other)
|
||||
max_exponent_ = max_exponent;
|
||||
}
|
||||
|
||||
static const int64_t RANGE_INF_MAX = int64_t(JSVAL_INT_MAX) + 1;
|
||||
static const int64_t RANGE_INF_MIN = int64_t(JSVAL_INT_MIN) - 1;
|
||||
|
||||
Range::Range(const MDefinition *def)
|
||||
: symbolicLower_(NULL),
|
||||
symbolicUpper_(NULL)
|
||||
@ -383,7 +380,7 @@ Range::Range(const MDefinition *def)
|
||||
else if (def->type() == MIRType_Boolean)
|
||||
set(0, 1);
|
||||
else
|
||||
set(RANGE_INF_MIN, RANGE_INF_MAX, true, MaxDoubleExponent);
|
||||
set(NoInt32LowerBound, NoInt32UpperBound, true, MaxDoubleExponent);
|
||||
symbolicLower_ = symbolicUpper_ = NULL;
|
||||
return;
|
||||
}
|
||||
@ -396,22 +393,22 @@ Range::Range(const MDefinition *def)
|
||||
}
|
||||
|
||||
static inline bool
|
||||
HasInfinite(const Range *lhs, const Range *rhs)
|
||||
MissingAnyInt32Bounds(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
return lhs->isLowerInfinite() || lhs->isUpperInfinite() ||
|
||||
rhs->isLowerInfinite() || rhs->isUpperInfinite();
|
||||
return !lhs->hasInt32LowerBound() || !lhs->hasInt32UpperBound() ||
|
||||
!rhs->hasInt32LowerBound() || !rhs->hasInt32UpperBound();
|
||||
}
|
||||
|
||||
Range *
|
||||
Range::add(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
int64_t l = (int64_t) lhs->lower_ + (int64_t) rhs->lower_;
|
||||
if (lhs->isLowerInfinite() || rhs->isLowerInfinite())
|
||||
l = RANGE_INF_MIN;
|
||||
if (!lhs->hasInt32LowerBound() || !rhs->hasInt32LowerBound())
|
||||
l = NoInt32LowerBound;
|
||||
|
||||
int64_t h = (int64_t) lhs->upper_ + (int64_t) rhs->upper_;
|
||||
if (lhs->isUpperInfinite() || rhs->isUpperInfinite())
|
||||
h = RANGE_INF_MAX;
|
||||
if (!lhs->hasInt32UpperBound() || !rhs->hasInt32UpperBound())
|
||||
h = NoInt32UpperBound;
|
||||
|
||||
return new Range(l, h, lhs->canHaveFractionalPart() || rhs->canHaveFractionalPart(),
|
||||
Max(lhs->exponent(), rhs->exponent()) + 1);
|
||||
@ -421,12 +418,12 @@ Range *
|
||||
Range::sub(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
int64_t l = (int64_t) lhs->lower_ - (int64_t) rhs->upper_;
|
||||
if (lhs->isLowerInfinite() || rhs->isUpperInfinite())
|
||||
l = RANGE_INF_MIN;
|
||||
if (!lhs->hasInt32LowerBound() || !rhs->hasInt32UpperBound())
|
||||
l = NoInt32LowerBound;
|
||||
|
||||
int64_t h = (int64_t) lhs->upper_ - (int64_t) rhs->lower_;
|
||||
if (lhs->isUpperInfinite() || rhs->isLowerInfinite())
|
||||
h = RANGE_INF_MAX;
|
||||
if (!lhs->hasInt32UpperBound() || !rhs->hasInt32LowerBound())
|
||||
h = NoInt32UpperBound;
|
||||
|
||||
return new Range(l, h, lhs->canHaveFractionalPart() || rhs->canHaveFractionalPart(),
|
||||
Max(lhs->exponent(), rhs->exponent()) + 1);
|
||||
@ -595,8 +592,8 @@ Range::mul(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
bool fractional = lhs->canHaveFractionalPart() || rhs->canHaveFractionalPart();
|
||||
uint16_t exponent = lhs->numBits() + rhs->numBits() - 1;
|
||||
if (HasInfinite(lhs, rhs))
|
||||
return new Range(RANGE_INF_MIN, RANGE_INF_MAX, fractional, exponent);
|
||||
if (MissingAnyInt32Bounds(lhs, rhs))
|
||||
return new Range(NoInt32LowerBound, NoInt32UpperBound, fractional, exponent);
|
||||
int64_t a = (int64_t)lhs->lower_ * (int64_t)rhs->lower_;
|
||||
int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_;
|
||||
int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_;
|
||||
@ -643,8 +640,8 @@ Range::ursh(const Range *lhs, int32_t c)
|
||||
|
||||
// If the value is always non-negative or always negative, we can simply
|
||||
// compute the correct range by shifting.
|
||||
if ((lhs->lower_ >= 0 && !lhs->isUpperInfinite()) ||
|
||||
(lhs->upper_ < 0 && !lhs->isLowerInfinite()))
|
||||
if ((lhs->lower_ >= 0 && lhs->hasInt32UpperBound()) ||
|
||||
(lhs->upper_ < 0 && lhs->hasInt32LowerBound()))
|
||||
{
|
||||
return new Range(
|
||||
(int64_t)((uint32_t)lhs->lower_ >> shift),
|
||||
@ -674,7 +671,7 @@ Range::rsh(const Range *lhs, const Range *rhs)
|
||||
Range *
|
||||
Range::ursh(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
return new Range(0, (lhs->lower() >= 0 && !lhs->isUpperInfinite()) ? lhs->upper() : UINT32_MAX);
|
||||
return new Range(0, (lhs->lower() >= 0 && lhs->hasInt32UpperBound()) ? lhs->upper() : UINT32_MAX);
|
||||
}
|
||||
|
||||
Range *
|
||||
@ -683,8 +680,8 @@ Range::abs(const Range *op)
|
||||
// Get the lower and upper values of the operand, and adjust them
|
||||
// for infinities. Range's constructor treats any value beyond the
|
||||
// int32_t range as infinity.
|
||||
int64_t l = (int64_t)op->lower() - op->isLowerInfinite();
|
||||
int64_t u = (int64_t)op->upper() + op->isUpperInfinite();
|
||||
int64_t l = (int64_t)op->lower() - !op->hasInt32LowerBound();
|
||||
int64_t u = (int64_t)op->upper() + !op->hasInt32UpperBound();
|
||||
|
||||
return new Range(Max(Max(int64_t(0), l), -u),
|
||||
Max(Abs(l), Abs(u)),
|
||||
@ -741,16 +738,16 @@ Range::update(const Range *other)
|
||||
{
|
||||
bool changed =
|
||||
lower_ != other->lower_ ||
|
||||
lower_infinite_ != other->lower_infinite_ ||
|
||||
hasInt32LowerBound_ != other->hasInt32LowerBound_ ||
|
||||
upper_ != other->upper_ ||
|
||||
upper_infinite_ != other->upper_infinite_ ||
|
||||
hasInt32UpperBound_ != other->hasInt32UpperBound_ ||
|
||||
canHaveFractionalPart_ != other->canHaveFractionalPart_ ||
|
||||
max_exponent_ != other->max_exponent_;
|
||||
if (changed) {
|
||||
lower_ = other->lower_;
|
||||
lower_infinite_ = other->lower_infinite_;
|
||||
hasInt32LowerBound_ = other->hasInt32LowerBound_;
|
||||
upper_ = other->upper_;
|
||||
upper_infinite_ = other->upper_infinite_;
|
||||
hasInt32UpperBound_ = other->hasInt32UpperBound_;
|
||||
canHaveFractionalPart_ = other->canHaveFractionalPart_;
|
||||
max_exponent_ = other->max_exponent_;
|
||||
}
|
||||
@ -827,12 +824,12 @@ MConstant::computeRange()
|
||||
if (IsNaN(d))
|
||||
return;
|
||||
|
||||
// Infinity is used to set both lower and upper to the range boundaries.
|
||||
// Beyond-int32 values are used to set both lower and upper to the range boundaries.
|
||||
if (IsInfinite(d)) {
|
||||
if (IsNegative(d))
|
||||
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
|
||||
setRange(new Range(Range::NoInt32LowerBound, Range::NoInt32LowerBound, false, exp));
|
||||
else
|
||||
setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp));
|
||||
setRange(new Range(Range::NoInt32UpperBound, Range::NoInt32UpperBound, false, exp));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -864,9 +861,9 @@ MConstant::computeRange()
|
||||
// This double has a precision loss. This also mean that it cannot
|
||||
// encode any values with fractional parts.
|
||||
if (IsNegative(d))
|
||||
setRange(new Range(RANGE_INF_MIN, RANGE_INF_MIN, false, exp));
|
||||
setRange(new Range(Range::NoInt32LowerBound, Range::NoInt32LowerBound, false, exp));
|
||||
else
|
||||
setRange(new Range(RANGE_INF_MAX, RANGE_INF_MAX, false, exp));
|
||||
setRange(new Range(Range::NoInt32UpperBound, Range::NoInt32UpperBound, false, exp));
|
||||
}
|
||||
}
|
||||
|
||||
@ -977,7 +974,7 @@ MUrsh::computeRange()
|
||||
}
|
||||
|
||||
JS_ASSERT(range()->lower() >= 0);
|
||||
if (type() == MIRType_Int32 && range()->isUpperInfinite())
|
||||
if (type() == MIRType_Int32 && !range()->hasInt32UpperBound())
|
||||
range()->extendUInt32ToInt32Min();
|
||||
}
|
||||
|
||||
@ -1155,7 +1152,7 @@ void
|
||||
MLoadTypedArrayElement::computeRange()
|
||||
{
|
||||
if (Range *range = GetTypedArrayRange(arrayType())) {
|
||||
if (type() == MIRType_Int32 && range->isUpperInfinite())
|
||||
if (type() == MIRType_Int32 && !range->hasInt32UpperBound())
|
||||
range->extendUInt32ToInt32Min();
|
||||
setRange(range);
|
||||
}
|
||||
@ -1493,12 +1490,12 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock *header, LoopIterationBound *loopBound
|
||||
|
||||
Range *initRange = initial->range();
|
||||
if (modified.constant > 0) {
|
||||
if (initRange && !initRange->isLowerInfinite())
|
||||
if (initRange && initRange->hasInt32LowerBound())
|
||||
phi->range()->setLower(initRange->lower());
|
||||
phi->range()->setSymbolicLower(new SymbolicBound(NULL, initialSum));
|
||||
phi->range()->setSymbolicUpper(new SymbolicBound(loopBound, limitSum));
|
||||
} else {
|
||||
if (initRange && !initRange->isUpperInfinite())
|
||||
if (initRange && initRange->hasInt32UpperBound())
|
||||
phi->range()->setUpper(initRange->upper());
|
||||
phi->range()->setSymbolicUpper(new SymbolicBound(NULL, initialSum));
|
||||
phi->range()->setSymbolicLower(new SymbolicBound(loopBound, limitSum));
|
||||
@ -1675,15 +1672,15 @@ RangeAnalysis::analyze()
|
||||
if (i->isAsmJSLoadHeap()) {
|
||||
MAsmJSLoadHeap *ins = i->toAsmJSLoadHeap();
|
||||
Range *range = ins->ptr()->range();
|
||||
if (range && !range->isLowerInfinite() && range->lower() >= 0 &&
|
||||
!range->isUpperInfinite() &&
|
||||
if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
|
||||
range->hasInt32UpperBound() &&
|
||||
(uint32_t) range->upper() < mir->minAsmJSHeapLength())
|
||||
ins->setSkipBoundsCheck(true);
|
||||
} else if (i->isAsmJSStoreHeap()) {
|
||||
MAsmJSStoreHeap *ins = i->toAsmJSStoreHeap();
|
||||
Range *range = ins->ptr()->range();
|
||||
if (range && !range->isLowerInfinite() && range->lower() >= 0 &&
|
||||
!range->isUpperInfinite() &&
|
||||
if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
|
||||
range->hasInt32UpperBound() &&
|
||||
(uint32_t) range->upper() < mir->minAsmJSHeapLength())
|
||||
ins->setSkipBoundsCheck(true);
|
||||
}
|
||||
@ -1732,8 +1729,8 @@ Range::clampToInt32()
|
||||
{
|
||||
if (isInt32())
|
||||
return;
|
||||
int64_t l = isLowerInfinite() ? JSVAL_INT_MIN : lower();
|
||||
int64_t h = isUpperInfinite() ? JSVAL_INT_MAX : upper();
|
||||
int64_t l = hasInt32LowerBound() ? lower() : JSVAL_INT_MIN;
|
||||
int64_t h = hasInt32UpperBound() ? upper() : JSVAL_INT_MAX;
|
||||
set(l, h);
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,15 @@ class Range : public TempObject {
|
||||
// 11 bits of signed exponent, so the max is encoded on 10 bits.
|
||||
static const uint16_t MaxDoubleExponent = mozilla::DoubleExponentBias;
|
||||
|
||||
// This range class uses int32_t ranges, but has several interfaces which
|
||||
// use int64_t, which either holds an int32_t value, or one of the following
|
||||
// special values which mean a value which is beyond the int32 range,
|
||||
// potentially including infinity or NaN. These special values are
|
||||
// guaranteed to compare greater, and less than, respectively, any int32_t
|
||||
// value.
|
||||
static const int64_t NoInt32UpperBound = int64_t(JSVAL_INT_MAX) + 1;
|
||||
static const int64_t NoInt32LowerBound = int64_t(JSVAL_INT_MIN) - 1;
|
||||
|
||||
private:
|
||||
// Absolute ranges.
|
||||
//
|
||||
@ -122,17 +131,17 @@ class Range : public TempObject {
|
||||
// and somewhat subtle.
|
||||
//
|
||||
// N.B.: All of the operations that compute new ranges based
|
||||
// on existing ranges will ignore the _infinite_ flags of the
|
||||
// on existing ranges will ignore the hasInt32*Bound_ flags of the
|
||||
// input ranges; that is, they implicitly clamp the ranges of
|
||||
// the inputs to [INT_MIN, INT_MAX]. Therefore, while our range might
|
||||
// be infinite (and could overflow), when using this information to
|
||||
// be unbounded (and could overflow), when using this information to
|
||||
// propagate through other ranges, we disregard this fact; if that code
|
||||
// executes, then the overflow did not occur, so we may safely assume
|
||||
// that the range is [INT_MIN, INT_MAX] instead.
|
||||
//
|
||||
// To facilitate this trick, we maintain the invariants that:
|
||||
// 1) lower_infinite == true implies lower_ == JSVAL_INT_MIN
|
||||
// 2) upper_infinite == true implies upper_ == JSVAL_INT_MAX
|
||||
// 1) hasInt32LowerBound_ == false implies lower_ == JSVAL_INT_MIN
|
||||
// 2) hasInt32UpperBound_ == false implies upper_ == JSVAL_INT_MAX
|
||||
//
|
||||
// As a second and less precise range analysis, we represent the maximal
|
||||
// exponent taken by a value. The exponent is calculated by taking the
|
||||
@ -141,10 +150,10 @@ class Range : public TempObject {
|
||||
// the Int32 this over approximation is rectified.
|
||||
|
||||
int32_t lower_;
|
||||
bool lower_infinite_;
|
||||
bool hasInt32LowerBound_;
|
||||
|
||||
int32_t upper_;
|
||||
bool upper_infinite_;
|
||||
bool hasInt32UpperBound_;
|
||||
|
||||
bool canHaveFractionalPart_;
|
||||
uint16_t max_exponent_;
|
||||
@ -156,21 +165,21 @@ class Range : public TempObject {
|
||||
public:
|
||||
Range()
|
||||
: lower_(JSVAL_INT_MIN),
|
||||
lower_infinite_(true),
|
||||
hasInt32LowerBound_(false),
|
||||
upper_(JSVAL_INT_MAX),
|
||||
upper_infinite_(true),
|
||||
hasInt32UpperBound_(false),
|
||||
canHaveFractionalPart_(true),
|
||||
max_exponent_(MaxDoubleExponent),
|
||||
symbolicLower_(NULL),
|
||||
symbolicUpper_(NULL)
|
||||
{
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
}
|
||||
|
||||
Range(int64_t l, int64_t h, bool f = false, uint16_t e = MaxInt32Exponent)
|
||||
: lower_infinite_(true),
|
||||
upper_infinite_(true),
|
||||
: hasInt32LowerBound_(false),
|
||||
hasInt32UpperBound_(false),
|
||||
canHaveFractionalPart_(f),
|
||||
max_exponent_(e),
|
||||
symbolicLower_(NULL),
|
||||
@ -182,22 +191,22 @@ class Range : public TempObject {
|
||||
setLowerInit(l);
|
||||
setUpperInit(h);
|
||||
rectifyExponent();
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
}
|
||||
|
||||
Range(const Range &other)
|
||||
: lower_(other.lower_),
|
||||
lower_infinite_(other.lower_infinite_),
|
||||
hasInt32LowerBound_(other.hasInt32LowerBound_),
|
||||
upper_(other.upper_),
|
||||
upper_infinite_(other.upper_infinite_),
|
||||
hasInt32UpperBound_(other.hasInt32UpperBound_),
|
||||
canHaveFractionalPart_(other.canHaveFractionalPart_),
|
||||
max_exponent_(other.max_exponent_),
|
||||
symbolicLower_(NULL),
|
||||
symbolicUpper_(NULL)
|
||||
{
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
}
|
||||
|
||||
Range(const MDefinition *def);
|
||||
@ -230,28 +239,28 @@ class Range : public TempObject {
|
||||
|
||||
static bool negativeZeroMul(const Range *lhs, const Range *rhs);
|
||||
|
||||
void makeLowerInfinite() {
|
||||
lower_infinite_ = true;
|
||||
void dropInt32LowerBound() {
|
||||
hasInt32LowerBound_ = false;
|
||||
lower_ = JSVAL_INT_MIN;
|
||||
if (max_exponent_ < MaxInt32Exponent)
|
||||
max_exponent_ = MaxInt32Exponent;
|
||||
}
|
||||
void makeUpperInfinite() {
|
||||
upper_infinite_ = true;
|
||||
void dropInt32UpperBound() {
|
||||
hasInt32UpperBound_ = false;
|
||||
upper_ = JSVAL_INT_MAX;
|
||||
if (max_exponent_ < MaxInt32Exponent)
|
||||
max_exponent_ = MaxInt32Exponent;
|
||||
}
|
||||
|
||||
bool isLowerInfinite() const {
|
||||
return lower_infinite_;
|
||||
bool hasInt32LowerBound() const {
|
||||
return hasInt32LowerBound_;
|
||||
}
|
||||
bool isUpperInfinite() const {
|
||||
return upper_infinite_;
|
||||
bool hasInt32UpperBound() const {
|
||||
return hasInt32UpperBound_;
|
||||
}
|
||||
|
||||
bool isInt32() const {
|
||||
return !isLowerInfinite() && !isUpperInfinite();
|
||||
return hasInt32LowerBound() && hasInt32UpperBound();
|
||||
}
|
||||
bool isBoolean() const {
|
||||
return lower() >= 0 && upper() <= 1;
|
||||
@ -288,39 +297,39 @@ class Range : public TempObject {
|
||||
void setLowerInit(int64_t x) {
|
||||
if (x > JSVAL_INT_MAX) { // c.c
|
||||
lower_ = JSVAL_INT_MAX;
|
||||
lower_infinite_ = false;
|
||||
hasInt32LowerBound_ = true;
|
||||
} else if (x < JSVAL_INT_MIN) {
|
||||
makeLowerInfinite();
|
||||
dropInt32LowerBound();
|
||||
} else {
|
||||
lower_ = (int32_t)x;
|
||||
lower_infinite_ = false;
|
||||
hasInt32LowerBound_ = true;
|
||||
}
|
||||
}
|
||||
void setLower(int64_t x) {
|
||||
setLowerInit(x);
|
||||
rectifyExponent();
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
}
|
||||
void setUpperInit(int64_t x) {
|
||||
if (x > JSVAL_INT_MAX) {
|
||||
makeUpperInfinite();
|
||||
dropInt32UpperBound();
|
||||
} else if (x < JSVAL_INT_MIN) { // c.c
|
||||
upper_ = JSVAL_INT_MIN;
|
||||
upper_infinite_ = false;
|
||||
hasInt32UpperBound_ = true;
|
||||
} else {
|
||||
upper_ = (int32_t)x;
|
||||
upper_infinite_ = false;
|
||||
hasInt32UpperBound_ = true;
|
||||
}
|
||||
}
|
||||
void setUpper(int64_t x) {
|
||||
setUpperInit(x);
|
||||
rectifyExponent();
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
}
|
||||
|
||||
void setInt32() {
|
||||
lower_infinite_ = false;
|
||||
upper_infinite_ = false;
|
||||
hasInt32LowerBound_ = true;
|
||||
hasInt32UpperBound_ = true;
|
||||
canHaveFractionalPart_ = false;
|
||||
max_exponent_ = MaxInt32Exponent;
|
||||
}
|
||||
@ -331,8 +340,8 @@ class Range : public TempObject {
|
||||
setUpperInit(h);
|
||||
canHaveFractionalPart_ = f;
|
||||
rectifyExponent();
|
||||
JS_ASSERT_IF(lower_infinite_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(upper_infinite_, upper_ == JSVAL_INT_MAX);
|
||||
JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
|
||||
JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
|
||||
}
|
||||
|
||||
// Make the lower end of this range at least INT32_MIN, and make
|
||||
@ -355,7 +364,7 @@ class Range : public TempObject {
|
||||
// representation by doing an overflow while keeping the upper infinity to
|
||||
// repesent the fact that the value might reach bigger numbers.
|
||||
void extendUInt32ToInt32Min() {
|
||||
JS_ASSERT(isUpperInfinite());
|
||||
JS_ASSERT(!hasInt32UpperBound());
|
||||
lower_ = JSVAL_INT_MIN;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user