| Index: src/scanner.cc
|
| diff --git a/src/scanner.cc b/src/scanner.cc
|
| index 7911be0cdbd95aed372f94968888d5f9f367d3aa..1a8d721c0ebed544b47efe1612c2ebaee2ec3285 100755
|
| --- a/src/scanner.cc
|
| +++ b/src/scanner.cc
|
| @@ -319,6 +319,26 @@ void KeywordMatcher::Step(uc32 input) {
|
| }
|
|
|
|
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Scanner::LiteralScope
|
| +
|
| +Scanner::LiteralScope::LiteralScope(Scanner* self)
|
| + : scanner_(self), complete_(false) {
|
| + self->StartLiteral();
|
| +}
|
| +
|
| +
|
| +Scanner::LiteralScope::~LiteralScope() {
|
| + if (!complete_) scanner_->DropLiteral();
|
| +}
|
| +
|
| +
|
| +void Scanner::LiteralScope::Complete() {
|
| + scanner_->TerminateLiteral();
|
| + complete_ = true;
|
| +}
|
| +
|
| // ----------------------------------------------------------------------------
|
| // Scanner
|
|
|
| @@ -386,8 +406,10 @@ void Scanner::Init(Handle<String> source,
|
| // Set c0_ (one character ahead)
|
| ASSERT(kCharacterLookaheadBufferSize == 1);
|
| Advance();
|
| - // Initialise current_ to not refer to a literal.
|
| + // Initialize current_ to not refer to a literal.
|
| current_.literal_chars = Vector<const char>();
|
| + // Reset literal buffer.
|
| + literal_buffer_.Reset();
|
|
|
| // Skip initial whitespace allowing HTML comment ends just like
|
| // after a newline and scan first token.
|
| @@ -423,11 +445,17 @@ void Scanner::AddChar(uc32 c) {
|
| literal_buffer_.AddChar(c);
|
| }
|
|
|
| +
|
| void Scanner::TerminateLiteral() {
|
| next_.literal_chars = literal_buffer_.EndLiteral();
|
| }
|
|
|
|
|
| +void Scanner::DropLiteral() {
|
| + literal_buffer_.DropLiteral();
|
| +}
|
| +
|
| +
|
| void Scanner::AddCharAdvance() {
|
| AddChar(c0_);
|
| Advance();
|
| @@ -636,7 +664,7 @@ void Scanner::ScanJson() {
|
| Token::Value Scanner::ScanJsonString() {
|
| ASSERT_EQ('"', c0_);
|
| Advance();
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| while (c0_ != '"' && c0_ > 0) {
|
| // Check for control character (0x00-0x1f) or unterminated string (<0).
|
| if (c0_ < 0x20) return Token::ILLEGAL;
|
| @@ -670,7 +698,9 @@ Token::Value Scanner::ScanJsonString() {
|
| for (int i = 0; i < 4; i++) {
|
| Advance();
|
| int digit = HexValue(c0_);
|
| - if (digit < 0) return Token::ILLEGAL;
|
| + if (digit < 0) {
|
| + return Token::ILLEGAL;
|
| + }
|
| value = value * 16 + digit;
|
| }
|
| AddChar(value);
|
| @@ -685,14 +715,14 @@ Token::Value Scanner::ScanJsonString() {
|
| if (c0_ != '"') {
|
| return Token::ILLEGAL;
|
| }
|
| - TerminateLiteral();
|
| + literal.Complete();
|
| Advance();
|
| return Token::STRING;
|
| }
|
|
|
|
|
| Token::Value Scanner::ScanJsonNumber() {
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| if (c0_ == '-') AddCharAdvance();
|
| if (c0_ == '0') {
|
| AddCharAdvance();
|
| @@ -720,21 +750,21 @@ Token::Value Scanner::ScanJsonNumber() {
|
| AddCharAdvance();
|
| } while (c0_ >= '0' && c0_ <= '9');
|
| }
|
| - TerminateLiteral();
|
| + literal.Complete();
|
| return Token::NUMBER;
|
| }
|
|
|
|
|
| Token::Value Scanner::ScanJsonIdentifier(const char* text,
|
| Token::Value token) {
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| while (*text != '\0') {
|
| if (c0_ != *text) return Token::ILLEGAL;
|
| Advance();
|
| text++;
|
| }
|
| if (kIsIdentifierPart.get(c0_)) return Token::ILLEGAL;
|
| - TerminateLiteral();
|
| + literal.Complete();
|
| return token;
|
| }
|
|
|
| @@ -1077,7 +1107,7 @@ Token::Value Scanner::ScanString() {
|
| uc32 quote = c0_;
|
| Advance(); // consume quote
|
|
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| while (c0_ != quote && c0_ >= 0 && !kIsLineTerminator.get(c0_)) {
|
| uc32 c = c0_;
|
| Advance();
|
| @@ -1088,10 +1118,8 @@ Token::Value Scanner::ScanString() {
|
| AddChar(c);
|
| }
|
| }
|
| - if (c0_ != quote) {
|
| - return Token::ILLEGAL;
|
| - }
|
| - TerminateLiteral();
|
| + if (c0_ != quote) return Token::ILLEGAL;
|
| + literal.Complete();
|
|
|
| Advance(); // consume quote
|
| return Token::STRING;
|
| @@ -1127,7 +1155,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|
|
| enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
|
|
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| if (seen_period) {
|
| // we have already seen a decimal point of the float
|
| AddChar('.');
|
| @@ -1143,12 +1171,13 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
| // hex number
|
| kind = HEX;
|
| AddCharAdvance();
|
| - if (!IsHexDigit(c0_))
|
| + if (!IsHexDigit(c0_)) {
|
| // we must have at least one hex digit after 'x'/'X'
|
| return Token::ILLEGAL;
|
| - while (IsHexDigit(c0_))
|
| + }
|
| + while (IsHexDigit(c0_)) {
|
| AddCharAdvance();
|
| -
|
| + }
|
| } else if ('0' <= c0_ && c0_ <= '7') {
|
| // (possible) octal number
|
| kind = OCTAL;
|
| @@ -1181,12 +1210,12 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
| AddCharAdvance();
|
| if (c0_ == '+' || c0_ == '-')
|
| AddCharAdvance();
|
| - if (!IsDecimalDigit(c0_))
|
| + if (!IsDecimalDigit(c0_)) {
|
| // we must have at least one decimal digit after 'e'/'E'
|
| return Token::ILLEGAL;
|
| + }
|
| ScanDecimalDigits();
|
| }
|
| - TerminateLiteral();
|
|
|
| // The source character immediately following a numeric literal must
|
| // not be an identifier start or a decimal digit; see ECMA-262
|
| @@ -1195,6 +1224,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
| if (IsDecimalDigit(c0_) || kIsIdentifierStart.get(c0_))
|
| return Token::ILLEGAL;
|
|
|
| + literal.Complete();
|
| +
|
| return Token::NUMBER;
|
| }
|
|
|
| @@ -1214,7 +1245,7 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
|
| Token::Value Scanner::ScanIdentifier() {
|
| ASSERT(kIsIdentifierStart.get(c0_));
|
|
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| KeywordMatcher keyword_match;
|
|
|
| // Scan identifier start character.
|
| @@ -1244,7 +1275,7 @@ Token::Value Scanner::ScanIdentifier() {
|
| Advance();
|
| }
|
| }
|
| - TerminateLiteral();
|
| + literal.Complete();
|
|
|
| return keyword_match.token();
|
| }
|
| @@ -1274,36 +1305,32 @@ bool Scanner::ScanRegExpPattern(bool seen_equal) {
|
| // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
|
| // the scanner should pass uninterpreted bodies to the RegExp
|
| // constructor.
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| if (seen_equal)
|
| AddChar('=');
|
|
|
| while (c0_ != '/' || in_character_class) {
|
| - if (kIsLineTerminator.get(c0_) || c0_ < 0)
|
| - return false;
|
| + if (kIsLineTerminator.get(c0_) || c0_ < 0) return false;
|
| if (c0_ == '\\') { // escaped character
|
| AddCharAdvance();
|
| - if (kIsLineTerminator.get(c0_) || c0_ < 0)
|
| - return false;
|
| + if (kIsLineTerminator.get(c0_) || c0_ < 0) return false;
|
| AddCharAdvance();
|
| } else { // unescaped character
|
| - if (c0_ == '[')
|
| - in_character_class = true;
|
| - if (c0_ == ']')
|
| - in_character_class = false;
|
| + if (c0_ == '[') in_character_class = true;
|
| + if (c0_ == ']') in_character_class = false;
|
| AddCharAdvance();
|
| }
|
| }
|
| Advance(); // consume '/'
|
|
|
| - TerminateLiteral();
|
| + literal.Complete();
|
|
|
| return true;
|
| }
|
|
|
| bool Scanner::ScanRegExpFlags() {
|
| // Scan regular expression flags.
|
| - StartLiteral();
|
| + LiteralScope literal(this);
|
| while (kIsIdentifierPart.get(c0_)) {
|
| if (c0_ == '\\') {
|
| uc32 c = ScanIdentifierUnicodeEscape();
|
| @@ -1316,7 +1343,7 @@ bool Scanner::ScanRegExpFlags() {
|
| }
|
| AddCharAdvance();
|
| }
|
| - TerminateLiteral();
|
| + literal.Complete();
|
|
|
| next_.location.end_pos = source_pos() - 1;
|
| return true;
|
|
|