Revision: 3433
Author: [email protected]
Date: Tue Dec  8 02:18:28 2009
Log: Fix subtle bug in Math.min and Math.max with non-Smi zero.
See http://codereview.chromium.org/470001
 From sra.
http://code.google.com/p/v8/source/detail?r=3433

Modified:
  /branches/bleeding_edge/src/math.js
  /branches/bleeding_edge/test/mjsunit/math-min-max.js

=======================================
--- /branches/bleeding_edge/src/math.js Mon Dec  7 00:38:20 2009
+++ /branches/bleeding_edge/src/math.js Tue Dec  8 02:18:28 2009
@@ -128,8 +128,9 @@
      var n = %_Arguments(i);
      if (!IS_NUMBER(n)) n = ToNumber(n);
      if (NUMBER_IS_NAN(n)) return n;
-    // Make sure +0 is considered greater than -0.
-    if (n > r || (r === 0 && n === 0 && !%_IsSmi(r))) r = n;
+    // Make sure +0 is considered greater than -0.  -0 is never a Smi, +0  
can be
+    // a Smi or heap number.
+    if (n > r || (r === 0 && n === 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
    }
    return r;
  }
@@ -147,8 +148,9 @@
      var n = %_Arguments(i);
      if (!IS_NUMBER(n)) n = ToNumber(n);
      if (NUMBER_IS_NAN(n)) return n;
-    // Make sure -0 is considered less than +0.
-    if (n < r || (r === 0 && n === 0 && !%_IsSmi(n))) r = n;
+    // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can  
b a
+    // Smi or a heap number.
+    if (n < r || (r === 0 && n === 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
    }
    return r;
  }
=======================================
--- /branches/bleeding_edge/test/mjsunit/math-min-max.js        Mon Dec  7  
00:38:20 2009
+++ /branches/bleeding_edge/test/mjsunit/math-min-max.js        Tue Dec  8  
02:18:28 2009
@@ -25,9 +25,11 @@
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+// Flags: --allow-natives-syntax
+
  // Test Math.min().

-assertEquals(Number.POSITIVE_INFINITY, Math.min());
+assertEquals(Infinity, Math.min());
  assertEquals(1, Math.min(1));
  assertEquals(1, Math.min(1, 2));
  assertEquals(1, Math.min(2, 1));
@@ -38,14 +40,26 @@
  assertEquals(1.1, Math.min(3.3, 2.2, 1.1));
  assertEquals(1.1, Math.min(2.2, 3.3, 1.1));

+// Prepare a non-Smi zero value.
+function returnsNonSmi(){ return 0.25; }
+var ZERO = returnsNonSmi() - returnsNonSmi();
+assertEquals(0, ZERO);
+assertEquals(Infinity, 1/ZERO);
+assertEquals(-Infinity, 1/-ZERO);
+assertFalse(%_IsSmi(ZERO));
+assertFalse(%_IsSmi(-ZERO));
+
  var o = {};
  o.valueOf = function() { return 1; };
  assertEquals(1, Math.min(2, 3, '1'));
  assertEquals(1, Math.min(3, o, 2));
  assertEquals(1, Math.min(o, 2));
-assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.min(-0, +0));
-assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.min(+0, -0));
-assertEquals(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.min(+0, -0, 1));
+assertEquals(-Infinity, Infinity / Math.min(-0, +0));
+assertEquals(-Infinity, Infinity / Math.min(+0, -0));
+assertEquals(-Infinity, Infinity / Math.min(+0, -0, 1));
+assertEquals(-Infinity, Infinity / Math.min(-0, ZERO));
+assertEquals(-Infinity, Infinity / Math.min(ZERO, -0));
+assertEquals(-Infinity, Infinity / Math.min(ZERO, -0, 1));
  assertEquals(-1, Math.min(+0, -0, -1));
  assertEquals(-1, Math.min(-1, +0, -0));
  assertEquals(-1, Math.min(+0, -1, -0));
@@ -73,9 +87,12 @@
  assertEquals(3, Math.max(2, '3', 1));
  assertEquals(3, Math.max(1, o, 2));
  assertEquals(3, Math.max(o, 1));
-assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.max(-0, +0));
-assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.max(+0, -0));
-assertEquals(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY /  
Math.max(+0, -0, -1));
+assertEquals(Infinity, Infinity / Math.max(-0, +0));
+assertEquals(Infinity, Infinity / Math.max(+0, -0));
+assertEquals(Infinity, Infinity / Math.max(+0, -0, -1));
+assertEquals(Infinity, Infinity / Math.max(-0, ZERO));
+assertEquals(Infinity, Infinity / Math.max(ZERO, -0));
+assertEquals(Infinity, Infinity / Math.max(ZERO, -0, -1));
  assertEquals(1, Math.max(+0, -0, +1));
  assertEquals(1, Math.max(+1, +0, -0));
  assertEquals(1, Math.max(+0, +1, -0));
@@ -83,3 +100,6 @@
  assertNaN(Math.max('oxen'));
  assertNaN(Math.max('oxen', 1));
  assertNaN(Math.max(1, 'oxen'));
+
+assertEquals(Infinity, 1/Math.max(ZERO, -0));
+assertEquals(Infinity, 1/Math.max(-0, ZERO));

-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to