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