Chromium Code Reviews| 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 |