Chromium Code Reviews

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: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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...)
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)) {
caitp (gmail) 2014/12/17 17:04:21 Is this check necessary? I think ScanTemplateSpan
arv (Not doing code reviews) 2014/12/17 17:56:20 It is not needed but it is dead code in case we ar
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
(...skipping 15 matching lines...)
732 break; 732 break;
733 } 733 }
734 case '0' : // fall through 734 case '0' : // fall through
735 case '1' : // fall through 735 case '1' : // fall through
736 case '2' : // fall through 736 case '2' : // fall through
737 case '3' : // fall through 737 case '3' : // fall through
738 case '4' : // fall through 738 case '4' : // fall through
739 case '5' : // fall through 739 case '5' : // fall through
740 case '6' : // fall through 740 case '6' : // fall through
741 case '7': 741 case '7':
742 c = ScanOctalEscape<capture_raw>(c, 2); 742 if (!in_template_literal) {
743 c = ScanOctalEscape<capture_raw>(c, 2);
744 }
743 break; 745 break;
744 } 746 }
745 747
746 // According to ECMA-262, section 7.8.4, characters not covered by the 748 // 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 749 // above cases should be illegal, but they are commonly handled as
748 // non-escaped characters by JS VMs. 750 // non-escaped characters by JS VMs.
749 AddLiteralChar(c); 751 AddLiteralChar(c);
750 return true; 752 return true;
751 } 753 }
752 754
(...skipping 27 matching lines...)
780 Token::Value Scanner::ScanString() { 782 Token::Value Scanner::ScanString() {
781 uc32 quote = c0_; 783 uc32 quote = c0_;
782 Advance(); // consume quote 784 Advance(); // consume quote
783 785
784 LiteralScope literal(this); 786 LiteralScope literal(this);
785 while (c0_ != quote && c0_ >= 0 787 while (c0_ != quote && c0_ >= 0
786 && !unicode_cache_->IsLineTerminator(c0_)) { 788 && !unicode_cache_->IsLineTerminator(c0_)) {
787 uc32 c = c0_; 789 uc32 c = c0_;
788 Advance(); 790 Advance();
789 if (c == '\\') { 791 if (c == '\\') {
790 if (c0_ < 0 || !ScanEscape<false>()) return Token::ILLEGAL; 792 if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL;
791 } else { 793 } else {
792 AddLiteralChar(c); 794 AddLiteralChar(c);
793 } 795 }
794 } 796 }
795 if (c0_ != quote) return Token::ILLEGAL; 797 if (c0_ != quote) return Token::ILLEGAL;
796 literal.Complete(); 798 literal.Complete();
797 799
798 Advance(); // consume quote 800 Advance(); // consume quote
799 return Token::STRING; 801 return Token::STRING;
800 } 802 }
(...skipping 10 matching lines...)
811 // | } LiteralChar* ` 813 // | } LiteralChar* `
812 // 814 //
813 // A TEMPLATE_SPAN should always be followed by an Expression, while a 815 // A TEMPLATE_SPAN should always be followed by an Expression, while a
814 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be 816 // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
815 // followed by an Expression. 817 // followed by an Expression.
816 818
817 Token::Value result = Token::TEMPLATE_SPAN; 819 Token::Value result = Token::TEMPLATE_SPAN;
818 LiteralScope literal(this); 820 LiteralScope literal(this);
819 StartRawLiteral(); 821 StartRawLiteral();
820 const bool capture_raw = true; 822 const bool capture_raw = true;
823 const bool in_template_literal = true;
821 824
822 while (true) { 825 while (true) {
823 uc32 c = c0_; 826 uc32 c = c0_;
824 Advance<capture_raw>(); 827 Advance<capture_raw>();
825 if (c == '`') { 828 if (c == '`') {
826 result = Token::TEMPLATE_TAIL; 829 result = Token::TEMPLATE_TAIL;
827 ReduceRawLiteralLength(1); 830 ReduceRawLiteralLength(1);
828 break; 831 break;
829 } else if (c == '$' && c0_ == '{') { 832 } else if (c == '$' && c0_ == '{') {
830 Advance<capture_raw>(); // Consume '{' 833 Advance<capture_raw>(); // Consume '{'
831 ReduceRawLiteralLength(2); 834 ReduceRawLiteralLength(2);
832 break; 835 break;
833 } else if (c == '\\') { 836 } else if (c == '\\') {
834 if (unicode_cache_->IsLineTerminator(c0_)) { 837 if (unicode_cache_->IsLineTerminator(c0_)) {
835 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty 838 // The TV of LineContinuation :: \ LineTerminatorSequence is the empty
836 // code unit sequence. 839 // code unit sequence.
837 uc32 lastChar = c0_; 840 uc32 lastChar = c0_;
838 Advance<capture_raw>(); 841 Advance<capture_raw>();
839 if (lastChar == '\r') { 842 if (lastChar == '\r') {
840 ReduceRawLiteralLength(1); // Remove \r 843 ReduceRawLiteralLength(1); // Remove \r
841 if (c0_ == '\n') { 844 if (c0_ == '\n') {
842 Advance<capture_raw>(); // Adds \n 845 Advance<capture_raw>(); // Adds \n
843 } else { 846 } else {
844 AddRawLiteralChar('\n'); 847 AddRawLiteralChar('\n');
845 } 848 }
846 } 849 }
847 } else if (c0_ == '0') {
848 Advance<capture_raw>();
849 AddLiteralChar('0');
850 } else { 850 } else {
851 ScanEscape<true>(); 851 ScanEscape<capture_raw, in_template_literal>();
caitp (gmail) 2014/12/17 17:04:21 How are these ever not <true, true> here?
arv (Not doing code reviews) 2014/12/17 17:56:20 They are always true, true here. I added the const
852 } 852 }
853 } else if (c < 0) { 853 } else if (c < 0) {
854 // Unterminated template literal 854 // Unterminated template literal
855 PushBack(c); 855 PushBack(c);
856 break; 856 break;
857 } else { 857 } else {
858 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A. 858 // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A.
859 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence 859 // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence
860 // consisting of the CV 0x000A. 860 // consisting of the CV 0x000A.
861 if (c == '\r') { 861 if (c == '\r') {
(...skipping 616 matching lines...)
1478 } 1478 }
1479 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); 1479 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1480 } 1480 }
1481 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); 1481 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1482 1482
1483 backing_store_.AddBlock(bytes); 1483 backing_store_.AddBlock(bytes);
1484 return backing_store_.EndSequence().start(); 1484 return backing_store_.EndSequence().start();
1485 } 1485 }
1486 1486
1487 } } // namespace v8::internal 1487 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine