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

Side by Side Diff: src/scanner.cc

Issue 811113002: ES6 template literals should not use legacy octal strings (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix backslash 0 Created 6 years 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
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 <stdint.h> 7 #include <stdint.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 10
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 // This function is only called to seek to the location 690 // This function is only called to seek to the location
691 // of the end of a function (at the "}" token). It doesn't matter 691 // of the end of a function (at the "}" token). It doesn't matter
692 // whether there was a line terminator in the part we skip. 692 // whether there was a line terminator in the part we skip.
693 has_line_terminator_before_next_ = false; 693 has_line_terminator_before_next_ = false;
694 has_multiline_comment_before_next_ = false; 694 has_multiline_comment_before_next_ = false;
695 } 695 }
696 Scan(); 696 Scan();
697 } 697 }
698 698
699 699
700 template <bool capture_raw> 700 template <bool capture_raw, bool in_template_literal>
701 bool Scanner::ScanEscape() { 701 bool Scanner::ScanEscape() {
702 uc32 c = c0_; 702 uc32 c = c0_;
703 Advance<capture_raw>(); 703 Advance<capture_raw>();
704 704
705 // Skip escaped newlines. 705 // Skip escaped newlines.
706 if (c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) { 706 if (!in_template_literal && c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) {
707 // Allow CR+LF newlines in multiline string literals. 707 // Allow CR+LF newlines in multiline string literals.
708 if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>(); 708 if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>();
709 // Allow LF+CR newlines in multiline string literals. 709 // Allow LF+CR newlines in multiline string literals.
710 if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance<capture_raw>(); 710 if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance<capture_raw>();
711 return true; 711 return true;
712 } 712 }
713 713
714 switch (c) { 714 switch (c) {
715 case '\'': // fall through 715 case '\'': // fall through
716 case '"' : // fall through 716 case '"' : // fall through
717 case '\\': break; 717 case '\\': break;
718 case 'b' : c = '\b'; break; 718 case 'b' : c = '\b'; break;
719 case 'f' : c = '\f'; break; 719 case 'f' : c = '\f'; break;
720 case 'n' : c = '\n'; break; 720 case 'n' : c = '\n'; break;
721 case 'r' : c = '\r'; break; 721 case 'r' : c = '\r'; break;
722 case 't' : c = '\t'; break; 722 case 't' : c = '\t'; break;
723 case 'u' : { 723 case 'u' : {
724 c = ScanUnicodeEscape<capture_raw>(); 724 c = ScanUnicodeEscape<capture_raw>();
725 if (c < 0) return false; 725 if (c < 0) return false;
726 break; 726 break;
727 } 727 }
728 case 'v' : c = '\v'; break; 728 case 'v' : c = '\v'; break;
729 case 'x' : { 729 case 'x' : {
730 c = ScanHexNumber<capture_raw>(2); 730 c = ScanHexNumber<capture_raw>(2);
731 if (c < 0) return false; 731 if (c < 0) return false;
732 break; 732 break;
733 } 733 }
734 case '0' : // fall through 734 case '0':
735 if (in_template_literal) {
736 // The TV of TemplateCharacter :: \ EscapeSequence is the CV of
737 // EscapeSequence.
738 // The CV of EscapeSequence :: 0 is the code unit value 0.
739 c = 0;
740 break;
741 }
742 // Fall through.
735 case '1' : // fall through 743 case '1' : // fall through
736 case '2' : // fall through 744 case '2' : // fall through
737 case '3' : // fall through 745 case '3' : // fall through
738 case '4' : // fall through 746 case '4' : // fall through
739 case '5' : // fall through 747 case '5' : // fall through
740 case '6' : // fall through 748 case '6' : // fall through
741 case '7': 749 case '7':
742 c = ScanOctalEscape<capture_raw>(c, 2); 750 if (!in_template_literal) {
751 c = ScanOctalEscape<capture_raw>(c, 2);
752 }
743 break; 753 break;
744 } 754 }
745 755
746 // According to ECMA-262, section 7.8.4, characters not covered by the 756 // According to ECMA-262, section 7.8.4, characters not covered by the
747 // above cases should be illegal, but they are commonly handled as 757 // above cases should be illegal, but they are commonly handled as
748 // non-escaped characters by JS VMs. 758 // non-escaped characters by JS VMs.
749 AddLiteralChar(c); 759 AddLiteralChar(c);
750 return true; 760 return true;
751 } 761 }
752 762
(...skipping 27 matching lines...) Expand all
780 Token::Value Scanner::ScanString() { 790 Token::Value Scanner::ScanString() {
781 uc32 quote = c0_; 791 uc32 quote = c0_;
782 Advance(); // consume quote 792 Advance(); // consume quote
783 793
784 LiteralScope literal(this); 794 LiteralScope literal(this);
785 while (c0_ != quote && c0_ >= 0 795 while (c0_ != quote && c0_ >= 0
786 && !unicode_cache_->IsLineTerminator(c0_)) { 796 && !unicode_cache_->IsLineTerminator(c0_)) {
787 uc32 c = c0_; 797 uc32 c = c0_;
788 Advance(); 798 Advance();
789 if (c == '\\') { 799 if (c == '\\') {
790 if (c0_ < 0 || !ScanEscape<false>()) return Token::ILLEGAL; 800 if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL;
791 } else { 801 } else {
792 AddLiteralChar(c); 802 AddLiteralChar(c);
793 } 803 }
794 } 804 }
795 if (c0_ != quote) return Token::ILLEGAL; 805 if (c0_ != quote) return Token::ILLEGAL;
796 literal.Complete(); 806 literal.Complete();
797 807
798 Advance(); // consume quote 808 Advance(); // consume quote
799 return Token::STRING; 809 return Token::STRING;
800 } 810 }
(...skipping 10 matching lines...) Expand all
811 // | } LiteralChar* ` 821 // | } LiteralChar* `
812 // 822 //
813 // A TEMPLATE_SPAN should always be followed by an Expression, while a 823 // A TEMPLATE_SPAN should always be followed by an Expression, while a
814 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be 824 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
815 // followed by an Expression. 825 // followed by an Expression.
816 826
817 Token::Value result = Token::TEMPLATE_SPAN; 827 Token::Value result = Token::TEMPLATE_SPAN;
818 LiteralScope literal(this); 828 LiteralScope literal(this);
819 StartRawLiteral(); 829 StartRawLiteral();
820 const bool capture_raw = true; 830 const bool capture_raw = true;
831 const bool in_template_literal = true;
821 832
822 while (true) { 833 while (true) {
823 uc32 c = c0_; 834 uc32 c = c0_;
824 Advance<capture_raw>(); 835 Advance<capture_raw>();
825 if (c == '`') { 836 if (c == '`') {
826 result = Token::TEMPLATE_TAIL; 837 result = Token::TEMPLATE_TAIL;
827 ReduceRawLiteralLength(1); 838 ReduceRawLiteralLength(1);
828 break; 839 break;
829 } else if (c == '$' && c0_ == '{') { 840 } else if (c == '$' && c0_ == '{') {
830 Advance<capture_raw>(); // Consume '{' 841 Advance<capture_raw>(); // Consume '{'
831 ReduceRawLiteralLength(2); 842 ReduceRawLiteralLength(2);
832 break; 843 break;
833 } else if (c == '\\') { 844 } else if (c == '\\') {
834 if (unicode_cache_->IsLineTerminator(c0_)) { 845 if (unicode_cache_->IsLineTerminator(c0_)) {
835 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty 846 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty
836 // code unit sequence. 847 // code unit sequence.
837 uc32 lastChar = c0_; 848 uc32 lastChar = c0_;
838 Advance<capture_raw>(); 849 Advance<capture_raw>();
839 if (lastChar == '\r') { 850 if (lastChar == '\r') {
840 ReduceRawLiteralLength(1); // Remove \r 851 ReduceRawLiteralLength(1); // Remove \r
841 if (c0_ == '\n') { 852 if (c0_ == '\n') {
842 Advance<capture_raw>(); // Adds \n 853 Advance<capture_raw>(); // Adds \n
843 } else { 854 } else {
844 AddRawLiteralChar('\n'); 855 AddRawLiteralChar('\n');
845 } 856 }
846 } 857 }
847 } else if (c0_ == '0') {
848 Advance<capture_raw>();
849 AddLiteralChar('0');
850 } else { 858 } else {
851 ScanEscape<true>(); 859 ScanEscape<capture_raw, in_template_literal>();
852 } 860 }
853 } else if (c < 0) { 861 } else if (c < 0) {
854 // Unterminated template literal 862 // Unterminated template literal
855 PushBack(c); 863 PushBack(c);
856 break; 864 break;
857 } else { 865 } else {
858 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A. 866 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A.
859 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence 867 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence
860 // consisting of the CV 0x000A. 868 // consisting of the CV 0x000A.
861 if (c == '\r') { 869 if (c == '\r') {
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1486 }
1479 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); 1487 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1480 } 1488 }
1481 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); 1489 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1482 1490
1483 backing_store_.AddBlock(bytes); 1491 backing_store_.AddBlock(bytes);
1484 return backing_store_.EndSequence().start(); 1492 return backing_store_.EndSequence().start();
1485 } 1493 }
1486 1494
1487 } } // namespace v8::internal 1495 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698