Commit db87b601 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Fix subtle bug in Math.min and Math.max with non-Smi zero.

See http://codereview.chromium.org/470001
From sra.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3433 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5bbb1d7b
......@@ -128,8 +128,9 @@ function MathMax(arg1, arg2) { // length == 2
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 @@ function MathMin(arg1, arg2) { // length == 2
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;
}
......
......@@ -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(1.1, 2.2, 3.3));
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 @@ o.valueOf = function() { return 3; };
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 @@ assertEquals(1, Math.max(-0, +1, +0));
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));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment