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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 442 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
443 tok == Token::RBRACE || | 443 tok == Token::RBRACE || |
444 tok == Token::EOS) { | 444 tok == Token::EOS) { |
445 return; | 445 return; |
446 } | 446 } |
447 Expect(Token::SEMICOLON, ok); | 447 Expect(Token::SEMICOLON, ok); |
448 } | 448 } |
449 | 449 |
450 bool peek_any_identifier() { | 450 bool peek_any_identifier() { |
451 Token::Value next = peek(); | 451 Token::Value next = peek(); |
452 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 452 return next == Token::IDENTIFIER || next == Token::AWAIT || |
453 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 453 next == Token::ENUM || next == Token::FUTURE_STRICT_RESERVED_WORD || |
454 next == Token::STATIC || next == Token::YIELD; | 454 next == Token::LET || next == Token::STATIC || next == Token::YIELD; |
455 } | 455 } |
456 | 456 |
457 bool CheckContextualKeyword(Vector<const char> keyword) { | 457 bool CheckContextualKeyword(Vector<const char> keyword) { |
458 if (PeekContextualKeyword(keyword)) { | 458 if (PeekContextualKeyword(keyword)) { |
459 Consume(Token::IDENTIFIER); | 459 Consume(Token::IDENTIFIER); |
460 return true; | 460 return true; |
461 } | 461 } |
462 return false; | 462 return false; |
463 } | 463 } |
464 | 464 |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
928 // so never lazily compile it. | 928 // so never lazily compile it. |
929 bool parenthesized_function_; | 929 bool parenthesized_function_; |
930 | 930 |
931 Scope* scope_; // Scope stack. | 931 Scope* scope_; // Scope stack. |
932 FunctionState* function_state_; // Function state stack. | 932 FunctionState* function_state_; // Function state stack. |
933 v8::Extension* extension_; | 933 v8::Extension* extension_; |
934 FuncNameInferrer* fni_; | 934 FuncNameInferrer* fni_; |
935 AstValueFactory* ast_value_factory_; // Not owned. | 935 AstValueFactory* ast_value_factory_; // Not owned. |
936 ParserRecorder* log_; | 936 ParserRecorder* log_; |
937 Mode mode_; | 937 Mode mode_; |
938 bool parsing_module_; | |
adamk
2016/02/24 19:13:25
Please initialize this to false in the constructor
| |
938 uintptr_t stack_limit_; | 939 uintptr_t stack_limit_; |
939 | 940 |
940 private: | 941 private: |
941 Zone* zone_; | 942 Zone* zone_; |
942 | 943 |
943 Scanner* scanner_; | 944 Scanner* scanner_; |
944 bool stack_overflow_; | 945 bool stack_overflow_; |
945 | 946 |
946 bool allow_lazy_; | 947 bool allow_lazy_; |
947 bool allow_natives_; | 948 bool allow_natives_; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1003 *arg = nullptr; | 1004 *arg = nullptr; |
1004 break; | 1005 break; |
1005 case Token::STRING: | 1006 case Token::STRING: |
1006 *message = MessageTemplate::kUnexpectedTokenString; | 1007 *message = MessageTemplate::kUnexpectedTokenString; |
1007 *arg = nullptr; | 1008 *arg = nullptr; |
1008 break; | 1009 break; |
1009 case Token::IDENTIFIER: | 1010 case Token::IDENTIFIER: |
1010 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 1011 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
1011 *arg = nullptr; | 1012 *arg = nullptr; |
1012 break; | 1013 break; |
1013 case Token::FUTURE_RESERVED_WORD: | 1014 case Token::AWAIT: |
1015 case Token::ENUM: | |
1014 *message = MessageTemplate::kUnexpectedReserved; | 1016 *message = MessageTemplate::kUnexpectedReserved; |
1015 *arg = nullptr; | 1017 *arg = nullptr; |
1016 break; | 1018 break; |
1017 case Token::LET: | 1019 case Token::LET: |
1018 case Token::STATIC: | 1020 case Token::STATIC: |
1019 case Token::YIELD: | 1021 case Token::YIELD: |
1020 case Token::FUTURE_STRICT_RESERVED_WORD: | 1022 case Token::FUTURE_STRICT_RESERVED_WORD: |
1021 *message = is_strict(language_mode()) | 1023 *message = is_strict(language_mode()) |
1022 ? MessageTemplate::kUnexpectedStrictReserved | 1024 ? MessageTemplate::kUnexpectedStrictReserved |
1023 : MessageTemplate::kUnexpectedTokenIdentifier; | 1025 : MessageTemplate::kUnexpectedTokenIdentifier; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1074 | 1076 |
1075 return result; | 1077 return result; |
1076 } | 1078 } |
1077 | 1079 |
1078 | 1080 |
1079 template <class Traits> | 1081 template <class Traits> |
1080 typename ParserBase<Traits>::IdentifierT | 1082 typename ParserBase<Traits>::IdentifierT |
1081 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, | 1083 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier, |
1082 bool* ok) { | 1084 bool* ok) { |
1083 Token::Value next = Next(); | 1085 Token::Value next = Next(); |
1084 if (next == Token::IDENTIFIER) { | 1086 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1085 IdentifierT name = this->GetSymbol(scanner()); | 1087 IdentifierT name = this->GetSymbol(scanner()); |
1086 // When this function is used to read a formal parameter, we don't always | 1088 // When this function is used to read a formal parameter, we don't always |
1087 // know whether the function is going to be strict or sloppy. Indeed for | 1089 // know whether the function is going to be strict or sloppy. Indeed for |
1088 // arrow functions we don't always know that the identifier we are reading | 1090 // arrow functions we don't always know that the identifier we are reading |
1089 // is actually a formal parameter. Therefore besides the errors that we | 1091 // is actually a formal parameter. Therefore besides the errors that we |
1090 // must detect because we know we're in strict mode, we also record any | 1092 // must detect because we know we're in strict mode, we also record any |
1091 // error that we might make in the future once we know the language mode. | 1093 // error that we might make in the future once we know the language mode. |
1092 if (this->IsEval(name)) { | 1094 if (this->IsEval(name)) { |
1093 classifier->RecordStrictModeFormalParameterError( | 1095 classifier->RecordStrictModeFormalParameterError( |
1094 scanner()->location(), MessageTemplate::kStrictEvalArguments); | 1096 scanner()->location(), MessageTemplate::kStrictEvalArguments); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1151 return Traits::EmptyIdentifier(); | 1153 return Traits::EmptyIdentifier(); |
1152 } | 1154 } |
1153 } | 1155 } |
1154 | 1156 |
1155 | 1157 |
1156 template <class Traits> | 1158 template <class Traits> |
1157 typename ParserBase<Traits>::IdentifierT | 1159 typename ParserBase<Traits>::IdentifierT |
1158 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( | 1160 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord( |
1159 bool is_generator, bool* is_strict_reserved, bool* ok) { | 1161 bool is_generator, bool* is_strict_reserved, bool* ok) { |
1160 Token::Value next = Next(); | 1162 Token::Value next = Next(); |
1161 if (next == Token::IDENTIFIER) { | 1163 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_)) { |
1162 *is_strict_reserved = false; | 1164 *is_strict_reserved = false; |
1163 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 1165 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
1164 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { | 1166 next == Token::STATIC || (next == Token::YIELD && !is_generator)) { |
1165 *is_strict_reserved = true; | 1167 *is_strict_reserved = true; |
1166 } else { | 1168 } else { |
1167 ReportUnexpectedToken(next); | 1169 ReportUnexpectedToken(next); |
1168 *ok = false; | 1170 *ok = false; |
1169 return Traits::EmptyIdentifier(); | 1171 return Traits::EmptyIdentifier(); |
1170 } | 1172 } |
1171 | 1173 |
1172 IdentifierT name = this->GetSymbol(scanner()); | 1174 IdentifierT name = this->GetSymbol(scanner()); |
1173 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1175 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1174 return name; | 1176 return name; |
1175 } | 1177 } |
1176 | 1178 |
1177 | |
1178 template <class Traits> | 1179 template <class Traits> |
1179 typename ParserBase<Traits>::IdentifierT | 1180 typename ParserBase<Traits>::IdentifierT |
1180 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 1181 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
1181 Token::Value next = Next(); | 1182 Token::Value next = Next(); |
1182 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 1183 if (next != Token::IDENTIFIER && next != Token::ENUM && |
1183 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 1184 next != Token::AWAIT && next != Token::LET && next != Token::STATIC && |
1184 next != Token::FUTURE_STRICT_RESERVED_WORD && | 1185 next != Token::YIELD && next != Token::FUTURE_STRICT_RESERVED_WORD && |
1185 next != Token::ESCAPED_KEYWORD && | 1186 next != Token::ESCAPED_KEYWORD && |
1186 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 1187 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { |
1187 this->ReportUnexpectedToken(next); | 1188 this->ReportUnexpectedToken(next); |
1188 *ok = false; | 1189 *ok = false; |
1189 return Traits::EmptyIdentifier(); | 1190 return Traits::EmptyIdentifier(); |
1190 } | 1191 } |
1191 | 1192 |
1192 IdentifierT name = this->GetSymbol(scanner()); | 1193 IdentifierT name = this->GetSymbol(scanner()); |
1193 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 1194 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
1194 return name; | 1195 return name; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1281 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1282 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1282 case Token::SMI: | 1283 case Token::SMI: |
1283 case Token::NUMBER: | 1284 case Token::NUMBER: |
1284 BindingPatternUnexpectedToken(classifier); | 1285 BindingPatternUnexpectedToken(classifier); |
1285 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1286 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1286 | 1287 |
1287 case Token::IDENTIFIER: | 1288 case Token::IDENTIFIER: |
1288 case Token::LET: | 1289 case Token::LET: |
1289 case Token::STATIC: | 1290 case Token::STATIC: |
1290 case Token::YIELD: | 1291 case Token::YIELD: |
1292 case Token::AWAIT: | |
1291 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1293 case Token::ESCAPED_STRICT_RESERVED_WORD: |
1292 case Token::FUTURE_STRICT_RESERVED_WORD: { | 1294 case Token::FUTURE_STRICT_RESERVED_WORD: { |
1293 // Using eval or arguments in this context is OK even in strict mode. | 1295 // Using eval or arguments in this context is OK even in strict mode. |
1294 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 1296 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
1295 return this->ExpressionFromIdentifier( | 1297 return this->ExpressionFromIdentifier( |
1296 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 1298 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
1297 } | 1299 } |
1298 | 1300 |
1299 case Token::STRING: { | 1301 case Token::STRING: { |
1300 BindingPatternUnexpectedToken(classifier); | 1302 BindingPatternUnexpectedToken(classifier); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1665 int beg_pos = peek_position(); | 1667 int beg_pos = peek_position(); |
1666 value = this->ParseAssignmentExpression( | 1668 value = this->ParseAssignmentExpression( |
1667 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1669 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1668 CheckDestructuringElement(value, classifier, beg_pos, | 1670 CheckDestructuringElement(value, classifier, beg_pos, |
1669 scanner()->location().end_pos); | 1671 scanner()->location().end_pos); |
1670 | 1672 |
1671 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1673 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
1672 *is_computed_name); | 1674 *is_computed_name); |
1673 } | 1675 } |
1674 | 1676 |
1675 if (Token::IsIdentifier(name_token, language_mode(), | 1677 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(), |
1676 this->is_generator()) && | 1678 parsing_module_) && |
1677 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1679 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1678 peek() == Token::ASSIGN)) { | 1680 peek() == Token::ASSIGN)) { |
1679 // PropertyDefinition | 1681 // PropertyDefinition |
1680 // IdentifierReference | 1682 // IdentifierReference |
1681 // CoverInitializedName | 1683 // CoverInitializedName |
1682 // | 1684 // |
1683 // CoverInitializedName | 1685 // CoverInitializedName |
1684 // IdentifierReference Initializer? | 1686 // IdentifierReference Initializer? |
1685 if (classifier->duplicate_finder() != nullptr && | 1687 if (classifier->duplicate_finder() != nullptr && |
1686 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1688 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3018 return false; | 3020 return false; |
3019 } | 3021 } |
3020 Token::Value next_next = PeekAhead(); | 3022 Token::Value next_next = PeekAhead(); |
3021 switch (next_next) { | 3023 switch (next_next) { |
3022 case Token::LBRACE: | 3024 case Token::LBRACE: |
3023 case Token::LBRACK: | 3025 case Token::LBRACK: |
3024 case Token::IDENTIFIER: | 3026 case Token::IDENTIFIER: |
3025 case Token::STATIC: | 3027 case Token::STATIC: |
3026 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 3028 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
3027 case Token::YIELD: | 3029 case Token::YIELD: |
3030 case Token::AWAIT: | |
3028 return true; | 3031 return true; |
3029 default: | 3032 default: |
3030 return false; | 3033 return false; |
3031 } | 3034 } |
3032 } | 3035 } |
3033 | 3036 |
3034 | 3037 |
3035 template <class Traits> | 3038 template <class Traits> |
3036 typename ParserBase<Traits>::ExpressionT | 3039 typename ParserBase<Traits>::ExpressionT |
3037 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3040 ParserBase<Traits>::ParseArrowFunctionLiteral( |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3372 has_seen_constructor_ = true; | 3375 has_seen_constructor_ = true; |
3373 return; | 3376 return; |
3374 } | 3377 } |
3375 } | 3378 } |
3376 | 3379 |
3377 | 3380 |
3378 } // namespace internal | 3381 } // namespace internal |
3379 } // namespace v8 | 3382 } // namespace v8 |
3380 | 3383 |
3381 #endif // V8_PARSING_PARSER_BASE_H | 3384 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |