| Index: src/scanner-base.cc
|
| diff --git a/src/scanner-base.cc b/src/scanner-base.cc
|
| index 377de342d137e94aa1cb35d5c72642e156ea010c..8242f81c3f11dedc982c63f06dd3e587f0283de3 100644
|
| --- a/src/scanner-base.cc
|
| +++ b/src/scanner-base.cc
|
| @@ -480,7 +480,7 @@ void JavaScriptScanner::Scan() {
|
|
|
| default:
|
| if (ScannerConstants::kIsIdentifierStart.get(c0_)) {
|
| - token = ScanIdentifier();
|
| + token = ScanIdentifierOrKeyword();
|
| } else if (IsDecimalDigit(c0_)) {
|
| token = ScanNumber(false);
|
| } else if (SkipWhiteSpace()) {
|
| @@ -559,7 +559,7 @@ Token::Value JavaScriptScanner::ScanString() {
|
| uc32 quote = c0_;
|
| Advance(); // consume quote
|
|
|
| - LiteralScope literal(this);
|
| + LiteralScope literal(this, kLiteralString);
|
| while (c0_ != quote && c0_ >= 0
|
| && !ScannerConstants::kIsLineTerminator.get(c0_)) {
|
| uc32 c = c0_;
|
| @@ -590,7 +590,7 @@ Token::Value JavaScriptScanner::ScanNumber(bool seen_period) {
|
|
|
| enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
|
|
|
| - LiteralScope literal(this);
|
| + LiteralScope literal(this, kLiteralNumber);
|
| if (seen_period) {
|
| // we have already seen a decimal point of the float
|
| AddLiteralChar('.');
|
| @@ -677,25 +677,44 @@ uc32 JavaScriptScanner::ScanIdentifierUnicodeEscape() {
|
| }
|
|
|
|
|
| -Token::Value JavaScriptScanner::ScanIdentifier() {
|
| +Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() {
|
| ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_));
|
| -
|
| - LiteralScope literal(this);
|
| + LiteralScope literal(this, kLiteralIdentifier);
|
| KeywordMatcher keyword_match;
|
| -
|
| // Scan identifier start character.
|
| if (c0_ == '\\') {
|
| uc32 c = ScanIdentifierUnicodeEscape();
|
| // Only allow legal identifier start characters.
|
| if (!ScannerConstants::kIsIdentifierStart.get(c)) return Token::ILLEGAL;
|
| AddLiteralChar(c);
|
| - keyword_match.Fail();
|
| - } else {
|
| - AddLiteralChar(c0_);
|
| - keyword_match.AddChar(c0_);
|
| - Advance();
|
| + return ScanIdentifierSuffix(&literal);
|
| + }
|
| +
|
| + uc32 first_char = c0_;
|
| + Advance();
|
| + AddLiteralChar(first_char);
|
| + if (!keyword_match.AddChar(first_char)) {
|
| + return ScanIdentifierSuffix(&literal);
|
| + }
|
| +
|
| + // Scan the rest of the identifier characters.
|
| + while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
|
| + if (c0_ != '\\') {
|
| + uc32 next_char = c0_;
|
| + Advance();
|
| + AddLiteralChar(next_char);
|
| + if (keyword_match.AddChar(next_char)) continue;
|
| + }
|
| + // Fallthrough if no loner able to complete keyword.
|
| + return ScanIdentifierSuffix(&literal);
|
| }
|
| + literal.Complete();
|
| +
|
| + return keyword_match.token();
|
| +}
|
| +
|
|
|
| +Token::Value JavaScriptScanner::ScanIdentifierSuffix(LiteralScope* literal) {
|
| // Scan the rest of the identifier characters.
|
| while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
|
| if (c0_ == '\\') {
|
| @@ -703,20 +722,17 @@ Token::Value JavaScriptScanner::ScanIdentifier() {
|
| // Only allow legal identifier part characters.
|
| if (!ScannerConstants::kIsIdentifierPart.get(c)) return Token::ILLEGAL;
|
| AddLiteralChar(c);
|
| - keyword_match.Fail();
|
| } else {
|
| AddLiteralChar(c0_);
|
| - keyword_match.AddChar(c0_);
|
| Advance();
|
| }
|
| }
|
| - literal.Complete();
|
| + literal->Complete();
|
|
|
| - return keyword_match.token();
|
| + return Token::IDENTIFIER;
|
| }
|
|
|
|
|
| -
|
| bool JavaScriptScanner::ScanRegExpPattern(bool seen_equal) {
|
| // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
|
| bool in_character_class = false;
|
| @@ -729,7 +745,7 @@ bool JavaScriptScanner::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.
|
| - LiteralScope literal(this);
|
| + LiteralScope literal(this, kLiteralRegExp);
|
| if (seen_equal)
|
| AddLiteralChar('=');
|
|
|
| @@ -752,9 +768,10 @@ bool JavaScriptScanner::ScanRegExpPattern(bool seen_equal) {
|
| return true;
|
| }
|
|
|
| +
|
| bool JavaScriptScanner::ScanRegExpFlags() {
|
| // Scan regular expression flags.
|
| - LiteralScope literal(this);
|
| + LiteralScope literal(this, kLiteralRegExpFlags);
|
| while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
|
| if (c0_ == '\\') {
|
| uc32 c = ScanIdentifierUnicodeEscape();
|
| @@ -868,9 +885,7 @@ void KeywordMatcher::Step(unibrow::uchar input) {
|
| break;
|
| case IN:
|
| token_ = Token::IDENTIFIER;
|
| - if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) {
|
| - return;
|
| - }
|
| + if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return;
|
| break;
|
| case N:
|
| if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
|
|
|