Skip to content
Browse files

Merged utils.cc v8utils.h utils.h and v8stdint.h into one utils.h file.

No modifications to the sources.
The methods in utils.cc have been moved to the header file inside the class declaration.

conversions.cc has been reordered and moved into double-conversion.cc.

--HG--
branch : staging
  • Loading branch information...
1 parent 16f03e0 commit e883c91e241920b605a105d5b3c4e2d3eef3e498 @floitschG floitschG committed Jan 20, 2011
Showing with 636 additions and 759 deletions.
  1. +540 −543 src/{conversions.cc → double-conversion.cc}
  2. +0 −71 src/utils.cc
  3. +96 −0 src/utils.h
  4. +0 −53 src/v8stdint.h
  5. +0 −92 src/v8utils.h
View
1,083 src/conversions.cc → src/double-conversion.cc
@@ -41,663 +41,660 @@ namespace internal {
namespace {
-// 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 char* CreateExponentialRepresentation(char* decimal_rep,
+ int exponent,
+ bool negative,
+ int significant_digits) {
+ bool negative_exponent = false;
+ if (exponent < 0) {
+ negative_exponent = true;
+ exponent = -exponent;
+ }
+ // Leave room in the result for appending a minus, for a period, the
+ // 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);
-// 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;
+ if (negative) builder.AddCharacter('-');
+ builder.AddCharacter(decimal_rep[0]);
+ if (significant_digits != 1) {
+ builder.AddCharacter('.');
+ builder.AddString(decimal_rep + 1);
+ int rep_length = StrLength(decimal_rep);
+ builder.AddPadding('0', significant_digits - rep_length);
}
- return false;
+
+ builder.AddCharacter('e');
+ builder.AddCharacter(negative_exponent ? '-' : '+');
+ builder.AddFormatted("%d", exponent);
+ return builder.Finalize();
}
+const char* DoubleToCString(double v, Vector<char> buffer) {
+ StringBuilder builder(buffer.start(), buffer.length());
-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);
-}
+ switch (fpclassify(v)) {
+ case FP_NAN:
+ builder.AddString("NaN");
+ break;
+ case FP_INFINITE:
+ if (v < 0.0) {
+ builder.AddString("-Infinity");
+ } else {
+ builder.AddString("Infinity");
+ }
+ break;
-static double SignedZero(bool sign) {
- return sign ? -0.0 : 0.0;
-}
+ case FP_ZERO:
+ builder.AddCharacter('0');
+ break;
+ default: {
+ int decimal_point;
+ int sign;
+ const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
+ char decimal_rep[kV8DtoaBufferCapacity];
+ int length;
-// 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 sign,
- bool allow_trailing_junk) {
- ASSERT(current != end);
+ DoubleToAscii(v, DTOA_SHORTEST, 0,
+ Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ &sign, &length, &decimal_point);
- // Skip leading 0s.
- while (*current == '0') {
- ++current;
- if (current == end) return SignedZero(sign);
- }
+ if (sign) builder.AddCharacter('-');
- int64_t number = 0;
- int exponent = 0;
- const int radix = (1 << radix_log_2);
+ if (length <= decimal_point && decimal_point <= 21) {
+ // ECMA-262 section 9.8.1 step 6.
+ builder.AddString(decimal_rep);
+ builder.AddPadding('0', decimal_point - length);
+
+ } else if (0 < decimal_point && decimal_point <= 21) {
+ // ECMA-262 section 9.8.1 step 7.
+ builder.AddSubstring(decimal_rep, decimal_point);
+ builder.AddCharacter('.');
+ builder.AddString(decimal_rep + decimal_point);
+
+ } else if (decimal_point <= 0 && decimal_point > -6) {
+ // ECMA-262 section 9.8.1 step 8.
+ builder.AddString("0.");
+ builder.AddPadding('0', -decimal_point);
+ builder.AddString(decimal_rep);
- 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;
+ // ECMA-262 section 9.8.1 step 9 and 10 combined.
+ builder.AddCharacter(decimal_rep[0]);
+ if (length != 1) {
+ builder.AddCharacter('.');
+ builder.AddString(decimal_rep + 1);
+ }
+ builder.AddCharacter('e');
+ builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
+ int exponent = decimal_point - 1;
+ if (exponent < 0) exponent = -exponent;
+ builder.AddFormatted("%d", exponent);
}
}
+ }
+ return builder.Finalize();
+}
- 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;
+char* DoubleToFixedCString(double value, int f) {
+ const int kMaxDigitsBeforePoint = 21;
+ const double kFirstNonFixed = 1e21;
+ const int kMaxDigitsAfterPoint = 20;
+ ASSERT(f >= 0);
+ ASSERT(f <= kMaxDigitsAfterPoint);
- bool zero_tail = true;
- while (true) {
- ++current;
- if (current == end || !isDigit(*current, radix)) break;
- zero_tail = zero_tail && *current == '0';
- exponent += radix_log_2;
- }
+ bool negative = false;
+ double abs_value = value;
+ if (value < 0) {
+ abs_value = -value;
+ negative = true;
+ }
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
- return JUNK_STRING_VALUE;
- }
+ // If abs_value has more than kMaxDigitsBeforePoint digits before the point
+ // use the non-fixed conversion routine.
+ if (abs_value >= kFirstNonFixed) {
+ char arr[100];
+ Vector<char> buffer(arr, ARRAY_SIZE(arr));
+ return StrDup(DoubleToCString(value, buffer));
+ }
- 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.
- }
- }
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ int sign;
+ // Add space for the '\0' byte.
+ const int kDecimalRepCapacity =
+ kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+ DoubleToAscii(value, DTOA_FIXED, f,
+ Vector<char>(decimal_rep, kDecimalRepCapacity),
+ &sign, &decimal_rep_length, &decimal_point);
- // Rounding up may cause overflow.
- if ((number & ((int64_t)1 << 53)) != 0) {
- exponent++;
- number >>= 1;
- }
- break;
- }
- ++current;
- } while (current != end);
+ // Create a representation that is padded with zeros if needed.
+ int zero_prefix_length = 0;
+ int zero_postfix_length = 0;
- ASSERT(number < ((int64_t)1 << 53));
- ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+ if (decimal_point <= 0) {
+ zero_prefix_length = -decimal_point + 1;
+ decimal_point = 1;
+ }
- if (exponent == 0) {
- if (sign) {
- if (number == 0) return -0.0;
- number = -number;
- }
- return static_cast<double>(number);
+ if (zero_prefix_length + decimal_rep_length < decimal_point + f) {
+ zero_postfix_length = decimal_point + f - decimal_rep_length -
+ zero_prefix_length;
}
- 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>(sign ? -number : number) * pow(2.0, exponent);
+ unsigned rep_length =
+ zero_prefix_length + decimal_rep_length + zero_postfix_length;
+ StringBuilder rep_builder(rep_length + 1);
+ rep_builder.AddPadding('0', zero_prefix_length);
+ rep_builder.AddString(decimal_rep);
+ rep_builder.AddPadding('0', zero_postfix_length);
+ char* rep = rep_builder.Finalize();
+
+ // 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);
+ if (negative) builder.AddCharacter('-');
+ builder.AddSubstring(rep, decimal_point);
+ if (f > 0) {
+ builder.AddCharacter('.');
+ builder.AddSubstring(rep + decimal_point, f);
+ }
+ DeleteArray(rep);
+ return builder.Finalize();
}
-// 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;
+char* DoubleToExponentialCString(double value, int f) {
+ const int kMaxDigitsAfterPoint = 20;
+ // f might be -1 to signal that f was undefined in JavaScript.
+ ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint);
- const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
+ bool negative = false;
+ if (value < 0) {
+ value = -value;
+ negative = true;
+ }
- // 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;
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ int sign;
+ // f corresponds to the digits after the point. There is always one digit
+ // before the point. The number of requested_digits equals hence f + 1.
+ // And we have to add one character for the null-terminator.
+ const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1;
+ // Make sure that the buffer is big enough, even if we fall back to the
+ // shortest representation (which happens when f equals -1).
+ ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1);
+ char decimal_rep[kV8DtoaBufferCapacity];
+ int decimal_rep_length;
- // 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;
+ if (f == -1) {
+ DoubleToAscii(value, DTOA_SHORTEST, 0,
+ Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ &sign, &decimal_rep_length, &decimal_point);
+ f = decimal_rep_length - 1;
+ } else {
+ DoubleToAscii(value, DTOA_PRECISION, f + 1,
+ Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ &sign, &decimal_rep_length, &decimal_point);
+ }
+ ASSERT(decimal_rep_length > 0);
+ ASSERT(decimal_rep_length <= f + 1);
- bool sign = false;
+ int exponent = decimal_point - 1;
+ char* result =
+ CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1);
- 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;
- sign = true;
- }
+ return result;
+}
- 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;
- }
+char* DoubleToPrecisionCString(double value, int p) {
+ const int kMinimalDigits = 1;
+ const int kMaximalDigits = 21;
+ ASSERT(p >= kMinimalDigits && p <= kMaximalDigits);
+ USE(kMinimalDigits);
- ASSERT(buffer_pos == 0);
- return sign ? -V8_INFINITY : V8_INFINITY;
+ bool negative = false;
+ if (value < 0) {
+ value = -value;
+ negative = true;
}
- bool leading_zero = false;
- if (*current == '0') {
- ++current;
- if (current == end) return SignedZero(sign);
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ int sign;
+ // Add one for the terminating null character.
+ const int kV8DtoaBufferCapacity = kMaximalDigits + 1;
+ char decimal_rep[kV8DtoaBufferCapacity];
+ int decimal_rep_length;
- leading_zero = true;
+ DoubleToAscii(value, DTOA_PRECISION, p,
+ Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
+ &sign, &decimal_rep_length, &decimal_point);
+ ASSERT(decimal_rep_length <= p);
- // 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".
- }
+ int exponent = decimal_point - 1;
- return InternalStringToIntDouble<4>(current,
- end,
- sign,
- allow_trailing_junk);
- }
+ char* result = NULL;
- // Ignore leading zeros in the integer part.
- while (*current == '0') {
- ++current;
- if (current == end) return SignedZero(sign);
+ if (exponent < -6 || exponent >= p) {
+ result =
+ CreateExponentialRepresentation(decimal_rep, exponent, negative, p);
+ } else {
+ // Use fixed notation.
+ //
+ // Leave room in the result for appending a minus, a period and in
+ // the case where decimal_point is not positive for a zero in
+ // front of the period.
+ unsigned result_size = (decimal_point <= 0)
+ ? -decimal_point + p + 3
+ : p + 2;
+ StringBuilder builder(result_size + 1);
+ if (negative) builder.AddCharacter('-');
+ if (decimal_point <= 0) {
+ builder.AddString("0.");
+ builder.AddPadding('0', -decimal_point);
+ builder.AddString(decimal_rep);
+ builder.AddPadding('0', p - decimal_rep_length);
+ } else {
+ const int m = Min(decimal_rep_length, decimal_point);
+ builder.AddSubstring(decimal_rep, m);
+ builder.AddPadding('0', decimal_point - decimal_rep_length);
+ if (decimal_point < p) {
+ builder.AddCharacter('.');
+ const int extra = negative ? 2 : 1;
+ if (decimal_rep_length > decimal_point) {
+ const int len = StrLength(decimal_rep + decimal_point);
+ const int n = Min(len, p - (builder.position() - extra));
+ builder.AddSubstring(decimal_rep + decimal_point, n);
+ }
+ builder.AddPadding('0', extra + (p - builder.position()));
+ }
}
+ result = builder.Finalize();
}
- bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
+ return result;
+}
- // 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;
- }
+// 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;
- if (significant_digits == 0) {
- octal = false;
+
+// 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;
+}
- 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;
- }
- }
+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);
+}
- 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(sign);
- exponent--; // Move this 0 into the exponent.
- }
- }
- // We don't emit a '.', but adjust the exponent instead.
- fractional_part = true;
+static double SignedZero(bool sign) {
+ return sign ? -0.0 : 0.0;
+}
- // 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;
- }
+// 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 sign,
+ bool allow_trailing_junk) {
+ ASSERT(current != end);
- // Parse exponential part.
- if (*current == 'e' || *current == 'E') {
- if (octal) return JUNK_STRING_VALUE;
+ // Skip leading 0s.
+ while (*current == '0') {
++current;
- if (current == end) {
- if (allow_trailing_junk) {
- goto parsing_done;
+ if (current == end) return SignedZero(sign);
+ }
+
+ 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;
}
}
- 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;
+ 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;
}
- }
- 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;
+ 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;
}
- ++current;
- } while (current != end && *current >= '0' && *current <= '9');
- exponent += (sign == '-' ? -num : num);
- }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return JUNK_STRING_VALUE;
+ }
- 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.
+ }
+ }
- parsing_done:
- exponent += insignificant_digits;
+ // Rounding up may cause overflow.
+ if ((number & ((int64_t)1 << 53)) != 0) {
+ exponent++;
+ number >>= 1;
+ }
+ break;
+ }
+ ++current;
+ } while (current != end);
- if (octal) {
- return InternalStringToIntDouble<3>(buffer,
- buffer + buffer_pos,
- sign,
- allow_trailing_junk);
- }
+ ASSERT(number < ((int64_t)1 << 53));
+ ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
- if (nonzero_digit_dropped) {
- buffer[buffer_pos++] = '1';
- exponent--;
+ if (exponent == 0) {
+ if (sign) {
+ if (number == 0) return -0.0;
+ number = -number;
+ }
+ return static_cast<double>(number);
}
- ASSERT(buffer_pos < kBufferSize);
- buffer[buffer_pos] = '\0';
-
- double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
- return sign ? -converted : converted;
+ 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>(sign ? -number : number) * pow(2.0, exponent);
}
-const char* DoubleToCString(double v, Vector<char> buffer) {
- StringBuilder builder(buffer.start(), buffer.length());
+// 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;
- switch (fpclassify(v)) {
- case FP_NAN:
- builder.AddString("NaN");
- break;
+ const bool allow_trailing_junk = (flags & ALLOW_TRAILING_JUNK) != 0;
- case FP_INFINITE:
- if (v < 0.0) {
- builder.AddString("-Infinity");
- } else {
- builder.AddString("Infinity");
- }
- break;
+ // 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;
- case FP_ZERO:
- builder.AddCharacter('0');
- break;
+ // 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;
- default: {
- int decimal_point;
- int sign;
- const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
- char decimal_rep[kV8DtoaBufferCapacity];
- int length;
+ bool sign = false;
- DoubleToAscii(v, DTOA_SHORTEST, 0,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
- &sign, &length, &decimal_point);
+ 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;
+ sign = true;
+ }
- if (sign) builder.AddCharacter('-');
+ static const char kInfinitySymbol[] = "Infinity";
+ if (*current == kInfinitySymbol[0]) {
+ if (!SubStringEquals(&current, end, kInfinitySymbol)) {
+ return JUNK_STRING_VALUE;
+ }
- if (length <= decimal_point && decimal_point <= 21) {
- // ECMA-262 section 9.8.1 step 6.
- builder.AddString(decimal_rep);
- builder.AddPadding('0', decimal_point - length);
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return JUNK_STRING_VALUE;
+ }
- } else if (0 < decimal_point && decimal_point <= 21) {
- // ECMA-262 section 9.8.1 step 7.
- builder.AddSubstring(decimal_rep, decimal_point);
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + decimal_point);
+ ASSERT(buffer_pos == 0);
+ return sign ? -V8_INFINITY : V8_INFINITY;
+ }
- } else if (decimal_point <= 0 && decimal_point > -6) {
- // ECMA-262 section 9.8.1 step 8.
- builder.AddString("0.");
- builder.AddPadding('0', -decimal_point);
- builder.AddString(decimal_rep);
+ bool leading_zero = false;
+ if (*current == '0') {
+ ++current;
+ if (current == end) return SignedZero(sign);
- } else {
- // ECMA-262 section 9.8.1 step 9 and 10 combined.
- builder.AddCharacter(decimal_rep[0]);
- if (length != 1) {
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + 1);
- }
- builder.AddCharacter('e');
- builder.AddCharacter((decimal_point >= 0) ? '+' : '-');
- int exponent = decimal_point - 1;
- if (exponent < 0) exponent = -exponent;
- builder.AddFormatted("%d", exponent);
+ 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 builder.Finalize();
-}
+ return InternalStringToIntDouble<4>(current,
+ end,
+ sign,
+ allow_trailing_junk);
+ }
-char* DoubleToFixedCString(double value, int f) {
- const int kMaxDigitsBeforePoint = 21;
- const double kFirstNonFixed = 1e21;
- const int kMaxDigitsAfterPoint = 20;
- ASSERT(f >= 0);
- ASSERT(f <= kMaxDigitsAfterPoint);
-
- bool negative = false;
- double abs_value = value;
- if (value < 0) {
- abs_value = -value;
- negative = true;
- }
-
- // If abs_value has more than kMaxDigitsBeforePoint digits before the point
- // use the non-fixed conversion routine.
- if (abs_value >= kFirstNonFixed) {
- char arr[100];
- Vector<char> buffer(arr, ARRAY_SIZE(arr));
- return StrDup(DoubleToCString(value, buffer));
+ // Ignore leading zeros in the integer part.
+ while (*current == '0') {
+ ++current;
+ if (current == end) return SignedZero(sign);
+ }
}
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- int sign;
- // Add space for the '\0' byte.
- const int kDecimalRepCapacity =
- kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1;
- char decimal_rep[kDecimalRepCapacity];
- int decimal_rep_length;
- DoubleToAscii(value, DTOA_FIXED, f,
- Vector<char>(decimal_rep, kDecimalRepCapacity),
- &sign, &decimal_rep_length, &decimal_point);
-
- // Create a representation that is padded with zeros if needed.
- int zero_prefix_length = 0;
- int zero_postfix_length = 0;
+ bool octal = leading_zero && (flags & ALLOW_OCTALS) != 0;
- if (decimal_point <= 0) {
- zero_prefix_length = -decimal_point + 1;
- decimal_point = 1;
+ // 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 (zero_prefix_length + decimal_rep_length < decimal_point + f) {
- zero_postfix_length = decimal_point + f - decimal_rep_length -
- zero_prefix_length;
+ if (significant_digits == 0) {
+ octal = false;
}
- unsigned rep_length =
- zero_prefix_length + decimal_rep_length + zero_postfix_length;
- StringBuilder rep_builder(rep_length + 1);
- rep_builder.AddPadding('0', zero_prefix_length);
- rep_builder.AddString(decimal_rep);
- rep_builder.AddPadding('0', zero_postfix_length);
- char* rep = rep_builder.Finalize();
-
- // 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);
- if (negative) builder.AddCharacter('-');
- builder.AddSubstring(rep, decimal_point);
- if (f > 0) {
- builder.AddCharacter('.');
- builder.AddSubstring(rep + decimal_point, f);
- }
- DeleteArray(rep);
- return builder.Finalize();
-}
+ 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;
+ }
+ }
-static char* CreateExponentialRepresentation(char* decimal_rep,
- int exponent,
- bool negative,
- int significant_digits) {
- bool negative_exponent = false;
- if (exponent < 0) {
- negative_exponent = true;
- exponent = -exponent;
- }
+ 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(sign);
+ exponent--; // Move this 0 into the exponent.
+ }
+ }
- // Leave room in the result for appending a minus, for a period, the
- // 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);
+ // We don't emit a '.', but adjust the exponent instead.
+ fractional_part = true;
- if (negative) builder.AddCharacter('-');
- builder.AddCharacter(decimal_rep[0]);
- if (significant_digits != 1) {
- builder.AddCharacter('.');
- builder.AddString(decimal_rep + 1);
- int rep_length = StrLength(decimal_rep);
- builder.AddPadding('0', significant_digits - rep_length);
+ // 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;
+ }
}
- builder.AddCharacter('e');
- builder.AddCharacter(negative_exponent ? '-' : '+');
- builder.AddFormatted("%d", exponent);
- return builder.Finalize();
-}
+ 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;
+ }
+ }
-char* DoubleToExponentialCString(double value, int f) {
- const int kMaxDigitsAfterPoint = 20;
- // f might be -1 to signal that f was undefined in JavaScript.
- ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint);
+ 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');
- bool negative = false;
- if (value < 0) {
- value = -value;
- negative = true;
+ exponent += (sign == '-' ? -num : num);
}
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- int sign;
- // f corresponds to the digits after the point. There is always one digit
- // before the point. The number of requested_digits equals hence f + 1.
- // And we have to add one character for the null-terminator.
- const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1;
- // Make sure that the buffer is big enough, even if we fall back to the
- // shortest representation (which happens when f equals -1).
- ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1);
- char decimal_rep[kV8DtoaBufferCapacity];
- int decimal_rep_length;
-
- if (f == -1) {
- DoubleToAscii(value, DTOA_SHORTEST, 0,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
- &sign, &decimal_rep_length, &decimal_point);
- f = decimal_rep_length - 1;
- } else {
- DoubleToAscii(value, DTOA_PRECISION, f + 1,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
- &sign, &decimal_rep_length, &decimal_point);
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return JUNK_STRING_VALUE;
}
- ASSERT(decimal_rep_length > 0);
- ASSERT(decimal_rep_length <= f + 1);
-
- int exponent = decimal_point - 1;
- char* result =
- CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1);
-
- return result;
-}
+ parsing_done:
+ exponent += insignificant_digits;
-char* DoubleToPrecisionCString(double value, int p) {
- const int kMinimalDigits = 1;
- const int kMaximalDigits = 21;
- ASSERT(p >= kMinimalDigits && p <= kMaximalDigits);
- USE(kMinimalDigits);
-
- bool negative = false;
- if (value < 0) {
- value = -value;
- negative = true;
+ if (octal) {
+ return InternalStringToIntDouble<3>(buffer,
+ buffer + buffer_pos,
+ sign,
+ allow_trailing_junk);
}
- // Find a sufficiently precise decimal representation of n.
- int decimal_point;
- int sign;
- // Add one for the terminating null character.
- const int kV8DtoaBufferCapacity = kMaximalDigits + 1;
- char decimal_rep[kV8DtoaBufferCapacity];
- int decimal_rep_length;
-
- DoubleToAscii(value, DTOA_PRECISION, p,
- Vector<char>(decimal_rep, kV8DtoaBufferCapacity),
- &sign, &decimal_rep_length, &decimal_point);
- ASSERT(decimal_rep_length <= p);
-
- int exponent = decimal_point - 1;
-
- char* result = NULL;
-
- if (exponent < -6 || exponent >= p) {
- result =
- CreateExponentialRepresentation(decimal_rep, exponent, negative, p);
- } else {
- // Use fixed notation.
- //
- // Leave room in the result for appending a minus, a period and in
- // the case where decimal_point is not positive for a zero in
- // front of the period.
- unsigned result_size = (decimal_point <= 0)
- ? -decimal_point + p + 3
- : p + 2;
- StringBuilder builder(result_size + 1);
- if (negative) builder.AddCharacter('-');
- if (decimal_point <= 0) {
- builder.AddString("0.");
- builder.AddPadding('0', -decimal_point);
- builder.AddString(decimal_rep);
- builder.AddPadding('0', p - decimal_rep_length);
- } else {
- const int m = Min(decimal_rep_length, decimal_point);
- builder.AddSubstring(decimal_rep, m);
- builder.AddPadding('0', decimal_point - decimal_rep_length);
- if (decimal_point < p) {
- builder.AddCharacter('.');
- const int extra = negative ? 2 : 1;
- if (decimal_rep_length > decimal_point) {
- const int len = StrLength(decimal_rep + decimal_point);
- const int n = Min(len, p - (builder.position() - extra));
- builder.AddSubstring(decimal_rep + decimal_point, n);
- }
- builder.AddPadding('0', extra + (p - builder.position()));
- }
- }
- result = builder.Finalize();
+ if (nonzero_digit_dropped) {
+ buffer[buffer_pos++] = '1';
+ exponent--;
}
- return result;
+ ASSERT(buffer_pos < kBufferSize);
+ buffer[buffer_pos] = '\0';
+
+ double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+ return sign ? -converted : converted;
}
} } // namespace v8::internal
View
71 src/utils.cc
@@ -1,71 +0,0 @@
-// Copyright 2006-2008 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 "v8.h"
-
-#include "platform.h"
-
-#include "sys/stat.h"
-
-namespace v8 {
-namespace internal {
-
-void StringBuilder::AddString(const char* s) {
- AddSubstring(s, StrLength(s));
-}
-
-
-void StringBuilder::AddSubstring(const char* s, int n) {
- ASSERT(!is_finalized() && position_ + n < buffer_.length());
- ASSERT(static_cast<size_t>(n) <= strlen(s));
- memcpy(&buffer_[position_], s, n * kCharSize);
- position_ += n;
-}
-
-
-void StringBuilder::AddPadding(char c, int count) {
- for (int i = 0; i < count; i++) {
- AddCharacter(c);
- }
-}
-
-
-char* StringBuilder::Finalize() {
- ASSERT(!is_finalized() && position_ < buffer_.length());
- buffer_[position_] = '\0';
- // Make sure nobody managed to add a 0-character to the
- // buffer while building the string.
- ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
- position_ = -1;
- ASSERT(is_finalized());
- return buffer_.start();
-}
-
-
-} } // namespace v8::internal
View
96 src/utils.h
@@ -31,6 +31,25 @@
#include <stdlib.h>
#include <string.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t; // NOLINT
+typedef unsigned short uint16_t; // NOLINT
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+// intptr_t and friends are defined in crtdefs.h through stdio.h.
+
+#else
+
+#include <stdint.h>
+
+#endif
+
namespace v8 {
namespace internal {
@@ -97,6 +116,83 @@ class Vector {
};
+// Helper class for building result strings in a character buffer. The
+// purpose of the class is to use safe operations that checks the
+// buffer bounds on all operations in debug mode.
+class StringBuilder {
+ public:
+ StringBuilder(char* buffer, int size)
+ : buffer_(buffer, size), position_(0) { }
+
+ ~StringBuilder() { if (!is_finalized()) Finalize(); }
+
+ int size() const { return buffer_.length(); }
+
+ // Get the current position in the builder.
+ int position() const {
+ ASSERT(!is_finalized());
+ return position_;
+ }
+
+ // Reset the position.
+ void Reset() { position_ = 0; }
+
+ // Add a single character to the builder. It is not allowed to add
+ // 0-characters; use the Finalize() method to terminate the string
+ // instead.
+ void AddCharacter(char c) {
+ ASSERT(c != '\0');
+ ASSERT(!is_finalized() && position_ < buffer_.length());
+ buffer_[position_++] = c;
+ }
+
+ // Add an entire string to the builder. Uses strlen() internally to
+ // compute the length of the input string.
+ void AddString(const char* s) {
+ AddSubstring(s, StrLength(s));
+ }
+
+
+ // Add the first 'n' characters of the given string 's' to the
+ // builder. The input string must have enough characters.
+ void AddSubstring(const char* s, int n) {
+ ASSERT(!is_finalized() && position_ + n < buffer_.length());
+ ASSERT(static_cast<size_t>(n) <= strlen(s));
+ memcpy(&buffer_[position_], s, n * kCharSize);
+ position_ += n;
+ }
+
+
+ // Add character padding to the builder. If count is non-positive,
+ // nothing is added to the builder.
+ void AddPadding(char c, int count) {
+ for (int i = 0; i < count; i++) {
+ AddCharacter(c);
+ }
+ }
+
+ // Finalize the string by 0-terminating it and returning the buffer.
+ char* Finalize() {
+ ASSERT(!is_finalized() && position_ < buffer_.length());
+ buffer_[position_] = '\0';
+ // Make sure nobody managed to add a 0-character to the
+ // buffer while building the string.
+ ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
+ position_ = -1;
+ ASSERT(is_finalized());
+ return buffer_.start();
+ }
+
+ private:
+ Vector<char> buffer_;
+ int position_;
+
+ bool is_finalized() const { return position_ < 0; }
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
+
+
// The type-based aliasing rule allows the compiler to assume that pointers of
// different types (for some definition of different) never alias each other.
// Thus the following code does not work:
View
53 src/v8stdint.h
@@ -1,53 +0,0 @@
-// 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.
-
-// Load definitions of standard types.
-
-#ifndef V8STDINT_H_
-#define V8STDINT_H_
-
-#include <stdio.h>
-
-#if defined(_WIN32) && !defined(__MINGW32__)
-
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t; // NOLINT
-typedef unsigned short uint16_t; // NOLINT
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-// intptr_t and friends are defined in crtdefs.h through stdio.h.
-
-#else
-
-#include <stdint.h>
-
-#endif
-
-#endif // V8STDINT_H_
View
92 src/v8utils.h
@@ -1,92 +0,0 @@
-// 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_V8UTILS_H_
-#define V8_V8UTILS_H_
-
-#include "utils.h"
-
-namespace v8 {
-namespace internal {
-
-// Helper class for building result strings in a character buffer. The
-// purpose of the class is to use safe operations that checks the
-// buffer bounds on all operations in debug mode.
-class StringBuilder {
- public:
- StringBuilder(char* buffer, int size)
- : buffer_(buffer, size), position_(0) { }
-
- ~StringBuilder() { if (!is_finalized()) Finalize(); }
-
- int size() const { return buffer_.length(); }
-
- // Get the current position in the builder.
- int position() const {
- ASSERT(!is_finalized());
- return position_;
- }
-
- // Reset the position.
- void Reset() { position_ = 0; }
-
- // Add a single character to the builder. It is not allowed to add
- // 0-characters; use the Finalize() method to terminate the string
- // instead.
- void AddCharacter(char c) {
- ASSERT(c != '\0');
- ASSERT(!is_finalized() && position_ < buffer_.length());
- buffer_[position_++] = c;
- }
-
- // Add an entire string to the builder. Uses strlen() internally to
- // compute the length of the input string.
- void AddString(const char* s);
-
- // Add the first 'n' characters of the given string 's' to the
- // builder. The input string must have enough characters.
- void AddSubstring(const char* s, int n);
-
- // Add character padding to the builder. If count is non-positive,
- // nothing is added to the builder.
- void AddPadding(char c, int count);
-
- // Finalize the string by 0-terminating it and returning the buffer.
- char* Finalize();
-
- private:
- Vector<char> buffer_;
- int position_;
-
- bool is_finalized() const { return position_ < 0; }
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-};
-
-} } // namespace v8::internal
-
-#endif // V8_V8UTILS_H_

0 comments on commit e883c91

Please sign in to comment.
Something went wrong with that request. Please try again.