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 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, | 1207 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
1206 bool* ok); | 1208 bool* ok); |
1207 StatementT ParseReturnStatement(bool* ok); | 1209 StatementT ParseReturnStatement(bool* ok); |
1208 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, | 1210 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, |
1209 bool* ok); | 1211 bool* ok); |
1210 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1212 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
1211 bool* ok); | 1213 bool* ok); |
1212 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1214 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
1213 bool* ok); | 1215 bool* ok); |
1214 StatementT ParseThrowStatement(bool* ok); | 1216 StatementT ParseThrowStatement(bool* ok); |
| 1217 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
| 1218 bool* ok); |
1215 | 1219 |
1216 bool IsNextLetKeyword(); | 1220 bool IsNextLetKeyword(); |
1217 bool IsTrivialExpression(); | 1221 bool IsTrivialExpression(); |
1218 | 1222 |
1219 // Checks if the expression is a valid reference expression (e.g., on the | 1223 // Checks if the expression is a valid reference expression (e.g., on the |
1220 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1224 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1221 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1225 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1222 ExpressionT CheckAndRewriteReferenceExpression( | 1226 ExpressionT CheckAndRewriteReferenceExpression( |
1223 ExpressionT expression, int beg_pos, int end_pos, | 1227 ExpressionT expression, int beg_pos, int end_pos, |
1224 MessageTemplate::Template message, bool* ok); | 1228 MessageTemplate::Template message, bool* ok); |
(...skipping 2983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4208 factory()->NewBlock(labels, 1, false, kNoSourcePosition); | 4212 factory()->NewBlock(labels, 1, false, kNoSourcePosition); |
4209 typename Types::Target target(this, result); | 4213 typename Types::Target target(this, result); |
4210 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); | 4214 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); |
4211 result->statements()->Add(statement, zone()); | 4215 result->statements()->Add(statement, zone()); |
4212 return result; | 4216 return result; |
4213 } | 4217 } |
4214 } | 4218 } |
4215 case Token::WITH: | 4219 case Token::WITH: |
4216 return ParseWithStatement(labels, ok); | 4220 return ParseWithStatement(labels, ok); |
4217 case Token::SWITCH: | 4221 case Token::SWITCH: |
4218 return impl()->ParseSwitchStatement(labels, ok); | 4222 return ParseSwitchStatement(labels, ok); |
4219 case Token::FUNCTION: | 4223 case Token::FUNCTION: |
4220 // FunctionDeclaration only allowed as a StatementListItem, not in | 4224 // FunctionDeclaration only allowed as a StatementListItem, not in |
4221 // an arbitrary Statement position. Exceptions such as | 4225 // an arbitrary Statement position. Exceptions such as |
4222 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses | 4226 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses |
4223 // are handled by calling ParseScopedStatement rather than | 4227 // are handled by calling ParseScopedStatement rather than |
4224 // ParseStatement directly. | 4228 // ParseStatement directly. |
4225 impl()->ReportMessageAt(scanner()->peek_location(), | 4229 impl()->ReportMessageAt(scanner()->peek_location(), |
4226 is_strict(language_mode()) | 4230 is_strict(language_mode()) |
4227 ? MessageTemplate::kStrictFunction | 4231 ? MessageTemplate::kStrictFunction |
4228 : MessageTemplate::kSloppyFunction); | 4232 : MessageTemplate::kSloppyFunction); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4443 | 4447 |
4444 int pos = peek_position(); | 4448 int pos = peek_position(); |
4445 Expect(Token::CONTINUE, CHECK_OK); | 4449 Expect(Token::CONTINUE, CHECK_OK); |
4446 IdentifierT label = impl()->EmptyIdentifier(); | 4450 IdentifierT label = impl()->EmptyIdentifier(); |
4447 Token::Value tok = peek(); | 4451 Token::Value tok = peek(); |
4448 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && | 4452 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && |
4449 tok != Token::RBRACE && tok != Token::EOS) { | 4453 tok != Token::RBRACE && tok != Token::EOS) { |
4450 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 4454 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
4451 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 4455 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
4452 } | 4456 } |
4453 typename Types::IterationStatementT target = | 4457 typename Types::IterationStatement target = |
4454 impl()->LookupContinueTarget(label, CHECK_OK); | 4458 impl()->LookupContinueTarget(label, CHECK_OK); |
4455 if (impl()->IsNullStatement(target)) { | 4459 if (impl()->IsNullStatement(target)) { |
4456 // Illegal continue statement. | 4460 // Illegal continue statement. |
4457 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; | 4461 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; |
4458 if (!impl()->IsEmptyIdentifier(label)) { | 4462 if (!impl()->IsEmptyIdentifier(label)) { |
4459 message = MessageTemplate::kUnknownLabel; | 4463 message = MessageTemplate::kUnknownLabel; |
4460 } | 4464 } |
4461 ReportMessage(message, label); | 4465 ReportMessage(message, label); |
4462 *ok = false; | 4466 *ok = false; |
4463 return impl()->NullStatement(); | 4467 return impl()->NullStatement(); |
(...skipping 17 matching lines...) Expand all Loading... |
4481 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 4485 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
4482 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 4486 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
4483 } | 4487 } |
4484 // Parse labeled break statements that target themselves into | 4488 // Parse labeled break statements that target themselves into |
4485 // empty statements, e.g. 'l1: l2: l3: break l2;' | 4489 // empty statements, e.g. 'l1: l2: l3: break l2;' |
4486 if (!impl()->IsEmptyIdentifier(label) && | 4490 if (!impl()->IsEmptyIdentifier(label) && |
4487 impl()->ContainsLabel(labels, label)) { | 4491 impl()->ContainsLabel(labels, label)) { |
4488 ExpectSemicolon(CHECK_OK); | 4492 ExpectSemicolon(CHECK_OK); |
4489 return factory()->NewEmptyStatement(pos); | 4493 return factory()->NewEmptyStatement(pos); |
4490 } | 4494 } |
4491 typename Types::BreakableStatementT target = | 4495 typename Types::BreakableStatement target = |
4492 impl()->LookupBreakTarget(label, CHECK_OK); | 4496 impl()->LookupBreakTarget(label, CHECK_OK); |
4493 if (impl()->IsNullStatement(target)) { | 4497 if (impl()->IsNullStatement(target)) { |
4494 // Illegal break statement. | 4498 // Illegal break statement. |
4495 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; | 4499 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; |
4496 if (!impl()->IsEmptyIdentifier(label)) { | 4500 if (!impl()->IsEmptyIdentifier(label)) { |
4497 message = MessageTemplate::kUnknownLabel; | 4501 message = MessageTemplate::kUnknownLabel; |
4498 } | 4502 } |
4499 ReportMessage(message, label); | 4503 ReportMessage(message, label); |
4500 *ok = false; | 4504 *ok = false; |
4501 return impl()->NullStatement(); | 4505 return impl()->NullStatement(); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4640 ReportMessage(MessageTemplate::kNewlineAfterThrow); | 4644 ReportMessage(MessageTemplate::kNewlineAfterThrow); |
4641 *ok = false; | 4645 *ok = false; |
4642 return impl()->NullStatement(); | 4646 return impl()->NullStatement(); |
4643 } | 4647 } |
4644 ExpressionT exception = ParseExpression(true, CHECK_OK); | 4648 ExpressionT exception = ParseExpression(true, CHECK_OK); |
4645 ExpectSemicolon(CHECK_OK); | 4649 ExpectSemicolon(CHECK_OK); |
4646 | 4650 |
4647 return impl()->NewThrowStatement(exception, pos); | 4651 return impl()->NewThrowStatement(exception, pos); |
4648 } | 4652 } |
4649 | 4653 |
| 4654 template <typename Impl> |
| 4655 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement( |
| 4656 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4657 // SwitchStatement :: |
| 4658 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 4659 // CaseClause :: |
| 4660 // 'case' Expression ':' StatementList |
| 4661 // 'default' ':' StatementList |
| 4662 |
| 4663 int switch_pos = peek_position(); |
| 4664 |
| 4665 Expect(Token::SWITCH, CHECK_OK); |
| 4666 Expect(Token::LPAREN, CHECK_OK); |
| 4667 ExpressionT tag = ParseExpression(true, CHECK_OK); |
| 4668 Expect(Token::RPAREN, CHECK_OK); |
| 4669 |
| 4670 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos); |
| 4671 |
| 4672 { |
| 4673 BlockState cases_block_state(&scope_state_); |
| 4674 cases_block_state.set_start_position(scanner()->location().beg_pos); |
| 4675 cases_block_state.SetNonlinear(); |
| 4676 typename Types::Target target(this, switch_statement); |
| 4677 |
| 4678 bool default_seen = false; |
| 4679 auto cases = impl()->NewCaseClauseList(4); |
| 4680 Expect(Token::LBRACE, CHECK_OK); |
| 4681 while (peek() != Token::RBRACE) { |
| 4682 // An empty label indicates the default case. |
| 4683 ExpressionT label = impl()->EmptyExpression(); |
| 4684 if (Check(Token::CASE)) { |
| 4685 label = ParseExpression(true, CHECK_OK); |
| 4686 } else { |
| 4687 Expect(Token::DEFAULT, CHECK_OK); |
| 4688 if (default_seen) { |
| 4689 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); |
| 4690 *ok = false; |
| 4691 return impl()->NullStatement(); |
| 4692 } |
| 4693 default_seen = true; |
| 4694 } |
| 4695 Expect(Token::COLON, CHECK_OK); |
| 4696 int clause_pos = position(); |
| 4697 StatementListT statements = impl()->NewStatementList(5); |
| 4698 while (peek() != Token::CASE && peek() != Token::DEFAULT && |
| 4699 peek() != Token::RBRACE) { |
| 4700 StatementT stat = ParseStatementListItem(CHECK_OK); |
| 4701 statements->Add(stat, zone()); |
| 4702 } |
| 4703 auto clause = factory()->NewCaseClause(label, statements, clause_pos); |
| 4704 cases->Add(clause, zone()); |
| 4705 } |
| 4706 Expect(Token::RBRACE, CHECK_OK); |
| 4707 |
| 4708 cases_block_state.set_end_position(scanner()->location().end_pos); |
| 4709 return impl()->RewriteSwitchStatement( |
| 4710 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope()); |
| 4711 } |
| 4712 } |
| 4713 |
4650 #undef CHECK_OK | 4714 #undef CHECK_OK |
4651 #undef CHECK_OK_CUSTOM | 4715 #undef CHECK_OK_CUSTOM |
4652 | 4716 |
4653 template <typename Impl> | 4717 template <typename Impl> |
4654 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 4718 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4655 Token::Value property) { | 4719 Token::Value property) { |
4656 if (property == Token::SMI || property == Token::NUMBER) return; | 4720 if (property == Token::SMI || property == Token::NUMBER) return; |
4657 | 4721 |
4658 if (IsProto()) { | 4722 if (IsProto()) { |
4659 if (has_seen_proto_) { | 4723 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4698 has_seen_constructor_ = true; | 4762 has_seen_constructor_ = true; |
4699 return; | 4763 return; |
4700 } | 4764 } |
4701 } | 4765 } |
4702 | 4766 |
4703 | 4767 |
4704 } // namespace internal | 4768 } // namespace internal |
4705 } // namespace v8 | 4769 } // namespace v8 |
4706 | 4770 |
4707 #endif // V8_PARSING_PARSER_BASE_H | 4771 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |