Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/scanner.cc

Issue 3137037: Ensure that scanner state is correctly reset when an error is encountered. (Closed)
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/scanner.h ('K') | « src/scanner.h ('k') | src/utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; 312 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return;
313 break; 313 break;
314 default: 314 default:
315 UNREACHABLE(); 315 UNREACHABLE();
316 } 316 }
317 // On fallthrough, it's a failure. 317 // On fallthrough, it's a failure.
318 state_ = UNMATCHABLE; 318 state_ = UNMATCHABLE;
319 } 319 }
320 320
321 321
322
323 // ----------------------------------------------------------------------------
324 // Scanner::LiteralScope
325
326 Scanner::LiteralScope::LiteralScope(Scanner* self)
327 : scanner_(self), complete_(false) {
328 self->StartLiteral();
329 }
330
331
332 Scanner::LiteralScope::~LiteralScope() {
333 if (!complete_) scanner_->DropLiteral();
334 }
335
336
337 void Scanner::LiteralScope::Complete() {
338 scanner_->TerminateLiteral();
339 complete_ = true;
340 }
341
322 // ---------------------------------------------------------------------------- 342 // ----------------------------------------------------------------------------
323 // Scanner 343 // Scanner
324 344
325 Scanner::Scanner(ParserMode pre) 345 Scanner::Scanner(ParserMode pre)
326 : is_pre_parsing_(pre == PREPARSE), stack_overflow_(false) { } 346 : is_pre_parsing_(pre == PREPARSE), stack_overflow_(false) { }
327 347
328 348
329 void Scanner::Initialize(Handle<String> source, 349 void Scanner::Initialize(Handle<String> source,
330 ParserLanguage language) { 350 ParserLanguage language) {
331 Init(source, NULL, 0, source->length(), language); 351 Init(source, NULL, 0, source->length(), language);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 start_position, 399 start_position,
380 end_position); 400 end_position);
381 source_ = &char_stream_buffer_; 401 source_ = &char_stream_buffer_;
382 } 402 }
383 403
384 is_parsing_json_ = (language == JSON); 404 is_parsing_json_ = (language == JSON);
385 405
386 // Set c0_ (one character ahead) 406 // Set c0_ (one character ahead)
387 ASSERT(kCharacterLookaheadBufferSize == 1); 407 ASSERT(kCharacterLookaheadBufferSize == 1);
388 Advance(); 408 Advance();
389 // Initialise current_ to not refer to a literal. 409 // Initialize current_ to not refer to a literal.
390 current_.literal_chars = Vector<const char>(); 410 current_.literal_chars = Vector<const char>();
411 // Reset literal buffer.
412 literal_buffer_.Reset();
391 413
392 // Skip initial whitespace allowing HTML comment ends just like 414 // Skip initial whitespace allowing HTML comment ends just like
393 // after a newline and scan first token. 415 // after a newline and scan first token.
394 has_line_terminator_before_next_ = true; 416 has_line_terminator_before_next_ = true;
395 SkipWhiteSpace(); 417 SkipWhiteSpace();
396 Scan(); 418 Scan();
397 } 419 }
398 420
399 421
400 Token::Value Scanner::Next() { 422 Token::Value Scanner::Next() {
(...skipping 15 matching lines...) Expand all
416 438
417 void Scanner::StartLiteral() { 439 void Scanner::StartLiteral() {
418 literal_buffer_.StartLiteral(); 440 literal_buffer_.StartLiteral();
419 } 441 }
420 442
421 443
422 void Scanner::AddChar(uc32 c) { 444 void Scanner::AddChar(uc32 c) {
423 literal_buffer_.AddChar(c); 445 literal_buffer_.AddChar(c);
424 } 446 }
425 447
448
426 void Scanner::TerminateLiteral() { 449 void Scanner::TerminateLiteral() {
427 next_.literal_chars = literal_buffer_.EndLiteral(); 450 next_.literal_chars = literal_buffer_.EndLiteral();
428 } 451 }
429 452
430 453
454 void Scanner::DropLiteral() {
455 literal_buffer_.DropLiteral();
456 }
457
458
431 void Scanner::AddCharAdvance() { 459 void Scanner::AddCharAdvance() {
432 AddChar(c0_); 460 AddChar(c0_);
433 Advance(); 461 Advance();
434 } 462 }
435 463
436 464
437 static inline bool IsByteOrderMark(uc32 c) { 465 static inline bool IsByteOrderMark(uc32 c) {
438 // The Unicode value U+FFFE is guaranteed never to be assigned as a 466 // The Unicode value U+FFFE is guaranteed never to be assigned as a
439 // Unicode character; this implies that in a Unicode context the 467 // Unicode character; this implies that in a Unicode context the
440 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF 468 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 } while (token == Token::WHITESPACE); 657 } while (token == Token::WHITESPACE);
630 658
631 next_.location.end_pos = source_pos(); 659 next_.location.end_pos = source_pos();
632 next_.token = token; 660 next_.token = token;
633 } 661 }
634 662
635 663
636 Token::Value Scanner::ScanJsonString() { 664 Token::Value Scanner::ScanJsonString() {
637 ASSERT_EQ('"', c0_); 665 ASSERT_EQ('"', c0_);
638 Advance(); 666 Advance();
639 StartLiteral(); 667 LiteralScope literal(this);
640 while (c0_ != '"' && c0_ > 0) { 668 while (c0_ != '"' && c0_ > 0) {
641 // Check for control character (0x00-0x1f) or unterminated string (<0). 669 // Check for control character (0x00-0x1f) or unterminated string (<0).
642 if (c0_ < 0x20) return Token::ILLEGAL; 670 if (c0_ < 0x20) return Token::ILLEGAL;
643 if (c0_ != '\\') { 671 if (c0_ != '\\') {
644 AddCharAdvance(); 672 AddCharAdvance();
645 } else { 673 } else {
646 Advance(); 674 Advance();
647 switch (c0_) { 675 switch (c0_) {
648 case '"': 676 case '"':
649 case '\\': 677 case '\\':
(...skipping 13 matching lines...) Expand all
663 AddChar('\x0d'); 691 AddChar('\x0d');
664 break; 692 break;
665 case 't': 693 case 't':
666 AddChar('\x09'); 694 AddChar('\x09');
667 break; 695 break;
668 case 'u': { 696 case 'u': {
669 uc32 value = 0; 697 uc32 value = 0;
670 for (int i = 0; i < 4; i++) { 698 for (int i = 0; i < 4; i++) {
671 Advance(); 699 Advance();
672 int digit = HexValue(c0_); 700 int digit = HexValue(c0_);
673 if (digit < 0) return Token::ILLEGAL; 701 if (digit < 0) {
702 return Token::ILLEGAL;
703 }
674 value = value * 16 + digit; 704 value = value * 16 + digit;
675 } 705 }
676 AddChar(value); 706 AddChar(value);
677 break; 707 break;
678 } 708 }
679 default: 709 default:
680 return Token::ILLEGAL; 710 return Token::ILLEGAL;
681 } 711 }
682 Advance(); 712 Advance();
683 } 713 }
684 } 714 }
685 if (c0_ != '"') { 715 if (c0_ != '"') {
686 return Token::ILLEGAL; 716 return Token::ILLEGAL;
687 } 717 }
688 TerminateLiteral(); 718 literal.Complete();
689 Advance(); 719 Advance();
690 return Token::STRING; 720 return Token::STRING;
691 } 721 }
692 722
693 723
694 Token::Value Scanner::ScanJsonNumber() { 724 Token::Value Scanner::ScanJsonNumber() {
695 StartLiteral(); 725 LiteralScope literal(this);
696 if (c0_ == '-') AddCharAdvance(); 726 if (c0_ == '-') AddCharAdvance();
697 if (c0_ == '0') { 727 if (c0_ == '0') {
698 AddCharAdvance(); 728 AddCharAdvance();
699 // Prefix zero is only allowed if it's the only digit before 729 // Prefix zero is only allowed if it's the only digit before
700 // a decimal point or exponent. 730 // a decimal point or exponent.
701 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; 731 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL;
702 } else { 732 } else {
703 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; 733 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL;
704 do { 734 do {
705 AddCharAdvance(); 735 AddCharAdvance();
706 } while (c0_ >= '0' && c0_ <= '9'); 736 } while (c0_ >= '0' && c0_ <= '9');
707 } 737 }
708 if (c0_ == '.') { 738 if (c0_ == '.') {
709 AddCharAdvance(); 739 AddCharAdvance();
710 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 740 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
711 do { 741 do {
712 AddCharAdvance(); 742 AddCharAdvance();
713 } while (c0_ >= '0' && c0_ <= '9'); 743 } while (c0_ >= '0' && c0_ <= '9');
714 } 744 }
715 if ((c0_ | 0x20) == 'e') { 745 if ((c0_ | 0x20) == 'e') {
716 AddCharAdvance(); 746 AddCharAdvance();
717 if (c0_ == '-' || c0_ == '+') AddCharAdvance(); 747 if (c0_ == '-' || c0_ == '+') AddCharAdvance();
718 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 748 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL;
719 do { 749 do {
720 AddCharAdvance(); 750 AddCharAdvance();
721 } while (c0_ >= '0' && c0_ <= '9'); 751 } while (c0_ >= '0' && c0_ <= '9');
722 } 752 }
723 TerminateLiteral(); 753 literal.Complete();
724 return Token::NUMBER; 754 return Token::NUMBER;
725 } 755 }
726 756
727 757
728 Token::Value Scanner::ScanJsonIdentifier(const char* text, 758 Token::Value Scanner::ScanJsonIdentifier(const char* text,
729 Token::Value token) { 759 Token::Value token) {
730 StartLiteral(); 760 LiteralScope literal(this);
731 while (*text != '\0') { 761 while (*text != '\0') {
732 if (c0_ != *text) return Token::ILLEGAL; 762 if (c0_ != *text) return Token::ILLEGAL;
733 Advance(); 763 Advance();
734 text++; 764 text++;
735 } 765 }
736 if (kIsIdentifierPart.get(c0_)) return Token::ILLEGAL; 766 if (kIsIdentifierPart.get(c0_)) return Token::ILLEGAL;
737 TerminateLiteral(); 767 literal.Complete();
738 return token; 768 return token;
739 } 769 }
740 770
741 771
742 void Scanner::ScanJavaScript() { 772 void Scanner::ScanJavaScript() {
743 next_.literal_chars = Vector<const char>(); 773 next_.literal_chars = Vector<const char>();
744 Token::Value token; 774 Token::Value token;
745 has_line_terminator_before_next_ = false; 775 has_line_terminator_before_next_ = false;
746 do { 776 do {
747 // Remember the position of the next token 777 // Remember the position of the next token
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // should be illegal, but they are commonly handled 1100 // should be illegal, but they are commonly handled
1071 // as non-escaped characters by JS VMs. 1101 // as non-escaped characters by JS VMs.
1072 AddChar(c); 1102 AddChar(c);
1073 } 1103 }
1074 1104
1075 1105
1076 Token::Value Scanner::ScanString() { 1106 Token::Value Scanner::ScanString() {
1077 uc32 quote = c0_; 1107 uc32 quote = c0_;
1078 Advance(); // consume quote 1108 Advance(); // consume quote
1079 1109
1080 StartLiteral(); 1110 LiteralScope literal(this);
1081 while (c0_ != quote && c0_ >= 0 && !kIsLineTerminator.get(c0_)) { 1111 while (c0_ != quote && c0_ >= 0 && !kIsLineTerminator.get(c0_)) {
1082 uc32 c = c0_; 1112 uc32 c = c0_;
1083 Advance(); 1113 Advance();
1084 if (c == '\\') { 1114 if (c == '\\') {
1085 if (c0_ < 0) return Token::ILLEGAL; 1115 if (c0_ < 0) return Token::ILLEGAL;
1086 ScanEscape(); 1116 ScanEscape();
1087 } else { 1117 } else {
1088 AddChar(c); 1118 AddChar(c);
1089 } 1119 }
1090 } 1120 }
1091 if (c0_ != quote) { 1121 if (c0_ != quote) return Token::ILLEGAL;
1092 return Token::ILLEGAL; 1122 literal.Complete();
1093 }
1094 TerminateLiteral();
1095 1123
1096 Advance(); // consume quote 1124 Advance(); // consume quote
1097 return Token::STRING; 1125 return Token::STRING;
1098 } 1126 }
1099 1127
1100 1128
1101 Token::Value Scanner::Select(Token::Value tok) { 1129 Token::Value Scanner::Select(Token::Value tok) {
1102 Advance(); 1130 Advance();
1103 return tok; 1131 return tok;
1104 } 1132 }
(...skipping 15 matching lines...) Expand all
1120 while (IsDecimalDigit(c0_)) 1148 while (IsDecimalDigit(c0_))
1121 AddCharAdvance(); 1149 AddCharAdvance();
1122 } 1150 }
1123 1151
1124 1152
1125 Token::Value Scanner::ScanNumber(bool seen_period) { 1153 Token::Value Scanner::ScanNumber(bool seen_period) {
1126 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction 1154 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
1127 1155
1128 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; 1156 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
1129 1157
1130 StartLiteral(); 1158 LiteralScope literal(this);
1131 if (seen_period) { 1159 if (seen_period) {
1132 // we have already seen a decimal point of the float 1160 // we have already seen a decimal point of the float
1133 AddChar('.'); 1161 AddChar('.');
1134 ScanDecimalDigits(); // we know we have at least one digit 1162 ScanDecimalDigits(); // we know we have at least one digit
1135 1163
1136 } else { 1164 } else {
1137 // if the first character is '0' we must check for octals and hex 1165 // if the first character is '0' we must check for octals and hex
1138 if (c0_ == '0') { 1166 if (c0_ == '0') {
1139 AddCharAdvance(); 1167 AddCharAdvance();
1140 1168
1141 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number 1169 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number
1142 if (c0_ == 'x' || c0_ == 'X') { 1170 if (c0_ == 'x' || c0_ == 'X') {
1143 // hex number 1171 // hex number
1144 kind = HEX; 1172 kind = HEX;
1145 AddCharAdvance(); 1173 AddCharAdvance();
1146 if (!IsHexDigit(c0_)) 1174 if (!IsHexDigit(c0_)) {
1147 // we must have at least one hex digit after 'x'/'X' 1175 // we must have at least one hex digit after 'x'/'X'
1148 return Token::ILLEGAL; 1176 return Token::ILLEGAL;
1149 while (IsHexDigit(c0_)) 1177 }
1178 while (IsHexDigit(c0_)) {
1150 AddCharAdvance(); 1179 AddCharAdvance();
1151 1180 }
1152 } else if ('0' <= c0_ && c0_ <= '7') { 1181 } else if ('0' <= c0_ && c0_ <= '7') {
1153 // (possible) octal number 1182 // (possible) octal number
1154 kind = OCTAL; 1183 kind = OCTAL;
1155 while (true) { 1184 while (true) {
1156 if (c0_ == '8' || c0_ == '9') { 1185 if (c0_ == '8' || c0_ == '9') {
1157 kind = DECIMAL; 1186 kind = DECIMAL;
1158 break; 1187 break;
1159 } 1188 }
1160 if (c0_ < '0' || '7' < c0_) break; 1189 if (c0_ < '0' || '7' < c0_) break;
1161 AddCharAdvance(); 1190 AddCharAdvance();
(...skipping 12 matching lines...) Expand all
1174 } 1203 }
1175 1204
1176 // scan exponent, if any 1205 // scan exponent, if any
1177 if (c0_ == 'e' || c0_ == 'E') { 1206 if (c0_ == 'e' || c0_ == 'E') {
1178 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number 1207 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number
1179 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed 1208 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed
1180 // scan exponent 1209 // scan exponent
1181 AddCharAdvance(); 1210 AddCharAdvance();
1182 if (c0_ == '+' || c0_ == '-') 1211 if (c0_ == '+' || c0_ == '-')
1183 AddCharAdvance(); 1212 AddCharAdvance();
1184 if (!IsDecimalDigit(c0_)) 1213 if (!IsDecimalDigit(c0_)) {
1185 // we must have at least one decimal digit after 'e'/'E' 1214 // we must have at least one decimal digit after 'e'/'E'
1186 return Token::ILLEGAL; 1215 return Token::ILLEGAL;
1216 }
1187 ScanDecimalDigits(); 1217 ScanDecimalDigits();
1188 } 1218 }
1189 TerminateLiteral();
1190 1219
1191 // The source character immediately following a numeric literal must 1220 // The source character immediately following a numeric literal must
1192 // not be an identifier start or a decimal digit; see ECMA-262 1221 // not be an identifier start or a decimal digit; see ECMA-262
1193 // section 7.8.3, page 17 (note that we read only one decimal digit 1222 // section 7.8.3, page 17 (note that we read only one decimal digit
1194 // if the value is 0). 1223 // if the value is 0).
1195 if (IsDecimalDigit(c0_) || kIsIdentifierStart.get(c0_)) 1224 if (IsDecimalDigit(c0_) || kIsIdentifierStart.get(c0_))
1196 return Token::ILLEGAL; 1225 return Token::ILLEGAL;
1197 1226
1227 literal.Complete();
1228
1198 return Token::NUMBER; 1229 return Token::NUMBER;
1199 } 1230 }
1200 1231
1201 1232
1202 uc32 Scanner::ScanIdentifierUnicodeEscape() { 1233 uc32 Scanner::ScanIdentifierUnicodeEscape() {
1203 Advance(); 1234 Advance();
1204 if (c0_ != 'u') return unibrow::Utf8::kBadChar; 1235 if (c0_ != 'u') return unibrow::Utf8::kBadChar;
1205 Advance(); 1236 Advance();
1206 uc32 c = ScanHexEscape('u', 4); 1237 uc32 c = ScanHexEscape('u', 4);
1207 // We do not allow a unicode escape sequence to start another 1238 // We do not allow a unicode escape sequence to start another
1208 // unicode escape sequence. 1239 // unicode escape sequence.
1209 if (c == '\\') return unibrow::Utf8::kBadChar; 1240 if (c == '\\') return unibrow::Utf8::kBadChar;
1210 return c; 1241 return c;
1211 } 1242 }
1212 1243
1213 1244
1214 Token::Value Scanner::ScanIdentifier() { 1245 Token::Value Scanner::ScanIdentifier() {
1215 ASSERT(kIsIdentifierStart.get(c0_)); 1246 ASSERT(kIsIdentifierStart.get(c0_));
1216 1247
1217 StartLiteral(); 1248 LiteralScope literal(this);
1218 KeywordMatcher keyword_match; 1249 KeywordMatcher keyword_match;
1219 1250
1220 // Scan identifier start character. 1251 // Scan identifier start character.
1221 if (c0_ == '\\') { 1252 if (c0_ == '\\') {
1222 uc32 c = ScanIdentifierUnicodeEscape(); 1253 uc32 c = ScanIdentifierUnicodeEscape();
1223 // Only allow legal identifier start characters. 1254 // Only allow legal identifier start characters.
1224 if (!kIsIdentifierStart.get(c)) return Token::ILLEGAL; 1255 if (!kIsIdentifierStart.get(c)) return Token::ILLEGAL;
1225 AddChar(c); 1256 AddChar(c);
1226 keyword_match.Fail(); 1257 keyword_match.Fail();
1227 } else { 1258 } else {
1228 AddChar(c0_); 1259 AddChar(c0_);
1229 keyword_match.AddChar(c0_); 1260 keyword_match.AddChar(c0_);
1230 Advance(); 1261 Advance();
1231 } 1262 }
1232 1263
1233 // Scan the rest of the identifier characters. 1264 // Scan the rest of the identifier characters.
1234 while (kIsIdentifierPart.get(c0_)) { 1265 while (kIsIdentifierPart.get(c0_)) {
1235 if (c0_ == '\\') { 1266 if (c0_ == '\\') {
1236 uc32 c = ScanIdentifierUnicodeEscape(); 1267 uc32 c = ScanIdentifierUnicodeEscape();
1237 // Only allow legal identifier part characters. 1268 // Only allow legal identifier part characters.
1238 if (!kIsIdentifierPart.get(c)) return Token::ILLEGAL; 1269 if (!kIsIdentifierPart.get(c)) return Token::ILLEGAL;
1239 AddChar(c); 1270 AddChar(c);
1240 keyword_match.Fail(); 1271 keyword_match.Fail();
1241 } else { 1272 } else {
1242 AddChar(c0_); 1273 AddChar(c0_);
1243 keyword_match.AddChar(c0_); 1274 keyword_match.AddChar(c0_);
1244 Advance(); 1275 Advance();
1245 } 1276 }
1246 } 1277 }
1247 TerminateLiteral(); 1278 literal.Complete();
1248 1279
1249 return keyword_match.token(); 1280 return keyword_match.token();
1250 } 1281 }
1251 1282
1252 1283
1253 1284
1254 bool Scanner::IsIdentifier(unibrow::CharacterStream* buffer) { 1285 bool Scanner::IsIdentifier(unibrow::CharacterStream* buffer) {
1255 // Checks whether the buffer contains an identifier (no escape). 1286 // Checks whether the buffer contains an identifier (no escape).
1256 if (!buffer->has_more()) return false; 1287 if (!buffer->has_more()) return false;
1257 if (!kIsIdentifierStart.get(buffer->GetNext())) return false; 1288 if (!kIsIdentifierStart.get(buffer->GetNext())) return false;
1258 while (buffer->has_more()) { 1289 while (buffer->has_more()) {
1259 if (!kIsIdentifierPart.get(buffer->GetNext())) return false; 1290 if (!kIsIdentifierPart.get(buffer->GetNext())) return false;
1260 } 1291 }
1261 return true; 1292 return true;
1262 } 1293 }
1263 1294
1264 1295
1265 bool Scanner::ScanRegExpPattern(bool seen_equal) { 1296 bool Scanner::ScanRegExpPattern(bool seen_equal) {
1266 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags 1297 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
1267 bool in_character_class = false; 1298 bool in_character_class = false;
1268 1299
1269 // Previous token is either '/' or '/=', in the second case, the 1300 // Previous token is either '/' or '/=', in the second case, the
1270 // pattern starts at =. 1301 // pattern starts at =.
1271 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); 1302 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);
1272 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); 1303 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);
1273 1304
1274 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, 1305 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
1275 // the scanner should pass uninterpreted bodies to the RegExp 1306 // the scanner should pass uninterpreted bodies to the RegExp
1276 // constructor. 1307 // constructor.
1277 StartLiteral(); 1308 LiteralScope literal(this);
1278 if (seen_equal) 1309 if (seen_equal)
1279 AddChar('='); 1310 AddChar('=');
1280 1311
1281 while (c0_ != '/' || in_character_class) { 1312 while (c0_ != '/' || in_character_class) {
1282 if (kIsLineTerminator.get(c0_) || c0_ < 0) 1313 if (kIsLineTerminator.get(c0_) || c0_ < 0) return false;
1283 return false;
1284 if (c0_ == '\\') { // escaped character 1314 if (c0_ == '\\') { // escaped character
1285 AddCharAdvance(); 1315 AddCharAdvance();
1286 if (kIsLineTerminator.get(c0_) || c0_ < 0) 1316 if (kIsLineTerminator.get(c0_) || c0_ < 0) return false;
1287 return false;
1288 AddCharAdvance(); 1317 AddCharAdvance();
1289 } else { // unescaped character 1318 } else { // unescaped character
1290 if (c0_ == '[') 1319 if (c0_ == '[') in_character_class = true;
1291 in_character_class = true; 1320 if (c0_ == ']') in_character_class = false;
1292 if (c0_ == ']')
1293 in_character_class = false;
1294 AddCharAdvance(); 1321 AddCharAdvance();
1295 } 1322 }
1296 } 1323 }
1297 Advance(); // consume '/' 1324 Advance(); // consume '/'
1298 1325
1299 TerminateLiteral(); 1326 literal.Complete();
1300 1327
1301 return true; 1328 return true;
1302 } 1329 }
1303 1330
1304 bool Scanner::ScanRegExpFlags() { 1331 bool Scanner::ScanRegExpFlags() {
1305 // Scan regular expression flags. 1332 // Scan regular expression flags.
1306 StartLiteral(); 1333 LiteralScope literal(this);
1307 while (kIsIdentifierPart.get(c0_)) { 1334 while (kIsIdentifierPart.get(c0_)) {
1308 if (c0_ == '\\') { 1335 if (c0_ == '\\') {
1309 uc32 c = ScanIdentifierUnicodeEscape(); 1336 uc32 c = ScanIdentifierUnicodeEscape();
1310 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) { 1337 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) {
1311 // We allow any escaped character, unlike the restriction on 1338 // We allow any escaped character, unlike the restriction on
1312 // IdentifierPart when it is used to build an IdentifierName. 1339 // IdentifierPart when it is used to build an IdentifierName.
1313 AddChar(c); 1340 AddChar(c);
1314 continue; 1341 continue;
1315 } 1342 }
1316 } 1343 }
1317 AddCharAdvance(); 1344 AddCharAdvance();
1318 } 1345 }
1319 TerminateLiteral(); 1346 literal.Complete();
1320 1347
1321 next_.location.end_pos = source_pos() - 1; 1348 next_.location.end_pos = source_pos() - 1;
1322 return true; 1349 return true;
1323 } 1350 }
1324 1351
1325 } } // namespace v8::internal 1352 } } // namespace v8::internal
OLDNEW
« src/scanner.h ('K') | « src/scanner.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698