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 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels, | 1186 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels, |
1187 bool legacy, bool* ok); | 1187 bool legacy, bool* ok); |
1188 | 1188 |
1189 StatementT ParseVariableStatement(VariableDeclarationContext var_context, | 1189 StatementT ParseVariableStatement(VariableDeclarationContext var_context, |
1190 ZoneList<const AstRawString*>* names, | 1190 ZoneList<const AstRawString*>* names, |
1191 bool* ok); | 1191 bool* ok); |
1192 | 1192 |
1193 // Magical syntax support. | 1193 // Magical syntax support. |
1194 ExpressionT ParseV8Intrinsic(bool* ok); | 1194 ExpressionT ParseV8Intrinsic(bool* ok); |
1195 | 1195 |
| 1196 ExpressionT ParseDoExpression(bool* ok); |
| 1197 |
1196 StatementT ParseDebuggerStatement(bool* ok); | 1198 StatementT ParseDebuggerStatement(bool* ok); |
1197 | 1199 |
1198 StatementT ParseExpressionOrLabelledStatement( | 1200 StatementT ParseExpressionOrLabelledStatement( |
1199 ZoneList<const AstRawString*>* labels, | 1201 ZoneList<const AstRawString*>* labels, |
1200 AllowLabelledFunctionStatement allow_function, bool* ok); | 1202 AllowLabelledFunctionStatement allow_function, bool* ok); |
1201 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok); | 1203 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok); |
1202 StatementT ParseContinueStatement(bool* ok); | 1204 StatementT ParseContinueStatement(bool* ok); |
1203 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, | 1205 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
1204 bool* ok); | 1206 bool* ok); |
1205 StatementT ParseReturnStatement(bool* ok); | 1207 StatementT ParseReturnStatement(bool* ok); |
1206 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, | 1208 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, |
1207 bool* ok); | 1209 bool* ok); |
| 1210 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1211 bool* ok); |
| 1212 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1213 bool* ok); |
| 1214 StatementT ParseThrowStatement(bool* ok); |
1208 | 1215 |
1209 bool IsNextLetKeyword(); | 1216 bool IsNextLetKeyword(); |
1210 bool IsTrivialExpression(); | 1217 bool IsTrivialExpression(); |
1211 | 1218 |
1212 // Checks if the expression is a valid reference expression (e.g., on the | 1219 // Checks if the expression is a valid reference expression (e.g., on the |
1213 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1220 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1214 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1221 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1215 ExpressionT CheckAndRewriteReferenceExpression( | 1222 ExpressionT CheckAndRewriteReferenceExpression( |
1216 ExpressionT expression, int beg_pos, int end_pos, | 1223 ExpressionT expression, int beg_pos, int end_pos, |
1217 MessageTemplate::Template message, bool* ok); | 1224 MessageTemplate::Template message, bool* ok); |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 case Token::MOD: | 1754 case Token::MOD: |
1748 if (allow_natives() || extension_ != NULL) { | 1755 if (allow_natives() || extension_ != NULL) { |
1749 BindingPatternUnexpectedToken(); | 1756 BindingPatternUnexpectedToken(); |
1750 return ParseV8Intrinsic(ok); | 1757 return ParseV8Intrinsic(ok); |
1751 } | 1758 } |
1752 break; | 1759 break; |
1753 | 1760 |
1754 case Token::DO: | 1761 case Token::DO: |
1755 if (allow_harmony_do_expressions()) { | 1762 if (allow_harmony_do_expressions()) { |
1756 BindingPatternUnexpectedToken(); | 1763 BindingPatternUnexpectedToken(); |
1757 return impl()->ParseDoExpression(ok); | 1764 return ParseDoExpression(ok); |
1758 } | 1765 } |
1759 break; | 1766 break; |
1760 | 1767 |
1761 default: | 1768 default: |
1762 break; | 1769 break; |
1763 } | 1770 } |
1764 | 1771 |
1765 ReportUnexpectedToken(Next()); | 1772 ReportUnexpectedToken(Next()); |
1766 *ok = false; | 1773 *ok = false; |
1767 return impl()->EmptyExpression(); | 1774 return impl()->EmptyExpression(); |
(...skipping 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3979 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 3986 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
3980 Scanner::Location spread_pos; | 3987 Scanner::Location spread_pos; |
3981 ExpressionClassifier classifier(this); | 3988 ExpressionClassifier classifier(this); |
3982 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); | 3989 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); |
3983 | 3990 |
3984 DCHECK(!spread_pos.IsValid()); | 3991 DCHECK(!spread_pos.IsValid()); |
3985 | 3992 |
3986 return impl()->NewV8Intrinsic(name, args, pos, ok); | 3993 return impl()->NewV8Intrinsic(name, args, pos, ok); |
3987 } | 3994 } |
3988 | 3995 |
| 3996 template <typename Impl> |
| 3997 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression( |
| 3998 bool* ok) { |
| 3999 // AssignmentExpression :: |
| 4000 // do '{' StatementList '}' |
| 4001 |
| 4002 int pos = peek_position(); |
| 4003 Expect(Token::DO, CHECK_OK); |
| 4004 BlockT block = ParseBlock(nullptr, CHECK_OK); |
| 4005 return impl()->RewriteDoExpression(block, pos, ok); |
| 4006 } |
| 4007 |
3989 // Redefinition of CHECK_OK for parsing statements. | 4008 // Redefinition of CHECK_OK for parsing statements. |
3990 #undef CHECK_OK | 4009 #undef CHECK_OK |
3991 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) | 4010 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) |
3992 | 4011 |
3993 template <typename Impl> | 4012 template <typename Impl> |
3994 typename ParserBase<Impl>::LazyParsingResult | 4013 typename ParserBase<Impl>::LazyParsingResult |
3995 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, | 4014 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, |
3996 bool may_abort, bool* ok) { | 4015 bool may_abort, bool* ok) { |
3997 // StatementList :: | 4016 // StatementList :: |
3998 // (StatementListItem)* <end_token> | 4017 // (StatementListItem)* <end_token> |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4161 // parsed into an empty statement. | 4180 // parsed into an empty statement. |
4162 switch (peek()) { | 4181 switch (peek()) { |
4163 case Token::LBRACE: | 4182 case Token::LBRACE: |
4164 return impl()->ParseBlock(labels, ok); | 4183 return impl()->ParseBlock(labels, ok); |
4165 case Token::SEMICOLON: | 4184 case Token::SEMICOLON: |
4166 Next(); | 4185 Next(); |
4167 return factory()->NewEmptyStatement(kNoSourcePosition); | 4186 return factory()->NewEmptyStatement(kNoSourcePosition); |
4168 case Token::IF: | 4187 case Token::IF: |
4169 return ParseIfStatement(labels, ok); | 4188 return ParseIfStatement(labels, ok); |
4170 case Token::DO: | 4189 case Token::DO: |
4171 return impl()->ParseDoWhileStatement(labels, ok); | 4190 return ParseDoWhileStatement(labels, ok); |
4172 case Token::WHILE: | 4191 case Token::WHILE: |
4173 return impl()->ParseWhileStatement(labels, ok); | 4192 return ParseWhileStatement(labels, ok); |
4174 case Token::FOR: | 4193 case Token::FOR: |
4175 return impl()->ParseForStatement(labels, ok); | 4194 return impl()->ParseForStatement(labels, ok); |
4176 case Token::CONTINUE: | 4195 case Token::CONTINUE: |
4177 case Token::BREAK: | 4196 case Token::BREAK: |
4178 case Token::RETURN: | 4197 case Token::RETURN: |
4179 case Token::THROW: | 4198 case Token::THROW: |
4180 case Token::TRY: { | 4199 case Token::TRY: { |
4181 // These statements must have their labels preserved in an enclosing | 4200 // These statements must have their labels preserved in an enclosing |
4182 // block, as the corresponding AST nodes do not currently store their | 4201 // block, as the corresponding AST nodes do not currently store their |
4183 // labels. | 4202 // labels. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4226 ParserBase<Impl>::ParseStatementAsUnlabelled( | 4245 ParserBase<Impl>::ParseStatementAsUnlabelled( |
4227 ZoneList<const AstRawString*>* labels, bool* ok) { | 4246 ZoneList<const AstRawString*>* labels, bool* ok) { |
4228 switch (peek()) { | 4247 switch (peek()) { |
4229 case Token::CONTINUE: | 4248 case Token::CONTINUE: |
4230 return ParseContinueStatement(ok); | 4249 return ParseContinueStatement(ok); |
4231 case Token::BREAK: | 4250 case Token::BREAK: |
4232 return ParseBreakStatement(labels, ok); | 4251 return ParseBreakStatement(labels, ok); |
4233 case Token::RETURN: | 4252 case Token::RETURN: |
4234 return ParseReturnStatement(ok); | 4253 return ParseReturnStatement(ok); |
4235 case Token::THROW: | 4254 case Token::THROW: |
4236 return impl()->ParseThrowStatement(ok); | 4255 return ParseThrowStatement(ok); |
4237 case Token::TRY: | 4256 case Token::TRY: |
4238 return impl()->ParseTryStatement(ok); | 4257 return impl()->ParseTryStatement(ok); |
4239 default: | 4258 default: |
4240 UNREACHABLE(); | 4259 UNREACHABLE(); |
4241 return impl()->NullStatement(); | 4260 return impl()->NullStatement(); |
4242 } | 4261 } |
4243 } | 4262 } |
4244 | 4263 |
4245 template <typename Impl> | 4264 template <typename Impl> |
4246 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( | 4265 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4558 StatementT body = impl()->NullStatement(); | 4577 StatementT body = impl()->NullStatement(); |
4559 { | 4578 { |
4560 BlockState block_state(&scope_state_, with_scope); | 4579 BlockState block_state(&scope_state_, with_scope); |
4561 with_scope->set_start_position(scanner()->peek_location().beg_pos); | 4580 with_scope->set_start_position(scanner()->peek_location().beg_pos); |
4562 body = ParseScopedStatement(labels, true, CHECK_OK); | 4581 body = ParseScopedStatement(labels, true, CHECK_OK); |
4563 with_scope->set_end_position(scanner()->location().end_pos); | 4582 with_scope->set_end_position(scanner()->location().end_pos); |
4564 } | 4583 } |
4565 return factory()->NewWithStatement(with_scope, expr, body, pos); | 4584 return factory()->NewWithStatement(with_scope, expr, body, pos); |
4566 } | 4585 } |
4567 | 4586 |
| 4587 template <typename Impl> |
| 4588 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement( |
| 4589 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4590 // DoStatement :: |
| 4591 // 'do' Statement 'while' '(' Expression ')' ';' |
| 4592 |
| 4593 auto loop = factory()->NewDoWhileStatement(labels, peek_position()); |
| 4594 typename Types::Target target(this, loop); |
| 4595 |
| 4596 Expect(Token::DO, CHECK_OK); |
| 4597 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 4598 Expect(Token::WHILE, CHECK_OK); |
| 4599 Expect(Token::LPAREN, CHECK_OK); |
| 4600 |
| 4601 ExpressionT cond = ParseExpression(true, CHECK_OK); |
| 4602 Expect(Token::RPAREN, CHECK_OK); |
| 4603 |
| 4604 // Allow do-statements to be terminated with and without |
| 4605 // semi-colons. This allows code such as 'do;while(0)return' to |
| 4606 // parse, which would not be the case if we had used the |
| 4607 // ExpectSemicolon() functionality here. |
| 4608 Check(Token::SEMICOLON); |
| 4609 |
| 4610 return impl()->InitializeLoop(loop, cond, body); |
| 4611 } |
| 4612 |
| 4613 template <typename Impl> |
| 4614 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement( |
| 4615 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4616 // WhileStatement :: |
| 4617 // 'while' '(' Expression ')' Statement |
| 4618 |
| 4619 auto loop = factory()->NewWhileStatement(labels, peek_position()); |
| 4620 typename Types::Target target(this, loop); |
| 4621 |
| 4622 Expect(Token::WHILE, CHECK_OK); |
| 4623 Expect(Token::LPAREN, CHECK_OK); |
| 4624 ExpressionT cond = ParseExpression(true, CHECK_OK); |
| 4625 Expect(Token::RPAREN, CHECK_OK); |
| 4626 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 4627 |
| 4628 return impl()->InitializeLoop(loop, cond, body); |
| 4629 } |
| 4630 |
| 4631 template <typename Impl> |
| 4632 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement( |
| 4633 bool* ok) { |
| 4634 // ThrowStatement :: |
| 4635 // 'throw' Expression ';' |
| 4636 |
| 4637 Expect(Token::THROW, CHECK_OK); |
| 4638 int pos = position(); |
| 4639 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 4640 ReportMessage(MessageTemplate::kNewlineAfterThrow); |
| 4641 *ok = false; |
| 4642 return impl()->NullStatement(); |
| 4643 } |
| 4644 ExpressionT exception = ParseExpression(true, CHECK_OK); |
| 4645 ExpectSemicolon(CHECK_OK); |
| 4646 |
| 4647 return impl()->NewThrowStatement(exception, pos); |
| 4648 } |
| 4649 |
4568 #undef CHECK_OK | 4650 #undef CHECK_OK |
4569 #undef CHECK_OK_CUSTOM | 4651 #undef CHECK_OK_CUSTOM |
4570 | 4652 |
4571 template <typename Impl> | 4653 template <typename Impl> |
4572 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 4654 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4573 Token::Value property) { | 4655 Token::Value property) { |
4574 if (property == Token::SMI || property == Token::NUMBER) return; | 4656 if (property == Token::SMI || property == Token::NUMBER) return; |
4575 | 4657 |
4576 if (IsProto()) { | 4658 if (IsProto()) { |
4577 if (has_seen_proto_) { | 4659 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4616 has_seen_constructor_ = true; | 4698 has_seen_constructor_ = true; |
4617 return; | 4699 return; |
4618 } | 4700 } |
4619 } | 4701 } |
4620 | 4702 |
4621 | 4703 |
4622 } // namespace internal | 4704 } // namespace internal |
4623 } // namespace v8 | 4705 } // namespace v8 |
4624 | 4706 |
4625 #endif // V8_PARSING_PARSER_BASE_H | 4707 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |