OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 20 matching lines...) Expand all Loading... |
31 #include "handles.h" | 31 #include "handles.h" |
32 #include "scanner.h" | 32 #include "scanner.h" |
33 #include "unicode-inl.h" | 33 #include "unicode-inl.h" |
34 | 34 |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // ---------------------------------------------------------------------------- | 38 // ---------------------------------------------------------------------------- |
39 // UTF8Buffer | 39 // UTF8Buffer |
40 | 40 |
41 UTF8Buffer::UTF8Buffer() : buffer_(kInitialCapacity) { } | 41 UTF8Buffer::UTF8Buffer() : buffer_(kInitialCapacity), recording_(false) { } |
42 | 42 |
43 | 43 |
44 UTF8Buffer::~UTF8Buffer() {} | 44 UTF8Buffer::~UTF8Buffer() {} |
45 | 45 |
46 | 46 |
47 void UTF8Buffer::AddCharSlow(uc32 c) { | 47 void UTF8Buffer::AddCharSlow(uc32 c) { |
48 ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar); | 48 ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar); |
49 int length = unibrow::Utf8::Length(c); | 49 int length = unibrow::Utf8::Length(c); |
50 Vector<char> block = buffer_.AddBlock(length, '\0'); | 50 Vector<char> block = buffer_.AddBlock(length, '\0'); |
51 #ifdef DEBUG | 51 #ifdef DEBUG |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 void CharacterStreamUTF16Buffer::SeekForward(int pos) { | 119 void CharacterStreamUTF16Buffer::SeekForward(int pos) { |
120 pos_ = pos; | 120 pos_ = pos; |
121 ASSERT(pushback_buffer()->is_empty()); | 121 ASSERT(pushback_buffer()->is_empty()); |
122 stream_->Seek(pos); | 122 stream_->Seek(pos); |
123 } | 123 } |
124 | 124 |
125 | 125 |
126 // ExternalStringUTF16Buffer | |
127 template <typename StringType, typename CharType> | |
128 ExternalStringUTF16Buffer<StringType, CharType>::ExternalStringUTF16Buffer() | |
129 : raw_data_(NULL) { } | |
130 | |
131 | |
132 template <typename StringType, typename CharType> | |
133 void ExternalStringUTF16Buffer<StringType, CharType>::Initialize( | |
134 Handle<StringType> data, | |
135 int start_position, | |
136 int end_position) { | |
137 ASSERT(!data.is_null()); | |
138 raw_data_ = data->resource()->data(); | |
139 | |
140 ASSERT(end_position <= data->length()); | |
141 if (start_position > 0) { | |
142 SeekForward(start_position); | |
143 } | |
144 end_ = | |
145 end_position != Scanner::kNoEndPosition ? end_position : data->length(); | |
146 } | |
147 | |
148 | |
149 template <typename StringType, typename CharType> | |
150 uc32 ExternalStringUTF16Buffer<StringType, CharType>::Advance() { | |
151 if (pos_ < end_) { | |
152 return raw_data_[pos_++]; | |
153 } else { | |
154 // note: currently the following increment is necessary to avoid a | |
155 // test-parser problem! | |
156 pos_++; | |
157 return static_cast<uc32>(-1); | |
158 } | |
159 } | |
160 | |
161 | |
162 template <typename StringType, typename CharType> | |
163 void ExternalStringUTF16Buffer<StringType, CharType>::PushBack(uc32 ch) { | |
164 pos_--; | |
165 ASSERT(pos_ >= Scanner::kCharacterLookaheadBufferSize); | |
166 ASSERT(raw_data_[pos_ - Scanner::kCharacterLookaheadBufferSize] == ch); | |
167 } | |
168 | |
169 | |
170 template <typename StringType, typename CharType> | |
171 void ExternalStringUTF16Buffer<StringType, CharType>::SeekForward(int pos) { | |
172 pos_ = pos; | |
173 } | |
174 | |
175 // ---------------------------------------------------------------------------- | 126 // ---------------------------------------------------------------------------- |
176 // Scanner::LiteralScope | 127 // Scanner::LiteralScope |
177 | 128 |
178 Scanner::LiteralScope::LiteralScope(Scanner* self) | 129 Scanner::LiteralScope::LiteralScope(Scanner* self) |
179 : scanner_(self), complete_(false) { | 130 : scanner_(self), complete_(false) { |
180 self->StartLiteral(); | 131 self->StartLiteral(); |
181 } | 132 } |
182 | 133 |
183 | 134 |
184 Scanner::LiteralScope::~LiteralScope() { | 135 Scanner::LiteralScope::~LiteralScope() { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 } | 241 } |
291 return current_.token; | 242 return current_.token; |
292 } | 243 } |
293 | 244 |
294 | 245 |
295 void Scanner::StartLiteral() { | 246 void Scanner::StartLiteral() { |
296 literal_buffer_.StartLiteral(); | 247 literal_buffer_.StartLiteral(); |
297 } | 248 } |
298 | 249 |
299 | 250 |
300 void Scanner::AddChar(uc32 c) { | 251 void Scanner::AddLiteralChar(uc32 c) { |
301 literal_buffer_.AddChar(c); | 252 literal_buffer_.AddChar(c); |
302 } | 253 } |
303 | 254 |
304 | 255 |
305 void Scanner::TerminateLiteral() { | 256 void Scanner::TerminateLiteral() { |
306 next_.literal_chars = literal_buffer_.EndLiteral(); | 257 next_.literal_chars = literal_buffer_.EndLiteral(); |
307 } | 258 } |
308 | 259 |
309 | 260 |
310 void Scanner::DropLiteral() { | 261 void Scanner::DropLiteral() { |
311 literal_buffer_.DropLiteral(); | 262 literal_buffer_.DropLiteral(); |
312 } | 263 } |
313 | 264 |
314 | 265 |
315 void Scanner::AddCharAdvance() { | 266 void Scanner::AddLiteralCharAdvance() { |
316 AddChar(c0_); | 267 AddLiteralChar(c0_); |
317 Advance(); | 268 Advance(); |
318 } | 269 } |
319 | 270 |
320 | 271 |
321 static inline bool IsByteOrderMark(uc32 c) { | 272 static inline bool IsByteOrderMark(uc32 c) { |
322 // The Unicode value U+FFFE is guaranteed never to be assigned as a | 273 // The Unicode value U+FFFE is guaranteed never to be assigned as a |
323 // Unicode character; this implies that in a Unicode context the | 274 // Unicode character; this implies that in a Unicode context the |
324 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF | 275 // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF |
325 // character expressed in little-endian byte order (since it could | 276 // character expressed in little-endian byte order (since it could |
326 // not be a U+FFFE character expressed in big-endian byte | 277 // not be a U+FFFE character expressed in big-endian byte |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 469 |
519 | 470 |
520 Token::Value Scanner::ScanJsonString() { | 471 Token::Value Scanner::ScanJsonString() { |
521 ASSERT_EQ('"', c0_); | 472 ASSERT_EQ('"', c0_); |
522 Advance(); | 473 Advance(); |
523 LiteralScope literal(this); | 474 LiteralScope literal(this); |
524 while (c0_ != '"' && c0_ > 0) { | 475 while (c0_ != '"' && c0_ > 0) { |
525 // Check for control character (0x00-0x1f) or unterminated string (<0). | 476 // Check for control character (0x00-0x1f) or unterminated string (<0). |
526 if (c0_ < 0x20) return Token::ILLEGAL; | 477 if (c0_ < 0x20) return Token::ILLEGAL; |
527 if (c0_ != '\\') { | 478 if (c0_ != '\\') { |
528 AddCharAdvance(); | 479 AddLiteralCharAdvance(); |
529 } else { | 480 } else { |
530 Advance(); | 481 Advance(); |
531 switch (c0_) { | 482 switch (c0_) { |
532 case '"': | 483 case '"': |
533 case '\\': | 484 case '\\': |
534 case '/': | 485 case '/': |
535 AddChar(c0_); | 486 AddLiteralChar(c0_); |
536 break; | 487 break; |
537 case 'b': | 488 case 'b': |
538 AddChar('\x08'); | 489 AddLiteralChar('\x08'); |
539 break; | 490 break; |
540 case 'f': | 491 case 'f': |
541 AddChar('\x0c'); | 492 AddLiteralChar('\x0c'); |
542 break; | 493 break; |
543 case 'n': | 494 case 'n': |
544 AddChar('\x0a'); | 495 AddLiteralChar('\x0a'); |
545 break; | 496 break; |
546 case 'r': | 497 case 'r': |
547 AddChar('\x0d'); | 498 AddLiteralChar('\x0d'); |
548 break; | 499 break; |
549 case 't': | 500 case 't': |
550 AddChar('\x09'); | 501 AddLiteralChar('\x09'); |
551 break; | 502 break; |
552 case 'u': { | 503 case 'u': { |
553 uc32 value = 0; | 504 uc32 value = 0; |
554 for (int i = 0; i < 4; i++) { | 505 for (int i = 0; i < 4; i++) { |
555 Advance(); | 506 Advance(); |
556 int digit = HexValue(c0_); | 507 int digit = HexValue(c0_); |
557 if (digit < 0) { | 508 if (digit < 0) { |
558 return Token::ILLEGAL; | 509 return Token::ILLEGAL; |
559 } | 510 } |
560 value = value * 16 + digit; | 511 value = value * 16 + digit; |
561 } | 512 } |
562 AddChar(value); | 513 AddLiteralChar(value); |
563 break; | 514 break; |
564 } | 515 } |
565 default: | 516 default: |
566 return Token::ILLEGAL; | 517 return Token::ILLEGAL; |
567 } | 518 } |
568 Advance(); | 519 Advance(); |
569 } | 520 } |
570 } | 521 } |
571 if (c0_ != '"') { | 522 if (c0_ != '"') { |
572 return Token::ILLEGAL; | 523 return Token::ILLEGAL; |
573 } | 524 } |
574 literal.Complete(); | 525 literal.Complete(); |
575 Advance(); | 526 Advance(); |
576 return Token::STRING; | 527 return Token::STRING; |
577 } | 528 } |
578 | 529 |
579 | 530 |
580 Token::Value Scanner::ScanJsonNumber() { | 531 Token::Value Scanner::ScanJsonNumber() { |
581 LiteralScope literal(this); | 532 LiteralScope literal(this); |
582 if (c0_ == '-') AddCharAdvance(); | 533 if (c0_ == '-') AddLiteralCharAdvance(); |
583 if (c0_ == '0') { | 534 if (c0_ == '0') { |
584 AddCharAdvance(); | 535 AddLiteralCharAdvance(); |
585 // Prefix zero is only allowed if it's the only digit before | 536 // Prefix zero is only allowed if it's the only digit before |
586 // a decimal point or exponent. | 537 // a decimal point or exponent. |
587 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; | 538 if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; |
588 } else { | 539 } else { |
589 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; | 540 if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; |
590 do { | 541 do { |
591 AddCharAdvance(); | 542 AddLiteralCharAdvance(); |
592 } while (c0_ >= '0' && c0_ <= '9'); | 543 } while (c0_ >= '0' && c0_ <= '9'); |
593 } | 544 } |
594 if (c0_ == '.') { | 545 if (c0_ == '.') { |
595 AddCharAdvance(); | 546 AddLiteralCharAdvance(); |
596 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; | 547 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; |
597 do { | 548 do { |
598 AddCharAdvance(); | 549 AddLiteralCharAdvance(); |
599 } while (c0_ >= '0' && c0_ <= '9'); | 550 } while (c0_ >= '0' && c0_ <= '9'); |
600 } | 551 } |
601 if (AsciiAlphaToLower(c0_) == 'e') { | 552 if (AsciiAlphaToLower(c0_) == 'e') { |
602 AddCharAdvance(); | 553 AddLiteralCharAdvance(); |
603 if (c0_ == '-' || c0_ == '+') AddCharAdvance(); | 554 if (c0_ == '-' || c0_ == '+') AddLiteralCharAdvance(); |
604 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; | 555 if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; |
605 do { | 556 do { |
606 AddCharAdvance(); | 557 AddLiteralCharAdvance(); |
607 } while (c0_ >= '0' && c0_ <= '9'); | 558 } while (c0_ >= '0' && c0_ <= '9'); |
608 } | 559 } |
609 literal.Complete(); | 560 literal.Complete(); |
610 return Token::NUMBER; | 561 return Token::NUMBER; |
611 } | 562 } |
612 | 563 |
613 | 564 |
614 Token::Value Scanner::ScanJsonIdentifier(const char* text, | 565 Token::Value Scanner::ScanJsonIdentifier(const char* text, |
615 Token::Value token) { | 566 Token::Value token) { |
616 LiteralScope literal(this); | 567 LiteralScope literal(this); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 case '3' : // fall through | 902 case '3' : // fall through |
952 case '4' : // fall through | 903 case '4' : // fall through |
953 case '5' : // fall through | 904 case '5' : // fall through |
954 case '6' : // fall through | 905 case '6' : // fall through |
955 case '7' : c = ScanOctalEscape(c, 2); break; | 906 case '7' : c = ScanOctalEscape(c, 2); break; |
956 } | 907 } |
957 | 908 |
958 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these | 909 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these |
959 // should be illegal, but they are commonly handled | 910 // should be illegal, but they are commonly handled |
960 // as non-escaped characters by JS VMs. | 911 // as non-escaped characters by JS VMs. |
961 AddChar(c); | 912 AddLiteralChar(c); |
962 } | 913 } |
963 | 914 |
964 | 915 |
965 Token::Value Scanner::ScanString() { | 916 Token::Value Scanner::ScanString() { |
966 uc32 quote = c0_; | 917 uc32 quote = c0_; |
967 Advance(); // consume quote | 918 Advance(); // consume quote |
968 | 919 |
969 LiteralScope literal(this); | 920 LiteralScope literal(this); |
970 while (c0_ != quote && c0_ >= 0 | 921 while (c0_ != quote && c0_ >= 0 |
971 && !ScannerConstants::kIsLineTerminator.get(c0_)) { | 922 && !ScannerConstants::kIsLineTerminator.get(c0_)) { |
972 uc32 c = c0_; | 923 uc32 c = c0_; |
973 Advance(); | 924 Advance(); |
974 if (c == '\\') { | 925 if (c == '\\') { |
975 if (c0_ < 0) return Token::ILLEGAL; | 926 if (c0_ < 0) return Token::ILLEGAL; |
976 ScanEscape(); | 927 ScanEscape(); |
977 } else { | 928 } else { |
978 AddChar(c); | 929 AddLiteralChar(c); |
979 } | 930 } |
980 } | 931 } |
981 if (c0_ != quote) return Token::ILLEGAL; | 932 if (c0_ != quote) return Token::ILLEGAL; |
982 literal.Complete(); | 933 literal.Complete(); |
983 | 934 |
984 Advance(); // consume quote | 935 Advance(); // consume quote |
985 return Token::STRING; | 936 return Token::STRING; |
986 } | 937 } |
987 | 938 |
988 | 939 |
(...skipping 10 matching lines...) Expand all Loading... |
999 return then; | 950 return then; |
1000 } else { | 951 } else { |
1001 return else_; | 952 return else_; |
1002 } | 953 } |
1003 } | 954 } |
1004 | 955 |
1005 | 956 |
1006 // Returns true if any decimal digits were scanned, returns false otherwise. | 957 // Returns true if any decimal digits were scanned, returns false otherwise. |
1007 void Scanner::ScanDecimalDigits() { | 958 void Scanner::ScanDecimalDigits() { |
1008 while (IsDecimalDigit(c0_)) | 959 while (IsDecimalDigit(c0_)) |
1009 AddCharAdvance(); | 960 AddLiteralCharAdvance(); |
1010 } | 961 } |
1011 | 962 |
1012 | 963 |
1013 Token::Value Scanner::ScanNumber(bool seen_period) { | 964 Token::Value Scanner::ScanNumber(bool seen_period) { |
1014 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction | 965 ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction |
1015 | 966 |
1016 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; | 967 enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; |
1017 | 968 |
1018 LiteralScope literal(this); | 969 LiteralScope literal(this); |
1019 if (seen_period) { | 970 if (seen_period) { |
1020 // we have already seen a decimal point of the float | 971 // we have already seen a decimal point of the float |
1021 AddChar('.'); | 972 AddLiteralChar('.'); |
1022 ScanDecimalDigits(); // we know we have at least one digit | 973 ScanDecimalDigits(); // we know we have at least one digit |
1023 | 974 |
1024 } else { | 975 } else { |
1025 // if the first character is '0' we must check for octals and hex | 976 // if the first character is '0' we must check for octals and hex |
1026 if (c0_ == '0') { | 977 if (c0_ == '0') { |
1027 AddCharAdvance(); | 978 AddLiteralCharAdvance(); |
1028 | 979 |
1029 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number | 980 // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number |
1030 if (c0_ == 'x' || c0_ == 'X') { | 981 if (c0_ == 'x' || c0_ == 'X') { |
1031 // hex number | 982 // hex number |
1032 kind = HEX; | 983 kind = HEX; |
1033 AddCharAdvance(); | 984 AddLiteralCharAdvance(); |
1034 if (!IsHexDigit(c0_)) { | 985 if (!IsHexDigit(c0_)) { |
1035 // we must have at least one hex digit after 'x'/'X' | 986 // we must have at least one hex digit after 'x'/'X' |
1036 return Token::ILLEGAL; | 987 return Token::ILLEGAL; |
1037 } | 988 } |
1038 while (IsHexDigit(c0_)) { | 989 while (IsHexDigit(c0_)) { |
1039 AddCharAdvance(); | 990 AddLiteralCharAdvance(); |
1040 } | 991 } |
1041 } else if ('0' <= c0_ && c0_ <= '7') { | 992 } else if ('0' <= c0_ && c0_ <= '7') { |
1042 // (possible) octal number | 993 // (possible) octal number |
1043 kind = OCTAL; | 994 kind = OCTAL; |
1044 while (true) { | 995 while (true) { |
1045 if (c0_ == '8' || c0_ == '9') { | 996 if (c0_ == '8' || c0_ == '9') { |
1046 kind = DECIMAL; | 997 kind = DECIMAL; |
1047 break; | 998 break; |
1048 } | 999 } |
1049 if (c0_ < '0' || '7' < c0_) break; | 1000 if (c0_ < '0' || '7' < c0_) break; |
1050 AddCharAdvance(); | 1001 AddLiteralCharAdvance(); |
1051 } | 1002 } |
1052 } | 1003 } |
1053 } | 1004 } |
1054 | 1005 |
1055 // Parse decimal digits and allow trailing fractional part. | 1006 // Parse decimal digits and allow trailing fractional part. |
1056 if (kind == DECIMAL) { | 1007 if (kind == DECIMAL) { |
1057 ScanDecimalDigits(); // optional | 1008 ScanDecimalDigits(); // optional |
1058 if (c0_ == '.') { | 1009 if (c0_ == '.') { |
1059 AddCharAdvance(); | 1010 AddLiteralCharAdvance(); |
1060 ScanDecimalDigits(); // optional | 1011 ScanDecimalDigits(); // optional |
1061 } | 1012 } |
1062 } | 1013 } |
1063 } | 1014 } |
1064 | 1015 |
1065 // scan exponent, if any | 1016 // scan exponent, if any |
1066 if (c0_ == 'e' || c0_ == 'E') { | 1017 if (c0_ == 'e' || c0_ == 'E') { |
1067 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number | 1018 ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number |
1068 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed | 1019 if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed |
1069 // scan exponent | 1020 // scan exponent |
1070 AddCharAdvance(); | 1021 AddLiteralCharAdvance(); |
1071 if (c0_ == '+' || c0_ == '-') | 1022 if (c0_ == '+' || c0_ == '-') |
1072 AddCharAdvance(); | 1023 AddLiteralCharAdvance(); |
1073 if (!IsDecimalDigit(c0_)) { | 1024 if (!IsDecimalDigit(c0_)) { |
1074 // we must have at least one decimal digit after 'e'/'E' | 1025 // we must have at least one decimal digit after 'e'/'E' |
1075 return Token::ILLEGAL; | 1026 return Token::ILLEGAL; |
1076 } | 1027 } |
1077 ScanDecimalDigits(); | 1028 ScanDecimalDigits(); |
1078 } | 1029 } |
1079 | 1030 |
1080 // The source character immediately following a numeric literal must | 1031 // The source character immediately following a numeric literal must |
1081 // not be an identifier start or a decimal digit; see ECMA-262 | 1032 // not be an identifier start or a decimal digit; see ECMA-262 |
1082 // section 7.8.3, page 17 (note that we read only one decimal digit | 1033 // section 7.8.3, page 17 (note that we read only one decimal digit |
(...skipping 23 matching lines...) Expand all Loading... |
1106 ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_)); | 1057 ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_)); |
1107 | 1058 |
1108 LiteralScope literal(this); | 1059 LiteralScope literal(this); |
1109 KeywordMatcher keyword_match; | 1060 KeywordMatcher keyword_match; |
1110 | 1061 |
1111 // Scan identifier start character. | 1062 // Scan identifier start character. |
1112 if (c0_ == '\\') { | 1063 if (c0_ == '\\') { |
1113 uc32 c = ScanIdentifierUnicodeEscape(); | 1064 uc32 c = ScanIdentifierUnicodeEscape(); |
1114 // Only allow legal identifier start characters. | 1065 // Only allow legal identifier start characters. |
1115 if (!ScannerConstants::kIsIdentifierStart.get(c)) return Token::ILLEGAL; | 1066 if (!ScannerConstants::kIsIdentifierStart.get(c)) return Token::ILLEGAL; |
1116 AddChar(c); | 1067 AddLiteralChar(c); |
1117 keyword_match.Fail(); | 1068 keyword_match.Fail(); |
1118 } else { | 1069 } else { |
1119 AddChar(c0_); | 1070 AddLiteralChar(c0_); |
1120 keyword_match.AddChar(c0_); | 1071 keyword_match.AddChar(c0_); |
1121 Advance(); | 1072 Advance(); |
1122 } | 1073 } |
1123 | 1074 |
1124 // Scan the rest of the identifier characters. | 1075 // Scan the rest of the identifier characters. |
1125 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { | 1076 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { |
1126 if (c0_ == '\\') { | 1077 if (c0_ == '\\') { |
1127 uc32 c = ScanIdentifierUnicodeEscape(); | 1078 uc32 c = ScanIdentifierUnicodeEscape(); |
1128 // Only allow legal identifier part characters. | 1079 // Only allow legal identifier part characters. |
1129 if (!ScannerConstants::kIsIdentifierPart.get(c)) return Token::ILLEGAL; | 1080 if (!ScannerConstants::kIsIdentifierPart.get(c)) return Token::ILLEGAL; |
1130 AddChar(c); | 1081 AddLiteralChar(c); |
1131 keyword_match.Fail(); | 1082 keyword_match.Fail(); |
1132 } else { | 1083 } else { |
1133 AddChar(c0_); | 1084 AddLiteralChar(c0_); |
1134 keyword_match.AddChar(c0_); | 1085 keyword_match.AddChar(c0_); |
1135 Advance(); | 1086 Advance(); |
1136 } | 1087 } |
1137 } | 1088 } |
1138 literal.Complete(); | 1089 literal.Complete(); |
1139 | 1090 |
1140 return keyword_match.token(); | 1091 return keyword_match.token(); |
1141 } | 1092 } |
1142 | 1093 |
1143 | 1094 |
1144 | 1095 |
1145 bool Scanner::ScanRegExpPattern(bool seen_equal) { | 1096 bool Scanner::ScanRegExpPattern(bool seen_equal) { |
1146 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags | 1097 // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags |
1147 bool in_character_class = false; | 1098 bool in_character_class = false; |
1148 | 1099 |
1149 // Previous token is either '/' or '/=', in the second case, the | 1100 // Previous token is either '/' or '/=', in the second case, the |
1150 // pattern starts at =. | 1101 // pattern starts at =. |
1151 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); | 1102 next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); |
1152 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); | 1103 next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); |
1153 | 1104 |
1154 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, | 1105 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, |
1155 // the scanner should pass uninterpreted bodies to the RegExp | 1106 // the scanner should pass uninterpreted bodies to the RegExp |
1156 // constructor. | 1107 // constructor. |
1157 LiteralScope literal(this); | 1108 LiteralScope literal(this); |
1158 if (seen_equal) | 1109 if (seen_equal) |
1159 AddChar('='); | 1110 AddLiteralChar('='); |
1160 | 1111 |
1161 while (c0_ != '/' || in_character_class) { | 1112 while (c0_ != '/' || in_character_class) { |
1162 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; | 1113 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; |
1163 if (c0_ == '\\') { // escaped character | 1114 if (c0_ == '\\') { // escaped character |
1164 AddCharAdvance(); | 1115 AddLiteralCharAdvance(); |
1165 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; | 1116 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; |
1166 AddCharAdvance(); | 1117 AddLiteralCharAdvance(); |
1167 } else { // unescaped character | 1118 } else { // unescaped character |
1168 if (c0_ == '[') in_character_class = true; | 1119 if (c0_ == '[') in_character_class = true; |
1169 if (c0_ == ']') in_character_class = false; | 1120 if (c0_ == ']') in_character_class = false; |
1170 AddCharAdvance(); | 1121 AddLiteralCharAdvance(); |
1171 } | 1122 } |
1172 } | 1123 } |
1173 Advance(); // consume '/' | 1124 Advance(); // consume '/' |
1174 | 1125 |
1175 literal.Complete(); | 1126 literal.Complete(); |
1176 | 1127 |
1177 return true; | 1128 return true; |
1178 } | 1129 } |
1179 | 1130 |
1180 bool Scanner::ScanRegExpFlags() { | 1131 bool Scanner::ScanRegExpFlags() { |
1181 // Scan regular expression flags. | 1132 // Scan regular expression flags. |
1182 LiteralScope literal(this); | 1133 LiteralScope literal(this); |
1183 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { | 1134 while (ScannerConstants::kIsIdentifierPart.get(c0_)) { |
1184 if (c0_ == '\\') { | 1135 if (c0_ == '\\') { |
1185 uc32 c = ScanIdentifierUnicodeEscape(); | 1136 uc32 c = ScanIdentifierUnicodeEscape(); |
1186 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) { | 1137 if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) { |
1187 // We allow any escaped character, unlike the restriction on | 1138 // We allow any escaped character, unlike the restriction on |
1188 // IdentifierPart when it is used to build an IdentifierName. | 1139 // IdentifierPart when it is used to build an IdentifierName. |
1189 AddChar(c); | 1140 AddLiteralChar(c); |
1190 continue; | 1141 continue; |
1191 } | 1142 } |
1192 } | 1143 } |
1193 AddCharAdvance(); | 1144 AddLiteralCharAdvance(); |
1194 } | 1145 } |
1195 literal.Complete(); | 1146 literal.Complete(); |
1196 | 1147 |
1197 next_.location.end_pos = source_pos() - 1; | 1148 next_.location.end_pos = source_pos() - 1; |
1198 return true; | 1149 return true; |
1199 } | 1150 } |
1200 | 1151 |
1201 } } // namespace v8::internal | 1152 } } // namespace v8::internal |
OLD | NEW |