Index: src/scanner.cc |
diff --git a/src/scanner.cc b/src/scanner.cc |
index 04712e9f32a8ea529cc3b02ff6210e4e0d2b6e91..7e429718ec96c5e56b1dc17121bf64543f5fd768 100644 |
--- a/src/scanner.cc |
+++ b/src/scanner.cc |
@@ -1177,7 +1177,7 @@ uc32 Scanner::ScanUnicodeEscape() { |
static Token::Value KeywordOrIdentifierToken(const uint8_t* input, |
- int input_length) { |
+ int input_length, bool escaped) { |
DCHECK(input_length >= 1); |
const int kMinLength = 2; |
const int kMaxLength = 10; |
@@ -1189,26 +1189,30 @@ static Token::Value KeywordOrIdentifierToken(const uint8_t* input, |
#define KEYWORD_GROUP_CASE(ch) \ |
break; \ |
case ch: |
-#define KEYWORD(keyword, token) \ |
- { \ |
- /* 'keyword' is a char array, so sizeof(keyword) is */ \ |
- /* strlen(keyword) plus 1 for the NUL char. */ \ |
- const int keyword_length = sizeof(keyword) - 1; \ |
- STATIC_ASSERT(keyword_length >= kMinLength); \ |
- STATIC_ASSERT(keyword_length <= kMaxLength); \ |
- if (input_length == keyword_length && \ |
- input[1] == keyword[1] && \ |
- (keyword_length <= 2 || input[2] == keyword[2]) && \ |
- (keyword_length <= 3 || input[3] == keyword[3]) && \ |
- (keyword_length <= 4 || input[4] == keyword[4]) && \ |
- (keyword_length <= 5 || input[5] == keyword[5]) && \ |
- (keyword_length <= 6 || input[6] == keyword[6]) && \ |
- (keyword_length <= 7 || input[7] == keyword[7]) && \ |
- (keyword_length <= 8 || input[8] == keyword[8]) && \ |
- (keyword_length <= 9 || input[9] == keyword[9])) { \ |
- return token; \ |
- } \ |
- } |
+#define KEYWORD(keyword, token) \ |
+ { \ |
+ /* 'keyword' is a char array, so sizeof(keyword) is */ \ |
+ /* strlen(keyword) plus 1 for the NUL char. */ \ |
+ const int keyword_length = sizeof(keyword) - 1; \ |
+ STATIC_ASSERT(keyword_length >= kMinLength); \ |
+ STATIC_ASSERT(keyword_length <= kMaxLength); \ |
+ if (input_length == keyword_length && input[1] == keyword[1] && \ |
+ (keyword_length <= 2 || input[2] == keyword[2]) && \ |
+ (keyword_length <= 3 || input[3] == keyword[3]) && \ |
+ (keyword_length <= 4 || input[4] == keyword[4]) && \ |
+ (keyword_length <= 5 || input[5] == keyword[5]) && \ |
+ (keyword_length <= 6 || input[6] == keyword[6]) && \ |
+ (keyword_length <= 7 || input[7] == keyword[7]) && \ |
+ (keyword_length <= 8 || input[8] == keyword[8]) && \ |
+ (keyword_length <= 9 || input[9] == keyword[9])) { \ |
+ if (escaped) { \ |
+ return token == Token::FUTURE_STRICT_RESERVED_WORD \ |
+ ? Token::ESCAPED_STRICT_RESERVED_WORD \ |
+ : Token::ESCAPED_KEYWORD; \ |
+ } \ |
+ return token; \ |
+ } \ |
+ } |
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD) |
} |
return Token::IDENTIFIER; |
@@ -1224,7 +1228,7 @@ bool Scanner::IdentifierIsFutureStrictReserved( |
return true; |
} |
return Token::FUTURE_STRICT_RESERVED_WORD == |
- KeywordOrIdentifierToken(string->raw_data(), string->length()); |
+ KeywordOrIdentifierToken(string->raw_data(), string->length(), false); |
} |
@@ -1257,7 +1261,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() { |
// Only a-z+: could be a keyword or identifier. |
literal.Complete(); |
Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); |
- return KeywordOrIdentifierToken(chars.start(), chars.length()); |
+ return KeywordOrIdentifierToken(chars.start(), chars.length(), false); |
} |
HandleLeadSurrogate(); |
@@ -1284,7 +1288,7 @@ Token::Value Scanner::ScanIdentifierOrKeyword() { |
return Token::ILLEGAL; |
} |
AddLiteralChar(c); |
- return ScanIdentifierSuffix(&literal); |
+ return ScanIdentifierSuffix(&literal, true); |
} else { |
uc32 first_char = c0_; |
Advance(); |
@@ -1300,24 +1304,26 @@ Token::Value Scanner::ScanIdentifierOrKeyword() { |
continue; |
} |
// Fallthrough if no longer able to complete keyword. |
- return ScanIdentifierSuffix(&literal); |
+ return ScanIdentifierSuffix(&literal, false); |
} |
literal.Complete(); |
if (next_.literal_chars->is_one_byte()) { |
Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); |
- return KeywordOrIdentifierToken(chars.start(), chars.length()); |
+ return KeywordOrIdentifierToken(chars.start(), chars.length(), false); |
} |
return Token::IDENTIFIER; |
} |
-Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) { |
+Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal, |
+ bool escaped) { |
// Scan the rest of the identifier characters. |
while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) { |
if (c0_ == '\\') { |
uc32 c = ScanIdentifierUnicodeEscape(); |
+ escaped = true; |
// Only allow legal identifier part characters. |
if (c < 0 || |
c == '\\' || |
@@ -1332,6 +1338,10 @@ Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) { |
} |
literal->Complete(); |
+ if (escaped && next_.literal_chars->is_one_byte()) { |
+ Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); |
+ return KeywordOrIdentifierToken(chars.start(), chars.length(), true); |
+ } |
return Token::IDENTIFIER; |
} |