Diff
Modified: trunk/LayoutTests/ChangeLog (165794 => 165795)
--- trunk/LayoutTests/ChangeLog 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/LayoutTests/ChangeLog 2014-03-18 03:21:22 UTC (rev 165795)
@@ -1,3 +1,15 @@
+2014-03-17 Tibor Meszaros <[email protected]>
+
+ Implement Math.hypot
+ https://bugs.webkit.org/show_bug.cgi?id=129486
+
+ Reviewed by Darin Adler.
+
+ * js/Object-getOwnPropertyNames-expected.txt:
+ * js/math-expected.txt:
+ * js/script-tests/Object-getOwnPropertyNames.js:
+ * js/script-tests/math.js:
+
2014-03-17 Jer Noble <[email protected]>
Layout Test mathml/wbr-in-mroot-crash.html crashes
Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (165794 => 165795)
--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2014-03-18 03:21:22 UTC (rev 165795)
@@ -58,7 +58,7 @@
PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']
PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
-PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','imul','log','log10','log1p','log2','max','min','pow','random','round','sin','sinh','sqrt','tan','tanh','trunc']
+PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sin','sinh','sqrt','tan','tanh','trunc']
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
PASS globalPropertyNames.indexOf('NaN') != -1 is true
PASS globalPropertyNames.indexOf('Infinity') != -1 is true
Modified: trunk/LayoutTests/js/math-expected.txt (165794 => 165795)
--- trunk/LayoutTests/js/math-expected.txt 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/LayoutTests/js/math-expected.txt 2014-03-18 03:21:22 UTC (rev 165795)
@@ -83,6 +83,29 @@
PASS Math.floor(-Number.MAX_VALUE) is -Number.MAX_VALUE
PASS Math.floor(Infinity) is Infinity
PASS Math.floor(-Infinity) is -Infinity
+PASS Math.hypot.length is 2
+PASS Math.hypot(NaN) is NaN
+PASS Math.hypot() is 0
+PASS Math.hypot(-0) is 0
+PASS Math.hypot(0) is 0
+PASS Math.hypot(-Infinity) is Infinity
+PASS Math.hypot(Infinity) is Infinity
+PASS Math.hypot(-3) is 3
+PASS Math.hypot(3, 4) is 5
+PASS Math.hypot(1, NaN, Infinity) is Infinity
+PASS Math.hypot(3, 4, 5) is 7.0710678118654755
+PASS Math.hypot(3, 4, '5') is 7.0710678118654755
+PASS Math.hypot(-3, -4) is 5
+PASS Math.hypot(3, -Infinity) is Infinity
+PASS Math.hypot(3, NaN) is NaN
+PASS Math.hypot(NaN, 3) is NaN
+PASS Math.hypot(0, NaN) is NaN
+PASS Math.hypot(NaN, 0) is NaN
+PASS Math.hypot(NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.hypot(NaN, NaN, {valueOf:function(){throw "err"}}) threw exception err.
+PASS Math.hypot({valueOf:function(){throw "error1"}}, {valueOf:function(){sideEffect = 1}}) threw exception error1.
+PASS sideEffect is 0
+PASS Math.hypot(3, 4, 'foo') is NaN
PASS Math.log(NaN) is NaN
PASS Math.log(0) is -Infinity
PASS Math.log(-0) is -Infinity
Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (165794 => 165795)
--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2014-03-18 03:21:22 UTC (rev 165795)
@@ -66,7 +66,7 @@
"RegExp.prototype": "['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']",
"Error": "['length', 'name', 'prototype']",
"Error.prototype": "['constructor', 'message', 'name', 'toString']",
- "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','imul','log','log10','log1p','log2','max','min','pow','random','round','sin','sinh','sqrt','tan','tanh','trunc']",
+ "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sin','sinh','sqrt','tan','tanh','trunc']",
"JSON": "['parse', 'stringify']"
};
Modified: trunk/LayoutTests/js/script-tests/math.js (165794 => 165795)
--- trunk/LayoutTests/js/script-tests/math.js 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/LayoutTests/js/script-tests/math.js 2014-03-18 03:21:22 UTC (rev 165795)
@@ -124,6 +124,31 @@
shouldBe("Math.floor(Infinity)", "Infinity");
shouldBe("Math.floor(-Infinity)", "-Infinity");
+shouldBe("Math.hypot.length","2");
+shouldBe("Math.hypot(NaN)", "NaN");
+shouldBe("Math.hypot()", "0");
+shouldBe("Math.hypot(-0)", "0");
+shouldBe("Math.hypot(0)", "0");
+shouldBe("Math.hypot(-Infinity)", "Infinity");
+shouldBe("Math.hypot(Infinity)", "Infinity");
+shouldBe("Math.hypot(-3)", "3");
+shouldBe("Math.hypot(3, 4)", "5");
+shouldBe("Math.hypot(1, NaN, Infinity)", "Infinity");
+shouldBe("Math.hypot(3, 4, 5)", "7.0710678118654755");
+shouldBe("Math.hypot(3, 4, '5')", "7.0710678118654755");
+shouldBe("Math.hypot(-3, -4)", "5");
+shouldBe("Math.hypot(3, -Infinity)", "Infinity");
+shouldBe("Math.hypot(3, NaN)", "NaN");
+shouldBe("Math.hypot(NaN, 3)", "NaN");
+shouldBe("Math.hypot(0, NaN)", "NaN");
+shouldBe("Math.hypot(NaN, 0)", "NaN");
+shouldThrow("Math.hypot(NaN, {valueOf:function(){throw \"err\"}})","'err'");
+shouldThrow("Math.hypot(NaN, NaN, {valueOf:function(){throw \"err\"}})","'err'");
+sideEffect = 0;
+shouldThrow("Math.hypot({valueOf:function(){throw \"error1\"}}, {valueOf:function(){sideEffect = 1}})", "'error1'");
+shouldBe('sideEffect', '0');
+shouldBe("Math.hypot(3, 4, 'foo')", "NaN");
+
shouldBe("Math.log(NaN)", "NaN");
shouldBe("Math.log(0)", "-Infinity");
shouldBe("Math.log(-0)", "-Infinity");
Modified: trunk/Source/_javascript_Core/ChangeLog (165794 => 165795)
--- trunk/Source/_javascript_Core/ChangeLog 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-03-18 03:21:22 UTC (rev 165795)
@@ -1,3 +1,14 @@
+2014-03-17 Tibor Meszaros <[email protected]>
+
+ Implement Math.hypot
+ https://bugs.webkit.org/show_bug.cgi?id=129486
+
+ Reviewed by Darin Adler.
+
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::finishCreation):
+ (JSC::mathProtoFuncHypot):
+
2014-03-17 Zsolt Borbely <[email protected]>
Fix the !ENABLE(PROMISES) build
Modified: trunk/Source/_javascript_Core/runtime/MathObject.cpp (165794 => 165795)
--- trunk/Source/_javascript_Core/runtime/MathObject.cpp 2014-03-18 03:17:44 UTC (rev 165794)
+++ trunk/Source/_javascript_Core/runtime/MathObject.cpp 2014-03-18 03:21:22 UTC (rev 165795)
@@ -29,6 +29,7 @@
#include <wtf/MathExtras.h>
#include <wtf/RandomNumber.h>
#include <wtf/RandomNumberSeed.h>
+#include <wtf/Vector.h>
namespace JSC {
@@ -50,6 +51,7 @@
static EncodedJSValue JSC_HOST_CALL mathProtoFuncExpm1(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncFround(ExecState*);
+static EncodedJSValue JSC_HOST_CALL mathProtoFuncHypot(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog1p(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog10(ExecState*);
@@ -108,6 +110,7 @@
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "expm1"), 1, mathProtoFuncExpm1, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "fround"), 1, mathProtoFuncFround, NoIntrinsic, DontEnum | Function);
+ putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "hypot"), 2, mathProtoFuncHypot, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log10"), 1, mathProtoFuncLog10, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log1p"), 1, mathProtoFuncLog1p, NoIntrinsic, DontEnum | Function);
@@ -175,6 +178,35 @@
return JSValue::encode(jsNumber(floor(exec->argument(0).toNumber(exec))));
}
+EncodedJSValue JSC_HOST_CALL mathProtoFuncHypot(ExecState* exec)
+{
+ unsigned argsCount = exec->argumentCount();
+ double max = 0;
+ Vector<double, 8> args;
+ args.reserveInitialCapacity(argsCount);
+ for (unsigned i = 0; i < argsCount; ++i) {
+ args.uncheckedAppend(exec->uncheckedArgument(i).toNumber(exec));
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
+ if (std::isinf(args[i]))
+ return JSValue::encode(jsDoubleNumber(+std::numeric_limits<double>::infinity()));
+ max = std::max(fabs(args[i]), max);
+ }
+ if (!max)
+ max = 1;
+ // Kahan summation algorithm significantly reduces the numerical error in the total obtained.
+ double sum = 0;
+ double compensation = 0;
+ for (double argument : args) {
+ double scaledArgument = argument / max;
+ double summand = scaledArgument * scaledArgument - compensation;
+ double preliminary = sum + summand;
+ compensation = (preliminary - sum) - summand;
+ sum = preliminary;
+ }
+ return JSValue::encode(jsDoubleNumber(sqrt(sum) * max));
+}
+
EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec)
{
return JSValue::encode(jsDoubleNumber(log(exec->argument(0).toNumber(exec))));