Fix a bunch of bugs that the fuzzers found (bug 765119, r=dvander)
☠☠ backed out by 15ec3a643b0b ☠ ☠
authorMarty Rosenberg <mrosenberg@mozilla.com>
Tue, 02 Oct 2012 04:34:28 -0400
changeset 108990 dbc7e1bc48d0ca6e85fc0e15a8b0d3767d66c6be
parent 108989 7895a56d434da2e97879ad4ae62395a0312ac809
child 108991 c25274efa6f68beea223adb7b100beeced7728c2
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersdvander
bugs765119
milestone18.0a1
Fix a bunch of bugs that the fuzzers found (bug 765119, r=dvander)
js/src/ion/MIR.h
js/src/ion/RangeAnalysis.cpp
js/src/ion/RangeAnalysis.h
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -2398,17 +2398,18 @@ class MAdd : public MBinaryArithInstruct
         return !isTruncated() && !range()->isFinite();
     }
 
     bool recomputeRange() {
         if (specialization() != MIRType_Int32)
             return false;
         Range *left = getOperand(0)->range();
         Range *right = getOperand(1)->range();
-        return range()->update(Range::add(left, right));
+        Range next = isTruncated() ? Range::addTruncate(left,right) : Range::add(left, right);
+        return range()->update(next);
     }
 };
 
 class MSub : public MBinaryArithInstruction
 {
     bool implicitTruncate_;
     MSub(MDefinition *left, MDefinition *right)
       : MBinaryArithInstruction(left, right),
@@ -2440,17 +2441,18 @@ class MSub : public MBinaryArithInstruct
         return !isTruncated() && !range()->isFinite();
     }
 
     bool recomputeRange() {
         if (specialization() != MIRType_Int32)
             return false;
         Range *left = getOperand(0)->range();
         Range *right = getOperand(1)->range();
-        return range()->update(Range::sub(left, right));
+        Range next = isTruncated() ? Range::subTruncate(left,right) : Range::sub(left, right);
+        return range()->update(next);
     }
 };
 
 class MMul : public MBinaryArithInstruction
 {
     bool canBeNegativeZero_;
 
     MMul(MDefinition *left, MDefinition *right, MIRType type)
--- a/js/src/ion/RangeAnalysis.cpp
+++ b/js/src/ion/RangeAnalysis.cpp
@@ -151,17 +151,17 @@ RangeAnalysis::addBetaNobes()
             bound = right->toConstant()->value().toInt32();
             val = left;
         } else {
             MDefinition *smaller = NULL;
             MDefinition *greater = NULL;
             if (jsop == JSOP_LT) {
                 smaller = left;
                 greater = right;
-            } else if (JSOP_GT) {
+            } else if (jsop == JSOP_GT) {
                 smaller = right;
                 greater = left;
             }
             if (smaller && greater) {
                 MBeta *beta;
                 beta = MBeta::New(smaller, Range(JSVAL_INT_MIN, JSVAL_INT_MAX-1));
                 block->insertBefore(*block->begin(), beta);
                 replaceDominatedUsesWith(smaller, beta, block);
@@ -317,16 +317,32 @@ Range::sub(const Range *lhs, const Range
 {
     Range ret(
         (int64_t)lhs->lower_ - (int64_t)rhs->upper_,
         (int64_t)lhs->upper_ - (int64_t)rhs->lower_);
     return ret;
 
 }
 Range
+Range::addTruncate(const Range *lhs, const Range *rhs)
+{
+    Range ret = Truncate((int64_t)lhs->lower_ + (int64_t)rhs->lower_,
+                         (int64_t)lhs->upper_ + (int64_t)rhs->upper_);
+    return ret;
+}
+
+Range
+Range::subTruncate(const Range *lhs, const Range *rhs)
+{
+    Range ret = Truncate((int64_t)lhs->lower_ - (int64_t)rhs->upper_,
+                         (int64_t)lhs->upper_ - (int64_t)rhs->lower_);
+    return ret;
+}
+
+Range
 Range::and_(const Range *lhs, const Range *rhs)
 {
     uint64_t lower = 0;
     // If both numbers can be negative, issues can be had.
     if (lhs->lower_ < 0 && rhs->lower_ < 0)
         lower = INT_MIN;
     uint64_t upper = lhs->upper_;
     if (rhs->upper_ < lhs->upper_)
--- a/js/src/ion/RangeAnalysis.h
+++ b/js/src/ion/RangeAnalysis.h
@@ -83,16 +83,24 @@ class Range {
     }
 
     Range(const Range &other)
     : lower_(other.lower_),
       lower_infinite_(other.lower_infinite_),
       upper_(other.upper_),
       upper_infinite_(other.upper_infinite_)
     {}
+    static Range Truncate(int64_t l, int64_t h) {
+        Range ret(l,h);
+        if (!ret.isFinite()) {
+            ret.makeLowerInfinite();
+            ret.makeUpperInfinite();
+        }
+        return ret;
+    }
 
     static int64_t abs64(int64_t x) {
 #ifdef WTF_OS_WINDOWS
         return _abs64(x);
 #else
         return llabs(x);
 #endif
     }
@@ -105,16 +113,18 @@ class Range {
 
     // Unlike the other operations, unionWith is an in-place
     // modification. This is to avoid a bunch of useless extra
     // copying when chaining together unions when handling Phi
     // nodes.
     void unionWith(const Range *other);
     void unionWith(RangeChangeCount *other);
     static Range intersect(const Range *lhs, const Range *rhs, bool *nullRange);
+    static Range addTruncate(const Range *lhs, const Range *rhs);
+    static Range subTruncate(const Range *lhs, const Range *rhs);
     static Range add(const Range *lhs, const Range *rhs);
     static Range sub(const Range *lhs, const Range *rhs);
     static Range mul(const Range *lhs, const Range *rhs);
     static Range and_(const Range *lhs, const Range *rhs);
     static Range shl(const Range *lhs, int32 c);
     static Range shr(const Range *lhs, int32 c);
 
     inline void makeLowerInfinite() {