| OLD | NEW |
| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 Advance(); | 90 Advance(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 return x; | 93 return x; |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of | 97 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of |
| 98 // ECMA-262. Other JS VMs support them. | 98 // ECMA-262. Other JS VMs support them. |
| 99 uc32 Scanner::ScanOctalEscape(uc32 c, int length) { | 99 uc32 Scanner::ScanOctalEscape(uc32 c, int length) { |
| 100 octal_pos_ = source_pos() - 1; // Already advanced | |
| 101 uc32 x = c - '0'; | 100 uc32 x = c - '0'; |
| 102 for (int i = 0; i < length; i++) { | 101 int i = 0; |
| 102 for (; i < length; i++) { |
| 103 int d = c0_ - '0'; | 103 int d = c0_ - '0'; |
| 104 if (d < 0 || d > 7) break; | 104 if (d < 0 || d > 7) break; |
| 105 int nx = x * 8 + d; | 105 int nx = x * 8 + d; |
| 106 if (nx >= 256) break; | 106 if (nx >= 256) break; |
| 107 x = nx; | 107 x = nx; |
| 108 Advance(); | 108 Advance(); |
| 109 } | 109 } |
| 110 // Anything excelt '\0' is an octal escape sequence, illegal in strict mode. |
| 111 // Remember the position of octal escape sequences so that better error |
| 112 // can be reported later (in strict mode). |
| 113 if (c != '0' || i > 0) { |
| 114 octal_pos_ = source_pos() - i - 1; // Already advanced |
| 115 } |
| 110 return x; | 116 return x; |
| 111 } | 117 } |
| 112 | 118 |
| 113 | 119 |
| 114 // ---------------------------------------------------------------------------- | 120 // ---------------------------------------------------------------------------- |
| 115 // JavaScriptScanner | 121 // JavaScriptScanner |
| 116 | 122 |
| 117 JavaScriptScanner::JavaScriptScanner(Isolate* isolate) : Scanner(isolate) {} | 123 JavaScriptScanner::JavaScriptScanner(Isolate* isolate) : Scanner(isolate) {} |
| 118 | 124 |
| 119 | 125 |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 return true; | 787 return true; |
| 782 } | 788 } |
| 783 | 789 |
| 784 // ---------------------------------------------------------------------------- | 790 // ---------------------------------------------------------------------------- |
| 785 // Keyword Matcher | 791 // Keyword Matcher |
| 786 | 792 |
| 787 KeywordMatcher::FirstState KeywordMatcher::first_states_[] = { | 793 KeywordMatcher::FirstState KeywordMatcher::first_states_[] = { |
| 788 { "break", KEYWORD_PREFIX, Token::BREAK }, | 794 { "break", KEYWORD_PREFIX, Token::BREAK }, |
| 789 { NULL, C, Token::ILLEGAL }, | 795 { NULL, C, Token::ILLEGAL }, |
| 790 { NULL, D, Token::ILLEGAL }, | 796 { NULL, D, Token::ILLEGAL }, |
| 791 { "else", KEYWORD_PREFIX, Token::ELSE }, | 797 { NULL, E, Token::ILLEGAL }, |
| 792 { NULL, F, Token::ILLEGAL }, | 798 { NULL, F, Token::ILLEGAL }, |
| 793 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 799 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 794 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 800 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 795 { NULL, I, Token::ILLEGAL }, | 801 { NULL, I, Token::ILLEGAL }, |
| 796 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 802 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 797 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 803 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 798 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 804 { "let", KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD }, |
| 799 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 805 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 800 { NULL, N, Token::ILLEGAL }, | 806 { NULL, N, Token::ILLEGAL }, |
| 801 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 807 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 802 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 808 { NULL, P, Token::ILLEGAL }, |
| 803 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 809 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 804 { "return", KEYWORD_PREFIX, Token::RETURN }, | 810 { "return", KEYWORD_PREFIX, Token::RETURN }, |
| 805 { "switch", KEYWORD_PREFIX, Token::SWITCH }, | 811 { NULL, S, Token::ILLEGAL }, |
| 806 { NULL, T, Token::ILLEGAL }, | 812 { NULL, T, Token::ILLEGAL }, |
| 807 { NULL, UNMATCHABLE, Token::ILLEGAL }, | 813 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 808 { NULL, V, Token::ILLEGAL }, | 814 { NULL, V, Token::ILLEGAL }, |
| 809 { NULL, W, Token::ILLEGAL } | 815 { NULL, W, Token::ILLEGAL }, |
| 816 { NULL, UNMATCHABLE, Token::ILLEGAL }, |
| 817 { "yield", KEYWORD_PREFIX, Token::FUTURE_RESERVED_WORD } |
| 810 }; | 818 }; |
| 811 | 819 |
| 812 | 820 |
| 813 void KeywordMatcher::Step(unibrow::uchar input) { | 821 void KeywordMatcher::Step(unibrow::uchar input) { |
| 814 switch (state_) { | 822 switch (state_) { |
| 815 case INITIAL: { | 823 case INITIAL: { |
| 816 // matching the first character is the only state with significant fanout. | 824 // matching the first character is the only state with significant fanout. |
| 817 // Match only lower-case letters in range 'b'..'w'. | 825 // Match only lower-case letters in range 'b'..'y'. |
| 818 unsigned int offset = input - kFirstCharRangeMin; | 826 unsigned int offset = input - kFirstCharRangeMin; |
| 819 if (offset < kFirstCharRangeLength) { | 827 if (offset < kFirstCharRangeLength) { |
| 820 state_ = first_states_[offset].state; | 828 state_ = first_states_[offset].state; |
| 821 if (state_ == KEYWORD_PREFIX) { | 829 if (state_ == KEYWORD_PREFIX) { |
| 822 keyword_ = first_states_[offset].keyword; | 830 keyword_ = first_states_[offset].keyword; |
| 823 counter_ = 1; | 831 counter_ = 1; |
| 824 keyword_token_ = first_states_[offset].token; | 832 keyword_token_ = first_states_[offset].token; |
| 825 } | 833 } |
| 826 return; | 834 return; |
| 827 } | 835 } |
| 828 break; | 836 break; |
| 829 } | 837 } |
| 830 case KEYWORD_PREFIX: | 838 case KEYWORD_PREFIX: |
| 831 if (static_cast<unibrow::uchar>(keyword_[counter_]) == input) { | 839 if (static_cast<unibrow::uchar>(keyword_[counter_]) == input) { |
| 832 counter_++; | 840 counter_++; |
| 833 if (keyword_[counter_] == '\0') { | 841 if (keyword_[counter_] == '\0') { |
| 834 state_ = KEYWORD_MATCHED; | 842 state_ = KEYWORD_MATCHED; |
| 835 token_ = keyword_token_; | 843 token_ = keyword_token_; |
| 836 } | 844 } |
| 837 return; | 845 return; |
| 838 } | 846 } |
| 839 break; | 847 break; |
| 840 case KEYWORD_MATCHED: | 848 case KEYWORD_MATCHED: |
| 841 token_ = Token::IDENTIFIER; | 849 token_ = Token::IDENTIFIER; |
| 842 break; | 850 break; |
| 843 case C: | 851 case C: |
| 844 if (MatchState(input, 'a', CA)) return; | 852 if (MatchState(input, 'a', CA)) return; |
| 853 if (MatchKeywordStart(input, "class", 1, |
| 854 Token::FUTURE_RESERVED_WORD)) return; |
| 845 if (MatchState(input, 'o', CO)) return; | 855 if (MatchState(input, 'o', CO)) return; |
| 846 break; | 856 break; |
| 847 case CA: | 857 case CA: |
| 848 if (MatchKeywordStart(input, "case", 2, Token::CASE)) return; | 858 if (MatchKeywordStart(input, "case", 2, Token::CASE)) return; |
| 849 if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return; | 859 if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return; |
| 850 break; | 860 break; |
| 851 case CO: | 861 case CO: |
| 852 if (MatchState(input, 'n', CON)) return; | 862 if (MatchState(input, 'n', CON)) return; |
| 853 break; | 863 break; |
| 854 case CON: | 864 case CON: |
| 855 if (MatchKeywordStart(input, "const", 3, Token::CONST)) return; | 865 if (MatchKeywordStart(input, "const", 3, Token::CONST)) return; |
| 856 if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return; | 866 if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return; |
| 857 break; | 867 break; |
| 858 case D: | 868 case D: |
| 859 if (MatchState(input, 'e', DE)) return; | 869 if (MatchState(input, 'e', DE)) return; |
| 860 if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return; | 870 if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return; |
| 861 break; | 871 break; |
| 862 case DE: | 872 case DE: |
| 863 if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return; | 873 if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return; |
| 864 if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return; | 874 if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return; |
| 865 if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return; | 875 if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return; |
| 866 break; | 876 break; |
| 877 case E: |
| 878 if (MatchKeywordStart(input, "else", 1, Token::ELSE)) return; |
| 879 if (MatchKeywordStart(input, "enum", 1, |
| 880 Token::FUTURE_RESERVED_WORD)) return; |
| 881 if (MatchState(input, 'x', EX)) return; |
| 882 break; |
| 883 case EX: |
| 884 if (MatchKeywordStart(input, "export", 2, |
| 885 Token::FUTURE_RESERVED_WORD)) return; |
| 886 if (MatchKeywordStart(input, "extends", 2, |
| 887 Token::FUTURE_RESERVED_WORD)) return; |
| 888 break; |
| 867 case F: | 889 case F: |
| 868 if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return; | 890 if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return; |
| 869 if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return; | 891 if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return; |
| 870 if (MatchKeywordStart(input, "for", 1, Token::FOR)) return; | 892 if (MatchKeywordStart(input, "for", 1, Token::FOR)) return; |
| 871 if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return; | 893 if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return; |
| 872 break; | 894 break; |
| 873 case I: | 895 case I: |
| 874 if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return; | 896 if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return; |
| 897 if (MatchState(input, 'm', IM)) return; |
| 875 if (MatchKeyword(input, 'n', IN, Token::IN)) return; | 898 if (MatchKeyword(input, 'n', IN, Token::IN)) return; |
| 876 break; | 899 break; |
| 900 case IM: |
| 901 if (MatchState(input, 'p', IMP)) return; |
| 902 break; |
| 903 case IMP: |
| 904 if (MatchKeywordStart(input, "implements", 3, |
| 905 Token::FUTURE_RESERVED_WORD )) return; |
| 906 if (MatchKeywordStart(input, "import", 3, |
| 907 Token::FUTURE_RESERVED_WORD)) return; |
| 908 break; |
| 877 case IN: | 909 case IN: |
| 878 token_ = Token::IDENTIFIER; | 910 token_ = Token::IDENTIFIER; |
| 911 if (MatchKeywordStart(input, "interface", 2, |
| 912 Token::FUTURE_RESERVED_WORD)) return; |
| 879 if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return; | 913 if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) return; |
| 880 break; | 914 break; |
| 881 case N: | 915 case N: |
| 882 if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return; | 916 if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return; |
| 883 if (MatchKeywordStart(input, "new", 1, Token::NEW)) return; | 917 if (MatchKeywordStart(input, "new", 1, Token::NEW)) return; |
| 884 if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return; | 918 if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return; |
| 885 break; | 919 break; |
| 920 case P: |
| 921 if (MatchKeywordStart(input, "package", 1, |
| 922 Token::FUTURE_RESERVED_WORD)) return; |
| 923 if (MatchState(input, 'r', PR)) return; |
| 924 if (MatchKeywordStart(input, "public", 1, |
| 925 Token::FUTURE_RESERVED_WORD)) return; |
| 926 break; |
| 927 case PR: |
| 928 if (MatchKeywordStart(input, "private", 2, |
| 929 Token::FUTURE_RESERVED_WORD)) return; |
| 930 if (MatchKeywordStart(input, "protected", 2, |
| 931 Token::FUTURE_RESERVED_WORD)) return; |
| 932 break; |
| 933 case S: |
| 934 if (MatchKeywordStart(input, "static", 1, |
| 935 Token::FUTURE_RESERVED_WORD)) return; |
| 936 if (MatchKeywordStart(input, "super", 1, |
| 937 Token::FUTURE_RESERVED_WORD)) return; |
| 938 if (MatchKeywordStart(input, "switch", 1, |
| 939 Token::SWITCH)) return; |
| 940 break; |
| 886 case T: | 941 case T: |
| 887 if (MatchState(input, 'h', TH)) return; | 942 if (MatchState(input, 'h', TH)) return; |
| 888 if (MatchState(input, 'r', TR)) return; | 943 if (MatchState(input, 'r', TR)) return; |
| 889 if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return; | 944 if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return; |
| 890 break; | 945 break; |
| 891 case TH: | 946 case TH: |
| 892 if (MatchKeywordStart(input, "this", 2, Token::THIS)) return; | 947 if (MatchKeywordStart(input, "this", 2, Token::THIS)) return; |
| 893 if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return; | 948 if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return; |
| 894 break; | 949 break; |
| 895 case TR: | 950 case TR: |
| 896 if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return; | 951 if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return; |
| 897 if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return; | 952 if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return; |
| 898 break; | 953 break; |
| 899 case V: | 954 case V: |
| 900 if (MatchKeywordStart(input, "var", 1, Token::VAR)) return; | 955 if (MatchKeywordStart(input, "var", 1, Token::VAR)) return; |
| 901 if (MatchKeywordStart(input, "void", 1, Token::VOID)) return; | 956 if (MatchKeywordStart(input, "void", 1, Token::VOID)) return; |
| 902 break; | 957 break; |
| 903 case W: | 958 case W: |
| 904 if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return; | 959 if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return; |
| 905 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; | 960 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; |
| 906 break; | 961 break; |
| 907 case UNMATCHABLE: | 962 case UNMATCHABLE: |
| 908 break; | 963 break; |
| 909 } | 964 } |
| 910 // On fallthrough, it's a failure. | 965 // On fallthrough, it's a failure. |
| 911 state_ = UNMATCHABLE; | 966 state_ = UNMATCHABLE; |
| 912 } | 967 } |
| 913 | 968 |
| 914 } } // namespace v8::internal | 969 } } // namespace v8::internal |
| OLD | NEW |