| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 67 |
| 68 return x; | 68 return x; |
| 69 } | 69 } |
| 70 | 70 |
| 71 | 71 |
| 72 | 72 |
| 73 // ---------------------------------------------------------------------------- | 73 // ---------------------------------------------------------------------------- |
| 74 // JavaScriptScanner | 74 // JavaScriptScanner |
| 75 | 75 |
| 76 JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants) | 76 JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants) |
| 77 : Scanner(scanner_contants), octal_pos_(Location::invalid()) { } | 77 : Scanner(scanner_contants), |
| 78 octal_pos_(Location::invalid()), |
| 79 harmony_block_scoping_(false) { } |
| 78 | 80 |
| 79 | 81 |
| 80 void JavaScriptScanner::Initialize(UC16CharacterStream* source) { | 82 void JavaScriptScanner::Initialize(UC16CharacterStream* source) { |
| 81 source_ = source; | 83 source_ = source; |
| 82 // Need to capture identifiers in order to recognize "get" and "set" | 84 // Need to capture identifiers in order to recognize "get" and "set" |
| 83 // in object literals. | 85 // in object literals. |
| 84 Init(); | 86 Init(); |
| 85 // Skip initial whitespace allowing HTML comment ends just like | 87 // Skip initial whitespace allowing HTML comment ends just like |
| 86 // after a newline and scan first token. | 88 // after a newline and scan first token. |
| 87 has_line_terminator_before_next_ = true; | 89 has_line_terminator_before_next_ = true; |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 // We do not allow a unicode escape sequence to start another | 808 // We do not allow a unicode escape sequence to start another |
| 807 // unicode escape sequence. | 809 // unicode escape sequence. |
| 808 if (c == '\\') return unibrow::Utf8::kBadChar; | 810 if (c == '\\') return unibrow::Utf8::kBadChar; |
| 809 return c; | 811 return c; |
| 810 } | 812 } |
| 811 | 813 |
| 812 | 814 |
| 813 // ---------------------------------------------------------------------------- | 815 // ---------------------------------------------------------------------------- |
| 814 // Keyword Matcher | 816 // Keyword Matcher |
| 815 | 817 |
| 816 #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ | 818 #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ |
| 817 KEYWORD_GROUP('b') \ | 819 KEYWORD_GROUP('b') \ |
| 818 KEYWORD("break", BREAK) \ | 820 KEYWORD("break", Token::BREAK) \ |
| 819 KEYWORD_GROUP('c') \ | 821 KEYWORD_GROUP('c') \ |
| 820 KEYWORD("case", CASE) \ | 822 KEYWORD("case", Token::CASE) \ |
| 821 KEYWORD("catch", CATCH) \ | 823 KEYWORD("catch", Token::CATCH) \ |
| 822 KEYWORD("class", FUTURE_RESERVED_WORD) \ | 824 KEYWORD("class", Token::FUTURE_RESERVED_WORD) \ |
| 823 KEYWORD("const", CONST) \ | 825 KEYWORD("const", Token::CONST) \ |
| 824 KEYWORD("continue", CONTINUE) \ | 826 KEYWORD("continue", Token::CONTINUE) \ |
| 825 KEYWORD_GROUP('d') \ | 827 KEYWORD_GROUP('d') \ |
| 826 KEYWORD("debugger", DEBUGGER) \ | 828 KEYWORD("debugger", Token::DEBUGGER) \ |
| 827 KEYWORD("default", DEFAULT) \ | 829 KEYWORD("default", Token::DEFAULT) \ |
| 828 KEYWORD("delete", DELETE) \ | 830 KEYWORD("delete", Token::DELETE) \ |
| 829 KEYWORD("do", DO) \ | 831 KEYWORD("do", Token::DO) \ |
| 830 KEYWORD_GROUP('e') \ | 832 KEYWORD_GROUP('e') \ |
| 831 KEYWORD("else", ELSE) \ | 833 KEYWORD("else", Token::ELSE) \ |
| 832 KEYWORD("enum", FUTURE_RESERVED_WORD) \ | 834 KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \ |
| 833 KEYWORD("export", FUTURE_RESERVED_WORD) \ | 835 KEYWORD("export", Token::FUTURE_RESERVED_WORD) \ |
| 834 KEYWORD("extends", FUTURE_RESERVED_WORD) \ | 836 KEYWORD("extends", Token::FUTURE_RESERVED_WORD) \ |
| 835 KEYWORD_GROUP('f') \ | 837 KEYWORD_GROUP('f') \ |
| 836 KEYWORD("false", FALSE_LITERAL) \ | 838 KEYWORD("false", Token::FALSE_LITERAL) \ |
| 837 KEYWORD("finally", FINALLY) \ | 839 KEYWORD("finally", Token::FINALLY) \ |
| 838 KEYWORD("for", FOR) \ | 840 KEYWORD("for", Token::FOR) \ |
| 839 KEYWORD("function", FUNCTION) \ | 841 KEYWORD("function", Token::FUNCTION) \ |
| 840 KEYWORD_GROUP('i') \ | 842 KEYWORD_GROUP('i') \ |
| 841 KEYWORD("if", IF) \ | 843 KEYWORD("if", Token::IF) \ |
| 842 KEYWORD("implements", FUTURE_STRICT_RESERVED_WORD) \ | 844 KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 843 KEYWORD("import", FUTURE_RESERVED_WORD) \ | 845 KEYWORD("import", Token::FUTURE_RESERVED_WORD) \ |
| 844 KEYWORD("in", IN) \ | 846 KEYWORD("in", Token::IN) \ |
| 845 KEYWORD("instanceof", INSTANCEOF) \ | 847 KEYWORD("instanceof", Token::INSTANCEOF) \ |
| 846 KEYWORD("interface", FUTURE_STRICT_RESERVED_WORD) \ | 848 KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 847 KEYWORD_GROUP('l') \ | 849 KEYWORD_GROUP('l') \ |
| 848 KEYWORD("let", FUTURE_STRICT_RESERVED_WORD) \ | 850 KEYWORD("let", harmony_block_scoping \ |
| 849 KEYWORD_GROUP('n') \ | 851 ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 850 KEYWORD("new", NEW) \ | 852 KEYWORD_GROUP('n') \ |
| 851 KEYWORD("null", NULL_LITERAL) \ | 853 KEYWORD("new", Token::NEW) \ |
| 852 KEYWORD_GROUP('p') \ | 854 KEYWORD("null", Token::NULL_LITERAL) \ |
| 853 KEYWORD("package", FUTURE_STRICT_RESERVED_WORD) \ | 855 KEYWORD_GROUP('p') \ |
| 854 KEYWORD("private", FUTURE_STRICT_RESERVED_WORD) \ | 856 KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 855 KEYWORD("protected", FUTURE_STRICT_RESERVED_WORD) \ | 857 KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 856 KEYWORD("public", FUTURE_STRICT_RESERVED_WORD) \ | 858 KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 857 KEYWORD_GROUP('r') \ | 859 KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 858 KEYWORD("return", RETURN) \ | 860 KEYWORD_GROUP('r') \ |
| 859 KEYWORD_GROUP('s') \ | 861 KEYWORD("return", Token::RETURN) \ |
| 860 KEYWORD("static", FUTURE_STRICT_RESERVED_WORD) \ | 862 KEYWORD_GROUP('s') \ |
| 861 KEYWORD("super", FUTURE_RESERVED_WORD) \ | 863 KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD) \ |
| 862 KEYWORD("switch", SWITCH) \ | 864 KEYWORD("super", Token::FUTURE_RESERVED_WORD) \ |
| 863 KEYWORD_GROUP('t') \ | 865 KEYWORD("switch", Token::SWITCH) \ |
| 864 KEYWORD("this", THIS) \ | 866 KEYWORD_GROUP('t') \ |
| 865 KEYWORD("throw", THROW) \ | 867 KEYWORD("this", Token::THIS) \ |
| 866 KEYWORD("true", TRUE_LITERAL) \ | 868 KEYWORD("throw", Token::THROW) \ |
| 867 KEYWORD("try", TRY) \ | 869 KEYWORD("true", Token::TRUE_LITERAL) \ |
| 868 KEYWORD("typeof", TYPEOF) \ | 870 KEYWORD("try", Token::TRY) \ |
| 869 KEYWORD_GROUP('v') \ | 871 KEYWORD("typeof", Token::TYPEOF) \ |
| 870 KEYWORD("var", VAR) \ | 872 KEYWORD_GROUP('v') \ |
| 871 KEYWORD("void", VOID) \ | 873 KEYWORD("var", Token::VAR) \ |
| 872 KEYWORD_GROUP('w') \ | 874 KEYWORD("void", Token::VOID) \ |
| 873 KEYWORD("while", WHILE) \ | 875 KEYWORD_GROUP('w') \ |
| 874 KEYWORD("with", WITH) \ | 876 KEYWORD("while", Token::WHILE) \ |
| 875 KEYWORD_GROUP('y') \ | 877 KEYWORD("with", Token::WITH) \ |
| 876 KEYWORD("yield", FUTURE_STRICT_RESERVED_WORD) | 878 KEYWORD_GROUP('y') \ |
| 879 KEYWORD("yield", Token::FUTURE_STRICT_RESERVED_WORD) |
| 877 | 880 |
| 878 | 881 |
| 879 static Token::Value KeywordOrIdentifierToken(const char* input, | 882 static Token::Value KeywordOrIdentifierToken(const char* input, |
| 880 int input_length) { | 883 int input_length, |
| 884 bool harmony_block_scoping) { |
| 881 ASSERT(input_length >= 1); | 885 ASSERT(input_length >= 1); |
| 882 const int kMinLength = 2; | 886 const int kMinLength = 2; |
| 883 const int kMaxLength = 10; | 887 const int kMaxLength = 10; |
| 884 if (input_length < kMinLength || input_length > kMaxLength) { | 888 if (input_length < kMinLength || input_length > kMaxLength) { |
| 885 return Token::IDENTIFIER; | 889 return Token::IDENTIFIER; |
| 886 } | 890 } |
| 887 switch (input[0]) { | 891 switch (input[0]) { |
| 888 default: | 892 default: |
| 889 #define KEYWORD_GROUP_CASE(ch) \ | 893 #define KEYWORD_GROUP_CASE(ch) \ |
| 890 break; \ | 894 break; \ |
| 891 case ch: | 895 case ch: |
| 892 #define KEYWORD(keyword, token) \ | 896 #define KEYWORD(keyword, token) \ |
| 893 { \ | 897 { \ |
| 894 /* 'keyword' is a char array, so sizeof(keyword) is */ \ | 898 /* 'keyword' is a char array, so sizeof(keyword) is */ \ |
| 895 /* strlen(keyword) plus 1 for the NUL char. */ \ | 899 /* strlen(keyword) plus 1 for the NUL char. */ \ |
| 896 const int keyword_length = sizeof(keyword) - 1; \ | 900 const int keyword_length = sizeof(keyword) - 1; \ |
| 897 STATIC_ASSERT(keyword_length >= kMinLength); \ | 901 STATIC_ASSERT(keyword_length >= kMinLength); \ |
| 898 STATIC_ASSERT(keyword_length <= kMaxLength); \ | 902 STATIC_ASSERT(keyword_length <= kMaxLength); \ |
| 899 if (input_length == keyword_length && \ | 903 if (input_length == keyword_length && \ |
| 900 input[1] == keyword[1] && \ | 904 input[1] == keyword[1] && \ |
| 901 (keyword_length <= 2 || input[2] == keyword[2]) && \ | 905 (keyword_length <= 2 || input[2] == keyword[2]) && \ |
| 902 (keyword_length <= 3 || input[3] == keyword[3]) && \ | 906 (keyword_length <= 3 || input[3] == keyword[3]) && \ |
| 903 (keyword_length <= 4 || input[4] == keyword[4]) && \ | 907 (keyword_length <= 4 || input[4] == keyword[4]) && \ |
| 904 (keyword_length <= 5 || input[5] == keyword[5]) && \ | 908 (keyword_length <= 5 || input[5] == keyword[5]) && \ |
| 905 (keyword_length <= 6 || input[6] == keyword[6]) && \ | 909 (keyword_length <= 6 || input[6] == keyword[6]) && \ |
| 906 (keyword_length <= 7 || input[7] == keyword[7]) && \ | 910 (keyword_length <= 7 || input[7] == keyword[7]) && \ |
| 907 (keyword_length <= 8 || input[8] == keyword[8]) && \ | 911 (keyword_length <= 8 || input[8] == keyword[8]) && \ |
| 908 (keyword_length <= 9 || input[9] == keyword[9])) { \ | 912 (keyword_length <= 9 || input[9] == keyword[9])) { \ |
| 909 return Token::token; \ | 913 return token; \ |
| 910 } \ | 914 } \ |
| 911 } | 915 } |
| 912 KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD) | 916 KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD) |
| 913 } | 917 } |
| 914 return Token::IDENTIFIER; | 918 return Token::IDENTIFIER; |
| 915 } | 919 } |
| 916 | 920 |
| 917 | 921 |
| 918 Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() { | 922 Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() { |
| 919 ASSERT(unicode_cache_->IsIdentifierStart(c0_)); | 923 ASSERT(unicode_cache_->IsIdentifierStart(c0_)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 940 continue; | 944 continue; |
| 941 } | 945 } |
| 942 // Fallthrough if no longer able to complete keyword. | 946 // Fallthrough if no longer able to complete keyword. |
| 943 return ScanIdentifierSuffix(&literal); | 947 return ScanIdentifierSuffix(&literal); |
| 944 } | 948 } |
| 945 | 949 |
| 946 literal.Complete(); | 950 literal.Complete(); |
| 947 | 951 |
| 948 if (next_.literal_chars->is_ascii()) { | 952 if (next_.literal_chars->is_ascii()) { |
| 949 Vector<const char> chars = next_.literal_chars->ascii_literal(); | 953 Vector<const char> chars = next_.literal_chars->ascii_literal(); |
| 950 return KeywordOrIdentifierToken(chars.start(), chars.length()); | 954 return KeywordOrIdentifierToken(chars.start(), |
| 955 chars.length(), |
| 956 harmony_block_scoping_); |
| 951 } | 957 } |
| 952 | 958 |
| 953 return Token::IDENTIFIER; | 959 return Token::IDENTIFIER; |
| 954 } | 960 } |
| 955 | 961 |
| 956 | 962 |
| 957 Token::Value JavaScriptScanner::ScanIdentifierSuffix(LiteralScope* literal) { | 963 Token::Value JavaScriptScanner::ScanIdentifierSuffix(LiteralScope* literal) { |
| 958 // Scan the rest of the identifier characters. | 964 // Scan the rest of the identifier characters. |
| 959 while (unicode_cache_->IsIdentifierPart(c0_)) { | 965 while (unicode_cache_->IsIdentifierPart(c0_)) { |
| 960 if (c0_ == '\\') { | 966 if (c0_ == '\\') { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 } | 1040 } |
| 1035 AddLiteralCharAdvance(); | 1041 AddLiteralCharAdvance(); |
| 1036 } | 1042 } |
| 1037 literal.Complete(); | 1043 literal.Complete(); |
| 1038 | 1044 |
| 1039 next_.location.end_pos = source_pos() - 1; | 1045 next_.location.end_pos = source_pos() - 1; |
| 1040 return true; | 1046 return true; |
| 1041 } | 1047 } |
| 1042 | 1048 |
| 1043 } } // namespace v8::internal | 1049 } } // namespace v8::internal |
| OLD | NEW |