LCOV - code coverage report
Current view: top level - src/builtins - builtins-math.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 24 24 100.0 %
Date: 2019-04-17 Functions: 3 4 75.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/builtins/builtins-utils.h"
       6             : #include "src/builtins/builtins.h"
       7             : #include "src/counters.h"
       8             : #include "src/objects-inl.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : 
      13             : // -----------------------------------------------------------------------------
      14             : // ES6 section 20.2.2 Function Properties of the Math Object
      15             : 
      16             : // ES6 section 20.2.2.18 Math.hypot ( value1, value2, ...values )
      17        1440 : BUILTIN(MathHypot) {
      18             :   HandleScope scope(isolate);
      19         288 :   int const length = args.length() - 1;
      20         288 :   if (length == 0) return Smi::kZero;
      21             :   DCHECK_LT(0, length);
      22             :   double max = 0;
      23             :   bool one_arg_is_nan = false;
      24             :   std::vector<double> abs_values;
      25         252 :   abs_values.reserve(length);
      26       15912 :   for (int i = 0; i < length; i++) {
      27        7830 :     Handle<Object> x = args.at(i + 1);
      28       15660 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
      29             :                                        Object::ToNumber(isolate, x));
      30        7830 :     double abs_value = std::abs(x->Number());
      31             : 
      32        7830 :     if (std::isnan(abs_value)) {
      33             :       one_arg_is_nan = true;
      34             :     } else {
      35        7758 :       abs_values.push_back(abs_value);
      36        7758 :       if (max < abs_value) {
      37             :         max = abs_value;
      38             :       }
      39             :     }
      40             :   }
      41             : 
      42         252 :   if (max == V8_INFINITY) {
      43          54 :     return *isolate->factory()->NewNumber(V8_INFINITY);
      44             :   }
      45             : 
      46         225 :   if (one_arg_is_nan) {
      47          54 :     return ReadOnlyRoots(isolate).nan_value();
      48             :   }
      49             : 
      50         171 :   if (max == 0) {
      51          36 :     return Smi::kZero;
      52             :   }
      53             :   DCHECK_GT(max, 0);
      54             : 
      55             :   // Kahan summation to avoid rounding errors.
      56             :   // Normalize the numbers to the largest one to avoid overflow.
      57             :   double sum = 0;
      58             :   double compensation = 0;
      59       15327 :   for (int i = 0; i < length; i++) {
      60       15192 :     double n = abs_values[i] / max;
      61        7596 :     double summand = n * n - compensation;
      62        7596 :     double preliminary = sum + summand;
      63        7596 :     compensation = (preliminary - sum) - summand;
      64             :     sum = preliminary;
      65             :   }
      66             : 
      67         270 :   return *isolate->factory()->NewNumber(std::sqrt(sum) * max);
      68             : }
      69             : 
      70             : }  // namespace internal
      71      121996 : }  // namespace v8

Generated by: LCOV version 1.10