| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 v8::Extension* extension, AstValueFactory* ast_value_factory, | 98 v8::Extension* extension, AstValueFactory* ast_value_factory, |
| 99 ParserRecorder* log, typename Traits::Type::Parser this_object) | 99 ParserRecorder* log, typename Traits::Type::Parser this_object) |
| 100 : Traits(this_object), | 100 : Traits(this_object), |
| 101 scope_(NULL), | 101 scope_(NULL), |
| 102 function_state_(NULL), | 102 function_state_(NULL), |
| 103 extension_(extension), | 103 extension_(extension), |
| 104 fni_(NULL), | 104 fni_(NULL), |
| 105 ast_value_factory_(ast_value_factory), | 105 ast_value_factory_(ast_value_factory), |
| 106 log_(log), | 106 log_(log), |
| 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 107 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
| 108 parsing_module_(false), |
| 108 stack_limit_(stack_limit), | 109 stack_limit_(stack_limit), |
| 109 zone_(zone), | 110 zone_(zone), |
| 110 scanner_(scanner), | 111 scanner_(scanner), |
| 111 stack_overflow_(false), | 112 stack_overflow_(false), |
| 112 allow_lazy_(false), | 113 allow_lazy_(false), |
| 113 allow_natives_(false), | 114 allow_natives_(false), |
| 114 allow_tailcalls_(false), | 115 allow_tailcalls_(false), |
| 115 allow_harmony_restrictive_declarations_(false), | 116 allow_harmony_restrictive_declarations_(false), |
| 116 allow_harmony_do_expressions_(false), | 117 allow_harmony_do_expressions_(false), |
| 117 allow_harmony_function_name_(false), | 118 allow_harmony_function_name_(false), |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 458 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
| 458 tok == Token::RBRACE || | 459 tok == Token::RBRACE || |
| 459 tok == Token::EOS) { | 460 tok == Token::EOS) { |
| 460 return; | 461 return; |
| 461 } | 462 } |
| 462 Expect(Token::SEMICOLON, ok); | 463 Expect(Token::SEMICOLON, ok); |
| 463 } | 464 } |
| 464 | 465 |
| 465 bool peek_any_identifier() { | 466 bool peek_any_identifier() { |
| 466 Token::Value next = peek(); | 467 Token::Value next = peek(); |
| 467 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 468 return next == Token::IDENTIFIER || next == Token::AWAIT || |
| 468 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 469 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 469 next == Token::STATIC || next == Token::YIELD; | 470 next == Token::LET || next == Token::STATIC || next == Token::YIELD; |
| 470 } | 471 } |
| 471 | 472 |
| 472 bool CheckContextualKeyword(Vector<const char> keyword) { | 473 bool CheckContextualKeyword(Vector<const char> keyword) { |
| 473 if (PeekContextualKeyword(keyword)) { | 474 if (PeekContextualKeyword(keyword)) { |
| 474 Consume(Token::IDENTIFIER); | 475 Consume(Token::IDENTIFIER); |
| 475 return true; | 476 return true; |
| 476 } | 477 } |
| 477 return false; | 478 return false; |
| 478 } | 479 } |
| 479 | 480 |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 bool has_seen_constructor_; | 904 bool has_seen_constructor_; |
| 904 }; | 905 }; |
| 905 | 906 |
| 906 Scope* scope_; // Scope stack. | 907 Scope* scope_; // Scope stack. |
| 907 FunctionState* function_state_; // Function state stack. | 908 FunctionState* function_state_; // Function state stack. |
| 908 v8::Extension* extension_; | 909 v8::Extension* extension_; |
| 909 FuncNameInferrer* fni_; | 910 FuncNameInferrer* fni_; |
| 910 AstValueFactory* ast_value_factory_; // Not owned. | 911 AstValueFactory* ast_value_factory_; // Not owned. |
| 911 ParserRecorder* log_; | 912 ParserRecorder* log_; |
| 912 Mode mode_; | 913 Mode mode_; |
| 914 bool parsing_module_; |
| 913 uintptr_t stack_limit_; | 915 uintptr_t stack_limit_; |
| 914 | 916 |
| 915 private: | 917 private: |
| 916 Zone* zone_; | 918 Zone* zone_; |
| 917 | 919 |
| 918 Scanner* scanner_; | 920 Scanner* scanner_; |
| 919 bool stack_overflow_; | 921 bool stack_overflow_; |
| 920 | 922 |
| 921 bool allow_lazy_; | 923 bool allow_lazy_; |
| 922 bool allow_natives_; | 924 bool allow_natives_; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 case Token::SMI: | 978 case Token::SMI: |
| 977 case Token::NUMBER: | 979 case Token::NUMBER: |
| 978 *message = MessageTemplate::kUnexpectedTokenNumber; | 980 *message = MessageTemplate::kUnexpectedTokenNumber; |
| 979 break; | 981 break; |
| 980 case Token::STRING: | 982 case Token::STRING: |
| 981 *message = MessageTemplate::kUnexpectedTokenString; | 983 *message = MessageTemplate::kUnexpectedTokenString; |
| 982 break; | 984 break; |
| 983 case Token::IDENTIFIER: | 985 case Token::IDENTIFIER: |
| 984 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 986 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
| 985 break; | 987 break; |
| 986 case Token::FUTURE_RESERVED_WORD: | 988 case Token::AWAIT: |
| 989 case Token::ENUM: |
| 987 *message = MessageTemplate::kUnexpectedReserved; | 990 *message = MessageTemplate::kUnexpectedReserved; |
| 988 break; | 991 break; |
| 989 case Token::LET: | 992 case Token::LET: |
| 990 case Token::STATIC: | 993 case Token::STATIC: |
| 991 case Token::YIELD: | 994 case Token::YIELD: |
| 992 case Token::FUTURE_STRICT_RESERVED_WORD: | 995 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 993 *message = is_strict(language_mode()) | 996 *message = is_strict(language_mode()) |
| 994 ? MessageTemplate::kUnexpectedStrictReserved | 997 ? MessageTemplate::kUnexpectedStrictReserved |
| 995 : MessageTemplate::kUnexpectedTokenIdentifier; | 998 : MessageTemplate::kUnexpectedTokenIdentifier; |
| 996 break; | 999 break; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 | 1054 |
| 1052 return result; | 1055 return result; |
| 1053 } | 1056 } |
| 1054 | 1057 |
| 1055 | 1058 |
| 1056 template <class Traits> | 1059 template <class Traits> |
| 1057 typename ParserBase<Traits>::IdentifierT | 1060 typename ParserBase<Traits>::IdentifierT |
| 1058 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1061 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
| 1059 bool* ok) { | 1062 bool* ok) { |
| 1060 Token::Value next = Next(); | 1063 Token::Value next = Next(); |
| 1061 if (next == Token::IDENTIFIER) { | 1064 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
| 1062 IdentifierT name = this->GetSymbol(scanner()); | 1065 IdentifierT name = this->GetSymbol(scanner()); |
| 1063 // 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 |
| 1064 // 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 |
| 1065 // 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 |
| 1066 // is actually a formal parameter. Therefore besides the errors that we | 1069 // is actually a formal parameter. Therefore besides the errors that we |
| 1067 // 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 |
| 1068 // 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. |
| 1069 if (this->IsEval(name)) { | 1072 if (this->IsEval(name)) { |
| 1070 classifier->RecordStrictModeFormalParameterError( | 1073 classifier->RecordStrictModeFormalParameterError( |
| 1071 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1074 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 return Traits::EmptyIdentifier(); | 1118 return Traits::EmptyIdentifier(); |
| 1116 } | 1119 } |
| 1117 } | 1120 } |
| 1118 | 1121 |
| 1119 | 1122 |
| 1120 template <class Traits> | 1123 template <class Traits> |
| 1121 typename ParserBase<Traits>::IdentifierT | 1124 typename ParserBase<Traits>::IdentifierT |
| 1122 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1125 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
| 1123 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1126 bool is_generator, bool* is_strict_reserved, bool* ok) { |
| 1124 Token::Value next = Next(); | 1127 Token::Value next = Next(); |
| 1125 if (next == Token::IDENTIFIER) { | 1128 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
| 1126 *is_strict_reserved = false; | 1129 *is_strict_reserved = false; |
| 1127 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1130 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 1128 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1131 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
| 1129 *is_strict_reserved = true; | 1132 *is_strict_reserved = true; |
| 1130 } else { | 1133 } else { |
| 1131 ReportUnexpectedToken(next); | 1134 ReportUnexpectedToken(next); |
| 1132 *ok = false; | 1135 *ok = false; |
| 1133 return Traits::EmptyIdentifier(); | 1136 return Traits::EmptyIdentifier(); |
| 1134 } | 1137 } |
| 1135 | 1138 |
| 1136 IdentifierT name = this->GetSymbol(scanner()); | 1139 IdentifierT name = this->GetSymbol(scanner()); |
| 1137 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1140 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1138 return name; | 1141 return name; |
| 1139 } | 1142 } |
| 1140 | 1143 |
| 1141 | |
| 1142 template <class Traits> | 1144 template <class Traits> |
| 1143 typename ParserBase<Traits>::IdentifierT | 1145 typename ParserBase<Traits>::IdentifierT |
| 1144 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1146 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
| 1145 Token::Value next = Next(); | 1147 Token::Value next = Next(); |
| 1146 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1148 if (next != Token::IDENTIFIER && next != Token::ENUM && |
| 1147 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1149 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
| 1148 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1150 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
| 1149 next != Token::ESCAPED_KEYWORD && | 1151 next != Token::ESCAPED_KEYWORD && |
| 1150 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1152 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
| 1151 this->ReportUnexpectedToken(next); | 1153 this->ReportUnexpectedToken(next); |
| 1152 *ok = false; | 1154 *ok = false; |
| 1153 return Traits::EmptyIdentifier(); | 1155 return Traits::EmptyIdentifier(); |
| 1154 } | 1156 } |
| 1155 | 1157 |
| 1156 IdentifierT name = this->GetSymbol(scanner()); | 1158 IdentifierT name = this->GetSymbol(scanner()); |
| 1157 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1159 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
| 1158 return name; | 1160 return name; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1237 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1236 case Token::SMI: | 1238 case Token::SMI: |
| 1237 case Token::NUMBER: | 1239 case Token::NUMBER: |
| 1238 BindingPatternUnexpectedToken(classifier); | 1240 BindingPatternUnexpectedToken(classifier); |
| 1239 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1241 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
| 1240 | 1242 |
| 1241 case Token::IDENTIFIER: | 1243 case Token::IDENTIFIER: |
| 1242 case Token::LET: | 1244 case Token::LET: |
| 1243 case Token::STATIC: | 1245 case Token::STATIC: |
| 1244 case Token::YIELD: | 1246 case Token::YIELD: |
| 1247 case Token::AWAIT: |
| 1245 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1248 case Token::ESCAPED_STRICT_RESERVED_WORD: |
| 1246 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1249 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1247 // 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. |
| 1248 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1251 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
| 1249 return this->ExpressionFromIdentifier( | 1252 return this->ExpressionFromIdentifier( |
| 1250 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1253 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
| 1251 } | 1254 } |
| 1252 | 1255 |
| 1253 case Token::STRING: { | 1256 case Token::STRING: { |
| 1254 BindingPatternUnexpectedToken(classifier); | 1257 BindingPatternUnexpectedToken(classifier); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 int beg_pos = peek_position(); | 1605 int beg_pos = peek_position(); |
| 1603 value = this->ParseAssignmentExpression( | 1606 value = this->ParseAssignmentExpression( |
| 1604 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1607 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1605 CheckDestructuringElement(value, classifier, beg_pos, | 1608 CheckDestructuringElement(value, classifier, beg_pos, |
| 1606 scanner()->location().end_pos); | 1609 scanner()->location().end_pos); |
| 1607 | 1610 |
| 1608 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1611 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
| 1609 *is_computed_name); | 1612 *is_computed_name); |
| 1610 } | 1613 } |
| 1611 | 1614 |
| 1612 if (Token::IsIdentifier(name_token, language_mode(), | 1615 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
| 1613 this->is_generator()) && | 1616 parsing_module_) && |
| 1614 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1617 (peek() == Token::COMMA || peek() == Token::RBRACE || |
| 1615 peek() == Token::ASSIGN)) { | 1618 peek() == Token::ASSIGN)) { |
| 1616 // PropertyDefinition | 1619 // PropertyDefinition |
| 1617 // IdentifierReference | 1620 // IdentifierReference |
| 1618 // CoverInitializedName | 1621 // CoverInitializedName |
| 1619 // | 1622 // |
| 1620 // CoverInitializedName | 1623 // CoverInitializedName |
| 1621 // IdentifierReference Initializer? | 1624 // IdentifierReference Initializer? |
| 1622 if (classifier->duplicate_finder() != nullptr && | 1625 if (classifier->duplicate_finder() != nullptr && |
| 1623 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1626 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| (...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2783 bool ParserBase<Traits>::IsNextLetKeyword() { | 2786 bool ParserBase<Traits>::IsNextLetKeyword() { |
| 2784 DCHECK(peek() == Token::LET); | 2787 DCHECK(peek() == Token::LET); |
| 2785 Token::Value next_next = PeekAhead(); | 2788 Token::Value next_next = PeekAhead(); |
| 2786 switch (next_next) { | 2789 switch (next_next) { |
| 2787 case Token::LBRACE: | 2790 case Token::LBRACE: |
| 2788 case Token::LBRACK: | 2791 case Token::LBRACK: |
| 2789 case Token::IDENTIFIER: | 2792 case Token::IDENTIFIER: |
| 2790 case Token::STATIC: | 2793 case Token::STATIC: |
| 2791 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 2794 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
| 2792 case Token::YIELD: | 2795 case Token::YIELD: |
| 2796 case Token::AWAIT: |
| 2793 return true; | 2797 return true; |
| 2794 default: | 2798 default: |
| 2795 return false; | 2799 return false; |
| 2796 } | 2800 } |
| 2797 } | 2801 } |
| 2798 | 2802 |
| 2799 | 2803 |
| 2800 template <class Traits> | 2804 template <class Traits> |
| 2801 typename ParserBase<Traits>::ExpressionT | 2805 typename ParserBase<Traits>::ExpressionT |
| 2802 ParserBase<Traits>::ParseArrowFunctionLiteral( | 2806 ParserBase<Traits>::ParseArrowFunctionLiteral( |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3112 has_seen_constructor_ = true; | 3116 has_seen_constructor_ = true; |
| 3113 return; | 3117 return; |
| 3114 } | 3118 } |
| 3115 } | 3119 } |
| 3116 | 3120 |
| 3117 | 3121 |
| 3118 } // namespace internal | 3122 } // namespace internal |
| 3119 } // namespace v8 | 3123 } // namespace v8 |
| 3120 | 3124 |
| 3121 #endif // V8_PARSING_PARSER_BASE_H | 3125 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |