From caf6856ade79330394c0510ffe42300f95198218 Mon Sep 17 00:00:00 2001 From: "floitschV8@gmail.com" Date: Thu, 7 Oct 2010 08:54:10 +0000 Subject: [PATCH] Move gay_strtod outside conversions.cc. This is the first part of removing calls to gay's strtod. Future CLs will get rid of calls to gay_strtod entirely. BUG= TEST= Review URL: http://codereview.chromium.org/3563009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5600 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/SConscript | 1 + src/conversions.cc | 74 +++++++++++----------------------------------- src/strtod.cc | 48 ++++++++++++++++++++++++++++++ src/strtod.h | 40 +++++++++++++++++++++++++ tools/gyp/v8.gyp | 2 ++ 5 files changed, 108 insertions(+), 57 deletions(-) create mode 100644 src/strtod.cc create mode 100644 src/strtod.h diff --git a/src/SConscript b/src/SConscript index 7883bf73f..2befcfaac 100755 --- a/src/SConscript +++ b/src/SConscript @@ -102,6 +102,7 @@ SOURCES = { spaces.cc string-search.cc string-stream.cc + strtod.cc stub-cache.cc token.cc top.cc diff --git a/src/conversions.cc b/src/conversions.cc index 0e5d48b0a..d41806405 100644 --- a/src/conversions.cc +++ b/src/conversions.cc @@ -34,6 +34,7 @@ #include "dtoa.h" #include "factory.h" #include "scanner.h" +#include "strtod.h" namespace v8 { namespace internal { @@ -103,8 +104,6 @@ static bool SubStringEquals(Iterator* current, } -extern "C" double gay_strtod(const char* s00, const char** se); - // Maximum number of significant digits in decimal representation. // The longest possible double in decimal representation is // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 @@ -353,8 +352,9 @@ static double InternalStringToInt(Iterator current, EndMark end, int radix) { } ASSERT(buffer_pos < kBufferSize); - buffer[buffer_pos++] = '\0'; - return sign ? -gay_strtod(buffer, NULL) : gay_strtod(buffer, NULL); + buffer[buffer_pos] = '\0'; + Vector buffer_vector(buffer, buffer_pos); + return sign ? -strtod(buffer_vector, NULL) : strtod(buffer_vector, NULL); } // The following code causes accumulating rounding error for numbers greater @@ -462,7 +462,6 @@ static double InternalStringToDouble(Iterator current, ++current; if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; } else if (*current == '-') { - buffer[buffer_pos++] = '-'; ++current; if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE; sign = true; @@ -478,8 +477,8 @@ static double InternalStringToDouble(Iterator current, return JUNK_STRING_VALUE; } - ASSERT(buffer_pos == 0 || buffer[0] == '-'); - return buffer_pos > 0 ? -V8_INFINITY : V8_INFINITY; + ASSERT(buffer_pos == 0); + return sign ? -V8_INFINITY : V8_INFINITY; } bool leading_zero = false; @@ -496,7 +495,6 @@ static double InternalStringToDouble(Iterator current, return JUNK_STRING_VALUE; // "0x". } - bool sign = (buffer_pos > 0 && buffer[0] == '-'); return InternalStringToIntDouble<4>(current, end, sign, @@ -533,6 +531,9 @@ static double InternalStringToDouble(Iterator current, } if (*current == '.') { + if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE; + if (octal) goto parsing_done; + ++current; if (current == end) { if (significant_digits == 0 && !leading_zero) { @@ -553,16 +554,16 @@ static double InternalStringToDouble(Iterator current, } } - ASSERT(buffer_pos < kBufferSize); - buffer[buffer_pos++] = '.'; + // We don't emit a '.', but adjust the exponent instead. fractional_part = true; - // There is the fractional part. + // There is a fractional part. while (*current >= '0' && *current <= '9') { if (significant_digits < kMaxSignificantDigits) { ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos++] = static_cast(*current); significant_digits++; + exponent--; } else { // Ignore insignificant digits in the fractional part. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; @@ -638,66 +639,25 @@ static double InternalStringToDouble(Iterator current, exponent += insignificant_digits; if (octal) { - bool sign = buffer[0] == '-'; - int start_pos = (sign ? 1 : 0); - - return InternalStringToIntDouble<3>(buffer + start_pos, + return InternalStringToIntDouble<3>(buffer, buffer + buffer_pos, sign, allow_trailing_junk); } if (nonzero_digit_dropped) { - if (insignificant_digits) buffer[buffer_pos++] = '.'; buffer[buffer_pos++] = '1'; - } - - // If the number has no more than kMaxDigitsInInt digits and doesn't have - // fractional part it could be parsed faster (without checks for - // spaces, overflow, etc.). - const int kMaxDigitsInInt = 9 * sizeof(int) / 4; // NOLINT - - if (exponent != 0) { - ASSERT(buffer_pos < kBufferSize); - buffer[buffer_pos++] = 'e'; - if (exponent < 0) { - ASSERT(buffer_pos < kBufferSize); - buffer[buffer_pos++] = '-'; - exponent = -exponent; - } - - // The minimal/maximal double is +/-1.7e-308. Given that - // the buffer contains at most 773 (kMaxSignificantDigits + 1) the - // minimal possible exponent is hence -(308 + 773)=-1081. - // Since leading zeros are removed the maximal exponent cannot exceed 308. - // If the following test triggers the result will be +/-infinity or +/-0. - if (exponent > 9999) exponent = 9999; - - const int exp_digits = 4; - for (int i = 0; i < exp_digits; i++) { - buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10; - exponent /= 10; - } - ASSERT(exponent == 0); - buffer_pos += exp_digits; - } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) { - if (significant_digits == 0) return SignedZero(sign); - ASSERT(buffer_pos > 0); - int num = 0; - int start_pos = (buffer[0] == '-' ? 1 : 0); - for (int i = start_pos; i < buffer_pos; i++) { - ASSERT(buffer[i] >= '0' && buffer[i] <= '9'); - num = 10 * num + (buffer[i] - '0'); - } - return static_cast(start_pos == 0 ? num : -num); + exponent--; } ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos] = '\0'; - return gay_strtod(buffer, NULL); + double converted = strtod(Vector(buffer, buffer_pos), exponent); + return sign? -converted: converted; } + double StringToDouble(String* str, int flags, double empty_string_val) { StringShape shape(str); if (shape.IsSequentialAscii()) { diff --git a/src/strtod.cc b/src/strtod.cc new file mode 100644 index 000000000..7e748d767 --- /dev/null +++ b/src/strtod.cc @@ -0,0 +1,48 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include + +#include "v8.h" + +#include "strtod.h" +// #include "cached-powers.h" + +namespace v8 { +namespace internal { + +extern "C" double gay_strtod(const char* s00, const char** se); + +double strtod(Vector buffer, int exponent) { + char gay_buffer[1024]; + buffer.start()[buffer.length()] = '\0'; + snprintf(gay_buffer, 1024, "%se%d", buffer.start(), exponent); + return gay_strtod(gay_buffer, NULL); +} + +} } // namespace v8::internal diff --git a/src/strtod.h b/src/strtod.h new file mode 100644 index 000000000..335274782 --- /dev/null +++ b/src/strtod.h @@ -0,0 +1,40 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_STRTOD_H_ +#define V8_STRTOD_H_ + +namespace v8 { +namespace internal { + +// The buffer must only contain digits in the range [0-9]. It must not +// contain a dot or a sign. It must not start with '0', and must not be empty. +double strtod(Vector buffer, int exponent); + +} } // namespace v8::internal + +#endif // V8_STRTOD_H_ \ No newline at end of file diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 436ae23f5..99e37a2f8 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -445,6 +445,8 @@ '../../src/string-search.h', '../../src/string-stream.cc', '../../src/string-stream.h', + '../../src/strtod.cc', + '../../src/strtod.h', '../../src/stub-cache.cc', '../../src/stub-cache.h', '../../src/token.cc', -- 2.34.1