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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 // typedef Expression; | 131 // typedef Expression; |
132 // typedef FunctionLiteral; | 132 // typedef FunctionLiteral; |
133 // typedef ObjectLiteralProperty; | 133 // typedef ObjectLiteralProperty; |
134 // typedef ClassLiteralProperty; | 134 // typedef ClassLiteralProperty; |
135 // typedef ExpressionList; | 135 // typedef ExpressionList; |
136 // typedef PropertyList; | 136 // typedef PropertyList; |
137 // typedef FormalParameters; | 137 // typedef FormalParameters; |
138 // typedef Statement; | 138 // typedef Statement; |
139 // typedef StatementList; | 139 // typedef StatementList; |
140 // typedef Block; | 140 // typedef Block; |
| 141 // typedef BreakableStatement; |
| 142 // typedef IterationStatement; |
141 // // For constructing objects returned by the traversing functions. | 143 // // For constructing objects returned by the traversing functions. |
142 // typedef Factory; | 144 // typedef Factory; |
143 // // For other implementation-specific tasks. | 145 // // For other implementation-specific tasks. |
144 // typedef Target; | 146 // typedef Target; |
145 // typedef TargetScope; | 147 // typedef TargetScope; |
146 // }; | 148 // }; |
147 | 149 |
148 template <typename Impl> | 150 template <typename Impl> |
149 struct ParserTypes; | 151 struct ParserTypes; |
150 | 152 |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, | 1212 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
1211 bool* ok); | 1213 bool* ok); |
1212 StatementT ParseReturnStatement(bool* ok); | 1214 StatementT ParseReturnStatement(bool* ok); |
1213 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, | 1215 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, |
1214 bool* ok); | 1216 bool* ok); |
1215 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1217 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
1216 bool* ok); | 1218 bool* ok); |
1217 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1219 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
1218 bool* ok); | 1220 bool* ok); |
1219 StatementT ParseThrowStatement(bool* ok); | 1221 StatementT ParseThrowStatement(bool* ok); |
| 1222 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
| 1223 bool* ok); |
1220 | 1224 |
1221 bool IsNextLetKeyword(); | 1225 bool IsNextLetKeyword(); |
1222 bool IsTrivialExpression(); | 1226 bool IsTrivialExpression(); |
1223 | 1227 |
1224 // Checks if the expression is a valid reference expression (e.g., on the | 1228 // Checks if the expression is a valid reference expression (e.g., on the |
1225 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1229 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1226 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1230 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1227 ExpressionT CheckAndRewriteReferenceExpression( | 1231 ExpressionT CheckAndRewriteReferenceExpression( |
1228 ExpressionT expression, int beg_pos, int end_pos, | 1232 ExpressionT expression, int beg_pos, int end_pos, |
1229 MessageTemplate::Template message, bool* ok); | 1233 MessageTemplate::Template message, bool* ok); |
(...skipping 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4275 factory()->NewBlock(labels, 1, false, kNoSourcePosition); | 4279 factory()->NewBlock(labels, 1, false, kNoSourcePosition); |
4276 typename Types::Target target(this, result); | 4280 typename Types::Target target(this, result); |
4277 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); | 4281 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); |
4278 result->statements()->Add(statement, zone()); | 4282 result->statements()->Add(statement, zone()); |
4279 return result; | 4283 return result; |
4280 } | 4284 } |
4281 } | 4285 } |
4282 case Token::WITH: | 4286 case Token::WITH: |
4283 return ParseWithStatement(labels, ok); | 4287 return ParseWithStatement(labels, ok); |
4284 case Token::SWITCH: | 4288 case Token::SWITCH: |
4285 return impl()->ParseSwitchStatement(labels, ok); | 4289 return ParseSwitchStatement(labels, ok); |
4286 case Token::FUNCTION: | 4290 case Token::FUNCTION: |
4287 // FunctionDeclaration only allowed as a StatementListItem, not in | 4291 // FunctionDeclaration only allowed as a StatementListItem, not in |
4288 // an arbitrary Statement position. Exceptions such as | 4292 // an arbitrary Statement position. Exceptions such as |
4289 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses | 4293 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses |
4290 // are handled by calling ParseScopedStatement rather than | 4294 // are handled by calling ParseScopedStatement rather than |
4291 // ParseStatement directly. | 4295 // ParseStatement directly. |
4292 impl()->ReportMessageAt(scanner()->peek_location(), | 4296 impl()->ReportMessageAt(scanner()->peek_location(), |
4293 is_strict(language_mode()) | 4297 is_strict(language_mode()) |
4294 ? MessageTemplate::kStrictFunction | 4298 ? MessageTemplate::kStrictFunction |
4295 : MessageTemplate::kSloppyFunction); | 4299 : MessageTemplate::kSloppyFunction); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4512 | 4516 |
4513 int pos = peek_position(); | 4517 int pos = peek_position(); |
4514 Expect(Token::CONTINUE, CHECK_OK); | 4518 Expect(Token::CONTINUE, CHECK_OK); |
4515 IdentifierT label = impl()->EmptyIdentifier(); | 4519 IdentifierT label = impl()->EmptyIdentifier(); |
4516 Token::Value tok = peek(); | 4520 Token::Value tok = peek(); |
4517 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && | 4521 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && |
4518 tok != Token::RBRACE && tok != Token::EOS) { | 4522 tok != Token::RBRACE && tok != Token::EOS) { |
4519 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 4523 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
4520 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 4524 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
4521 } | 4525 } |
4522 typename Types::IterationStatementT target = | 4526 typename Types::IterationStatement target = |
4523 impl()->LookupContinueTarget(label, CHECK_OK); | 4527 impl()->LookupContinueTarget(label, CHECK_OK); |
4524 if (impl()->IsNullStatement(target)) { | 4528 if (impl()->IsNullStatement(target)) { |
4525 // Illegal continue statement. | 4529 // Illegal continue statement. |
4526 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; | 4530 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; |
4527 if (!impl()->IsEmptyIdentifier(label)) { | 4531 if (!impl()->IsEmptyIdentifier(label)) { |
4528 message = MessageTemplate::kUnknownLabel; | 4532 message = MessageTemplate::kUnknownLabel; |
4529 } | 4533 } |
4530 ReportMessage(message, label); | 4534 ReportMessage(message, label); |
4531 *ok = false; | 4535 *ok = false; |
4532 return impl()->NullStatement(); | 4536 return impl()->NullStatement(); |
(...skipping 17 matching lines...) Expand all Loading... |
4550 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 4554 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
4551 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 4555 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
4552 } | 4556 } |
4553 // Parse labeled break statements that target themselves into | 4557 // Parse labeled break statements that target themselves into |
4554 // empty statements, e.g. 'l1: l2: l3: break l2;' | 4558 // empty statements, e.g. 'l1: l2: l3: break l2;' |
4555 if (!impl()->IsEmptyIdentifier(label) && | 4559 if (!impl()->IsEmptyIdentifier(label) && |
4556 impl()->ContainsLabel(labels, label)) { | 4560 impl()->ContainsLabel(labels, label)) { |
4557 ExpectSemicolon(CHECK_OK); | 4561 ExpectSemicolon(CHECK_OK); |
4558 return factory()->NewEmptyStatement(pos); | 4562 return factory()->NewEmptyStatement(pos); |
4559 } | 4563 } |
4560 typename Types::BreakableStatementT target = | 4564 typename Types::BreakableStatement target = |
4561 impl()->LookupBreakTarget(label, CHECK_OK); | 4565 impl()->LookupBreakTarget(label, CHECK_OK); |
4562 if (impl()->IsNullStatement(target)) { | 4566 if (impl()->IsNullStatement(target)) { |
4563 // Illegal break statement. | 4567 // Illegal break statement. |
4564 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; | 4568 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; |
4565 if (!impl()->IsEmptyIdentifier(label)) { | 4569 if (!impl()->IsEmptyIdentifier(label)) { |
4566 message = MessageTemplate::kUnknownLabel; | 4570 message = MessageTemplate::kUnknownLabel; |
4567 } | 4571 } |
4568 ReportMessage(message, label); | 4572 ReportMessage(message, label); |
4569 *ok = false; | 4573 *ok = false; |
4570 return impl()->NullStatement(); | 4574 return impl()->NullStatement(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4711 ReportMessage(MessageTemplate::kNewlineAfterThrow); | 4715 ReportMessage(MessageTemplate::kNewlineAfterThrow); |
4712 *ok = false; | 4716 *ok = false; |
4713 return impl()->NullStatement(); | 4717 return impl()->NullStatement(); |
4714 } | 4718 } |
4715 ExpressionT exception = ParseExpression(true, CHECK_OK); | 4719 ExpressionT exception = ParseExpression(true, CHECK_OK); |
4716 ExpectSemicolon(CHECK_OK); | 4720 ExpectSemicolon(CHECK_OK); |
4717 | 4721 |
4718 return impl()->NewThrowStatement(exception, pos); | 4722 return impl()->NewThrowStatement(exception, pos); |
4719 } | 4723 } |
4720 | 4724 |
| 4725 template <typename Impl> |
| 4726 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement( |
| 4727 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4728 // SwitchStatement :: |
| 4729 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 4730 // CaseClause :: |
| 4731 // 'case' Expression ':' StatementList |
| 4732 // 'default' ':' StatementList |
| 4733 |
| 4734 int switch_pos = peek_position(); |
| 4735 |
| 4736 Expect(Token::SWITCH, CHECK_OK); |
| 4737 Expect(Token::LPAREN, CHECK_OK); |
| 4738 ExpressionT tag = ParseExpression(true, CHECK_OK); |
| 4739 Expect(Token::RPAREN, CHECK_OK); |
| 4740 |
| 4741 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos); |
| 4742 |
| 4743 { |
| 4744 BlockState cases_block_state(&scope_state_); |
| 4745 cases_block_state.set_start_position(scanner()->location().beg_pos); |
| 4746 cases_block_state.SetNonlinear(); |
| 4747 typename Types::Target target(this, switch_statement); |
| 4748 |
| 4749 bool default_seen = false; |
| 4750 auto cases = impl()->NewCaseClauseList(4); |
| 4751 Expect(Token::LBRACE, CHECK_OK); |
| 4752 while (peek() != Token::RBRACE) { |
| 4753 // An empty label indicates the default case. |
| 4754 ExpressionT label = impl()->EmptyExpression(); |
| 4755 if (Check(Token::CASE)) { |
| 4756 label = ParseExpression(true, CHECK_OK); |
| 4757 } else { |
| 4758 Expect(Token::DEFAULT, CHECK_OK); |
| 4759 if (default_seen) { |
| 4760 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); |
| 4761 *ok = false; |
| 4762 return impl()->NullStatement(); |
| 4763 } |
| 4764 default_seen = true; |
| 4765 } |
| 4766 Expect(Token::COLON, CHECK_OK); |
| 4767 int clause_pos = position(); |
| 4768 StatementListT statements = impl()->NewStatementList(5); |
| 4769 while (peek() != Token::CASE && peek() != Token::DEFAULT && |
| 4770 peek() != Token::RBRACE) { |
| 4771 StatementT stat = ParseStatementListItem(CHECK_OK); |
| 4772 statements->Add(stat, zone()); |
| 4773 } |
| 4774 auto clause = factory()->NewCaseClause(label, statements, clause_pos); |
| 4775 cases->Add(clause, zone()); |
| 4776 } |
| 4777 Expect(Token::RBRACE, CHECK_OK); |
| 4778 |
| 4779 cases_block_state.set_end_position(scanner()->location().end_pos); |
| 4780 return impl()->RewriteSwitchStatement( |
| 4781 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope()); |
| 4782 } |
| 4783 } |
| 4784 |
4721 #undef CHECK_OK | 4785 #undef CHECK_OK |
4722 #undef CHECK_OK_CUSTOM | 4786 #undef CHECK_OK_CUSTOM |
4723 | 4787 |
4724 template <typename Impl> | 4788 template <typename Impl> |
4725 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 4789 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4726 Token::Value property) { | 4790 Token::Value property) { |
4727 if (property == Token::SMI || property == Token::NUMBER) return; | 4791 if (property == Token::SMI || property == Token::NUMBER) return; |
4728 | 4792 |
4729 if (IsProto()) { | 4793 if (IsProto()) { |
4730 if (has_seen_proto_) { | 4794 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4769 has_seen_constructor_ = true; | 4833 has_seen_constructor_ = true; |
4770 return; | 4834 return; |
4771 } | 4835 } |
4772 } | 4836 } |
4773 | 4837 |
4774 | 4838 |
4775 } // namespace internal | 4839 } // namespace internal |
4776 } // namespace v8 | 4840 } // namespace v8 |
4777 | 4841 |
4778 #endif // V8_PARSING_PARSER_BASE_H | 4842 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |