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

Side by Side Diff: src/scanner-base.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « src/scanner-base.h ('k') | src/scopeinfo.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 if (!kIsIdentifierPart.get(buffer->GetNext())) { 57 if (!kIsIdentifierPart.get(buffer->GetNext())) {
58 return false; 58 return false;
59 } 59 }
60 } 60 }
61 return true; 61 return true;
62 } 62 }
63 63
64 // ---------------------------------------------------------------------------- 64 // ----------------------------------------------------------------------------
65 // Scanner 65 // Scanner
66 66
67 Scanner::Scanner() { } 67 Scanner::Scanner()
68 : octal_pos_(kNoOctalLocation) { }
68 69
69 70
70 uc32 Scanner::ScanHexEscape(uc32 c, int length) { 71 uc32 Scanner::ScanHexEscape(uc32 c, int length) {
71 ASSERT(length <= 4); // prevent overflow 72 ASSERT(length <= 4); // prevent overflow
72 73
73 uc32 digits[4]; 74 uc32 digits[4];
74 uc32 x = 0; 75 uc32 x = 0;
75 for (int i = 0; i < length; i++) { 76 for (int i = 0; i < length; i++) {
76 digits[i] = c0_; 77 digits[i] = c0_;
77 int d = HexValue(c0_); 78 int d = HexValue(c0_);
(...skipping 14 matching lines...) Expand all
92 } 93 }
93 94
94 return x; 95 return x;
95 } 96 }
96 97
97 98
98 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of 99 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of
99 // ECMA-262. Other JS VMs support them. 100 // ECMA-262. Other JS VMs support them.
100 uc32 Scanner::ScanOctalEscape(uc32 c, int length) { 101 uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
101 uc32 x = c - '0'; 102 uc32 x = c - '0';
102 for (int i = 0; i < length; i++) { 103 int i = 0;
104 for (; i < length; i++) {
103 int d = c0_ - '0'; 105 int d = c0_ - '0';
104 if (d < 0 || d > 7) break; 106 if (d < 0 || d > 7) break;
105 int nx = x * 8 + d; 107 int nx = x * 8 + d;
106 if (nx >= 256) break; 108 if (nx >= 256) break;
107 x = nx; 109 x = nx;
108 Advance(); 110 Advance();
109 } 111 }
112 // Anything excelt '\0' is an octal escape sequence, illegal in strict mode.
113 // Remember the position of octal escape sequences so that better error
114 // can be reported later (in strict mode).
115 if (c != '0' || i > 0) {
116 octal_pos_ = source_pos() - i - 1; // Already advanced
117 }
110 return x; 118 return x;
111 } 119 }
112 120
113 121
114 // ---------------------------------------------------------------------------- 122 // ----------------------------------------------------------------------------
115 // JavaScriptScanner 123 // JavaScriptScanner
116 124
117 JavaScriptScanner::JavaScriptScanner() : Scanner() {} 125 JavaScriptScanner::JavaScriptScanner() : Scanner() {}
118 126
119 127
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 AddLiteralCharAdvance(); 602 AddLiteralCharAdvance();
595 } 603 }
596 } else if ('0' <= c0_ && c0_ <= '7') { 604 } else if ('0' <= c0_ && c0_ <= '7') {
597 // (possible) octal number 605 // (possible) octal number
598 kind = OCTAL; 606 kind = OCTAL;
599 while (true) { 607 while (true) {
600 if (c0_ == '8' || c0_ == '9') { 608 if (c0_ == '8' || c0_ == '9') {
601 kind = DECIMAL; 609 kind = DECIMAL;
602 break; 610 break;
603 } 611 }
604 if (c0_ < '0' || '7' < c0_) break; 612 if (c0_ < '0' || '7' < c0_) {
613 // Octal literal finished.
614 octal_pos_ = next_.location.beg_pos;
615 break;
616 }
605 AddLiteralCharAdvance(); 617 AddLiteralCharAdvance();
606 } 618 }
607 } 619 }
608 } 620 }
609 621
610 // Parse decimal digits and allow trailing fractional part. 622 // Parse decimal digits and allow trailing fractional part.
611 if (kind == DECIMAL) { 623 if (kind == DECIMAL) {
612 ScanDecimalDigits(); // optional 624 ScanDecimalDigits(); // optional
613 if (c0_ == '.') { 625 if (c0_ == '.') {
614 AddLiteralCharAdvance(); 626 AddLiteralCharAdvance();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 736
725 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, 737 // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
726 // the scanner should pass uninterpreted bodies to the RegExp 738 // the scanner should pass uninterpreted bodies to the RegExp
727 // constructor. 739 // constructor.
728 LiteralScope literal(this); 740 LiteralScope literal(this);
729 if (seen_equal) 741 if (seen_equal)
730 AddLiteralChar('='); 742 AddLiteralChar('=');
731 743
732 while (c0_ != '/' || in_character_class) { 744 while (c0_ != '/' || in_character_class) {
733 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; 745 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false;
734 if (c0_ == '\\') { // escaped character 746 if (c0_ == '\\') { // Escape sequence.
735 AddLiteralCharAdvance(); 747 AddLiteralCharAdvance();
736 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false; 748 if (ScannerConstants::kIsLineTerminator.get(c0_) || c0_ < 0) return false;
737 AddLiteralCharAdvance(); 749 AddLiteralCharAdvance();
738 } else { // unescaped character 750 // If the escape allows more characters, i.e., \x??, \u????, or \c?,
751 // only "safe" characters are allowed (letters, digits, underscore),
752 // otherwise the escape isn't valid and the invalid character has
753 // its normal meaning. I.e., we can just continue scanning without
754 // worrying whether the following characters are part of the escape
755 // or not, since any '/', '\\' or '[' is guaranteed to not be part
756 // of the escape sequence.
757 } else { // Unescaped character.
739 if (c0_ == '[') in_character_class = true; 758 if (c0_ == '[') in_character_class = true;
740 if (c0_ == ']') in_character_class = false; 759 if (c0_ == ']') in_character_class = false;
741 AddLiteralCharAdvance(); 760 AddLiteralCharAdvance();
742 } 761 }
743 } 762 }
744 Advance(); // consume '/' 763 Advance(); // consume '/'
745 764
746 literal.Complete(); 765 literal.Complete();
747 766
748 return true; 767 return true;
(...skipping 21 matching lines...) Expand all
770 return true; 789 return true;
771 } 790 }
772 791
773 // ---------------------------------------------------------------------------- 792 // ----------------------------------------------------------------------------
774 // Keyword Matcher 793 // Keyword Matcher
775 794
776 KeywordMatcher::FirstState KeywordMatcher::first_states_[] = { 795 KeywordMatcher::FirstState KeywordMatcher::first_states_[] = {
777 { "break", KEYWORD_PREFIX, Token::BREAK }, 796 { "break", KEYWORD_PREFIX, Token::BREAK },
778 { NULL, C, Token::ILLEGAL }, 797 { NULL, C, Token::ILLEGAL },
779 { NULL, D, Token::ILLEGAL }, 798 { NULL, D, Token::ILLEGAL },
780 { "else", KEYWORD_PREFIX, Token::ELSE }, 799 { NULL, E, Token::ILLEGAL },
781 { NULL, F, Token::ILLEGAL }, 800 { NULL, F, Token::ILLEGAL },
782 { NULL, UNMATCHABLE, Token::ILLEGAL }, 801 { NULL, UNMATCHABLE, Token::ILLEGAL },
783 { NULL, UNMATCHABLE, Token::ILLEGAL }, 802 { NULL, UNMATCHABLE, Token::ILLEGAL },
784 { NULL, I, Token::ILLEGAL }, 803 { NULL, I, Token::ILLEGAL },
785 { NULL, UNMATCHABLE, Token::ILLEGAL }, 804 { NULL, UNMATCHABLE, Token::ILLEGAL },
786 { NULL, UNMATCHABLE, Token::ILLEGAL }, 805 { NULL, UNMATCHABLE, Token::ILLEGAL },
787 { NULL, UNMATCHABLE, Token::ILLEGAL }, 806 { "let", KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD },
788 { NULL, UNMATCHABLE, Token::ILLEGAL }, 807 { NULL, UNMATCHABLE, Token::ILLEGAL },
789 { NULL, N, Token::ILLEGAL }, 808 { NULL, N, Token::ILLEGAL },
790 { NULL, UNMATCHABLE, Token::ILLEGAL }, 809 { NULL, UNMATCHABLE, Token::ILLEGAL },
791 { NULL, UNMATCHABLE, Token::ILLEGAL }, 810 { NULL, P, Token::ILLEGAL },
792 { NULL, UNMATCHABLE, Token::ILLEGAL }, 811 { NULL, UNMATCHABLE, Token::ILLEGAL },
793 { "return", KEYWORD_PREFIX, Token::RETURN }, 812 { "return", KEYWORD_PREFIX, Token::RETURN },
794 { "switch", KEYWORD_PREFIX, Token::SWITCH }, 813 { NULL, S, Token::ILLEGAL },
795 { NULL, T, Token::ILLEGAL }, 814 { NULL, T, Token::ILLEGAL },
796 { NULL, UNMATCHABLE, Token::ILLEGAL }, 815 { NULL, UNMATCHABLE, Token::ILLEGAL },
797 { NULL, V, Token::ILLEGAL }, 816 { NULL, V, Token::ILLEGAL },
798 { NULL, W, Token::ILLEGAL } 817 { NULL, W, Token::ILLEGAL },
818 { NULL, UNMATCHABLE, Token::ILLEGAL },
819 { "yield", KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD }
799 }; 820 };
800 821
801 822
802 void KeywordMatcher::Step(unibrow::uchar input) { 823 void KeywordMatcher::Step(unibrow::uchar input) {
803 switch (state_) { 824 switch (state_) {
804 case INITIAL: { 825 case INITIAL: {
805 // matching the first character is the only state with significant fanout. 826 // matching the first character is the only state with significant fanout.
806 // Match only lower-case letters in range 'b'..'w'. 827 // Match only lower-case letters in range 'b'..'y'.
807 unsigned int offset = input - kFirstCharRangeMin; 828 unsigned int offset = input - kFirstCharRangeMin;
808 if (offset < kFirstCharRangeLength) { 829 if (offset < kFirstCharRangeLength) {
809 state_ = first_states_[offset].state; 830 state_ = first_states_[offset].state;
810 if (state_ == KEYWORD_PREFIX) { 831 if (state_ == KEYWORD_PREFIX) {
811 keyword_ = first_states_[offset].keyword; 832 keyword_ = first_states_[offset].keyword;
812 counter_ = 1; 833 counter_ = 1;
813 keyword_token_ = first_states_[offset].token; 834 keyword_token_ = first_states_[offset].token;
814 } 835 }
815 return; 836 return;
816 } 837 }
817 break; 838 break;
818 } 839 }
819 case KEYWORD_PREFIX: 840 case KEYWORD_PREFIX:
820 if (static_cast<unibrow::uchar>(keyword_[counter_]) == input) { 841 if (static_cast<unibrow::uchar>(keyword_[counter_]) == input) {
821 counter_++; 842 counter_++;
822 if (keyword_[counter_] == '\0') { 843 if (keyword_[counter_] == '\0') {
823 state_ = KEYWORD_MATCHED; 844 state_ = KEYWORD_MATCHED;
824 token_ = keyword_token_; 845 token_ = keyword_token_;
825 } 846 }
826 return; 847 return;
827 } 848 }
828 break; 849 break;
829 case KEYWORD_MATCHED: 850 case KEYWORD_MATCHED:
830 token_ = Token::IDENTIFIER; 851 token_ = Token::IDENTIFIER;
831 break; 852 break;
832 case C: 853 case C:
833 if (MatchState(input, 'a', CA)) return; 854 if (MatchState(input, 'a', CA)) return;
855 if (MatchKeywordStart(input, "class", 1,
856 Token::FUTURE_RESERVED_WORD)) return;
834 if (MatchState(input, 'o', CO)) return; 857 if (MatchState(input, 'o', CO)) return;
835 break; 858 break;
836 case CA: 859 case CA:
837 if (MatchKeywordStart(input, "case", 2, Token::CASE)) return; 860 if (MatchKeywordStart(input, "case", 2, Token::CASE)) return;
838 if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return; 861 if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return;
839 break; 862 break;
840 case CO: 863 case CO:
841 if (MatchState(input, 'n', CON)) return; 864 if (MatchState(input, 'n', CON)) return;
842 break; 865 break;
843 case CON: 866 case CON:
844 if (MatchKeywordStart(input, "const", 3, Token::CONST)) return; 867 if (MatchKeywordStart(input, "const", 3, Token::CONST)) return;
845 if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return; 868 if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return;
846 break; 869 break;
847 case D: 870 case D:
848 if (MatchState(input, 'e', DE)) return; 871 if (MatchState(input, 'e', DE)) return;
849 if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return; 872 if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return;
850 break; 873 break;
851 case DE: 874 case DE:
852 if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return; 875 if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return;
853 if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return; 876 if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return;
854 if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return; 877 if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return;
855 break; 878 break;
879 case E:
880 if (MatchKeywordStart(input, "else", 1, Token::ELSE)) return;
881 if (MatchKeywordStart(input, "enum", 1,
882 Token::FUTURE_RESERVED_WORD)) return;
883 if (MatchState(input, 'x', EX)) return;
884 break;
885 case EX:
886 if (MatchKeywordStart(input, "export", 2,
887 Token::FUTURE_RESERVED_WORD)) return;
888 if (MatchKeywordStart(input, "extends", 2,
889 Token::FUTURE_RESERVED_WORD)) return;
890 break;
856 case F: 891 case F:
857 if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return; 892 if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return;
858 if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return; 893 if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return;
859 if (MatchKeywordStart(input, "for", 1, Token::FOR)) return; 894 if (MatchKeywordStart(input, "for", 1, Token::FOR)) return;
860 if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return; 895 if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return;
861 break; 896 break;
862 case I: 897 case I:
863 if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return; 898 if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return;
899 if (MatchState(input, 'm', IM)) return;
864 if (MatchKeyword(input, 'n', IN, Token::IN)) return; 900 if (MatchKeyword(input, 'n', IN, Token::IN)) return;
865 break; 901 break;
902 case IM:
903 if (MatchState(input, 'p', IMP)) return;
904 break;
905 case IMP:
906 if (MatchKeywordStart(input, "implements", 3,
907 Token::FUTURE_RESERVED_WORD )) return;
908 if (MatchKeywordStart(input, "import", 3,
909 Token::FUTURE_RESERVED_WORD)) return;
910 break;
866 case IN: 911 case IN:
867 token_ = Token::IDENTIFIER; 912 token_ = Token::IDENTIFIER;
913 if (MatchKeywordStart(input, "interface", 2,
914 Token::FUTURE_RESERVED_WORD)) return;
868 if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return; 915 if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return;
869 break; 916 break;
870 case N: 917 case N:
871 if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return; 918 if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
872 if (MatchKeywordStart(input, "new", 1, Token::NEW)) return; 919 if (MatchKeywordStart(input, "new", 1, Token::NEW)) return;
873 if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return; 920 if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return;
874 break; 921 break;
922 case P:
923 if (MatchKeywordStart(input, "package", 1,
924 Token::FUTURE_RESERVED_WORD)) return;
925 if (MatchState(input, 'r', PR)) return;
926 if (MatchKeywordStart(input, "public", 1,
927 Token::FUTURE_RESERVED_WORD)) return;
928 break;
929 case PR:
930 if (MatchKeywordStart(input, "private", 2,
931 Token::FUTURE_RESERVED_WORD)) return;
932 if (MatchKeywordStart(input, "protected", 2,
933 Token::FUTURE_RESERVED_WORD)) return;
934 break;
935 case S:
936 if (MatchKeywordStart(input, "static", 1,
937 Token::FUTURE_RESERVED_WORD)) return;
938 if (MatchKeywordStart(input, "super", 1,
939 Token::FUTURE_RESERVED_WORD)) return;
940 if (MatchKeywordStart(input, "switch", 1,
941 Token::SWITCH)) return;
942 break;
875 case T: 943 case T:
876 if (MatchState(input, 'h', TH)) return; 944 if (MatchState(input, 'h', TH)) return;
877 if (MatchState(input, 'r', TR)) return; 945 if (MatchState(input, 'r', TR)) return;
878 if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return; 946 if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return;
879 break; 947 break;
880 case TH: 948 case TH:
881 if (MatchKeywordStart(input, "this", 2, Token::THIS)) return; 949 if (MatchKeywordStart(input, "this", 2, Token::THIS)) return;
882 if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return; 950 if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return;
883 break; 951 break;
884 case TR: 952 case TR:
885 if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return; 953 if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return;
886 if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return; 954 if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return;
887 break; 955 break;
888 case V: 956 case V:
889 if (MatchKeywordStart(input, "var", 1, Token::VAR)) return; 957 if (MatchKeywordStart(input, "var", 1, Token::VAR)) return;
890 if (MatchKeywordStart(input, "void", 1, Token::VOID)) return; 958 if (MatchKeywordStart(input, "void", 1, Token::VOID)) return;
891 break; 959 break;
892 case W: 960 case W:
893 if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return; 961 if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return;
894 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; 962 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return;
895 break; 963 break;
896 case UNMATCHABLE: 964 case UNMATCHABLE:
897 break; 965 break;
898 } 966 }
899 // On fallthrough, it's a failure. 967 // On fallthrough, it's a failure.
900 state_ = UNMATCHABLE; 968 state_ = UNMATCHABLE;
901 } 969 }
902 970
903 } } // namespace v8::internal 971 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scanner-base.h ('k') | src/scopeinfo.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698