Revision: 6658
Author: [email protected]
Date: Mon Feb 7 00:57:06 2011
Log: Improve ScanJsonNumber.
Review URL: http://codereview.chromium.org/6334106
http://code.google.com/p/v8/source/detail?r=6658
Modified:
/branches/bleeding_edge/src/array.js
/branches/bleeding_edge/src/conversions.cc
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/scanner.cc
/branches/bleeding_edge/src/scanner.h
=======================================
--- /branches/bleeding_edge/src/array.js Tue Feb 1 04:31:16 2011
+++ /branches/bleeding_edge/src/array.js Mon Feb 7 00:57:06 2011
@@ -1018,9 +1018,11 @@
} else {
index = TO_INTEGER(index);
// If index is negative, index from the end of the array.
- if (index < 0) index = length + index;
- // If index is still negative, search the entire array.
- if (index < 0) index = 0;
+ if (index < 0) {
+ index = length + index;
+ // If index is still negative, search the entire array.
+ if (index < 0) index = 0;
+ }
}
var min = index;
var max = length;
=======================================
--- /branches/bleeding_edge/src/conversions.cc Tue Dec 7 03:01:02 2010
+++ /branches/bleeding_edge/src/conversions.cc Mon Feb 7 00:57:06 2011
@@ -125,8 +125,8 @@
}
-static double SignedZero(bool sign) {
- return sign ? -0.0 : 0.0;
+static double SignedZero(bool negative) {
+ return negative ? -0.0 : 0.0;
}
@@ -134,14 +134,14 @@
template <int radix_log_2, class Iterator, class EndMark>
static double InternalStringToIntDouble(Iterator current,
EndMark end,
- bool sign,
+ bool negative,
bool allow_trailing_junk) {
ASSERT(current != end);
// Skip leading 0s.
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
}
int64_t number = 0;
@@ -217,7 +217,7 @@
ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
if (exponent == 0) {
- if (sign) {
+ if (negative) {
if (number == 0) return -0.0;
number = -number;
}
@@ -227,7 +227,7 @@
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);
+ return static_cast<double>(negative ? -number : number) * pow(2.0,
exponent);
}
@@ -238,7 +238,7 @@
if (!AdvanceToNonspace(¤t, end)) return empty_string_val;
- bool sign = false;
+ bool negative = false;
bool leading_zero = false;
if (*current == '+') {
@@ -248,14 +248,14 @@
} else if (*current == '-') {
++current;
if (!AdvanceToNonspace(¤t, end)) return JUNK_STRING_VALUE;
- sign = true;
+ negative = true;
}
if (radix == 0) {
// Radix detection.
if (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
if (*current == 'x' || *current == 'X') {
radix = 16;
++current;
@@ -271,7 +271,7 @@
if (*current == '0') {
// Allow "0x" prefix.
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
if (*current == 'x' || *current == 'X') {
++current;
if (current == end) return JUNK_STRING_VALUE;
@@ -287,7 +287,7 @@
while (*current == '0') {
leading_zero = true;
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
}
if (!leading_zero && !isDigit(*current, radix)) {
@@ -298,21 +298,21 @@
switch (radix) {
case 2:
return InternalStringToIntDouble<1>(
- current, end, sign, allow_trailing_junk);
+ current, end, negative, allow_trailing_junk);
case 4:
return InternalStringToIntDouble<2>(
- current, end, sign, allow_trailing_junk);
+ current, end, negative, allow_trailing_junk);
case 8:
return InternalStringToIntDouble<3>(
- current, end, sign, allow_trailing_junk);
+ current, end, negative, allow_trailing_junk);
case 16:
return InternalStringToIntDouble<4>(
- current, end, sign, allow_trailing_junk);
+ current, end, negative, allow_trailing_junk);
case 32:
return InternalStringToIntDouble<5>(
- current, end, sign, allow_trailing_junk);
+ current, end, negative, allow_trailing_junk);
default:
UNREACHABLE();
}
@@ -344,7 +344,7 @@
ASSERT(buffer_pos < kBufferSize);
buffer[buffer_pos] = '\0';
Vector<const char> buffer_vector(buffer, buffer_pos);
- return sign ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
+ return negative ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
}
// The following code causes accumulating rounding error for numbers
greater
@@ -406,7 +406,7 @@
return JUNK_STRING_VALUE;
}
- return sign ? -v : v;
+ return negative ? -v : v;
}
@@ -445,7 +445,7 @@
bool nonzero_digit_dropped = false;
bool fractional_part = false;
- bool sign = false;
+ bool negative = false;
if (*current == '+') {
// Ignore leading sign.
@@ -454,7 +454,7 @@
} else if (*current == '-') {
++current;
if (current == end) return JUNK_STRING_VALUE;
- sign = true;
+ negative = true;
}
static const char kInfinitySymbol[] = "Infinity";
@@ -468,13 +468,13 @@
}
ASSERT(buffer_pos == 0);
- return sign ? -V8_INFINITY : V8_INFINITY;
+ return negative ? -V8_INFINITY : V8_INFINITY;
}
bool leading_zero = false;
if (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
leading_zero = true;
@@ -487,14 +487,14 @@
return InternalStringToIntDouble<4>(current,
end,
- sign,
+ negative,
allow_trailing_junk);
}
// Ignore leading zeros in the integer part.
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
}
}
@@ -539,7 +539,7 @@
// leading zeros (if any).
while (*current == '0') {
++current;
- if (current == end) return SignedZero(sign);
+ if (current == end) return SignedZero(negative);
exponent--; // Move this 0 into the exponent.
}
}
@@ -631,7 +631,7 @@
if (octal) {
return InternalStringToIntDouble<3>(buffer,
buffer + buffer_pos,
- sign,
+ negative,
allow_trailing_junk);
}
@@ -644,7 +644,7 @@
buffer[buffer_pos] = '\0';
double converted = Strtod(Vector<const char>(buffer, buffer_pos),
exponent);
- return sign ? -converted : converted;
+ return negative ? -converted : converted;
}
@@ -702,26 +702,12 @@
const char* DoubleToCString(double v, Vector<char> buffer) {
- StringBuilder builder(buffer.start(), buffer.length());
-
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;
-
- case FP_ZERO:
- builder.AddCharacter('0');
- break;
-
+ case FP_NAN: return "NaN";
+ case FP_INFINITE: return (v < 0.0 ? "-Infinity" : "Infinity");
+ case FP_ZERO: return "0";
default: {
+ StringBuilder builder(buffer.start(), buffer.length());
int decimal_point;
int sign;
const int kV8DtoaBufferCapacity = kBase10MaximalLength + 1;
@@ -764,9 +750,9 @@
if (exponent < 0) exponent = -exponent;
builder.AddFormatted("%d", exponent);
}
+ return builder.Finalize();
}
}
- return builder.Finalize();
}
=======================================
--- /branches/bleeding_edge/src/parser.cc Fri Feb 4 10:36:37 2011
+++ /branches/bleeding_edge/src/parser.cc Mon Feb 7 00:57:06 2011
@@ -4013,16 +4013,10 @@
Handle<Object> JsonParser::ParseJsonValue() {
Token::Value token = scanner_.Next();
switch (token) {
- case Token::STRING: {
+ case Token::STRING:
return GetString();
- }
- case Token::NUMBER: {
- ASSERT(scanner_.is_literal_ascii());
- double value = StringToDouble(scanner_.literal_ascii_string(),
- NO_FLAGS, // Hex, octal or trailing
junk.
- OS::nan_value());
- return Factory::NewNumber(value);
- }
+ case Token::NUMBER:
+ return Factory::NewNumber(scanner_.number());
case Token::FALSE_LITERAL:
return Factory::false_value();
case Token::TRUE_LITERAL:
=======================================
--- /branches/bleeding_edge/src/scanner.cc Fri Jan 14 02:49:18 2011
+++ /branches/bleeding_edge/src/scanner.cc Mon Feb 7 00:57:06 2011
@@ -516,17 +516,30 @@
Token::Value JsonScanner::ScanJsonNumber() {
LiteralScope literal(this);
- if (c0_ == '-') AddLiteralCharAdvance();
+ bool negative = false;
+
+ if (c0_ == '-') {
+ AddLiteralCharAdvance();
+ negative = true;
+ }
if (c0_ == '0') {
AddLiteralCharAdvance();
// Prefix zero is only allowed if it's the only digit before
// a decimal point or exponent.
if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL;
} else {
+ int i = 0;
+ int digits = 0;
if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL;
do {
+ i = i * 10 + c0_ - '0';
+ digits++;
AddLiteralCharAdvance();
} while (c0_ >= '0' && c0_ <= '9');
+ if (c0_ != '.' && c0_ != 'e' && c0_ != 'E' && digits < 10) {
+ number_ = (negative ? -i : i);
+ return Token::NUMBER;
+ }
}
if (c0_ == '.') {
AddLiteralCharAdvance();
@@ -544,6 +557,10 @@
} while (c0_ >= '0' && c0_ <= '9');
}
literal.Complete();
+ ASSERT_NOT_NULL(next_.literal_chars);
+ number_ = StringToDouble(next_.literal_chars->ascii_literal(),
+ NO_FLAGS, // Hex, octal or trailing junk.
+ OS::nan_value());
return Token::NUMBER;
}
=======================================
--- /branches/bleeding_edge/src/scanner.h Fri Jan 14 02:49:18 2011
+++ /branches/bleeding_edge/src/scanner.h Mon Feb 7 00:57:06 2011
@@ -148,6 +148,12 @@
// Returns the next token.
Token::Value Next();
+ // Returns the value of a number token.
+ double number() {
+ return number_;
+ }
+
+
protected:
// Skip past JSON whitespace (only space, tab, newline and
carrige-return).
bool SkipJsonWhiteSpace();
@@ -178,6 +184,9 @@
// are the only valid JSON identifiers (productions JSONBooleanLiteral,
// JSONNullLiteral).
Token::Value ScanJsonIdentifier(const char* text, Token::Value token);
+
+ // Holds the value of a scanned number token.
+ double number_;
};
} } // namespace v8::internal
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev