OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 448 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
449 tok == Token::RBRACE || | 449 tok == Token::RBRACE || |
450 tok == Token::EOS) { | 450 tok == Token::EOS) { |
451 return; | 451 return; |
452 } | 452 } |
453 Expect(Token::SEMICOLON, ok); | 453 Expect(Token::SEMICOLON, ok); |
454 } | 454 } |
455 | 455 |
456 bool peek_any_identifier() { | 456 bool peek_any_identifier() { |
457 Token::Value next = peek(); | 457 Token::Value next = peek(); |
458 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 458 return next == Token::IDENTIFIER || next == Token::AWAIT || |
459 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 459 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || |
460 next == Token::STATIC || next == Token::YIELD; | 460 next == Token::LET || next == Token::STATIC || next == Token::YIELD; |
461 } | 461 } |
462 | 462 |
463 bool CheckContextualKeyword(Vector<const char> keyword) { | 463 bool CheckContextualKeyword(Vector<const char> keyword) { |
464 if (PeekContextualKeyword(keyword)) { | 464 if (PeekContextualKeyword(keyword)) { |
465 Consume(Token::IDENTIFIER); | 465 Consume(Token::IDENTIFIER); |
466 return true; | 466 return true; |
467 } | 467 } |
468 return false; | 468 return false; |
469 } | 469 } |
470 | 470 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 // so never lazily compile it. | 908 // so never lazily compile it. |
909 bool parenthesized_function_; | 909 bool parenthesized_function_; |
910 | 910 |
911 Scope* scope_; // Scope stack. | 911 Scope* scope_; // Scope stack. |
912 FunctionState* function_state_; // Function state stack. | 912 FunctionState* function_state_; // Function state stack. |
913 v8::Extension* extension_; | 913 v8::Extension* extension_; |
914 FuncNameInferrer* fni_; | 914 FuncNameInferrer* fni_; |
915 AstValueFactory* ast_value_factory_; // Not owned. | 915 AstValueFactory* ast_value_factory_; // Not owned. |
916 ParserRecorder* log_; | 916 ParserRecorder* log_; |
917 Mode mode_; | 917 Mode mode_; |
| 918 bool parsing_module_; |
918 uintptr_t stack_limit_; | 919 uintptr_t stack_limit_; |
919 | 920 |
920 private: | 921 private: |
921 Zone* zone_; | 922 Zone* zone_; |
922 | 923 |
923 Scanner* scanner_; | 924 Scanner* scanner_; |
924 bool stack_overflow_; | 925 bool stack_overflow_; |
925 | 926 |
926 bool allow_lazy_; | 927 bool allow_lazy_; |
927 bool allow_natives_; | 928 bool allow_natives_; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 case Token::SMI: | 978 case Token::SMI: |
978 case Token::NUMBER: | 979 case Token::NUMBER: |
979 *message = MessageTemplate::kUnexpectedTokenNumber; | 980 *message = MessageTemplate::kUnexpectedTokenNumber; |
980 break; | 981 break; |
981 case Token::STRING: | 982 case Token::STRING: |
982 *message = MessageTemplate::kUnexpectedTokenString; | 983 *message = MessageTemplate::kUnexpectedTokenString; |
983 break; | 984 break; |
984 case Token::IDENTIFIER: | 985 case Token::IDENTIFIER: |
985 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 986 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
986 break; | 987 break; |
987 case Token::FUTURE_RESERVED_WORD: | 988 case Token::AWAIT: |
| 989 case Token::ENUM: |
988 *message = MessageTemplate::kUnexpectedReserved; | 990 *message = MessageTemplate::kUnexpectedReserved; |
989 break; | 991 break; |
990 case Token::LET: | 992 case Token::LET: |
991 case Token::STATIC: | 993 case Token::STATIC: |
992 case Token::YIELD: | 994 case Token::YIELD: |
993 case Token::FUTURE_STRICT_RESERVED_WORD: | 995 case Token::FUTURE_STRICT_RESERVED_WORD: |
994 *message = is_strict(language_mode()) | 996 *message = is_strict(language_mode()) |
995 ? MessageTemplate::kUnexpectedStrictReserved | 997 ? MessageTemplate::kUnexpectedStrictReserved |
996 : MessageTemplate::kUnexpectedTokenIdentifier; | 998 : MessageTemplate::kUnexpectedTokenIdentifier; |
997 break; | 999 break; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 | 1054 |
1053 return result; | 1055 return result; |
1054 } | 1056 } |
1055 | 1057 |
1056 | 1058 |
1057 template <class Traits> | 1059 template <class Traits> |
1058 typename ParserBase<Traits>::IdentifierT | 1060 typename ParserBase<Traits>::IdentifierT |
1059 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1061 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
1060 bool* ok) { | 1062 bool* ok) { |
1061 Token::Value next = Next(); | 1063 Token::Value next = Next(); |
1062 if (next == Token::IDENTIFIER) { | 1064 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1063 IdentifierT name = this->GetSymbol(scanner()); | 1065 IdentifierT name = this->GetSymbol(scanner()); |
1064 // When this function is used to read a formal parameter, we don't always | 1066 // When this function is used to read a formal parameter, we don't always |
1065 // know whether the function is going to be strict or sloppy. Indeed for | 1067 // know whether the function is going to be strict or sloppy. Indeed for |
1066 // arrow functions we don't always know that the identifier we are reading | 1068 // arrow functions we don't always know that the identifier we are reading |
1067 // is actually a formal parameter. Therefore besides the errors that we | 1069 // is actually a formal parameter. Therefore besides the errors that we |
1068 // must detect because we know we're in strict mode, we also record any | 1070 // must detect because we know we're in strict mode, we also record any |
1069 // error that we might make in the future once we know the language mode. | 1071 // error that we might make in the future once we know the language mode. |
1070 if (this->IsEval(name)) { | 1072 if (this->IsEval(name)) { |
1071 classifier->RecordStrictModeFormalParameterError( | 1073 classifier->RecordStrictModeFormalParameterError( |
1072 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1074 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 return Traits::EmptyIdentifier(); | 1118 return Traits::EmptyIdentifier(); |
1117 } | 1119 } |
1118 } | 1120 } |
1119 | 1121 |
1120 | 1122 |
1121 template <class Traits> | 1123 template <class Traits> |
1122 typename ParserBase<Traits>::IdentifierT | 1124 typename ParserBase<Traits>::IdentifierT |
1123 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1125 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
1124 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1126 bool is_generator, bool* is_strict_reserved, bool* ok) { |
1125 Token::Value next = Next(); | 1127 Token::Value next = Next(); |
1126 if (next == Token::IDENTIFIER) { | 1128 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1127 *is_strict_reserved = false; | 1129 *is_strict_reserved = false; |
1128 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1130 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1129 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1131 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
1130 *is_strict_reserved = true; | 1132 *is_strict_reserved = true; |
1131 } else { | 1133 } else { |
1132 ReportUnexpectedToken(next); | 1134 ReportUnexpectedToken(next); |
1133 *ok = false; | 1135 *ok = false; |
1134 return Traits::EmptyIdentifier(); | 1136 return Traits::EmptyIdentifier(); |
1135 } | 1137 } |
1136 | 1138 |
1137 IdentifierT name = this->GetSymbol(scanner()); | 1139 IdentifierT name = this->GetSymbol(scanner()); |
1138 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1140 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1139 return name; | 1141 return name; |
1140 } | 1142 } |
1141 | 1143 |
1142 | |
1143 template <class Traits> | 1144 template <class Traits> |
1144 typename ParserBase<Traits>::IdentifierT | 1145 typename ParserBase<Traits>::IdentifierT |
1145 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1146 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1146 Token::Value next = Next(); | 1147 Token::Value next = Next(); |
1147 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1148 if (next != Token::IDENTIFIER && next != Token::ENUM && |
1148 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1149 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
1149 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1150 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
1150 next != Token::ESCAPED_KEYWORD && | 1151 next != Token::ESCAPED_KEYWORD && |
1151 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1152 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1152 this->ReportUnexpectedToken(next); | 1153 this->ReportUnexpectedToken(next); |
1153 *ok = false; | 1154 *ok = false; |
1154 return Traits::EmptyIdentifier(); | 1155 return Traits::EmptyIdentifier(); |
1155 } | 1156 } |
1156 | 1157 |
1157 IdentifierT name = this->GetSymbol(scanner()); | 1158 IdentifierT name = this->GetSymbol(scanner()); |
1158 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1159 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1159 return name; | 1160 return name; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1237 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1237 case Token::SMI: | 1238 case Token::SMI: |
1238 case Token::NUMBER: | 1239 case Token::NUMBER: |
1239 BindingPatternUnexpectedToken(classifier); | 1240 BindingPatternUnexpectedToken(classifier); |
1240 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1241 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1241 | 1242 |
1242 case Token::IDENTIFIER: | 1243 case Token::IDENTIFIER: |
1243 case Token::LET: | 1244 case Token::LET: |
1244 case Token::STATIC: | 1245 case Token::STATIC: |
1245 case Token::YIELD: | 1246 case Token::YIELD: |
| 1247 case Token::AWAIT: |
1246 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1248 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1247 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1249 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1248 // Using eval or arguments in this context is OK even in strict mode. | 1250 // Using eval or arguments in this context is OK even in strict mode. |
1249 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1251 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
1250 return this->ExpressionFromIdentifier( | 1252 return this->ExpressionFromIdentifier( |
1251 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1253 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
1252 } | 1254 } |
1253 | 1255 |
1254 case Token::STRING: { | 1256 case Token::STRING: { |
1255 BindingPatternUnexpectedToken(classifier); | 1257 BindingPatternUnexpectedToken(classifier); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 int beg_pos = peek_position(); | 1609 int beg_pos = peek_position(); |
1608 value = this->ParseAssignmentExpression( | 1610 value = this->ParseAssignmentExpression( |
1609 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1611 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1610 CheckDestructuringElement(value, classifier, beg_pos, | 1612 CheckDestructuringElement(value, classifier, beg_pos, |
1611 scanner()->location().end_pos); | 1613 scanner()->location().end_pos); |
1612 | 1614 |
1613 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1615 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
1614 *is_computed_name); | 1616 *is_computed_name); |
1615 } | 1617 } |
1616 | 1618 |
1617 if (Token::IsIdentifier(name_token, language_mode(), | 1619 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
1618 this->is_generator()) && | 1620 parsing_module_) && |
1619 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1621 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1620 peek() == Token::ASSIGN)) { | 1622 peek() == Token::ASSIGN)) { |
1621 // PropertyDefinition | 1623 // PropertyDefinition |
1622 // IdentifierReference | 1624 // IdentifierReference |
1623 // CoverInitializedName | 1625 // CoverInitializedName |
1624 // | 1626 // |
1625 // CoverInitializedName | 1627 // CoverInitializedName |
1626 // IdentifierReference Initializer? | 1628 // IdentifierReference Initializer? |
1627 if (classifier->duplicate_finder() != nullptr && | 1629 if (classifier->duplicate_finder() != nullptr && |
1628 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1630 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2791 return false; | 2793 return false; |
2792 } | 2794 } |
2793 Token::Value next_next = PeekAhead(); | 2795 Token::Value next_next = PeekAhead(); |
2794 switch (next_next) { | 2796 switch (next_next) { |
2795 case Token::LBRACE: | 2797 case Token::LBRACE: |
2796 case Token::LBRACK: | 2798 case Token::LBRACK: |
2797 case Token::IDENTIFIER: | 2799 case Token::IDENTIFIER: |
2798 case Token::STATIC: | 2800 case Token::STATIC: |
2799 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 2801 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
2800 case Token::YIELD: | 2802 case Token::YIELD: |
| 2803 case Token::AWAIT: |
2801 return true; | 2804 return true; |
2802 default: | 2805 default: |
2803 return false; | 2806 return false; |
2804 } | 2807 } |
2805 } | 2808 } |
2806 | 2809 |
2807 | 2810 |
2808 template <class Traits> | 2811 template <class Traits> |
2809 typename ParserBase<Traits>::ExpressionT | 2812 typename ParserBase<Traits>::ExpressionT |
2810 ParserBase<Traits>::ParseArrowFunctionLiteral( | 2813 ParserBase<Traits>::ParseArrowFunctionLiteral( |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3123 has_seen_constructor_ = true; | 3126 has_seen_constructor_ = true; |
3124 return; | 3127 return; |
3125 } | 3128 } |
3126 } | 3129 } |
3127 | 3130 |
3128 | 3131 |
3129 } // namespace internal | 3132 } // namespace internal |
3130 } // namespace v8 | 3133 } // namespace v8 |
3131 | 3134 |
3132 #endif // V8_PARSING_PARSER_BASE_H | 3135 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |