13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_CONVERSIONS_INL_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_CONVERSIONS_INL_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <limits.h> // Required for INT_MAX etc. 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <math.h> 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <float.h> // Required for DBL_MAX and on Win32 for finite() 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdarg.h> 35589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "globals.h" // Required for V8_INFINITY 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Extra POSIX/ANSI functions for Win32/MSVC. 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "conversions.h" 41589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "double.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h" 43589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "scanner.h" 44589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "strtod.h" 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline double JunkStringValue() { 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return BitCast<double, uint64_t>(kQuietNaNMask); 513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// The fast double-to-unsigned-int conversion routine does not guarantee 556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// rounding towards zero, or any reasonable value if the argument is larger 566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// than what fits in an unsigned 32-bit integer. 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline unsigned int FastD2UI(double x) { 586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // There is no unsigned version of lrint, so there is no fast path 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // in this function as there is in FastD2I. Using lrint doesn't work 606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // for values of 2^31 and above. 616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Convert "small enough" doubles to uint32_t by fixing the 32 636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // least significant non-fractional bits in the low 32 bits of the 646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // double, and reading them from there. 656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const double k2Pow52 = 4503599627370496.0; 666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool negative = x < 0; 676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (negative) { 686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block x = -x; 696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (x < k2Pow52) { 716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block x += k2Pow52; 726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block uint32_t result; 736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Address mantissa_ptr = reinterpret_cast<Address>(&x); 746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Copy least significant 32 bits of mantissa. 756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block memcpy(&result, mantissa_ptr, sizeof(result)); 766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return negative ? ~result + 1 : result; 776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Large number (outside uint32 range), Infinity or NaN. 796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return 0x80000000u; // Return integer indefinite. 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline double DoubleToInteger(double x) { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (isnan(x)) return 0; 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!isfinite(x) || x == 0) return x; 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (x >= 0) ? floor(x) : ceil(x); 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint32_t DoubleToInt32(double x) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t i = FastD2I(x); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FastI2D(i) == x) return i; 93589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Double d(x); 94589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch int exponent = d.Exponent(); 95589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (exponent < 0) { 96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (exponent <= -Double::kSignificandSize) return 0; 97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return d.Sign() * static_cast<int32_t>(d.Significand() >> -exponent); 98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } else { 99589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (exponent > 31) return 0; 100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return d.Sign() * static_cast<int32_t>(d.Significand() << exponent); 101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <class Iterator, class EndMark> 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool SubStringEquals(Iterator* current, 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EndMark end, 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* substring) { 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(**current == *substring); 1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (substring++; *substring != '\0'; substring++) { 1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++*current; 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == end || **current != *substring) return false; 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++*current; 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Returns true if a nonspace character has been found and false if the 1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// end was been reached before finding a nonspace character. 1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <class Iterator, class EndMark> 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline bool AdvanceToNonspace(UnicodeCache* unicode_cache, 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Iterator* current, 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EndMark end) { 1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current != end) { 1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!unicode_cache->IsWhiteSpace(**current)) return true; 1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++*current; 1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 1303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <int radix_log_2, class Iterator, class EndMark> 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochdouble InternalStringToIntDouble(UnicodeCache* unicode_cache, 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Iterator current, 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EndMark end, 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool negative, 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool allow_trailing_junk) { 1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(current != end); 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Skip leading 0s. 1433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current == '0') { 1443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 1453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int64_t number = 0; 1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int exponent = 0; 1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int radix = (1 << radix_log_2); 1513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 1533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int digit; 1543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current >= '0' && *current <= '9' && *current < '0' + radix) { 1553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch digit = static_cast<char>(*current) - '0'; 1563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) { 1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch digit = static_cast<char>(*current) - 'a' + 10; 1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) { 1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch digit = static_cast<char>(*current) - 'A' + 10; 1603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 1613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (allow_trailing_junk || 1623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch !AdvanceToNonspace(unicode_cache, ¤t, end)) { 1633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 1643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 1653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number = number * radix + digit; 1703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int overflow = static_cast<int>(number >> 53); 1713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (overflow != 0) { 1723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Overflow occurred. Need to determine which direction to round the 1733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // result. 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int overflow_bits_count = 1; 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (overflow > 1) { 1763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch overflow_bits_count++; 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch overflow >>= 1; 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int dropped_bits_mask = ((1 << overflow_bits_count) - 1); 1813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int dropped_bits = static_cast<int>(number) & dropped_bits_mask; 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number >>= overflow_bits_count; 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent = overflow_bits_count; 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool zero_tail = true; 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (true) { 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end || !isDigit(*current, radix)) break; 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch zero_tail = zero_tail && *current == '0'; 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent += radix_log_2; 1913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!allow_trailing_junk && 1943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceToNonspace(unicode_cache, ¤t, end)) { 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 1963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int middle_value = (1 << (overflow_bits_count - 1)); 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (dropped_bits > middle_value) { 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number++; // Rounding up. 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (dropped_bits == middle_value) { 2023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Rounding to even to consistency with decimals: half-way case rounds 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // up if significant part is odd and down otherwise. 2043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if ((number & 1) != 0 || !zero_tail) { 2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number++; // Rounding up. 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Rounding up may cause overflow. 2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if ((number & ((int64_t)1 << 53)) != 0) { 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent++; 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number >>= 1; 2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (current != end); 2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(number < ((int64_t)1 << 53)); 2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); 2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (exponent == 0) { 2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (negative) { 2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (number == 0) return -0.0; 2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch number = -number; 2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<double>(number); 2283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(number != 0); 2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The double could be constructed faster from number (mantissa), exponent 2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // and sign. Assuming it's a rare case more simple code is used. 2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return static_cast<double>(negative ? -number : number) * pow(2.0, exponent); 2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <class Iterator, class EndMark> 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochdouble InternalStringToInt(UnicodeCache* unicode_cache, 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Iterator current, 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EndMark end, 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int radix) { 2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const bool allow_trailing_junk = true; 2433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const double empty_string_val = JunkStringValue(); 2443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 2463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return empty_string_val; 2473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool negative = false; 2503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool leading_zero = false; 2513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '+') { 2533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Ignore leading sign; skip following spaces. 2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 2563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 2573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (*current == '-') { 2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 2613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch negative = true; 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (radix == 0) { 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Radix detection. 2683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '0') { 2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == 'x' || *current == 'X') { 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch radix = 16; 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return JunkStringValue(); 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch radix = 8; 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch leading_zero = true; 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch radix = 10; 2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (radix == 16) { 2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '0') { 2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allow "0x" prefix. 2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == 'x' || *current == 'X') { 2883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 2893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return JunkStringValue(); 2903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 2913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch leading_zero = true; 2923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (radix < 2 || radix > 36) return JunkStringValue(); 2973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Skip leading zeros. 2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current == '0') { 3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch leading_zero = true; 3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 3023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 3033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!leading_zero && !isDigit(*current, radix)) { 3063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 3073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IsPowerOf2(radix)) { 3103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (radix) { 3113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 2: 3123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<1>( 3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unicode_cache, current, end, negative, allow_trailing_junk); 3143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 4: 3153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<2>( 3163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unicode_cache, current, end, negative, allow_trailing_junk); 3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 8: 3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<3>( 3193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unicode_cache, current, end, negative, allow_trailing_junk); 3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 16: 3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<4>( 3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unicode_cache, current, end, negative, allow_trailing_junk); 3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch case 32: 3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<5>( 3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unicode_cache, current, end, negative, allow_trailing_junk); 3283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch default: 3293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch UNREACHABLE(); 3303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (radix == 10) { 3343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Parsing with strtod. 3353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308. 3363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero 3373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // end. 3383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kBufferSize = kMaxSignificantDigits + 2; 3393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char buffer[kBufferSize]; 3403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int buffer_pos = 0; 3413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current >= '0' && *current <= '9') { 3423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (buffer_pos <= kMaxSignificantDigits) { 3433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the number has more than kMaxSignificantDigits it will be parsed 3443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // as infinity. 3453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos < kBufferSize); 3463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos++] = static_cast<char>(*current); 3473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) break; 3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!allow_trailing_junk && 3533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceToNonspace(unicode_cache, ¤t, end)) { 3543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 3553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos < kBufferSize); 3583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos] = '\0'; 3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Vector<const char> buffer_vector(buffer, buffer_pos); 3603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0); 3613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The following code causes accumulating rounding error for numbers greater 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10, 3653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 16, or 32, then mathInt may be an implementation-dependent approximation to 3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the mathematical integer value" (15.1.2.2). 3673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int lim_0 = '0' + (radix < 10 ? radix : 10); 3693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int lim_a = 'a' + (radix - 10); 3703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int lim_A = 'A' + (radix - 10); 3713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // NOTE: The code for computing the value may seem a bit complex at 3733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // first glance. It is structured to use 32-bit multiply-and-add 3743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // loops as long as possible to avoid loosing precision. 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch double v = 0.0; 3773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool done = false; 3783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 3793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Parse the longest part of the string starting at index j 3803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // possible while keeping the multiplier, and thus the part 3813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // itself, within 32 bits. 3823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned int part = 0, multiplier = 1; 3833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (true) { 3843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int d; 3853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current >= '0' && *current < lim_0) { 3863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch d = *current - '0'; 3873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (*current >= 'a' && *current < lim_a) { 3883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch d = *current - 'a' + 10; 3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (*current >= 'A' && *current < lim_A) { 3903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch d = *current - 'A' + 10; 3913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch done = true; 3933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Update the value of the part as long as the multiplier fits 3973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in 32 bits. When we can't guarantee that the next iteration 3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // will not overflow the multiplier, we stop parsing the part 3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // by leaving the loop. 4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const unsigned int kMaximumMultiplier = 0xffffffffU / 36; 4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t m = multiplier * radix; 4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (m > kMaximumMultiplier) break; 4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch part = part * radix + d; 4043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch multiplier = m; 4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(multiplier > part); 4063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 4083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 4093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch done = true; 4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break; 4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Update the value and skip the part in the string. 4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v = v * multiplier + part; 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (!done); 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!allow_trailing_junk && 4193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceToNonspace(unicode_cache, ¤t, end)) { 4203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 4213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return negative ? -v : v; 4243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 4253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Converts a string to a double value. Assumes the Iterator supports 4283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// the following operations: 4293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 1. current == end (other ops are not allowed), current != end. 4303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 2. *current - gets the current character in the sequence. 4313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 3. ++current (advances the position). 4323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate <class Iterator, class EndMark> 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochdouble InternalStringToDouble(UnicodeCache* unicode_cache, 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Iterator current, 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EndMark end, 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags, 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double empty_string_val) { 4383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // To make sure that iterator dereferencing is valid the following 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // convention is used: 4403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 1. Each '++current' statement is followed by check for equality to 'end'. 4413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 2. If AdvanceToNonspace returned false then current == end. 4423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 3. If 'current' becomes be equal to 'end' the function returns or goes to 4433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 'parsing_done'. 4443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 4. 'current' is not dereferenced after the 'parsing_done' label. 4453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 5. Code before 'parsing_done' may rely on 'current != end'. 4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!AdvanceToNonspace(unicode_cache, ¤t, end)) { 4473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return empty_string_val; 4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0; 4513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The longest form of simplified number is: "-<significant digits>'.1eXXX\0". 4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kBufferSize = kMaxSignificantDigits + 10; 4543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char buffer[kBufferSize]; // NOLINT: size is known at compile time. 4553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int buffer_pos = 0; 4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Exponent will be adjusted if insignificant digits of the integer part 4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // or insignificant leading zeros of the fractional part are dropped. 4593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int exponent = 0; 4603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int significant_digits = 0; 4613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int insignificant_digits = 0; 4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool nonzero_digit_dropped = false; 4633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool negative = false; 4653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '+') { 4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Ignore leading sign. 4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return JunkStringValue(); 4703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (*current == '-') { 4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return JunkStringValue(); 4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch negative = true; 4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const char kInfinitySymbol[] = "Infinity"; 4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == kInfinitySymbol[0]) { 4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!SubStringEquals(¤t, end, kInfinitySymbol)) { 4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!allow_trailing_junk && 4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceToNonspace(unicode_cache, ¤t, end)) { 4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos == 0); 4883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return negative ? -V8_INFINITY : V8_INFINITY; 4893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool leading_zero = false; 4923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '0') { 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch leading_zero = true; 4973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // It could be hexadecimal value. 4993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) { 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end || !isDigit(*current, 16)) { 5023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); // "0x". 5033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<4>(unicode_cache, 5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch current, 5073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch end, 5083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch negative, 5093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch allow_trailing_junk); 5103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Ignore leading zeros in the integer part. 5133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current == '0') { 5143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 5163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0; 5203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Copy significant digits of the integer part (if any) to the buffer. 5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current >= '0' && *current <= '9') { 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (significant_digits < kMaxSignificantDigits) { 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos < kBufferSize); 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos++] = static_cast<char>(*current); 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch significant_digits++; 5273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Will later check if it's an octal in the buffer. 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch insignificant_digits++; // Move the digit into the exponential part. 5303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 5313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch octal = octal && *current < '8'; 5333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) goto parsing_done; 5353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (significant_digits == 0) { 5383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch octal = false; 5393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '.') { 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (octal && !allow_trailing_junk) return JunkStringValue(); 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (octal) goto parsing_done; 5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 5473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (significant_digits == 0 && !leading_zero) { 5483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 5493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch goto parsing_done; 5513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (significant_digits == 0) { 5553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // octal = false; 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Integer part consists of 0 or is absent. Significant digits start after 5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // leading zeros (if any). 5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current == '0') { 5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) return SignedZero(negative); 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent--; // Move this 0 into the exponent. 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // There is a fractional part. We don't emit a '.', but adjust the exponent 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // instead. 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch while (*current >= '0' && *current <= '9') { 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (significant_digits < kMaxSignificantDigits) { 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos < kBufferSize); 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos++] = static_cast<char>(*current); 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch significant_digits++; 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent--; 5733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Ignore insignificant digits in the fractional part. 5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 5763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) goto parsing_done; 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!leading_zero && exponent == 0 && significant_digits == 0) { 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If leading_zeros is true then the string contains zeros. 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If exponent < 0 then string was [+-]\.0*... 5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If significant_digits != 0 the string is not equal to 0. 5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Otherwise there are no digits in the string. 5873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Parse exponential part. 5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == 'e' || *current == 'E') { 5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (octal) return JunkStringValue(); 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (allow_trailing_junk) { 5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch goto parsing_done; 5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char sign = '+'; 6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (*current == '+' || *current == '-') { 6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch sign = static_cast<char>(*current); 6043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end) { 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (allow_trailing_junk) { 6073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch goto parsing_done; 6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (current == end || *current < '0' || *current > '9') { 6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (allow_trailing_junk) { 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch goto parsing_done; 6173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 6193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int max_exponent = INT_MAX / 2; 6233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); 6243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int num = 0; 6253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch do { 6263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check overflow. 6273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int digit = *current - '0'; 6283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (num >= max_exponent / 10 6293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { 6303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch num = max_exponent; 6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch num = num * 10 + digit; 6333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++current; 6353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } while (current != end && *current >= '0' && *current <= '9'); 6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent += (sign == '-' ? -num : num); 6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!allow_trailing_junk && 6413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AdvanceToNonspace(unicode_cache, ¤t, end)) { 6423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return JunkStringValue(); 6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch parsing_done: 6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent += insignificant_digits; 6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (octal) { 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToIntDouble<3>(unicode_cache, 6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer, 6513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer + buffer_pos, 6523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch negative, 6533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch allow_trailing_junk); 6543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (nonzero_digit_dropped) { 6573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos++] = '1'; 6583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch exponent--; 6593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(buffer_pos < kBufferSize); 6623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch buffer[buffer_pos] = '\0'; 6633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent); 6653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return negative ? -converted : converted; 6663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_CONVERSIONS_INL_H_ 671