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 <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 | 30 |
31 // ---------------------------------------------------------------------------- | 31 // ---------------------------------------------------------------------------- |
32 // Scanner | 32 // Scanner |
33 | 33 |
34 Scanner::Scanner(UnicodeCache* unicode_cache) | 34 Scanner::Scanner(UnicodeCache* unicode_cache) |
35 : unicode_cache_(unicode_cache), | 35 : unicode_cache_(unicode_cache), |
36 octal_pos_(Location::invalid()), | 36 octal_pos_(Location::invalid()), |
37 harmony_scoping_(false), | 37 harmony_scoping_(false), |
38 harmony_modules_(false), | 38 harmony_modules_(false), |
39 harmony_numeric_literals_(false) { } | 39 harmony_numeric_literals_(false), |
| 40 harmony_classes_(false) { } |
40 | 41 |
41 | 42 |
42 void Scanner::Initialize(Utf16CharacterStream* source) { | 43 void Scanner::Initialize(Utf16CharacterStream* source) { |
43 source_ = source; | 44 source_ = source; |
44 // Need to capture identifiers in order to recognize "get" and "set" | 45 // Need to capture identifiers in order to recognize "get" and "set" |
45 // in object literals. | 46 // in object literals. |
46 Init(); | 47 Init(); |
47 // Skip initial whitespace allowing HTML comment ends just like | 48 // Skip initial whitespace allowing HTML comment ends just like |
48 // after a newline and scan first token. | 49 // after a newline and scan first token. |
49 has_line_terminator_before_next_ = true; | 50 has_line_terminator_before_next_ = true; |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 Advance(); | 895 Advance(); |
895 uc32 result = ScanHexNumber(4); | 896 uc32 result = ScanHexNumber(4); |
896 if (result < 0) PushBack('u'); | 897 if (result < 0) PushBack('u'); |
897 return result; | 898 return result; |
898 } | 899 } |
899 | 900 |
900 | 901 |
901 // ---------------------------------------------------------------------------- | 902 // ---------------------------------------------------------------------------- |
902 // Keyword Matcher | 903 // Keyword Matcher |
903 | 904 |
904 #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ | 905 #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ |
905 KEYWORD_GROUP('b') \ | 906 KEYWORD_GROUP('b') \ |
906 KEYWORD("break", Token::BREAK) \ | 907 KEYWORD("break", Token::BREAK) \ |
907 KEYWORD_GROUP('c') \ | 908 KEYWORD_GROUP('c') \ |
908 KEYWORD("case", Token::CASE) \ | 909 KEYWORD("case", Token::CASE) \ |
909 KEYWORD("catch", Token::CATCH) \ | 910 KEYWORD("catch", Token::CATCH) \ |
910 KEYWORD("class", Token::FUTURE_RESERVED_WORD) \ | 911 KEYWORD("class", Token::FUTURE_RESERVED_WORD) \ |
911 KEYWORD("const", Token::CONST) \ | 912 KEYWORD("const", Token::CONST) \ |
912 KEYWORD("continue", Token::CONTINUE) \ | 913 KEYWORD("continue", Token::CONTINUE) \ |
913 KEYWORD_GROUP('d') \ | 914 KEYWORD_GROUP('d') \ |
914 KEYWORD("debugger", Token::DEBUGGER) \ | 915 KEYWORD("debugger", Token::DEBUGGER) \ |
915 KEYWORD("default", Token::DEFAULT) \ | 916 KEYWORD("default", Token::DEFAULT) \ |
916 KEYWORD("delete", Token::DELETE) \ | 917 KEYWORD("delete", Token::DELETE) \ |
917 KEYWORD("do", Token::DO) \ | 918 KEYWORD("do", Token::DO) \ |
918 KEYWORD_GROUP('e') \ | 919 KEYWORD_GROUP('e') \ |
919 KEYWORD("else", Token::ELSE) \ | 920 KEYWORD("else", Token::ELSE) \ |
920 KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \ | 921 KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \ |
921 KEYWORD("export", harmony_modules \ | 922 KEYWORD("export", \ |
922 ? Token::EXPORT : Token::FUTURE_RESERVED_WORD) \ | 923 harmony_modules ? Token::EXPORT : Token::FUTURE_RESERVED_WORD) \ |
923 KEYWORD("extends", Token::FUTURE_RESERVED_WORD) \ | 924 KEYWORD("extends", Token::FUTURE_RESERVED_WORD) \ |
924 KEYWORD_GROUP('f') \ | 925 KEYWORD_GROUP('f') \ |
925 KEYWORD("false", Token::FALSE_LITERAL) \ | 926 KEYWORD("false", Token::FALSE_LITERAL) \ |
926 KEYWORD("finally", Token::FINALLY) \ | 927 KEYWORD("finally", Token::FINALLY) \ |
927 KEYWORD("for", Token::FOR) \ | 928 KEYWORD("for", Token::FOR) \ |
928 KEYWORD("function", Token::FUNCTION) \ | 929 KEYWORD("function", Token::FUNCTION) \ |
929 KEYWORD_GROUP('i') \ | 930 KEYWORD_GROUP('i') \ |
930 KEYWORD("if", Token::IF) \ | 931 KEYWORD("if", Token::IF) \ |
931 KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \ | 932 KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \ |
932 KEYWORD("import", harmony_modules \ | 933 KEYWORD("import", \ |
933 ? Token::IMPORT : Token::FUTURE_RESERVED_WORD) \ | 934 harmony_modules ? Token::IMPORT : Token::FUTURE_RESERVED_WORD) \ |
934 KEYWORD("in", Token::IN) \ | 935 KEYWORD("in", Token::IN) \ |
935 KEYWORD("instanceof", Token::INSTANCEOF) \ | 936 KEYWORD("instanceof", Token::INSTANCEOF) \ |
936 KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \ | 937 KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \ |
937 KEYWORD_GROUP('l') \ | 938 KEYWORD_GROUP('l') \ |
938 KEYWORD("let", harmony_scoping \ | 939 KEYWORD("let", \ |
939 ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \ | 940 harmony_scoping ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \ |
940 KEYWORD_GROUP('n') \ | 941 KEYWORD_GROUP('n') \ |
941 KEYWORD("new", Token::NEW) \ | 942 KEYWORD("new", Token::NEW) \ |
942 KEYWORD("null", Token::NULL_LITERAL) \ | 943 KEYWORD("null", Token::NULL_LITERAL) \ |
943 KEYWORD_GROUP('p') \ | 944 KEYWORD_GROUP('p') \ |
944 KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \ | 945 KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \ |
945 KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \ | 946 KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \ |
946 KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \ | 947 KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \ |
947 KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \ | 948 KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \ |
948 KEYWORD_GROUP('r') \ | 949 KEYWORD_GROUP('r') \ |
949 KEYWORD("return", Token::RETURN) \ | 950 KEYWORD("return", Token::RETURN) \ |
950 KEYWORD_GROUP('s') \ | 951 KEYWORD_GROUP('s') \ |
951 KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD) \ | 952 KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD) \ |
952 KEYWORD("super", Token::FUTURE_RESERVED_WORD) \ | 953 KEYWORD("super", \ |
953 KEYWORD("switch", Token::SWITCH) \ | 954 harmony_classes ? Token::SUPER : Token::FUTURE_RESERVED_WORD) \ |
954 KEYWORD_GROUP('t') \ | 955 KEYWORD("switch", Token::SWITCH) \ |
955 KEYWORD("this", Token::THIS) \ | 956 KEYWORD_GROUP('t') \ |
956 KEYWORD("throw", Token::THROW) \ | 957 KEYWORD("this", Token::THIS) \ |
957 KEYWORD("true", Token::TRUE_LITERAL) \ | 958 KEYWORD("throw", Token::THROW) \ |
958 KEYWORD("try", Token::TRY) \ | 959 KEYWORD("true", Token::TRUE_LITERAL) \ |
959 KEYWORD("typeof", Token::TYPEOF) \ | 960 KEYWORD("try", Token::TRY) \ |
960 KEYWORD_GROUP('v') \ | 961 KEYWORD("typeof", Token::TYPEOF) \ |
961 KEYWORD("var", Token::VAR) \ | 962 KEYWORD_GROUP('v') \ |
962 KEYWORD("void", Token::VOID) \ | 963 KEYWORD("var", Token::VAR) \ |
963 KEYWORD_GROUP('w') \ | 964 KEYWORD("void", Token::VOID) \ |
964 KEYWORD("while", Token::WHILE) \ | 965 KEYWORD_GROUP('w') \ |
965 KEYWORD("with", Token::WITH) \ | 966 KEYWORD("while", Token::WHILE) \ |
966 KEYWORD_GROUP('y') \ | 967 KEYWORD("with", Token::WITH) \ |
| 968 KEYWORD_GROUP('y') \ |
967 KEYWORD("yield", Token::YIELD) | 969 KEYWORD("yield", Token::YIELD) |
968 | 970 |
969 | 971 |
970 static Token::Value KeywordOrIdentifierToken(const uint8_t* input, | 972 static Token::Value KeywordOrIdentifierToken(const uint8_t* input, |
971 int input_length, | 973 int input_length, |
972 bool harmony_scoping, | 974 bool harmony_scoping, |
973 bool harmony_modules) { | 975 bool harmony_modules, |
| 976 bool harmony_classes) { |
974 DCHECK(input_length >= 1); | 977 DCHECK(input_length >= 1); |
975 const int kMinLength = 2; | 978 const int kMinLength = 2; |
976 const int kMaxLength = 10; | 979 const int kMaxLength = 10; |
977 if (input_length < kMinLength || input_length > kMaxLength) { | 980 if (input_length < kMinLength || input_length > kMaxLength) { |
978 return Token::IDENTIFIER; | 981 return Token::IDENTIFIER; |
979 } | 982 } |
980 switch (input[0]) { | 983 switch (input[0]) { |
981 default: | 984 default: |
982 #define KEYWORD_GROUP_CASE(ch) \ | 985 #define KEYWORD_GROUP_CASE(ch) \ |
983 break; \ | 986 break; \ |
(...skipping 23 matching lines...) Expand all Loading... |
1007 return Token::IDENTIFIER; | 1010 return Token::IDENTIFIER; |
1008 } | 1011 } |
1009 | 1012 |
1010 | 1013 |
1011 bool Scanner::IdentifierIsFutureStrictReserved( | 1014 bool Scanner::IdentifierIsFutureStrictReserved( |
1012 const AstRawString* string) const { | 1015 const AstRawString* string) const { |
1013 // Keywords are always 1-byte strings. | 1016 // Keywords are always 1-byte strings. |
1014 return string->is_one_byte() && | 1017 return string->is_one_byte() && |
1015 Token::FUTURE_STRICT_RESERVED_WORD == | 1018 Token::FUTURE_STRICT_RESERVED_WORD == |
1016 KeywordOrIdentifierToken(string->raw_data(), string->length(), | 1019 KeywordOrIdentifierToken(string->raw_data(), string->length(), |
1017 harmony_scoping_, harmony_modules_); | 1020 harmony_scoping_, harmony_modules_, |
| 1021 harmony_classes_); |
1018 } | 1022 } |
1019 | 1023 |
1020 | 1024 |
1021 Token::Value Scanner::ScanIdentifierOrKeyword() { | 1025 Token::Value Scanner::ScanIdentifierOrKeyword() { |
1022 DCHECK(unicode_cache_->IsIdentifierStart(c0_)); | 1026 DCHECK(unicode_cache_->IsIdentifierStart(c0_)); |
1023 LiteralScope literal(this); | 1027 LiteralScope literal(this); |
1024 // Scan identifier start character. | 1028 // Scan identifier start character. |
1025 if (c0_ == '\\') { | 1029 if (c0_ == '\\') { |
1026 uc32 c = ScanIdentifierUnicodeEscape(); | 1030 uc32 c = ScanIdentifierUnicodeEscape(); |
1027 // Only allow legal identifier start characters. | 1031 // Only allow legal identifier start characters. |
(...skipping 22 matching lines...) Expand all Loading... |
1050 return ScanIdentifierSuffix(&literal); | 1054 return ScanIdentifierSuffix(&literal); |
1051 } | 1055 } |
1052 | 1056 |
1053 literal.Complete(); | 1057 literal.Complete(); |
1054 | 1058 |
1055 if (next_.literal_chars->is_one_byte()) { | 1059 if (next_.literal_chars->is_one_byte()) { |
1056 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); | 1060 Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal(); |
1057 return KeywordOrIdentifierToken(chars.start(), | 1061 return KeywordOrIdentifierToken(chars.start(), |
1058 chars.length(), | 1062 chars.length(), |
1059 harmony_scoping_, | 1063 harmony_scoping_, |
1060 harmony_modules_); | 1064 harmony_modules_, |
| 1065 harmony_classes_); |
1061 } | 1066 } |
1062 | 1067 |
1063 return Token::IDENTIFIER; | 1068 return Token::IDENTIFIER; |
1064 } | 1069 } |
1065 | 1070 |
1066 | 1071 |
1067 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) { | 1072 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) { |
1068 // Scan the rest of the identifier characters. | 1073 // Scan the rest of the identifier characters. |
1069 while (unicode_cache_->IsIdentifierPart(c0_)) { | 1074 while (unicode_cache_->IsIdentifierPart(c0_)) { |
1070 if (c0_ == '\\') { | 1075 if (c0_ == '\\') { |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1355 } | 1360 } |
1356 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); | 1361 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); |
1357 } | 1362 } |
1358 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); | 1363 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); |
1359 | 1364 |
1360 backing_store_.AddBlock(bytes); | 1365 backing_store_.AddBlock(bytes); |
1361 return backing_store_.EndSequence().start(); | 1366 return backing_store_.EndSequence().start(); |
1362 } | 1367 } |
1363 | 1368 |
1364 } } // namespace v8::internal | 1369 } } // namespace v8::internal |
OLD | NEW |