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

Side by Side Diff: src/parsing/scanner.cc

Issue 2240513003: Scanner::LiteralBuffer usage cleanup. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Feedback fix compiler issues. Created 4 years, 4 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
« no previous file with comments | « src/parsing/scanner.h ('k') | src/parsing/token.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Features shared by parsing and pre-parsing scanners. 5 // Features shared by parsing and pre-parsing scanners.
6 6
7 #include "src/parsing/scanner.h" 7 #include "src/parsing/scanner.h"
8 8
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 253 }
254 has_line_terminator_before_next_ = false; 254 has_line_terminator_before_next_ = false;
255 has_multiline_comment_before_next_ = false; 255 has_multiline_comment_before_next_ = false;
256 if (static_cast<unsigned>(c0_) <= 0x7f) { 256 if (static_cast<unsigned>(c0_) <= 0x7f) {
257 Token::Value token = static_cast<Token::Value>(one_char_tokens[c0_]); 257 Token::Value token = static_cast<Token::Value>(one_char_tokens[c0_]);
258 if (token != Token::ILLEGAL) { 258 if (token != Token::ILLEGAL) {
259 int pos = source_pos(); 259 int pos = source_pos();
260 next_.token = token; 260 next_.token = token;
261 next_.location.beg_pos = pos; 261 next_.location.beg_pos = pos;
262 next_.location.end_pos = pos + 1; 262 next_.location.end_pos = pos + 1;
263 next_.literal_chars = nullptr;
264 next_.raw_literal_chars = nullptr;
263 Advance(); 265 Advance();
264 return current_.token; 266 return current_.token;
265 } 267 }
266 } 268 }
267 Scan(); 269 Scan();
268 return current_.token; 270 return current_.token;
269 } 271 }
270 272
271 273
272 Token::Value Scanner::PeekAhead() { 274 Token::Value Scanner::PeekAhead() {
275 DCHECK(next_.token != Token::DIV);
276 DCHECK(next_.token != Token::ASSIGN_DIV);
277
273 if (next_next_.token != Token::UNINITIALIZED) { 278 if (next_next_.token != Token::UNINITIALIZED) {
274 return next_next_.token; 279 return next_next_.token;
275 } 280 }
276 TokenDesc prev = current_; 281 TokenDesc prev = current_;
277 bool has_line_terminator_before_next = 282 bool has_line_terminator_before_next =
278 has_line_terminator_before_next_ || has_multiline_comment_before_next_; 283 has_line_terminator_before_next_ || has_multiline_comment_before_next_;
279 Next(); 284 Next();
280 has_line_terminator_after_next_ = 285 has_line_terminator_after_next_ =
281 has_line_terminator_before_next_ || has_multiline_comment_before_next_; 286 has_line_terminator_before_next_ || has_multiline_comment_before_next_;
282 has_line_terminator_before_next_ = has_line_terminator_before_next; 287 has_line_terminator_before_next_ = has_line_terminator_before_next;
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 } 729 }
725 break; 730 break;
726 } 731 }
727 732
728 // Continue scanning for tokens as long as we're just skipping 733 // Continue scanning for tokens as long as we're just skipping
729 // whitespace. 734 // whitespace.
730 } while (token == Token::WHITESPACE); 735 } while (token == Token::WHITESPACE);
731 736
732 next_.location.end_pos = source_pos(); 737 next_.location.end_pos = source_pos();
733 next_.token = token; 738 next_.token = token;
739
740 #ifdef DEBUG
741 SanityCheckTokenDesc(current_);
742 SanityCheckTokenDesc(next_);
743 SanityCheckTokenDesc(next_next_);
744 #endif
734 } 745 }
735 746
747 #ifdef DEBUG
748 void Scanner::SanityCheckTokenDesc(const TokenDesc& token) const {
749 // Most tokens should not have literal_chars or even raw_literal chars.
750 // The rules are:
751 // - UNINITIALIZED: we don't care.
752 // - TEMPLATE_*: need both literal + raw literal chars.
753 // - IDENTIFIERS, STRINGS, etc.: need a literal, but no raw literal.
754 // - all others: should have neither.
755
756 switch (token.token) {
757 case Token::UNINITIALIZED:
758 // token.literal_chars & other members might be garbage. That's ok.
759 break;
760 case Token::TEMPLATE_SPAN:
761 case Token::TEMPLATE_TAIL:
762 DCHECK_NOT_NULL(token.raw_literal_chars);
763 DCHECK_NOT_NULL(token.literal_chars);
764 break;
765 case Token::ESCAPED_KEYWORD:
766 case Token::ESCAPED_STRICT_RESERVED_WORD:
767 case Token::FUTURE_STRICT_RESERVED_WORD:
768 case Token::IDENTIFIER:
769 case Token::NUMBER:
770 case Token::REGEXP_LITERAL:
771 case Token::SMI:
772 case Token::STRING:
773 DCHECK_NOT_NULL(token.literal_chars);
774 DCHECK_NULL(token.raw_literal_chars);
775 break;
776 default:
777 DCHECK_NULL(token.literal_chars);
778 DCHECK_NULL(token.raw_literal_chars);
779 break;
780 }
781 }
782 #endif // DEBUG
736 783
737 void Scanner::SeekForward(int pos) { 784 void Scanner::SeekForward(int pos) {
738 // After this call, we will have the token at the given position as 785 // After this call, we will have the token at the given position as
739 // the "next" token. The "current" token will be invalid. 786 // the "next" token. The "current" token will be invalid.
740 if (pos == next_.location.beg_pos) return; 787 if (pos == next_.location.beg_pos) return;
741 int current_pos = source_pos(); 788 int current_pos = source_pos();
742 DCHECK_EQ(next_.location.end_pos, current_pos); 789 DCHECK_EQ(next_.location.end_pos, current_pos);
743 // Positions inside the lookahead token aren't supported. 790 // Positions inside the lookahead token aren't supported.
744 DCHECK(pos >= current_pos); 791 DCHECK(pos >= current_pos);
745 if (pos != current_pos) { 792 if (pos != current_pos) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 } 994 }
948 } 995 }
949 literal.Complete(); 996 literal.Complete();
950 next_.location.end_pos = source_pos(); 997 next_.location.end_pos = source_pos();
951 next_.token = result; 998 next_.token = result;
952 return result; 999 return result;
953 } 1000 }
954 1001
955 1002
956 Token::Value Scanner::ScanTemplateStart() { 1003 Token::Value Scanner::ScanTemplateStart() {
1004 DCHECK(next_next_.token == Token::UNINITIALIZED);
957 DCHECK(c0_ == '`'); 1005 DCHECK(c0_ == '`');
958 next_.location.beg_pos = source_pos(); 1006 next_.location.beg_pos = source_pos();
959 Advance(); // Consume ` 1007 Advance(); // Consume `
960 return ScanTemplateSpan(); 1008 return ScanTemplateSpan();
961 } 1009 }
962 1010
963 1011
964 Token::Value Scanner::ScanTemplateContinuation() { 1012 Token::Value Scanner::ScanTemplateContinuation() {
965 DCHECK_EQ(next_.token, Token::RBRACE); 1013 DCHECK_EQ(next_.token, Token::RBRACE);
966 next_.location.beg_pos = source_pos() - 1; // We already consumed } 1014 next_.location.beg_pos = source_pos() - 1; // We already consumed }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 KEYWORD_GROUP('v') \ 1257 KEYWORD_GROUP('v') \
1210 KEYWORD("var", Token::VAR) \ 1258 KEYWORD("var", Token::VAR) \
1211 KEYWORD("void", Token::VOID) \ 1259 KEYWORD("void", Token::VOID) \
1212 KEYWORD_GROUP('w') \ 1260 KEYWORD_GROUP('w') \
1213 KEYWORD("while", Token::WHILE) \ 1261 KEYWORD("while", Token::WHILE) \
1214 KEYWORD("with", Token::WITH) \ 1262 KEYWORD("with", Token::WITH) \
1215 KEYWORD_GROUP('y') \ 1263 KEYWORD_GROUP('y') \
1216 KEYWORD("yield", Token::YIELD) 1264 KEYWORD("yield", Token::YIELD)
1217 1265
1218 static Token::Value KeywordOrIdentifierToken(const uint8_t* input, 1266 static Token::Value KeywordOrIdentifierToken(const uint8_t* input,
1219 int input_length, bool escaped) { 1267 int input_length) {
1220 DCHECK(input_length >= 1); 1268 DCHECK(input_length >= 1);
1221 const int kMinLength = 2; 1269 const int kMinLength = 2;
1222 const int kMaxLength = 10; 1270 const int kMaxLength = 10;
1223 if (input_length < kMinLength || input_length > kMaxLength) { 1271 if (input_length < kMinLength || input_length > kMaxLength) {
1224 return Token::IDENTIFIER; 1272 return Token::IDENTIFIER;
1225 } 1273 }
1226 switch (input[0]) { 1274 switch (input[0]) {
1227 default: 1275 default:
1228 #define KEYWORD_GROUP_CASE(ch) \ 1276 #define KEYWORD_GROUP_CASE(ch) \
1229 break; \ 1277 break; \
1230 case ch: 1278 case ch:
1231 #define KEYWORD(keyword, token) \ 1279 #define KEYWORD(keyword, token) \
1232 { \ 1280 { \
1233 /* 'keyword' is a char array, so sizeof(keyword) is */ \ 1281 /* 'keyword' is a char array, so sizeof(keyword) is */ \
1234 /* strlen(keyword) plus 1 for the NUL char. */ \ 1282 /* strlen(keyword) plus 1 for the NUL char. */ \
1235 const int keyword_length = sizeof(keyword) - 1; \ 1283 const int keyword_length = sizeof(keyword) - 1; \
1236 STATIC_ASSERT(keyword_length >= kMinLength); \ 1284 STATIC_ASSERT(keyword_length >= kMinLength); \
1237 STATIC_ASSERT(keyword_length <= kMaxLength); \ 1285 STATIC_ASSERT(keyword_length <= kMaxLength); \
1238 if (input_length == keyword_length && input[1] == keyword[1] && \ 1286 if (input_length == keyword_length && input[1] == keyword[1] && \
1239 (keyword_length <= 2 || input[2] == keyword[2]) && \ 1287 (keyword_length <= 2 || input[2] == keyword[2]) && \
1240 (keyword_length <= 3 || input[3] == keyword[3]) && \ 1288 (keyword_length <= 3 || input[3] == keyword[3]) && \
1241 (keyword_length <= 4 || input[4] == keyword[4]) && \ 1289 (keyword_length <= 4 || input[4] == keyword[4]) && \
1242 (keyword_length <= 5 || input[5] == keyword[5]) && \ 1290 (keyword_length <= 5 || input[5] == keyword[5]) && \
1243 (keyword_length <= 6 || input[6] == keyword[6]) && \ 1291 (keyword_length <= 6 || input[6] == keyword[6]) && \
1244 (keyword_length <= 7 || input[7] == keyword[7]) && \ 1292 (keyword_length <= 7 || input[7] == keyword[7]) && \
1245 (keyword_length <= 8 || input[8] == keyword[8]) && \ 1293 (keyword_length <= 8 || input[8] == keyword[8]) && \
1246 (keyword_length <= 9 || input[9] == keyword[9])) { \ 1294 (keyword_length <= 9 || input[9] == keyword[9])) { \
1247 if (escaped) { \
1248 /* TODO(adamk): YIELD should be handled specially. */ \
1249 return (token == Token::FUTURE_STRICT_RESERVED_WORD || \
1250 token == Token::LET || token == Token::STATIC) \
1251 ? Token::ESCAPED_STRICT_RESERVED_WORD \
1252 : Token::ESCAPED_KEYWORD; \
1253 } \
1254 return token; \ 1295 return token; \
1255 } \ 1296 } \
1256 } 1297 }
1257 KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD) 1298 KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
1258 } 1299 }
1259 return Token::IDENTIFIER; 1300 return Token::IDENTIFIER;
1260 } 1301 }
1261 1302
1262 1303
1263 bool Scanner::IdentifierIsFutureStrictReserved( 1304 bool Scanner::IdentifierIsFutureStrictReserved(
1264 const AstRawString* string) const { 1305 const AstRawString* string) const {
1265 // Keywords are always 1-byte strings. 1306 // Keywords are always 1-byte strings.
1266 if (!string->is_one_byte()) return false; 1307 if (!string->is_one_byte()) return false;
1267 if (string->IsOneByteEqualTo("let") || string->IsOneByteEqualTo("static") || 1308 if (string->IsOneByteEqualTo("let") || string->IsOneByteEqualTo("static") ||
1268 string->IsOneByteEqualTo("yield")) { 1309 string->IsOneByteEqualTo("yield")) {
1269 return true; 1310 return true;
1270 } 1311 }
1271 return Token::FUTURE_STRICT_RESERVED_WORD == 1312 return Token::FUTURE_STRICT_RESERVED_WORD ==
1272 KeywordOrIdentifierToken(string->raw_data(), string->length(), false); 1313 KeywordOrIdentifierToken(string->raw_data(), string->length());
1273 } 1314 }
1274 1315
1275 1316
1276 Token::Value Scanner::ScanIdentifierOrKeyword() { 1317 Token::Value Scanner::ScanIdentifierOrKeyword() {
1277 DCHECK(unicode_cache_->IsIdentifierStart(c0_)); 1318 DCHECK(unicode_cache_->IsIdentifierStart(c0_));
1278 LiteralScope literal(this); 1319 LiteralScope literal(this);
1279 if (IsInRange(c0_, 'a', 'z')) { 1320 if (IsInRange(c0_, 'a', 'z')) {
1280 do { 1321 do {
1281 char first_char = static_cast<char>(c0_); 1322 char first_char = static_cast<char>(c0_);
1282 Advance<false, false>(); 1323 Advance<false, false>();
(...skipping 10 matching lines...) Expand all
1293 char first_char = static_cast<char>(c0_); 1334 char first_char = static_cast<char>(c0_);
1294 Advance<false, false>(); 1335 Advance<false, false>();
1295 AddLiteralChar(first_char); 1336 AddLiteralChar(first_char);
1296 } 1337 }
1297 if (c0_ <= kMaxAscii && c0_ != '\\') { 1338 if (c0_ <= kMaxAscii && c0_ != '\\') {
1298 literal.Complete(); 1339 literal.Complete();
1299 return Token::IDENTIFIER; 1340 return Token::IDENTIFIER;
1300 } 1341 }
1301 } else if (c0_ <= kMaxAscii && c0_ != '\\') { 1342 } else if (c0_ <= kMaxAscii && c0_ != '\\') {
1302 // Only a-z+: could be a keyword or identifier. 1343 // Only a-z+: could be a keyword or identifier.
1303 literal.Complete();
1304 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); 1344 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal();
1305 return KeywordOrIdentifierToken(chars.start(), chars.length(), false); 1345 Token::Value token =
1346 KeywordOrIdentifierToken(chars.start(), chars.length());
1347 if (token == Token::IDENTIFIER ||
1348 token == Token::FUTURE_STRICT_RESERVED_WORD)
1349 literal.Complete();
1350 return token;
1306 } 1351 }
1307 1352
1308 HandleLeadSurrogate(); 1353 HandleLeadSurrogate();
1309 } else if (IsInRange(c0_, 'A', 'Z') || c0_ == '_' || c0_ == '$') { 1354 } else if (IsInRange(c0_, 'A', 'Z') || c0_ == '_' || c0_ == '$') {
1310 do { 1355 do {
1311 char first_char = static_cast<char>(c0_); 1356 char first_char = static_cast<char>(c0_);
1312 Advance<false, false>(); 1357 Advance<false, false>();
1313 AddLiteralChar(first_char); 1358 AddLiteralChar(first_char);
1314 } while (IsAsciiIdentifier(c0_)); 1359 } while (IsAsciiIdentifier(c0_));
1315 1360
(...skipping 25 matching lines...) Expand all
1341 if (c0_ != '\\') { 1386 if (c0_ != '\\') {
1342 uc32 next_char = c0_; 1387 uc32 next_char = c0_;
1343 Advance(); 1388 Advance();
1344 AddLiteralChar(next_char); 1389 AddLiteralChar(next_char);
1345 continue; 1390 continue;
1346 } 1391 }
1347 // Fallthrough if no longer able to complete keyword. 1392 // Fallthrough if no longer able to complete keyword.
1348 return ScanIdentifierSuffix(&literal, false); 1393 return ScanIdentifierSuffix(&literal, false);
1349 } 1394 }
1350 1395
1351 literal.Complete();
1352
1353 if (next_.literal_chars->is_one_byte()) { 1396 if (next_.literal_chars->is_one_byte()) {
1354 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); 1397 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal();
1355 return KeywordOrIdentifierToken(chars.start(), chars.length(), false); 1398 Token::Value token =
1399 KeywordOrIdentifierToken(chars.start(), chars.length());
1400 if (token == Token::IDENTIFIER) literal.Complete();
1401 return token;
1356 } 1402 }
1403 literal.Complete();
1357 return Token::IDENTIFIER; 1404 return Token::IDENTIFIER;
1358 } 1405 }
1359 1406
1360 1407
1361 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal, 1408 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal,
1362 bool escaped) { 1409 bool escaped) {
1363 // Scan the rest of the identifier characters. 1410 // Scan the rest of the identifier characters.
1364 while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) { 1411 while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
1365 if (c0_ == '\\') { 1412 if (c0_ == '\\') {
1366 uc32 c = ScanIdentifierUnicodeEscape(); 1413 uc32 c = ScanIdentifierUnicodeEscape();
1367 escaped = true; 1414 escaped = true;
1368 // Only allow legal identifier part characters. 1415 // Only allow legal identifier part characters.
1369 if (c < 0 || 1416 if (c < 0 ||
1370 c == '\\' || 1417 c == '\\' ||
1371 !unicode_cache_->IsIdentifierPart(c)) { 1418 !unicode_cache_->IsIdentifierPart(c)) {
1372 return Token::ILLEGAL; 1419 return Token::ILLEGAL;
1373 } 1420 }
1374 AddLiteralChar(c); 1421 AddLiteralChar(c);
1375 } else { 1422 } else {
1376 AddLiteralChar(c0_); 1423 AddLiteralChar(c0_);
1377 Advance(); 1424 Advance();
1378 } 1425 }
1379 } 1426 }
1380 literal->Complete(); 1427 literal->Complete();
1381 1428
1382 if (escaped && next_.literal_chars->is_one_byte()) { 1429 if (escaped && next_.literal_chars->is_one_byte()) {
1383 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); 1430 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal();
1384 return KeywordOrIdentifierToken(chars.start(), chars.length(), true); 1431 Token::Value token =
1432 KeywordOrIdentifierToken(chars.start(), chars.length());
1433 /* TODO(adamk): YIELD should be handled specially. */
1434 if (token == Token::IDENTIFIER) {
1435 return Token::IDENTIFIER;
1436 } else if (token == Token::FUTURE_STRICT_RESERVED_WORD ||
1437 token == Token::LET || token == Token::STATIC) {
1438 return Token::ESCAPED_STRICT_RESERVED_WORD;
1439 } else {
1440 return Token::ESCAPED_KEYWORD;
1441 }
1385 } 1442 }
1386 return Token::IDENTIFIER; 1443 return Token::IDENTIFIER;
1387 } 1444 }
1388 1445
1446 bool Scanner::ScanRegExpPattern() {
1447 DCHECK(next_next_.token == Token::UNINITIALIZED);
1448 DCHECK(next_.token == Token::DIV || next_.token == Token::ASSIGN_DIV);
1389 1449
1390 bool Scanner::ScanRegExpPattern(bool seen_equal) {
1391 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags 1450 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
1392 bool in_character_class = false; 1451 bool in_character_class = false;
1452 bool seen_equal = (next_.token == Token::ASSIGN_DIV);
1393 1453
1394 // Previous token is either '/' or '/=', in the second case, the 1454 // Previous token is either '/' or '/=', in the second case, the
1395 // pattern starts at =. 1455 // pattern starts at =.
1396 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); 1456 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);
1397 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); 1457 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);
1398 1458
1399 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, 1459 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
1400 // the scanner should pass uninterpreted bodies to the RegExp 1460 // the scanner should pass uninterpreted bodies to the RegExp
1401 // constructor. 1461 // constructor.
1402 LiteralScope literal(this); 1462 LiteralScope literal(this);
(...skipping 19 matching lines...) Expand all
1422 // octal esacpes in strict mode. 1482 // octal esacpes in strict mode.
1423 } else { // Unescaped character. 1483 } else { // Unescaped character.
1424 if (c0_ == '[') in_character_class = true; 1484 if (c0_ == '[') in_character_class = true;
1425 if (c0_ == ']') in_character_class = false; 1485 if (c0_ == ']') in_character_class = false;
1426 AddLiteralCharAdvance(); 1486 AddLiteralCharAdvance();
1427 } 1487 }
1428 } 1488 }
1429 Advance(); // consume '/' 1489 Advance(); // consume '/'
1430 1490
1431 literal.Complete(); 1491 literal.Complete();
1432 1492 next_.token = Token::REGEXP_LITERAL;
1433 return true; 1493 return true;
1434 } 1494 }
1435 1495
1436 1496
1437 Maybe<RegExp::Flags> Scanner::ScanRegExpFlags() { 1497 Maybe<RegExp::Flags> Scanner::ScanRegExpFlags() {
1498 DCHECK(next_.token == Token::REGEXP_LITERAL);
1499
1438 // Scan regular expression flags. 1500 // Scan regular expression flags.
1439 LiteralScope literal(this);
1440 int flags = 0; 1501 int flags = 0;
1441 while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) { 1502 while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
1442 RegExp::Flags flag = RegExp::kNone; 1503 RegExp::Flags flag = RegExp::kNone;
1443 switch (c0_) { 1504 switch (c0_) {
1444 case 'g': 1505 case 'g':
1445 flag = RegExp::kGlobal; 1506 flag = RegExp::kGlobal;
1446 break; 1507 break;
1447 case 'i': 1508 case 'i':
1448 flag = RegExp::kIgnoreCase; 1509 flag = RegExp::kIgnoreCase;
1449 break; 1510 break;
1450 case 'm': 1511 case 'm':
1451 flag = RegExp::kMultiline; 1512 flag = RegExp::kMultiline;
1452 break; 1513 break;
1453 case 'u': 1514 case 'u':
1454 flag = RegExp::kUnicode; 1515 flag = RegExp::kUnicode;
1455 break; 1516 break;
1456 case 'y': 1517 case 'y':
1457 flag = RegExp::kSticky; 1518 flag = RegExp::kSticky;
1458 break; 1519 break;
1459 default: 1520 default:
1460 return Nothing<RegExp::Flags>(); 1521 return Nothing<RegExp::Flags>();
1461 } 1522 }
1462 if (flags & flag) return Nothing<RegExp::Flags>(); 1523 if (flags & flag) {
1463 AddLiteralCharAdvance(); 1524 return Nothing<RegExp::Flags>();
1525 }
1526 Advance();
1464 flags |= flag; 1527 flags |= flag;
1465 } 1528 }
1466 literal.Complete();
1467 1529
1468 next_.location.end_pos = source_pos(); 1530 next_.location.end_pos = source_pos();
1469 return Just(RegExp::Flags(flags)); 1531 return Just(RegExp::Flags(flags));
1470 } 1532 }
1471 1533
1472 1534
1473 const AstRawString* Scanner::CurrentSymbol(AstValueFactory* ast_value_factory) { 1535 const AstRawString* Scanner::CurrentSymbol(AstValueFactory* ast_value_factory) {
1474 if (is_literal_one_byte()) { 1536 if (is_literal_one_byte()) {
1475 return ast_value_factory->GetOneByteString(literal_one_byte_string()); 1537 return ast_value_factory->GetOneByteString(literal_one_byte_string());
1476 } 1538 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); 1765 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1704 } 1766 }
1705 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); 1767 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1706 1768
1707 backing_store_.AddBlock(bytes); 1769 backing_store_.AddBlock(bytes);
1708 return backing_store_.EndSequence().start(); 1770 return backing_store_.EndSequence().start();
1709 } 1771 }
1710 1772
1711 } // namespace internal 1773 } // namespace internal
1712 } // namespace v8 1774 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/scanner.h ('k') | src/parsing/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698