summaryrefslogtreecommitdiff
path: root/deps/v8/src/conversions.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-07-08 16:40:11 -0700
committerRyan Dahl <ry@tinyclouds.org>2011-07-08 16:40:11 -0700
commite5564a3f29e0a818832a97c7c3b28d7c8b3b0460 (patch)
tree4b48a6577080d5e44da4d2cbebb7fe7951660de8 /deps/v8/src/conversions.cc
parent0df2f74d364826053641395b01c2fcb1345057a9 (diff)
downloadnode-e5564a3f29e0a818832a97c7c3b28d7c8b3b0460.tar.gz
Upgrade V8 to 3.4.10
Diffstat (limited to 'deps/v8/src/conversions.cc')
-rw-r--r--deps/v8/src/conversions.cc708
1 files changed, 46 insertions, 662 deletions
diff --git a/deps/v8/src/conversions.cc b/deps/v8/src/conversions.cc
index a348235d6..232eda08c 100644
--- a/deps/v8/src/conversions.cc
+++ b/deps/v8/src/conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 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:
@@ -28,676 +28,41 @@
#include <stdarg.h>
#include <limits.h>
-#include "v8.h"
-
#include "conversions-inl.h"
#include "dtoa.h"
-#include "factory.h"
#include "scanner-base.h"
#include "strtod.h"
+#include "utils.h"
namespace v8 {
namespace internal {
-namespace {
-
-// C++-style iterator adaptor for StringInputBuffer
-// (unlike C++ iterators the end-marker has different type).
-class StringInputBufferIterator {
- public:
- class EndMarker {};
-
- explicit StringInputBufferIterator(StringInputBuffer* buffer);
-
- int operator*() const;
- void operator++();
- bool operator==(EndMarker const&) const { return end_; }
- bool operator!=(EndMarker const& m) const { return !end_; }
-
- private:
- StringInputBuffer* const buffer_;
- int current_;
- bool end_;
-};
-
-
-StringInputBufferIterator::StringInputBufferIterator(
- StringInputBuffer* buffer) : buffer_(buffer) {
- ++(*this);
-}
-
-int StringInputBufferIterator::operator*() const {
- return current_;
-}
-
-
-void StringInputBufferIterator::operator++() {
- end_ = !buffer_->has_more();
- if (!end_) {
- current_ = buffer_->GetNext();
- }
-}
-}
-
-
-template <class Iterator, class EndMark>
-static bool SubStringEquals(Iterator* current,
- EndMark end,
- const char* substring) {
- ASSERT(**current == *substring);
- for (substring++; *substring != '\0'; substring++) {
- ++*current;
- if (*current == end || **current != *substring) return false;
- }
- ++*current;
- return true;
-}
-
-
-// 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
-// (768 digits). If we parse a number whose first digits are equal to a
-// mean of 2 adjacent doubles (that could have up to 769 digits) the result
-// must be rounded to the bigger one unless the tail consists of zeros, so
-// we don't need to preserve all the digits.
-const int kMaxSignificantDigits = 772;
-
-
-static const double JUNK_STRING_VALUE = OS::nan_value();
-
-
-// Returns true if a nonspace found and false if the end has reached.
-template <class Iterator, class EndMark>
-static inline bool AdvanceToNonspace(Iterator* current, EndMark end) {
- while (*current != end) {
- if (!ScannerConstants::kIsWhiteSpace.get(**current)) return true;
- ++*current;
- }
- return false;
-}
-
-
-static bool isDigit(int x, int radix) {
- return (x >= '0' && x <= '9' && x < '0' + radix)
- || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
- || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
-}
-
-
-static double SignedZero(bool negative) {
- return negative ? -0.0 : 0.0;
-}
-
-
-// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2, class Iterator, class EndMark>
-static double InternalStringToIntDouble(Iterator current,
- EndMark end,
- bool negative,
- bool allow_trailing_junk) {
- ASSERT(current != end);
-
- // Skip leading 0s.
- while (*current == '0') {
- ++current;
- if (current == end) return SignedZero(negative);
- }
-
- int64_t number = 0;
- int exponent = 0;
- const int radix = (1 << radix_log_2);
-
- do {
- int digit;
- if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
- digit = static_cast<char>(*current) - '0';
- } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
- digit = static_cast<char>(*current) - 'a' + 10;
- } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
- digit = static_cast<char>(*current) - 'A' + 10;
- } else {
- if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
- break;
- } else {
- return JUNK_STRING_VALUE;
- }
- }
-
- number = number * radix + digit;
- int overflow = static_cast<int>(number >> 53);
- if (overflow != 0) {
- // Overflow occurred. Need to determine which direction to round the
- // result.
- int overflow_bits_count = 1;
- while (overflow > 1) {
- overflow_bits_count++;
- overflow >>= 1;
- }
-
- int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
- int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
- number >>= overflow_bits_count;
- exponent = overflow_bits_count;
-
- bool zero_tail = true;
- while (true) {
- ++current;
- if (current == end || !isDigit(*current, radix)) break;
- zero_tail = zero_tail && *current == '0';
- exponent += radix_log_2;
- }
-
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
-
- int middle_value = (1 << (overflow_bits_count - 1));
- if (dropped_bits > middle_value) {
- number++; // Rounding up.
- } else if (dropped_bits == middle_value) {
- // Rounding to even to consistency with decimals: half-way case rounds
- // up if significant part is odd and down otherwise.
- if ((number & 1) != 0 || !zero_tail) {
- number++; // Rounding up.
- }
- }
-
- // Rounding up may cause overflow.
- if ((number & ((int64_t)1 << 53)) != 0) {
- exponent++;
- number >>= 1;
- }
- break;
- }
- ++current;
- } while (current != end);
-
- ASSERT(number < ((int64_t)1 << 53));
- ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
-
- if (exponent == 0) {
- if (negative) {
- if (number == 0) return -0.0;
- number = -number;
- }
- return static_cast<double>(number);
- }
-
- ASSERT(number != 0);
- // The double could be constructed faster from number (mantissa), exponent
- // and sign. Assuming it's a rare case more simple code is used.
- return static_cast<double>(negative ? -number : number) * pow(2.0, exponent);
-}
-
-
-template <class Iterator, class EndMark>
-static double InternalStringToInt(Iterator current, EndMark end, int radix) {
- const bool allow_trailing_junk = true;
- const double empty_string_val = JUNK_STRING_VALUE;
-
- if (!AdvanceToNonspace(&current, end)) return empty_string_val;
-
- bool negative = false;
- bool leading_zero = false;
-
- if (*current == '+') {
- // Ignore leading sign; skip following spaces.
- ++current;
- if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
- } else if (*current == '-') {
- ++current;
- if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
- negative = true;
- }
-
- if (radix == 0) {
- // Radix detection.
- if (*current == '0') {
- ++current;
- if (current == end) return SignedZero(negative);
- if (*current == 'x' || *current == 'X') {
- radix = 16;
- ++current;
- if (current == end) return JUNK_STRING_VALUE;
- } else {
- radix = 8;
- leading_zero = true;
- }
- } else {
- radix = 10;
- }
- } else if (radix == 16) {
- if (*current == '0') {
- // Allow "0x" prefix.
- ++current;
- if (current == end) return SignedZero(negative);
- if (*current == 'x' || *current == 'X') {
- ++current;
- if (current == end) return JUNK_STRING_VALUE;
- } else {
- leading_zero = true;
- }
- }
- }
-
- if (radix < 2 || radix > 36) return JUNK_STRING_VALUE;
-
- // Skip leading zeros.
- while (*current == '0') {
- leading_zero = true;
- ++current;
- if (current == end) return SignedZero(negative);
- }
-
- if (!leading_zero && !isDigit(*current, radix)) {
- return JUNK_STRING_VALUE;
- }
-
- if (IsPowerOf2(radix)) {
- switch (radix) {
- case 2:
- return InternalStringToIntDouble<1>(
- current, end, negative, allow_trailing_junk);
- case 4:
- return InternalStringToIntDouble<2>(
- current, end, negative, allow_trailing_junk);
- case 8:
- return InternalStringToIntDouble<3>(
- current, end, negative, allow_trailing_junk);
-
- case 16:
- return InternalStringToIntDouble<4>(
- current, end, negative, allow_trailing_junk);
-
- case 32:
- return InternalStringToIntDouble<5>(
- current, end, negative, allow_trailing_junk);
- default:
- UNREACHABLE();
- }
- }
-
- if (radix == 10) {
- // Parsing with strtod.
- const int kMaxSignificantDigits = 309; // Doubles are less than 1.8e308.
- // The buffer may contain up to kMaxSignificantDigits + 1 digits and a zero
- // end.
- const int kBufferSize = kMaxSignificantDigits + 2;
- char buffer[kBufferSize];
- int buffer_pos = 0;
- while (*current >= '0' && *current <= '9') {
- if (buffer_pos <= kMaxSignificantDigits) {
- // If the number has more than kMaxSignificantDigits it will be parsed
- // as infinity.
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos++] = static_cast<char>(*current);
- }
- ++current;
- if (current == end) break;
- }
-
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
-
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos] = '\0';
- Vector<const char> buffer_vector(buffer, buffer_pos);
- return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
- }
-
- // The following code causes accumulating rounding error for numbers greater
- // than ~2^56. It's explicitly allowed in the spec: "if R is not 2, 4, 8, 10,
- // 16, or 32, then mathInt may be an implementation-dependent approximation to
- // the mathematical integer value" (15.1.2.2).
-
- int lim_0 = '0' + (radix < 10 ? radix : 10);
- int lim_a = 'a' + (radix - 10);
- int lim_A = 'A' + (radix - 10);
-
- // NOTE: The code for computing the value may seem a bit complex at
- // first glance. It is structured to use 32-bit multiply-and-add
- // loops as long as possible to avoid loosing precision.
-
- double v = 0.0;
- bool done = false;
- do {
- // Parse the longest part of the string starting at index j
- // possible while keeping the multiplier, and thus the part
- // itself, within 32 bits.
- unsigned int part = 0, multiplier = 1;
- while (true) {
- int d;
- if (*current >= '0' && *current < lim_0) {
- d = *current - '0';
- } else if (*current >= 'a' && *current < lim_a) {
- d = *current - 'a' + 10;
- } else if (*current >= 'A' && *current < lim_A) {
- d = *current - 'A' + 10;
- } else {
- done = true;
- break;
- }
-
- // Update the value of the part as long as the multiplier fits
- // in 32 bits. When we can't guarantee that the next iteration
- // will not overflow the multiplier, we stop parsing the part
- // by leaving the loop.
- const unsigned int kMaximumMultiplier = 0xffffffffU / 36;
- uint32_t m = multiplier * radix;
- if (m > kMaximumMultiplier) break;
- part = part * radix + d;
- multiplier = m;
- ASSERT(multiplier > part);
-
- ++current;
- if (current == end) {
- done = true;
- break;
- }
- }
-
- // Update the value and skip the part in the string.
- v = v * multiplier + part;
- } while (!done);
-
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
-
- return negative ? -v : v;
-}
-
-
-// Converts a string to a double value. Assumes the Iterator supports
-// the following operations:
-// 1. current == end (other ops are not allowed), current != end.
-// 2. *current - gets the current character in the sequence.
-// 3. ++current (advances the position).
-template <class Iterator, class EndMark>
-static double InternalStringToDouble(Iterator current,
- EndMark end,
- int flags,
- double empty_string_val) {
- // To make sure that iterator dereferencing is valid the following
- // convention is used:
- // 1. Each '++current' statement is followed by check for equality to 'end'.
- // 2. If AdvanceToNonspace returned false then current == end.
- // 3. If 'current' becomes be equal to 'end' the function returns or goes to
- // 'parsing_done'.
- // 4. 'current' is not dereferenced after the 'parsing_done' label.
- // 5. Code before 'parsing_done' may rely on 'current != end'.
- if (!AdvanceToNonspace(&current, end)) return empty_string_val;
-
- const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
-
- // The longest form of simplified number is: "-<significant digits>'.1eXXX\0".
- const int kBufferSize = kMaxSignificantDigits + 10;
- char buffer[kBufferSize]; // NOLINT: size is known at compile time.
- int buffer_pos = 0;
-
- // Exponent will be adjusted if insignificant digits of the integer part
- // or insignificant leading zeros of the fractional part are dropped.
- int exponent = 0;
- int significant_digits = 0;
- int insignificant_digits = 0;
- bool nonzero_digit_dropped = false;
- bool fractional_part = false;
-
- bool negative = false;
-
- if (*current == '+') {
- // Ignore leading sign.
- ++current;
- if (current == end) return JUNK_STRING_VALUE;
- } else if (*current == '-') {
- ++current;
- if (current == end) return JUNK_STRING_VALUE;
- negative = true;
- }
-
- static const char kInfinitySymbol[] = "Infinity";
- if (*current == kInfinitySymbol[0]) {
- if (!SubStringEquals(&current, end, kInfinitySymbol)) {
- return JUNK_STRING_VALUE;
- }
-
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
-
- ASSERT(buffer_pos == 0);
- return negative ? -V8_INFINITY : V8_INFINITY;
- }
-
- bool leading_zero = false;
- if (*current == '0') {
- ++current;
- if (current == end) return SignedZero(negative);
-
- leading_zero = true;
-
- // It could be hexadecimal value.
- if ((flags & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
- ++current;
- if (current == end || !isDigit(*current, 16)) {
- return JUNK_STRING_VALUE; // "0x".
- }
-
- return InternalStringToIntDouble<4>(current,
- end,
- negative,
- allow_trailing_junk);
- }
- // Ignore leading zeros in the integer part.
- while (*current == '0') {
- ++current;
- if (current == end) return SignedZero(negative);
- }
- }
-
- bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
-
- // Copy significant digits of the integer part (if any) to the buffer.
- while (*current >= '0' && *current <= '9') {
- if (significant_digits < kMaxSignificantDigits) {
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos++] = static_cast<char>(*current);
- significant_digits++;
- // Will later check if it's an octal in the buffer.
- } else {
- insignificant_digits++; // Move the digit into the exponential part.
- nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
- }
- octal = octal && *current < '8';
- ++current;
- if (current == end) goto parsing_done;
- }
-
- if (significant_digits == 0) {
- octal = false;
- }
-
- 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) {
- return JUNK_STRING_VALUE;
- } else {
- goto parsing_done;
- }
- }
-
- if (significant_digits == 0) {
- // octal = false;
- // Integer part consists of 0 or is absent. Significant digits start after
- // leading zeros (if any).
- while (*current == '0') {
- ++current;
- if (current == end) return SignedZero(negative);
- exponent--; // Move this 0 into the exponent.
- }
- }
-
- // We don't emit a '.', but adjust the exponent instead.
- fractional_part = true;
-
- // 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';
- }
- ++current;
- if (current == end) goto parsing_done;
- }
- }
-
- if (!leading_zero && exponent == 0 && significant_digits == 0) {
- // If leading_zeros is true then the string contains zeros.
- // If exponent < 0 then string was [+-]\.0*...
- // If significant_digits != 0 the string is not equal to 0.
- // Otherwise there are no digits in the string.
- return JUNK_STRING_VALUE;
- }
- // Parse exponential part.
- if (*current == 'e' || *current == 'E') {
- if (octal) return JUNK_STRING_VALUE;
- ++current;
- if (current == end) {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return JUNK_STRING_VALUE;
- }
- }
- char sign = '+';
- if (*current == '+' || *current == '-') {
- sign = static_cast<char>(*current);
- ++current;
- if (current == end) {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return JUNK_STRING_VALUE;
- }
- }
- }
-
- if (current == end || *current < '0' || *current > '9') {
- if (allow_trailing_junk) {
- goto parsing_done;
- } else {
- return JUNK_STRING_VALUE;
- }
- }
-
- const int max_exponent = INT_MAX / 2;
- ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
- int num = 0;
- do {
- // Check overflow.
- int digit = *current - '0';
- if (num >= max_exponent / 10
- && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
- num = max_exponent;
- } else {
- num = num * 10 + digit;
- }
- ++current;
- } while (current != end && *current >= '0' && *current <= '9');
-
- exponent += (sign == '-' ? -num : num);
- }
-
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
-
- parsing_done:
- exponent += insignificant_digits;
-
- if (octal) {
- return InternalStringToIntDouble<3>(buffer,
- buffer + buffer_pos,
- negative,
- allow_trailing_junk);
- }
-
- if (nonzero_digit_dropped) {
- buffer[buffer_pos++] = '1';
- exponent--;
- }
-
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos] = '\0';
-
- double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
- return negative ? -converted : converted;
-}
-
-
-double StringToDouble(String* str, int flags, double empty_string_val) {
- StringShape shape(str);
- if (shape.IsSequentialAscii()) {
- const char* begin = SeqAsciiString::cast(str)->GetChars();
- const char* end = begin + str->length();
- return InternalStringToDouble(begin, end, flags, empty_string_val);
- } else if (shape.IsSequentialTwoByte()) {
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
- const uc16* end = begin + str->length();
- return InternalStringToDouble(begin, end, flags, empty_string_val);
- } else {
- StringInputBuffer buffer(str);
- return InternalStringToDouble(StringInputBufferIterator(&buffer),
- StringInputBufferIterator::EndMarker(),
- flags,
- empty_string_val);
- }
-}
-
-
-double StringToInt(String* str, int radix) {
- StringShape shape(str);
- if (shape.IsSequentialAscii()) {
- const char* begin = SeqAsciiString::cast(str)->GetChars();
- const char* end = begin + str->length();
- return InternalStringToInt(begin, end, radix);
- } else if (shape.IsSequentialTwoByte()) {
- const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
- const uc16* end = begin + str->length();
- return InternalStringToInt(begin, end, radix);
- } else {
- StringInputBuffer buffer(str);
- return InternalStringToInt(StringInputBufferIterator(&buffer),
- StringInputBufferIterator::EndMarker(),
- radix);
- }
-}
-
-
-double StringToDouble(const char* str, int flags, double empty_string_val) {
+double StringToDouble(UnicodeCache* unicode_cache,
+ const char* str, int flags, double empty_string_val) {
const char* end = str + StrLength(str);
- return InternalStringToDouble(str, end, flags, empty_string_val);
+ return InternalStringToDouble(unicode_cache, str, end, flags,
+ empty_string_val);
}
-double StringToDouble(Vector<const char> str,
+double StringToDouble(UnicodeCache* unicode_cache,
+ Vector<const char> str,
int flags,
double empty_string_val) {
const char* end = str.start() + str.length();
- return InternalStringToDouble(str.start(), end, flags, empty_string_val);
+ return InternalStringToDouble(unicode_cache, str.start(), end, flags,
+ empty_string_val);
+}
+
+double StringToDouble(UnicodeCache* unicode_cache,
+ Vector<const uc16> str,
+ int flags,
+ double empty_string_val) {
+ const uc16* end = str.start() + str.length();
+ return InternalStringToDouble(unicode_cache, str.start(), end, flags,
+ empty_string_val);
}
@@ -707,7 +72,7 @@ const char* DoubleToCString(double v, Vector<char> buffer) {
case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
case FP_ZERO: return "0";
default: {
- StringBuilder builder(buffer.start(), buffer.length());
+ SimpleStringBuilder builder(buffer.start(), buffer.length());
int decimal_point;
int sign;
const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
@@ -748,7 +113,7 @@ const char* DoubleToCString(double v, Vector<char> buffer) {
builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
int exponent = decimal_point - 1;
if (exponent < 0) exponent = -exponent;
- builder.AddFormatted("%d", exponent);
+ builder.AddDecimalInteger(exponent);
}
return builder.Finalize();
}
@@ -826,7 +191,7 @@ char* DoubleToFixedCString(double value, int f) {
unsigned rep_length =
zero_prefix_length + decimal_rep_length + zero_postfix_length;
- StringBuilder rep_builder(rep_length + 1);
+ SimpleStringBuilder rep_builder(rep_length + 1);
rep_builder.AddPadding('0', zero_prefix_length);
rep_builder.AddString(decimal_rep);
rep_builder.AddPadding('0', zero_postfix_length);
@@ -835,7 +200,7 @@ char* DoubleToFixedCString(double value, int f) {
// Create the result string by appending a minus and putting in a
// decimal point if needed.
unsigned result_size = decimal_point + f + 2;
- StringBuilder builder(result_size + 1);
+ SimpleStringBuilder builder(result_size + 1);
if (negative) builder.AddCharacter('-');
builder.AddSubstring(rep, decimal_point);
if (f > 0) {
@@ -861,7 +226,7 @@ static char* CreateExponentialRepresentation(char* decimal_rep,
// letter 'e', a minus or a plus depending on the exponent, and a
// three digit exponent.
unsigned result_size = significant_digits + 7;
- StringBuilder builder(result_size + 1);
+ SimpleStringBuilder builder(result_size + 1);
if (negative) builder.AddCharacter('-');
builder.AddCharacter(decimal_rep[0]);
@@ -874,7 +239,7 @@ static char* CreateExponentialRepresentation(char* decimal_rep,
builder.AddCharacter('e');
builder.AddCharacter(negative_exponent ? '-' : '+');
- builder.AddFormatted("%d", exponent);
+ builder.AddDecimalInteger(exponent);
return builder.Finalize();
}
@@ -966,7 +331,7 @@ char* DoubleToPrecisionCString(double value, int p) {
unsigned result_size = (decimal_point <= 0)
? -decimal_point + p + 3
: p + 2;
- StringBuilder builder(result_size + 1);
+ SimpleStringBuilder builder(result_size + 1);
if (negative) builder.AddCharacter('-');
if (decimal_point <= 0) {
builder.AddString("0.");
@@ -1058,7 +423,7 @@ char* DoubleToRadixCString(double value, int radix) {
// If the number has a decimal part, leave room for the period.
if (decimal_pos > 0) result_size++;
// Allocate result and fill in the parts.
- StringBuilder builder(result_size + 1);
+ SimpleStringBuilder builder(result_size + 1);
builder.AddSubstring(integer_buffer + integer_pos + 1, integer_part_size);
if (decimal_pos > 0) builder.AddCharacter('.');
builder.AddSubstring(decimal_buffer, decimal_pos);
@@ -1066,4 +431,23 @@ char* DoubleToRadixCString(double value, int radix) {
}
+static Mutex* dtoa_lock_one = OS::CreateMutex();
+static Mutex* dtoa_lock_zero = OS::CreateMutex();
+
+
} } // namespace v8::internal
+
+
+extern "C" {
+void ACQUIRE_DTOA_LOCK(int n) {
+ ASSERT(n == 0 || n == 1);
+ (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->Lock();
+}
+
+
+void FREE_DTOA_LOCK(int n) {
+ ASSERT(n == 0 || n == 1);
+ (n == 0 ? v8::internal::dtoa_lock_zero : v8::internal::dtoa_lock_one)->
+ Unlock();
+}
+}