LCOV - code coverage report
Current view: top level - src - conversions-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 254 264 96.2 %
Date: 2017-04-26 Functions: 20 26 76.9 %

          Line data    Source code
       1             : // Copyright 2011 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             : #ifndef V8_CONVERSIONS_INL_H_
       6             : #define V8_CONVERSIONS_INL_H_
       7             : 
       8             : #include <float.h>         // Required for DBL_MAX and on Win32 for finite()
       9             : #include <limits.h>        // Required for INT_MAX etc.
      10             : #include <stdarg.h>
      11             : #include <cmath>
      12             : #include "src/globals.h"       // Required for V8_INFINITY
      13             : #include "src/unicode-cache-inl.h"
      14             : 
      15             : // ----------------------------------------------------------------------------
      16             : // Extra POSIX/ANSI functions for Win32/MSVC.
      17             : 
      18             : #include "src/base/bits.h"
      19             : #include "src/base/platform/platform.h"
      20             : #include "src/conversions.h"
      21             : #include "src/double.h"
      22             : #include "src/objects-inl.h"
      23             : #include "src/strtod.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : 
      28             : inline double JunkStringValue() {
      29             :   return bit_cast<double, uint64_t>(kQuietNaNMask);
      30             : }
      31             : 
      32             : 
      33             : inline double SignedZero(bool negative) {
      34      697773 :   return negative ? uint64_to_double(Double::kSignMask) : 0.0;
      35             : }
      36             : 
      37             : 
      38             : // The fast double-to-unsigned-int conversion routine does not guarantee
      39             : // rounding towards zero, or any reasonable value if the argument is larger
      40             : // than what fits in an unsigned 32-bit integer.
      41             : inline unsigned int FastD2UI(double x) {
      42             :   // There is no unsigned version of lrint, so there is no fast path
      43             :   // in this function as there is in FastD2I. Using lrint doesn't work
      44             :   // for values of 2^31 and above.
      45             : 
      46             :   // Convert "small enough" doubles to uint32_t by fixing the 32
      47             :   // least significant non-fractional bits in the low 32 bits of the
      48             :   // double, and reading them from there.
      49             :   const double k2Pow52 = 4503599627370496.0;
      50     1694652 :   bool negative = x < 0;
      51     1694652 :   if (negative) {
      52           0 :     x = -x;
      53             :   }
      54     1694652 :   if (x < k2Pow52) {
      55     1694652 :     x += k2Pow52;
      56             :     uint32_t result;
      57             : #ifndef V8_TARGET_BIG_ENDIAN
      58             :     Address mantissa_ptr = reinterpret_cast<Address>(&x);
      59             : #else
      60             :     Address mantissa_ptr = reinterpret_cast<Address>(&x) + kInt32Size;
      61             : #endif
      62             :     // Copy least significant 32 bits of mantissa.
      63             :     memcpy(&result, mantissa_ptr, sizeof(result));
      64     1694652 :     return negative ? ~result + 1 : result;
      65             :   }
      66             :   // Large number (outside uint32 range), Infinity or NaN.
      67             :   return 0x80000000u;  // Return integer indefinite.
      68             : }
      69             : 
      70             : 
      71             : inline float DoubleToFloat32(double x) {
      72             :   // TODO(yangguo): This static_cast is implementation-defined behaviour in C++,
      73             :   // so we may need to do the conversion manually instead to match the spec.
      74        2469 :   volatile float f = static_cast<float>(x);
      75        2469 :   return f;
      76             : }
      77             : 
      78             : 
      79      655638 : inline double DoubleToInteger(double x) {
      80      655638 :   if (std::isnan(x)) return 0;
      81      647205 :   if (!std::isfinite(x) || x == 0) return x;
      82      345526 :   return (x >= 0) ? std::floor(x) : std::ceil(x);
      83             : }
      84             : 
      85             : 
      86    23556933 : int32_t DoubleToInt32(double x) {
      87             :   int32_t i = FastD2I(x);
      88    23556933 :   if (FastI2D(i) == x) return i;
      89             :   Double d(x);
      90             :   int exponent = d.Exponent();
      91     2545618 :   if (exponent < 0) {
      92      410688 :     if (exponent <= -Double::kSignificandSize) return 0;
      93      380887 :     return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent);
      94             :   } else {
      95     2134930 :     if (exponent > 31) return 0;
      96        3627 :     return d.Sign() * static_cast<int32_t>(d.Significand() << exponent);
      97             :   }
      98             : }
      99             : 
     100             : bool DoubleToSmiInteger(double value, int* smi_int_value) {
     101    60661073 :   if (IsMinusZero(value)) return false;
     102             :   int i = FastD2IChecked(value);
     103    60323026 :   if (value != i || !Smi::IsValid(i)) return false;
     104             :   *smi_int_value = i;
     105             :   return true;
     106             : }
     107             : 
     108             : bool IsSmiDouble(double value) {
     109     2837653 :   return !IsMinusZero(value) && value >= Smi::kMinValue &&
     110     5651053 :          value <= Smi::kMaxValue && value == FastI2D(FastD2I(value));
     111             : }
     112             : 
     113             : 
     114             : bool IsInt32Double(double value) {
     115     1355471 :   return !IsMinusZero(value) && value >= kMinInt && value <= kMaxInt &&
     116             :          value == FastI2D(FastD2I(value));
     117             : }
     118             : 
     119             : 
     120     1744099 : bool IsUint32Double(double value) {
     121     3438589 :   return !IsMinusZero(value) && value >= 0 && value <= kMaxUInt32 &&
     122     1744099 :          value == FastUI2D(FastD2UI(value));
     123             : }
     124             : 
     125             : bool DoubleToUint32IfEqualToSelf(double value, uint32_t* uint32_value) {
     126             :   const double k2Pow52 = 4503599627370496.0;
     127             :   const uint32_t kValidTopBits = 0x43300000;
     128             :   const uint64_t kBottomBitMask = V8_2PART_UINT64_C(0x00000000, FFFFFFFF);
     129             : 
     130             :   // Add 2^52 to the double, to place valid uint32 values in the low-significant
     131             :   // bits of the exponent, by effectively setting the (implicit) top bit of the
     132             :   // significand. Note that this addition also normalises 0.0 and -0.0.
     133       87813 :   double shifted_value = value + k2Pow52;
     134             : 
     135             :   // At this point, a valid uint32 valued double will be represented as:
     136             :   //
     137             :   // sign = 0
     138             :   // exponent = 52
     139             :   // significand = 1. 00...00 <value>
     140             :   //       implicit^          ^^^^^^^ 32 bits
     141             :   //                  ^^^^^^^^^^^^^^^ 52 bits
     142             :   //
     143             :   // Therefore, we can first check the top 32 bits to make sure that the sign,
     144             :   // exponent and remaining significand bits are valid, and only then check the
     145             :   // value in the bottom 32 bits.
     146             : 
     147             :   uint64_t result = bit_cast<uint64_t>(shifted_value);
     148       87813 :   if ((result >> 32) == kValidTopBits) {
     149       86308 :     *uint32_value = result & kBottomBitMask;
     150       86308 :     return FastUI2D(result & kBottomBitMask) == value;
     151             :   }
     152             :   return false;
     153             : }
     154             : 
     155     9258705 : int32_t NumberToInt32(Object* number) {
     156    18502271 :   if (number->IsSmi()) return Smi::cast(number)->value();
     157       15139 :   return DoubleToInt32(number->Number());
     158             : }
     159             : 
     160    13938039 : uint32_t NumberToUint32(Object* number) {
     161    27846773 :   if (number->IsSmi()) return Smi::cast(number)->value();
     162       29305 :   return DoubleToUint32(number->Number());
     163             : }
     164             : 
     165       10942 : uint32_t PositiveNumberToUint32(Object* number) {
     166       10942 :   if (number->IsSmi()) {
     167             :     int value = Smi::cast(number)->value();
     168        9857 :     if (value <= 0) return 0;
     169        3006 :     return value;
     170             :   }
     171             :   DCHECK(number->IsHeapNumber());
     172             :   double value = number->Number();
     173             :   // Catch all values smaller than 1 and use the double-negation trick for NANs.
     174        1085 :   if (!(value >= 1)) return 0;
     175             :   uint32_t max = std::numeric_limits<uint32_t>::max();
     176         395 :   if (value < max) return static_cast<uint32_t>(value);
     177             :   return max;
     178             : }
     179             : 
     180             : int64_t NumberToInt64(Object* number) {
     181       12270 :   if (number->IsSmi()) return Smi::cast(number)->value();
     182         588 :   return static_cast<int64_t>(number->Number());
     183             : }
     184             : 
     185    18923226 : bool TryNumberToSize(Object* number, size_t* result) {
     186             :   // Do not create handles in this function! Don't use SealHandleScope because
     187             :   // the function can be used concurrently.
     188    56631355 :   if (number->IsSmi()) {
     189             :     int value = Smi::cast(number)->value();
     190             :     DCHECK(static_cast<unsigned>(Smi::kMaxValue) <=
     191             :            std::numeric_limits<size_t>::max());
     192    56614352 :     if (value >= 0) {
     193    56614352 :       *result = static_cast<size_t>(value);
     194    18923226 :       return true;
     195             :     }
     196             :     return false;
     197             :   } else {
     198             :     DCHECK(number->IsHeapNumber());
     199             :     double value = HeapNumber::cast(number)->value();
     200             :     // If value is compared directly to the limit, the limit will be
     201             :     // casted to a double and could end up as limit + 1,
     202             :     // because a double might not have enough mantissa bits for it.
     203             :     // So we might as well cast the limit first, and use < instead of <=.
     204             :     double maxSize = static_cast<double>(std::numeric_limits<size_t>::max());
     205       17003 :     if (value >= 0 && value < maxSize) {
     206       17003 :       *result = static_cast<size_t>(value);
     207           0 :       return true;
     208             :     } else {
     209             :       return false;
     210             :     }
     211             :   }
     212             : }
     213             : 
     214    37572950 : size_t NumberToSize(Object* number) {
     215             :   size_t result = 0;
     216             :   bool is_valid = TryNumberToSize(number, &result);
     217    37572950 :   CHECK(is_valid);
     218    37572950 :   return result;
     219             : }
     220             : 
     221             : 
     222             : uint32_t DoubleToUint32(double x) {
     223    17006275 :   return static_cast<uint32_t>(DoubleToInt32(x));
     224             : }
     225             : 
     226             : 
     227             : template <class Iterator, class EndMark>
     228             : bool SubStringEquals(Iterator* current,
     229             :                      EndMark end,
     230             :                      const char* substring) {
     231             :   DCHECK(**current == *substring);
     232      105700 :   for (substring++; *substring != '\0'; substring++) {
     233      105771 :     ++*current;
     234      105771 :     if (*current == end || **current != *substring) return false;
     235             :   }
     236       15088 :   ++*current;
     237             :   return true;
     238             : }
     239             : 
     240             : 
     241             : // Returns true if a nonspace character has been found and false if the
     242             : // end was been reached before finding a nonspace character.
     243             : template <class Iterator, class EndMark>
     244     8324620 : inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
     245             :                               Iterator* current,
     246             :                               EndMark end) {
     247    16656587 :   while (*current != end) {
     248    16596546 :     if (!unicode_cache->IsWhiteSpaceOrLineTerminator(**current)) return true;
     249        7347 :     ++*current;
     250             :   }
     251             :   return false;
     252             : }
     253             : 
     254             : 
     255             : // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
     256             : template <int radix_log_2, class Iterator, class EndMark>
     257      547160 : double InternalStringToIntDouble(UnicodeCache* unicode_cache,
     258             :                                  Iterator current,
     259             :                                  EndMark end,
     260             :                                  bool negative,
     261             :                                  bool allow_trailing_junk) {
     262             :   DCHECK(current != end);
     263             : 
     264             :   // Skip leading 0s.
     265     1152324 :   while (*current == '0') {
     266       65842 :     ++current;
     267       73680 :     if (current == end) return SignedZero(negative);
     268             :   }
     269             : 
     270             :   int64_t number = 0;
     271             :   int exponent = 0;
     272             :   const int radix = (1 << radix_log_2);
     273             : 
     274     2189912 :   do {
     275             :     int digit;
     276     2190598 :     if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
     277     1561496 :       digit = static_cast<char>(*current) - '0';
     278      629074 :     } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
     279      585370 :       digit = static_cast<char>(*current) - 'a' + 10;
     280       43704 :     } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
     281       43604 :       digit = static_cast<char>(*current) - 'A' + 10;
     282             :     } else {
     283         173 :       if (allow_trailing_junk ||
     284          45 :           !AdvanceToNonspace(unicode_cache, &current, end)) {
     285             :         break;
     286             :       } else {
     287             :         return JunkStringValue();
     288             :       }
     289             :     }
     290             : 
     291     2190470 :     number = number * radix + digit;
     292     2190470 :     int overflow = static_cast<int>(number >> 53);
     293     2190470 :     if (overflow != 0) {
     294             :       // Overflow occurred. Need to determine which direction to round the
     295             :       // result.
     296             :       int overflow_bits_count = 1;
     297        2109 :       while (overflow > 1) {
     298        1551 :         overflow_bits_count++;
     299        1551 :         overflow >>= 1;
     300             :       }
     301             : 
     302         558 :       int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
     303         558 :       int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
     304         558 :       number >>= overflow_bits_count;
     305             :       exponent = overflow_bits_count;
     306             : 
     307             :       bool zero_tail = true;
     308             :       while (true) {
     309       33273 :         ++current;
     310       33273 :         if (current == end || !isDigit(*current, radix)) break;
     311       32715 :         zero_tail = zero_tail && *current == '0';
     312       32715 :         exponent += radix_log_2;
     313             :       }
     314             : 
     315        1045 :       if (!allow_trailing_junk &&
     316         487 :           AdvanceToNonspace(unicode_cache, &current, end)) {
     317             :         return JunkStringValue();
     318             :       }
     319             : 
     320         558 :       int middle_value = (1 << (overflow_bits_count - 1));
     321         558 :       if (dropped_bits > middle_value) {
     322          46 :         number++;  // Rounding up.
     323         512 :       } else if (dropped_bits == middle_value) {
     324             :         // Rounding to even to consistency with decimals: half-way case rounds
     325             :         // up if significant part is odd and down otherwise.
     326         223 :         if ((number & 1) != 0 || !zero_tail) {
     327         163 :           number++;  // Rounding up.
     328             :         }
     329             :       }
     330             : 
     331             :       // Rounding up may cause overflow.
     332         558 :       if ((number & (static_cast<int64_t>(1) << 53)) != 0) {
     333          16 :         exponent++;
     334          16 :         number >>= 1;
     335             :       }
     336       32715 :       break;
     337             :     }
     338     2189912 :     ++current;
     339             :   } while (current != end);
     340             : 
     341             :   DCHECK(number < ((int64_t)1 << 53));
     342             :   DCHECK(static_cast<int64_t>(static_cast<double>(number)) == number);
     343             : 
     344      539307 :   if (exponent == 0) {
     345      538749 :     if (negative) {
     346          14 :       if (number == 0) return -0.0;
     347          14 :       number = -number;
     348             :     }
     349      538749 :     return static_cast<double>(number);
     350             :   }
     351             : 
     352             :   DCHECK(number != 0);
     353         558 :   return std::ldexp(static_cast<double>(negative ? -number : number), exponent);
     354             : }
     355             : 
     356             : // ES6 18.2.5 parseInt(string, radix)
     357             : template <class Iterator, class EndMark>
     358     2104377 : double InternalStringToInt(UnicodeCache* unicode_cache,
     359             :                            Iterator current,
     360             :                            EndMark end,
     361             :                            int radix) {
     362             :   const bool allow_trailing_junk = true;
     363             :   const double empty_string_val = JunkStringValue();
     364             : 
     365     2104377 :   if (!AdvanceToNonspace(unicode_cache, &current, end)) {
     366             :     return empty_string_val;
     367             :   }
     368             : 
     369             :   bool negative = false;
     370             :   bool leading_zero = false;
     371             : 
     372     2104349 :   if (*current == '+') {
     373             :     // Ignore leading sign; skip following spaces.
     374         103 :     ++current;
     375         103 :     if (current == end) {
     376             :       return JunkStringValue();
     377             :     }
     378     2104246 :   } else if (*current == '-') {
     379       91098 :     ++current;
     380       91098 :     if (current == end) {
     381             :       return JunkStringValue();
     382             :     }
     383             :     negative = true;
     384             :   }
     385             : 
     386     2104335 :   if (radix == 0) {
     387             :     // Radix detection.
     388             :     radix = 10;
     389     2103755 :     if (*current == '0') {
     390       27669 :       ++current;
     391       33680 :       if (current == end) return SignedZero(negative);
     392       21658 :       if (*current == 'x' || *current == 'X') {
     393             :         radix = 16;
     394       21513 :         ++current;
     395       21513 :         if (current == end) return JunkStringValue();
     396             :       } else {
     397             :         leading_zero = true;
     398             :       }
     399             :     }
     400         580 :   } else if (radix == 16) {
     401         279 :     if (*current == '0') {
     402             :       // Allow "0x" prefix.
     403         223 :       ++current;
     404         223 :       if (current == end) return SignedZero(negative);
     405         223 :       if (*current == 'x' || *current == 'X') {
     406         169 :         ++current;
     407         169 :         if (current == end) return JunkStringValue();
     408             :       } else {
     409             :         leading_zero = true;
     410             :       }
     411             :     }
     412             :   }
     413             : 
     414     2098266 :   if (radix < 2 || radix > 36) return JunkStringValue();
     415             : 
     416             :   // Skip leading zeros.
     417     2098486 :   while (*current == '0') {
     418             :     leading_zero = true;
     419         220 :     ++current;
     420         220 :     if (current == end) return SignedZero(negative);
     421             :   }
     422             : 
     423     2098266 :   if (!leading_zero && !isDigit(*current, radix)) {
     424             :     return JunkStringValue();
     425             :   }
     426             : 
     427      263905 :   if (base::bits::IsPowerOfTwo32(radix)) {
     428       21833 :     switch (radix) {
     429             :       case 2:
     430             :         return InternalStringToIntDouble<1>(
     431          73 :             unicode_cache, current, end, negative, allow_trailing_junk);
     432             :       case 4:
     433             :         return InternalStringToIntDouble<2>(
     434           0 :             unicode_cache, current, end, negative, allow_trailing_junk);
     435             :       case 8:
     436             :         return InternalStringToIntDouble<3>(
     437          56 :             unicode_cache, current, end, negative, allow_trailing_junk);
     438             : 
     439             :       case 16:
     440             :         return InternalStringToIntDouble<4>(
     441       21704 :             unicode_cache, current, end, negative, allow_trailing_junk);
     442             : 
     443             :       case 32:
     444             :         return InternalStringToIntDouble<5>(
     445           0 :             unicode_cache, current, end, negative, allow_trailing_junk);
     446             :       default:
     447           0 :         UNREACHABLE();
     448             :     }
     449             :   }
     450             : 
     451      242072 :   if (radix == 10) {
     452             :     // Parsing with strtod.
     453             :     const int kMaxSignificantDigits = 309;  // Doubles are less than 1.8e308.
     454             :     // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
     455             :     // end.
     456             :     const int kBufferSize = kMaxSignificantDigits + 2;
     457             :     char buffer[kBufferSize];
     458             :     int buffer_pos = 0;
     459     1762347 :     while (*current >= '0' && *current <= '9') {
     460     1760348 :       if (buffer_pos <= kMaxSignificantDigits) {
     461             :         // If the number has more than kMaxSignificantDigits it will be parsed
     462             :         // as infinity.
     463             :         DCHECK(buffer_pos < kBufferSize);
     464     1759289 :         buffer[buffer_pos++] = static_cast<char>(*current);
     465             :       }
     466     1760348 :       ++current;
     467     1760348 :       if (current == end) break;
     468             :     }
     469             : 
     470             :     if (!allow_trailing_junk &&
     471             :         AdvanceToNonspace(unicode_cache, &current, end)) {
     472             :       return JunkStringValue();
     473             :     }
     474             : 
     475             :     SLOW_DCHECK(buffer_pos < kBufferSize);
     476      242027 :     buffer[buffer_pos] = '\0';
     477             :     Vector<const char> buffer_vector(buffer, buffer_pos);
     478      242027 :     return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
     479             :   }
     480             : 
     481             :   // The following code causes accumulating rounding error for numbers greater
     482             :   // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
     483             :   // 16, or 32, then mathInt may be an implementation-dependent approximation to
     484             :   // the mathematical integer value" (15.1.2.2).
     485             : 
     486          45 :   int lim_0 = '0' + (radix < 10 ? radix : 10);
     487          45 :   int lim_a = 'a' + (radix - 10);
     488          45 :   int lim_A = 'A' + (radix - 10);
     489             : 
     490             :   // NOTE: The code for computing the value may seem a bit complex at
     491             :   // first glance. It is structured to use 32-bit multiply-and-add
     492             :   // loops as long as possible to avoid loosing precision.
     493             : 
     494             :   double v = 0.0;
     495             :   bool done = false;
     496          75 :   do {
     497             :     // Parse the longest part of the string starting at index j
     498             :     // possible while keeping the multiplier, and thus the part
     499             :     // itself, within 32 bits.
     500             :     unsigned int part = 0, multiplier = 1;
     501             :     while (true) {
     502             :       int d;
     503         510 :       if (*current >= '0' && *current < lim_0) {
     504         510 :         d = *current - '0';
     505           0 :       } else if (*current >= 'a' && *current < lim_a) {
     506           0 :         d = *current - 'a' + 10;
     507           0 :       } else if (*current >= 'A' && *current < lim_A) {
     508           0 :         d = *current - 'A' + 10;
     509             :       } else {
     510             :         done = true;
     511             :         break;
     512             :       }
     513             : 
     514             :       // Update the value of the part as long as the multiplier fits
     515             :       // in 32 bits. When we can't guarantee that the next iteration
     516             :       // will not overflow the multiplier, we stop parsing the part
     517             :       // by leaving the loop.
     518             :       const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
     519         510 :       uint32_t m = multiplier * radix;
     520         510 :       if (m > kMaximumMultiplier) break;
     521         480 :       part = part * radix + d;
     522             :       multiplier = m;
     523             :       DCHECK(multiplier > part);
     524             : 
     525         480 :       ++current;
     526         480 :       if (current == end) {
     527             :         done = true;
     528             :         break;
     529             :       }
     530             :     }
     531             : 
     532             :     // Update the value and skip the part in the string.
     533          75 :     v = v * multiplier + part;
     534             :   } while (!done);
     535             : 
     536             :   if (!allow_trailing_junk &&
     537             :       AdvanceToNonspace(unicode_cache, &current, end)) {
     538             :     return JunkStringValue();
     539             :   }
     540             : 
     541          45 :   return negative ? -v : v;
     542             : }
     543             : 
     544             : 
     545             : // Converts a string to a double value. Assumes the Iterator supports
     546             : // the following operations:
     547             : // 1. current == end (other ops are not allowed), current != end.
     548             : // 2. *current - gets the current character in the sequence.
     549             : // 3. ++current (advances the position).
     550             : template <class Iterator, class EndMark>
     551     6179209 : double InternalStringToDouble(UnicodeCache* unicode_cache,
     552             :                               Iterator current,
     553             :                               EndMark end,
     554             :                               int flags,
     555             :                               double empty_string_val) {
     556             :   // To make sure that iterator dereferencing is valid the following
     557             :   // convention is used:
     558             :   // 1. Each '++current' statement is followed by check for equality to 'end'.
     559             :   // 2. If AdvanceToNonspace returned false then current == end.
     560             :   // 3. If 'current' becomes be equal to 'end' the function returns or goes to
     561             :   // 'parsing_done'.
     562             :   // 4. 'current' is not dereferenced after the 'parsing_done' label.
     563             :   // 5. Code before 'parsing_done' may rely on 'current != end'.
     564     6179209 :   if (!AdvanceToNonspace(unicode_cache, &current, end)) {
     565             :     return empty_string_val;
     566             :   }
     567             : 
     568     6178536 :   const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
     569             : 
     570             :   // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
     571             :   const int kBufferSize = kMaxSignificantDigits + 10;
     572             :   char buffer[kBufferSize];  // NOLINT: size is known at compile time.
     573             :   int buffer_pos = 0;
     574             : 
     575             :   // Exponent will be adjusted if insignificant digits of the integer part
     576             :   // or insignificant leading zeros of the fractional part are dropped.
     577             :   int exponent = 0;
     578             :   int significant_digits = 0;
     579             :   int insignificant_digits = 0;
     580             :   bool nonzero_digit_dropped = false;
     581             : 
     582             :   enum Sign {
     583             :     NONE,
     584             :     NEGATIVE,
     585             :     POSITIVE
     586             :   };
     587             : 
     588             :   Sign sign = NONE;
     589             : 
     590     6178536 :   if (*current == '+') {
     591             :     // Ignore leading sign.
     592        6019 :     ++current;
     593        6019 :     if (current == end) return JunkStringValue();
     594             :     sign = POSITIVE;
     595     6172517 :   } else if (*current == '-') {
     596       15332 :     ++current;
     597       15332 :     if (current == end) return JunkStringValue();
     598             :     sign = NEGATIVE;
     599             :   }
     600             : 
     601             :   static const char kInfinityString[] = "Infinity";
     602     6178536 :   if (*current == kInfinityString[0]) {
     603       15159 :     if (!SubStringEquals(&current, end, kInfinityString)) {
     604             :       return JunkStringValue();
     605             :     }
     606             : 
     607       30162 :     if (!allow_trailing_junk &&
     608       15074 :         AdvanceToNonspace(unicode_cache, &current, end)) {
     609             :       return JunkStringValue();
     610             :     }
     611             : 
     612             :     DCHECK(buffer_pos == 0);
     613       15073 :     return (sign == NEGATIVE) ? -V8_INFINITY : V8_INFINITY;
     614             :   }
     615             : 
     616             :   bool leading_zero = false;
     617     6163377 :   if (*current == '0') {
     618     2419294 :     ++current;
     619     3051762 :     if (current == end) return SignedZero(sign == NEGATIVE);
     620             : 
     621             :     leading_zero = true;
     622             : 
     623             :     // It could be hexadecimal value.
     624     1786826 :     if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
     625      370209 :       ++current;
     626      370209 :       if (current == end || !isDigit(*current, 16) || sign != NONE) {
     627             :         return JunkStringValue();  // "0x".
     628             :       }
     629             : 
     630             :       return InternalStringToIntDouble<4>(unicode_cache,
     631             :                                           current,
     632             :                                           end,
     633             :                                           false,
     634      370089 :                                           allow_trailing_junk);
     635             : 
     636             :     // It could be an explicit octal value.
     637     1416617 :     } else if ((flags & ALLOW_OCTAL) && (*current == 'o' || *current == 'O')) {
     638         211 :       ++current;
     639         211 :       if (current == end || !isDigit(*current, 8) || sign != NONE) {
     640             :         return JunkStringValue();  // "0o".
     641             :       }
     642             : 
     643             :       return InternalStringToIntDouble<3>(unicode_cache,
     644             :                                           current,
     645             :                                           end,
     646             :                                           false,
     647         211 :                                           allow_trailing_junk);
     648             : 
     649             :     // It could be a binary value.
     650     1416406 :     } else if ((flags & ALLOW_BINARY) && (*current == 'b' || *current == 'B')) {
     651         176 :       ++current;
     652         352 :       if (current == end || !isBinaryDigit(*current) || sign != NONE) {
     653             :         return JunkStringValue();  // "0b".
     654             :       }
     655             : 
     656             :       return InternalStringToIntDouble<1>(unicode_cache,
     657             :                                           current,
     658             :                                           end,
     659             :                                           false,
     660         176 :                                           allow_trailing_junk);
     661             :     }
     662             : 
     663             :     // Ignore leading zeros in the integer part.
     664     1416297 :     while (*current == '0') {
     665       22242 :       ++current;
     666       44417 :       if (current == end) return SignedZero(sign == NEGATIVE);
     667             :     }
     668             :   }
     669             : 
     670     5138138 :   bool octal = leading_zero && (flags & ALLOW_IMPLICIT_OCTAL) != 0;
     671             : 
     672             :   // Copy significant digits of the integer part (if any) to the buffer.
     673    15574598 :   while (*current >= '0' && *current <= '9') {
     674     6477085 :     if (significant_digits < kMaxSignificantDigits) {
     675             :       DCHECK(buffer_pos < kBufferSize);
     676     6473244 :       buffer[buffer_pos++] = static_cast<char>(*current);
     677     6473244 :       significant_digits++;
     678             :       // Will later check if it's an octal in the buffer.
     679             :     } else {
     680        3841 :       insignificant_digits++;  // Move the digit into the exponential part.
     681        3841 :       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
     682             :     }
     683     6477085 :     octal = octal && *current < '8';
     684     6477085 :     ++current;
     685     6477085 :     if (current == end) goto parsing_done;
     686             :   }
     687             : 
     688     3959375 :   if (significant_digits == 0) {
     689             :     octal = false;
     690             :   }
     691             : 
     692     3959375 :   if (*current == '.') {
     693     1436423 :     if (octal && !allow_trailing_junk) return JunkStringValue();
     694     1436409 :     if (octal) goto parsing_done;
     695             : 
     696     1436409 :     ++current;
     697     1436409 :     if (current == end) {
     698         264 :       if (significant_digits == 0 && !leading_zero) {
     699             :         return JunkStringValue();
     700             :       } else {
     701             :         goto parsing_done;
     702             :       }
     703             :     }
     704             : 
     705     1436145 :     if (significant_digits == 0) {
     706             :       // octal = false;
     707             :       // Integer part consists of 0 or is absent. Significant digits start after
     708             :       // leading zeros (if any).
     709     1267956 :       while (*current == '0') {
     710       54193 :         ++current;
     711       83474 :         if (current == end) return SignedZero(sign == NEGATIVE);
     712       24912 :         exponent--;  // Move this 0 into the exponent.
     713             :       }
     714             :     }
     715             : 
     716             :     // There is a fractional part.  We don't emit a '.', but adjust the exponent
     717             :     // instead.
     718     1923771 :     while (*current >= '0' && *current <= '9') {
     719     1915912 :       if (significant_digits < kMaxSignificantDigits) {
     720             :         DCHECK(buffer_pos < kBufferSize);
     721     1913749 :         buffer[buffer_pos++] = static_cast<char>(*current);
     722     1913749 :         significant_digits++;
     723     1913749 :         exponent--;
     724             :       } else {
     725             :         // Ignore insignificant digits in the fractional part.
     726        2163 :         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
     727             :       }
     728     1915912 :       ++current;
     729     1915912 :       if (current == end) goto parsing_done;
     730             :     }
     731             :   }
     732             : 
     733     2530811 :   if (!leading_zero && exponent == 0 && significant_digits == 0) {
     734             :     // If leading_zeros is true then the string contains zeros.
     735             :     // If exponent < 0 then string was [+-]\.0*...
     736             :     // If significant_digits != 0 the string is not equal to 0.
     737             :     // Otherwise there are no digits in the string.
     738             :     return JunkStringValue();
     739             :   }
     740             : 
     741             :   // Parse exponential part.
     742       25727 :   if (*current == 'e' || *current == 'E') {
     743       15576 :     if (octal) return JunkStringValue();
     744       15562 :     ++current;
     745       15562 :     if (current == end) {
     746          22 :       if (allow_trailing_junk) {
     747             :         goto parsing_done;
     748             :       } else {
     749             :         return JunkStringValue();
     750             :       }
     751             :     }
     752             :     char sign = '+';
     753       15540 :     if (*current == '+' || *current == '-') {
     754        7342 :       sign = static_cast<char>(*current);
     755        7342 :       ++current;
     756        7342 :       if (current == end) {
     757           7 :         if (allow_trailing_junk) {
     758             :           goto parsing_done;
     759             :         } else {
     760             :           return JunkStringValue();
     761             :         }
     762             :       }
     763             :     }
     764             : 
     765       15533 :     if (current == end || *current < '0' || *current > '9') {
     766          15 :       if (allow_trailing_junk) {
     767             :         goto parsing_done;
     768             :       } else {
     769             :         return JunkStringValue();
     770             :       }
     771             :     }
     772             : 
     773             :     const int max_exponent = INT_MAX / 2;
     774             :     DCHECK(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
     775             :     int num = 0;
     776       23799 :     do {
     777             :       // Check overflow.
     778       23799 :       int digit = *current - '0';
     779       23799 :       if (num >= max_exponent / 10
     780           0 :           && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
     781             :         num = max_exponent;
     782             :       } else {
     783       23799 :         num = num * 10 + digit;
     784             :       }
     785       23799 :       ++current;
     786             :     } while (current != end && *current >= '0' && *current <= '9');
     787             : 
     788       15518 :     exponent += (sign == '-' ? -num : num);
     789             :   }
     790             : 
     791       51097 :   if (!allow_trailing_junk &&
     792       25428 :       AdvanceToNonspace(unicode_cache, &current, end)) {
     793             :     return JunkStringValue();
     794             :   }
     795             : 
     796             :   parsing_done:
     797     2595704 :   exponent += insignificant_digits;
     798             : 
     799     2595704 :   if (octal) {
     800             :     return InternalStringToIntDouble<3>(unicode_cache,
     801             :                                         buffer,
     802             :                                         buffer + buffer_pos,
     803             :                                         sign == NEGATIVE,
     804      154851 :                                         allow_trailing_junk);
     805             :   }
     806             : 
     807     2440853 :   if (nonzero_digit_dropped) {
     808          21 :     buffer[buffer_pos++] = '1';
     809          21 :     exponent--;
     810             :   }
     811             : 
     812             :   SLOW_DCHECK(buffer_pos < kBufferSize);
     813     2440853 :   buffer[buffer_pos] = '\0';
     814             : 
     815     2440853 :   double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
     816     2440853 :   return (sign == NEGATIVE) ? -converted : converted;
     817             : }
     818             : 
     819             : }  // namespace internal
     820             : }  // namespace v8
     821             : 
     822             : #endif  // V8_CONVERSIONS_INL_H_

Generated by: LCOV version 1.10