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

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 some more syntax errors 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 // \ 0 DecimalDigit is never allowed in templates.
737 if (IsDecimalDigit(c0_)) {
738 Advance<capture_raw>();
739 return false;
caitp (gmail) 2014/12/17 19:35:56 I feel like we should just let ScanOctalEscape do
740 }
741
742 // The TV of TemplateCharacter :: \ EscapeSequence is the CV of
743 // EscapeSequence.
744 // The CV of EscapeSequence :: 0 is the code unit value 0.
745 c = 0;
746 break;
747 }
748 // Fall through.
735 case '1' : // fall through 749 case '1' : // fall through
736 case '2' : // fall through 750 case '2' : // fall through
737 case '3' : // fall through 751 case '3' : // fall through
738 case '4' : // fall through 752 case '4' : // fall through
739 case '5' : // fall through 753 case '5' : // fall through
740 case '6' : // fall through 754 case '6' : // fall through
741 case '7': 755 case '7':
742 c = ScanOctalEscape<capture_raw>(c, 2); 756 if (!in_template_literal) {
757 c = ScanOctalEscape<capture_raw>(c, 2);
758 }
743 break; 759 break;
744 } 760 }
745 761
746 // According to ECMA-262, section 7.8.4, characters not covered by the 762 // 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 763 // above cases should be illegal, but they are commonly handled as
748 // non-escaped characters by JS VMs. 764 // non-escaped characters by JS VMs.
749 AddLiteralChar(c); 765 AddLiteralChar(c);
750 return true; 766 return true;
751 } 767 }
752 768
(...skipping 27 matching lines...) Expand all
780 Token::Value Scanner::ScanString() { 796 Token::Value Scanner::ScanString() {
781 uc32 quote = c0_; 797 uc32 quote = c0_;
782 Advance(); // consume quote 798 Advance(); // consume quote
783 799
784 LiteralScope literal(this); 800 LiteralScope literal(this);
785 while (c0_ != quote && c0_ >= 0 801 while (c0_ != quote && c0_ >= 0
786 && !unicode_cache_->IsLineTerminator(c0_)) { 802 && !unicode_cache_->IsLineTerminator(c0_)) {
787 uc32 c = c0_; 803 uc32 c = c0_;
788 Advance(); 804 Advance();
789 if (c == '\\') { 805 if (c == '\\') {
790 if (c0_ < 0 || !ScanEscape<false>()) return Token::ILLEGAL; 806 if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL;
791 } else { 807 } else {
792 AddLiteralChar(c); 808 AddLiteralChar(c);
793 } 809 }
794 } 810 }
795 if (c0_ != quote) return Token::ILLEGAL; 811 if (c0_ != quote) return Token::ILLEGAL;
796 literal.Complete(); 812 literal.Complete();
797 813
798 Advance(); // consume quote 814 Advance(); // consume quote
799 return Token::STRING; 815 return Token::STRING;
800 } 816 }
(...skipping 10 matching lines...) Expand all
811 // | } LiteralChar* ` 827 // | } LiteralChar* `
812 // 828 //
813 // A TEMPLATE_SPAN should always be followed by an Expression, while a 829 // A TEMPLATE_SPAN should always be followed by an Expression, while a
814 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be 830 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
815 // followed by an Expression. 831 // followed by an Expression.
816 832
817 Token::Value result = Token::TEMPLATE_SPAN; 833 Token::Value result = Token::TEMPLATE_SPAN;
818 LiteralScope literal(this); 834 LiteralScope literal(this);
819 StartRawLiteral(); 835 StartRawLiteral();
820 const bool capture_raw = true; 836 const bool capture_raw = true;
837 const bool in_template_literal = true;
821 838
822 while (true) { 839 while (true) {
823 uc32 c = c0_; 840 uc32 c = c0_;
824 Advance<capture_raw>(); 841 Advance<capture_raw>();
825 if (c == '`') { 842 if (c == '`') {
826 result = Token::TEMPLATE_TAIL; 843 result = Token::TEMPLATE_TAIL;
827 ReduceRawLiteralLength(1); 844 ReduceRawLiteralLength(1);
828 break; 845 break;
829 } else if (c == '$' && c0_ == '{') { 846 } else if (c == '$' && c0_ == '{') {
830 Advance<capture_raw>(); // Consume '{' 847 Advance<capture_raw>(); // Consume '{'
831 ReduceRawLiteralLength(2); 848 ReduceRawLiteralLength(2);
832 break; 849 break;
833 } else if (c == '\\') { 850 } else if (c == '\\') {
834 if (unicode_cache_->IsLineTerminator(c0_)) { 851 if (unicode_cache_->IsLineTerminator(c0_)) {
835 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty 852 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty
836 // code unit sequence. 853 // code unit sequence.
837 uc32 lastChar = c0_; 854 uc32 lastChar = c0_;
838 Advance<capture_raw>(); 855 Advance<capture_raw>();
839 if (lastChar == '\r') { 856 if (lastChar == '\r') {
840 ReduceRawLiteralLength(1); // Remove \r 857 ReduceRawLiteralLength(1); // Remove \r
841 if (c0_ == '\n') { 858 if (c0_ == '\n') {
842 Advance<capture_raw>(); // Adds \n 859 Advance<capture_raw>(); // Adds \n
843 } else { 860 } else {
844 AddRawLiteralChar('\n'); 861 AddRawLiteralChar('\n');
845 } 862 }
846 } 863 }
847 } else if (c0_ == '0') { 864 } else if (!ScanEscape<capture_raw, in_template_literal>()) {
848 Advance<capture_raw>(); 865 return Token::ILLEGAL;
849 AddLiteralChar('0');
850 } else {
851 ScanEscape<true>();
852 } 866 }
853 } else if (c < 0) { 867 } else if (c < 0) {
854 // Unterminated template literal 868 // Unterminated template literal
855 PushBack(c); 869 PushBack(c);
856 break; 870 break;
857 } else { 871 } else {
858 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A. 872 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A.
859 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence 873 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence
860 // consisting of the CV 0x000A. 874 // consisting of the CV 0x000A.
861 if (c == '\r') { 875 if (c == '\r') {
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 } 1492 }
1479 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); 1493 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1480 } 1494 }
1481 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); 1495 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1482 1496
1483 backing_store_.AddBlock(bytes); 1497 backing_store_.AddBlock(bytes);
1484 return backing_store_.EndSequence().start(); 1498 return backing_store_.EndSequence().start();
1485 } 1499 }
1486 1500
1487 } } // namespace v8::internal 1501 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698