Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Unified Diff: src/builtins.cc

Issue 2102223005: [builtins] Migrate Math.hypot() to C++ builtins. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@MathAbs
Patch Set: Do not add Math.hypot() to list of optimized functions. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins.h ('k') | src/js/math.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index e5af799cd973ea5b4971ff3572e653cdba0cc4fa..4ddc633ff0d57df32ebffc1e2efd31a364825195 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -2268,6 +2268,58 @@ BUILTIN(MathAsin) {
return *isolate->factory()->NewHeapNumber(std::asin(x->Number()));
}
+// ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values )
+BUILTIN(MathHypot) {
+ HandleScope scope(isolate);
+ int const length = args.length() - 1;
+ if (length == 0) return Smi::FromInt(0);
+ DCHECK_LT(0, length);
+ double max = 0;
+ bool one_arg_is_nan = false;
+ List<double> abs_values(length);
+ for (int i = 0; i < length; i++) {
+ Handle<Object> x = args.at<Object>(i + 1);
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x));
+ double abs_value = std::abs(x->Number());
+
+ if (std::isnan(abs_value)) {
+ one_arg_is_nan = true;
+ } else {
+ abs_values.Add(abs_value);
+ if (max < abs_value) {
+ max = abs_value;
+ }
+ }
+ }
+
+ if (max == V8_INFINITY) {
+ return *isolate->factory()->NewNumber(V8_INFINITY);
+ }
+
+ if (one_arg_is_nan) {
+ return *isolate->factory()->nan_value();
+ }
+
+ if (max == 0) {
+ return Smi::FromInt(0);
+ }
+ DCHECK_GT(max, 0);
+
+ // Kahan summation to avoid rounding errors.
+ // Normalize the numbers to the largest one to avoid overflow.
+ double sum = 0;
+ double compensation = 0;
+ for (int i = 0; i < length; i++) {
+ double n = abs_values.at(i) / max;
+ double summand = n * n - compensation;
+ double preliminary = sum + summand;
+ compensation = (preliminary - sum) - summand;
+ sum = preliminary;
+ }
+
+ return *isolate->factory()->NewNumber(std::sqrt(sum) * max);
+}
+
// ES6 section 20.2.2.6 Math.atan ( x )
void Builtins::Generate_MathAtan(CodeStubAssembler* assembler) {
using compiler::Node;
« no previous file with comments | « src/builtins.h ('k') | src/js/math.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698