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/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels, | 1191 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels, |
1192 bool legacy, bool* ok); | 1192 bool legacy, bool* ok); |
1193 | 1193 |
1194 StatementT ParseVariableStatement(VariableDeclarationContext var_context, | 1194 StatementT ParseVariableStatement(VariableDeclarationContext var_context, |
1195 ZoneList<const AstRawString*>* names, | 1195 ZoneList<const AstRawString*>* names, |
1196 bool* ok); | 1196 bool* ok); |
1197 | 1197 |
1198 // Magical syntax support. | 1198 // Magical syntax support. |
1199 ExpressionT ParseV8Intrinsic(bool* ok); | 1199 ExpressionT ParseV8Intrinsic(bool* ok); |
1200 | 1200 |
| 1201 ExpressionT ParseDoExpression(bool* ok); |
| 1202 |
1201 StatementT ParseDebuggerStatement(bool* ok); | 1203 StatementT ParseDebuggerStatement(bool* ok); |
1202 | 1204 |
1203 StatementT ParseExpressionOrLabelledStatement( | 1205 StatementT ParseExpressionOrLabelledStatement( |
1204 ZoneList<const AstRawString*>* labels, | 1206 ZoneList<const AstRawString*>* labels, |
1205 AllowLabelledFunctionStatement allow_function, bool* ok); | 1207 AllowLabelledFunctionStatement allow_function, bool* ok); |
1206 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok); | 1208 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok); |
1207 StatementT ParseContinueStatement(bool* ok); | 1209 StatementT ParseContinueStatement(bool* ok); |
1208 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, | 1210 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
1209 bool* ok); | 1211 bool* ok); |
1210 StatementT ParseReturnStatement(bool* ok); | 1212 StatementT ParseReturnStatement(bool* ok); |
1211 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, | 1213 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, |
1212 bool* ok); | 1214 bool* ok); |
| 1215 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1216 bool* ok); |
| 1217 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1218 bool* ok); |
| 1219 StatementT ParseThrowStatement(bool* ok); |
1213 | 1220 |
1214 bool IsNextLetKeyword(); | 1221 bool IsNextLetKeyword(); |
1215 bool IsTrivialExpression(); | 1222 bool IsTrivialExpression(); |
1216 | 1223 |
1217 // Checks if the expression is a valid reference expression (e.g., on the | 1224 // Checks if the expression is a valid reference expression (e.g., on the |
1218 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1225 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1219 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1226 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1220 ExpressionT CheckAndRewriteReferenceExpression( | 1227 ExpressionT CheckAndRewriteReferenceExpression( |
1221 ExpressionT expression, int beg_pos, int end_pos, | 1228 ExpressionT expression, int beg_pos, int end_pos, |
1222 MessageTemplate::Template message, bool* ok); | 1229 MessageTemplate::Template message, bool* ok); |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1752 case Token::MOD: | 1759 case Token::MOD: |
1753 if (allow_natives() || extension_ != NULL) { | 1760 if (allow_natives() || extension_ != NULL) { |
1754 BindingPatternUnexpectedToken(); | 1761 BindingPatternUnexpectedToken(); |
1755 return ParseV8Intrinsic(ok); | 1762 return ParseV8Intrinsic(ok); |
1756 } | 1763 } |
1757 break; | 1764 break; |
1758 | 1765 |
1759 case Token::DO: | 1766 case Token::DO: |
1760 if (allow_harmony_do_expressions()) { | 1767 if (allow_harmony_do_expressions()) { |
1761 BindingPatternUnexpectedToken(); | 1768 BindingPatternUnexpectedToken(); |
1762 return impl()->ParseDoExpression(ok); | 1769 return ParseDoExpression(ok); |
1763 } | 1770 } |
1764 break; | 1771 break; |
1765 | 1772 |
1766 default: | 1773 default: |
1767 break; | 1774 break; |
1768 } | 1775 } |
1769 | 1776 |
1770 ReportUnexpectedToken(Next()); | 1777 ReportUnexpectedToken(Next()); |
1771 *ok = false; | 1778 *ok = false; |
1772 return impl()->EmptyExpression(); | 1779 return impl()->EmptyExpression(); |
(...skipping 2273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4046 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 4053 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
4047 Scanner::Location spread_pos; | 4054 Scanner::Location spread_pos; |
4048 ExpressionClassifier classifier(this); | 4055 ExpressionClassifier classifier(this); |
4049 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); | 4056 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); |
4050 | 4057 |
4051 DCHECK(!spread_pos.IsValid()); | 4058 DCHECK(!spread_pos.IsValid()); |
4052 | 4059 |
4053 return impl()->NewV8Intrinsic(name, args, pos, ok); | 4060 return impl()->NewV8Intrinsic(name, args, pos, ok); |
4054 } | 4061 } |
4055 | 4062 |
| 4063 template <typename Impl> |
| 4064 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression( |
| 4065 bool* ok) { |
| 4066 // AssignmentExpression :: |
| 4067 // do '{' StatementList '}' |
| 4068 |
| 4069 int pos = peek_position(); |
| 4070 Expect(Token::DO, CHECK_OK); |
| 4071 BlockT block = ParseBlock(nullptr, CHECK_OK); |
| 4072 return impl()->RewriteDoExpression(block, pos, ok); |
| 4073 } |
| 4074 |
4056 // Redefinition of CHECK_OK for parsing statements. | 4075 // Redefinition of CHECK_OK for parsing statements. |
4057 #undef CHECK_OK | 4076 #undef CHECK_OK |
4058 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) | 4077 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) |
4059 | 4078 |
4060 template <typename Impl> | 4079 template <typename Impl> |
4061 typename ParserBase<Impl>::LazyParsingResult | 4080 typename ParserBase<Impl>::LazyParsingResult |
4062 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, | 4081 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, |
4063 bool may_abort, bool* ok) { | 4082 bool may_abort, bool* ok) { |
4064 // StatementList :: | 4083 // StatementList :: |
4065 // (StatementListItem)* <end_token> | 4084 // (StatementListItem)* <end_token> |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4228 // parsed into an empty statement. | 4247 // parsed into an empty statement. |
4229 switch (peek()) { | 4248 switch (peek()) { |
4230 case Token::LBRACE: | 4249 case Token::LBRACE: |
4231 return impl()->ParseBlock(labels, ok); | 4250 return impl()->ParseBlock(labels, ok); |
4232 case Token::SEMICOLON: | 4251 case Token::SEMICOLON: |
4233 Next(); | 4252 Next(); |
4234 return factory()->NewEmptyStatement(kNoSourcePosition); | 4253 return factory()->NewEmptyStatement(kNoSourcePosition); |
4235 case Token::IF: | 4254 case Token::IF: |
4236 return ParseIfStatement(labels, ok); | 4255 return ParseIfStatement(labels, ok); |
4237 case Token::DO: | 4256 case Token::DO: |
4238 return impl()->ParseDoWhileStatement(labels, ok); | 4257 return ParseDoWhileStatement(labels, ok); |
4239 case Token::WHILE: | 4258 case Token::WHILE: |
4240 return impl()->ParseWhileStatement(labels, ok); | 4259 return ParseWhileStatement(labels, ok); |
4241 case Token::FOR: | 4260 case Token::FOR: |
4242 return impl()->ParseForStatement(labels, ok); | 4261 return impl()->ParseForStatement(labels, ok); |
4243 case Token::CONTINUE: | 4262 case Token::CONTINUE: |
4244 case Token::BREAK: | 4263 case Token::BREAK: |
4245 case Token::RETURN: | 4264 case Token::RETURN: |
4246 case Token::THROW: | 4265 case Token::THROW: |
4247 case Token::TRY: { | 4266 case Token::TRY: { |
4248 // These statements must have their labels preserved in an enclosing | 4267 // These statements must have their labels preserved in an enclosing |
4249 // block, as the corresponding AST nodes do not currently store their | 4268 // block, as the corresponding AST nodes do not currently store their |
4250 // labels. | 4269 // labels. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4293 ParserBase<Impl>::ParseStatementAsUnlabelled( | 4312 ParserBase<Impl>::ParseStatementAsUnlabelled( |
4294 ZoneList<const AstRawString*>* labels, bool* ok) { | 4313 ZoneList<const AstRawString*>* labels, bool* ok) { |
4295 switch (peek()) { | 4314 switch (peek()) { |
4296 case Token::CONTINUE: | 4315 case Token::CONTINUE: |
4297 return ParseContinueStatement(ok); | 4316 return ParseContinueStatement(ok); |
4298 case Token::BREAK: | 4317 case Token::BREAK: |
4299 return ParseBreakStatement(labels, ok); | 4318 return ParseBreakStatement(labels, ok); |
4300 case Token::RETURN: | 4319 case Token::RETURN: |
4301 return ParseReturnStatement(ok); | 4320 return ParseReturnStatement(ok); |
4302 case Token::THROW: | 4321 case Token::THROW: |
4303 return impl()->ParseThrowStatement(ok); | 4322 return ParseThrowStatement(ok); |
4304 case Token::TRY: | 4323 case Token::TRY: |
4305 return impl()->ParseTryStatement(ok); | 4324 return impl()->ParseTryStatement(ok); |
4306 default: | 4325 default: |
4307 UNREACHABLE(); | 4326 UNREACHABLE(); |
4308 return impl()->NullStatement(); | 4327 return impl()->NullStatement(); |
4309 } | 4328 } |
4310 } | 4329 } |
4311 | 4330 |
4312 template <typename Impl> | 4331 template <typename Impl> |
4313 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( | 4332 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4627 StatementT body = impl()->NullStatement(); | 4646 StatementT body = impl()->NullStatement(); |
4628 { | 4647 { |
4629 BlockState block_state(&scope_state_, with_scope); | 4648 BlockState block_state(&scope_state_, with_scope); |
4630 with_scope->set_start_position(scanner()->peek_location().beg_pos); | 4649 with_scope->set_start_position(scanner()->peek_location().beg_pos); |
4631 body = ParseScopedStatement(labels, true, CHECK_OK); | 4650 body = ParseScopedStatement(labels, true, CHECK_OK); |
4632 with_scope->set_end_position(scanner()->location().end_pos); | 4651 with_scope->set_end_position(scanner()->location().end_pos); |
4633 } | 4652 } |
4634 return factory()->NewWithStatement(with_scope, expr, body, pos); | 4653 return factory()->NewWithStatement(with_scope, expr, body, pos); |
4635 } | 4654 } |
4636 | 4655 |
| 4656 template <typename Impl> |
| 4657 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement( |
| 4658 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4659 // DoStatement :: |
| 4660 // 'do' Statement 'while' '(' Expression ')' ';' |
| 4661 |
| 4662 auto loop = factory()->NewDoWhileStatement(labels, peek_position()); |
| 4663 typename Types::Target target(this, loop); |
| 4664 |
| 4665 Expect(Token::DO, CHECK_OK); |
| 4666 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 4667 Expect(Token::WHILE, CHECK_OK); |
| 4668 Expect(Token::LPAREN, CHECK_OK); |
| 4669 |
| 4670 ExpressionT cond = ParseExpression(true, CHECK_OK); |
| 4671 Expect(Token::RPAREN, CHECK_OK); |
| 4672 |
| 4673 // Allow do-statements to be terminated with and without |
| 4674 // semi-colons. This allows code such as 'do;while(0)return' to |
| 4675 // parse, which would not be the case if we had used the |
| 4676 // ExpectSemicolon() functionality here. |
| 4677 Check(Token::SEMICOLON); |
| 4678 |
| 4679 loop->Initialize(cond, body); |
| 4680 return loop; |
| 4681 } |
| 4682 |
| 4683 template <typename Impl> |
| 4684 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement( |
| 4685 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4686 // WhileStatement :: |
| 4687 // 'while' '(' Expression ')' Statement |
| 4688 |
| 4689 auto loop = factory()->NewWhileStatement(labels, peek_position()); |
| 4690 typename Types::Target target(this, loop); |
| 4691 |
| 4692 Expect(Token::WHILE, CHECK_OK); |
| 4693 Expect(Token::LPAREN, CHECK_OK); |
| 4694 ExpressionT cond = ParseExpression(true, CHECK_OK); |
| 4695 Expect(Token::RPAREN, CHECK_OK); |
| 4696 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 4697 |
| 4698 loop->Initialize(cond, body); |
| 4699 return loop; |
| 4700 } |
| 4701 |
| 4702 template <typename Impl> |
| 4703 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement( |
| 4704 bool* ok) { |
| 4705 // ThrowStatement :: |
| 4706 // 'throw' Expression ';' |
| 4707 |
| 4708 Expect(Token::THROW, CHECK_OK); |
| 4709 int pos = position(); |
| 4710 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 4711 ReportMessage(MessageTemplate::kNewlineAfterThrow); |
| 4712 *ok = false; |
| 4713 return impl()->NullStatement(); |
| 4714 } |
| 4715 ExpressionT exception = ParseExpression(true, CHECK_OK); |
| 4716 ExpectSemicolon(CHECK_OK); |
| 4717 |
| 4718 return impl()->NewThrowStatement(exception, pos); |
| 4719 } |
| 4720 |
4637 #undef CHECK_OK | 4721 #undef CHECK_OK |
4638 #undef CHECK_OK_CUSTOM | 4722 #undef CHECK_OK_CUSTOM |
4639 | 4723 |
4640 template <typename Impl> | 4724 template <typename Impl> |
4641 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 4725 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4642 Token::Value property) { | 4726 Token::Value property) { |
4643 if (property == Token::SMI || property == Token::NUMBER) return; | 4727 if (property == Token::SMI || property == Token::NUMBER) return; |
4644 | 4728 |
4645 if (IsProto()) { | 4729 if (IsProto()) { |
4646 if (has_seen_proto_) { | 4730 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4685 has_seen_constructor_ = true; | 4769 has_seen_constructor_ = true; |
4686 return; | 4770 return; |
4687 } | 4771 } |
4688 } | 4772 } |
4689 | 4773 |
4690 | 4774 |
4691 } // namespace internal | 4775 } // namespace internal |
4692 } // namespace v8 | 4776 } // namespace v8 |
4693 | 4777 |
4694 #endif // V8_PARSING_PARSER_BASE_H | 4778 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |