Move gay_strtod outside conversions.cc.
authorfloitschV8@gmail.com <floitschV8@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Oct 2010 08:54:10 +0000 (08:54 +0000)
committerfloitschV8@gmail.com <floitschV8@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Oct 2010 08:54:10 +0000 (08:54 +0000)
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
src/conversions.cc
src/strtod.cc [new file with mode: 0644]
src/strtod.h [new file with mode: 0644]
tools/gyp/v8.gyp

index 7883bf73f18e7c29ff9db2343b63ddb22e9c77c8..2befcfaac6d522f8f3ec785fa51dc6b2f629194e 100755 (executable)
@@ -102,6 +102,7 @@ SOURCES = {
     spaces.cc
     string-search.cc
     string-stream.cc
+    strtod.cc
     stub-cache.cc
     token.cc
     top.cc
index 0e5d48b0a4de29aa29925ef667dce6df526de00f..d4180640518279db9a19ab9580f6d15b5800cb80 100644 (file)
@@ -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<char> 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(&current, end)) return JUNK_STRING_VALUE;
   } else if (*current == '-') {
-    buffer[buffer_pos++] = '-';
     ++current;
     if (!AdvanceToNonspace(&current, 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<char>(*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<double>(start_pos == 0 ? num : -num);
+    exponent--;
   }
 
   ASSERT(buffer_pos < kBufferSize);
   buffer[buffer_pos] = '\0';
 
-  return gay_strtod(buffer, NULL);
+  double converted = strtod(Vector<char>(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 (file)
index 0000000..7e748d7
--- /dev/null
@@ -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 <stdarg.h>
+#include <limits.h>
+
+#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<char> 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 (file)
index 0000000..3352747
--- /dev/null
@@ -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<char> buffer, int exponent);
+
+} }  // namespace v8::internal
+
+#endif  // V8_STRTOD_H_
\ No newline at end of file
index 436ae23f551d4ba9af8846dda74b4a459c5f91c4..99e37a2f83cbdd65791471bc2cdb1e9bae72886a 100644 (file)
         '../../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',