Commit 264fa75e authored by bmeurer's avatar bmeurer Committed by Commit bot

[math] Fix Math.hypot to properly call ToNumber on all arguments.

The spec requires all Math functions to first call ToNumber on all
arguments before doing any other observable operation.  So early
return in case of Infinity is not valid.

Drive-by-fix: Remove the use of %_Arguments / %_ArgumentsLength and
use (strict) arguments instead of allocating a temporary InternalArray
explicitly.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/1669773002

Cr-Commit-Position: refs/heads/master@{#33717}
parent db74cccf
......@@ -164,17 +164,14 @@ function MathHypot(x, y) { // Function length is 2.
// We may want to introduce fast paths for two arguments and when
// normalization to avoid overflow is not necessary. For now, we
// simply assume the general case.
var length = %_ArgumentsLength();
var args = new InternalArray(length);
var length = arguments.length;
var max = 0;
for (var i = 0; i < length; i++) {
var n = %_Arguments(i);
n = TO_NUMBER(n);
if (n === INFINITY || n === -INFINITY) return INFINITY;
n = MathAbs(n);
var n = MathAbs(arguments[i]);
if (n > max) max = n;
args[i] = n;
arguments[i] = n;
}
if (max === INFINITY) return INFINITY;
// Kahan summation to avoid rounding errors.
// Normalize the numbers to the largest one to avoid overflow.
......@@ -182,7 +179,7 @@ function MathHypot(x, y) { // Function length is 2.
var sum = 0;
var compensation = 0;
for (var i = 0; i < length; i++) {
var n = args[i] / max;
var n = arguments[i] / max;
var summand = n * n - compensation;
var preliminary = sum + summand;
compensation = (preliminary - sum) - summand;
......
......@@ -56,6 +56,13 @@ x = "";
assertEquals(1, Math.pow(v, w));
assertEquals("hestfisk", x, "pow");
x = "";
var a = {valueOf: function() { x += "hest"; return 1/0; }};
var b = {valueOf: function() { x += "fisk"; return 1}};
assertEquals(1/0, Math.hypot(a, b));
assertEquals("hestfisk", x, "hypot");
var year = { valueOf: function() { x += 1; return 2007; } };
var month = { valueOf: function() { x += 2; return 2; } };
var date = { valueOf: function() { x += 3; return 4; } };
......
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