| 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 |