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