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 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 : declarations(4), | 624 : declarations(4), |
625 first_initializer_loc(Scanner::Location::invalid()), | 625 first_initializer_loc(Scanner::Location::invalid()), |
626 bindings_loc(Scanner::Location::invalid()) {} | 626 bindings_loc(Scanner::Location::invalid()) {} |
627 | 627 |
628 DeclarationDescriptor descriptor; | 628 DeclarationDescriptor descriptor; |
629 List<Declaration> declarations; | 629 List<Declaration> declarations; |
630 Scanner::Location first_initializer_loc; | 630 Scanner::Location first_initializer_loc; |
631 Scanner::Location bindings_loc; | 631 Scanner::Location bindings_loc; |
632 }; | 632 }; |
633 | 633 |
| 634 struct CatchInfo { |
| 635 public: |
| 636 explicit CatchInfo(ParserBase* parser) |
| 637 : name(parser->impl()->EmptyIdentifier()), |
| 638 variable(nullptr), |
| 639 pattern(parser->impl()->EmptyExpression()), |
| 640 scope(nullptr), |
| 641 init_block(parser->impl()->NullBlock()), |
| 642 inner_block(parser->impl()->NullBlock()), |
| 643 for_promise_reject(false), |
| 644 bound_names(1, parser->zone()), |
| 645 tail_call_expressions(parser->zone()) {} |
| 646 IdentifierT name; |
| 647 Variable* variable; |
| 648 ExpressionT pattern; |
| 649 Scope* scope; |
| 650 BlockT init_block; |
| 651 BlockT inner_block; |
| 652 bool for_promise_reject; |
| 653 ZoneList<const AstRawString*> bound_names; |
| 654 TailCallExpressionList tail_call_expressions; |
| 655 }; |
| 656 |
634 DeclarationScope* NewScriptScope() const { | 657 DeclarationScope* NewScriptScope() const { |
635 return new (zone()) DeclarationScope(zone(), ast_value_factory()); | 658 return new (zone()) DeclarationScope(zone(), ast_value_factory()); |
636 } | 659 } |
637 | 660 |
638 DeclarationScope* NewVarblockScope() const { | 661 DeclarationScope* NewVarblockScope() const { |
639 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE); | 662 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE); |
640 } | 663 } |
641 | 664 |
642 ModuleScope* NewModuleScope(DeclarationScope* parent) const { | 665 ModuleScope* NewModuleScope(DeclarationScope* parent) const { |
643 return new (zone()) ModuleScope(parent, ast_value_factory()); | 666 return new (zone()) ModuleScope(parent, ast_value_factory()); |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 StatementT ParseReturnStatement(bool* ok); | 1237 StatementT ParseReturnStatement(bool* ok); |
1215 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, | 1238 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, |
1216 bool* ok); | 1239 bool* ok); |
1217 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1240 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
1218 bool* ok); | 1241 bool* ok); |
1219 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1242 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
1220 bool* ok); | 1243 bool* ok); |
1221 StatementT ParseThrowStatement(bool* ok); | 1244 StatementT ParseThrowStatement(bool* ok); |
1222 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | 1245 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
1223 bool* ok); | 1246 bool* ok); |
| 1247 StatementT ParseTryStatement(bool* ok); |
1224 | 1248 |
1225 bool IsNextLetKeyword(); | 1249 bool IsNextLetKeyword(); |
1226 bool IsTrivialExpression(); | 1250 bool IsTrivialExpression(); |
1227 | 1251 |
1228 // Checks if the expression is a valid reference expression (e.g., on the | 1252 // Checks if the expression is a valid reference expression (e.g., on the |
1229 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1253 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1230 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1254 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1231 ExpressionT CheckAndRewriteReferenceExpression( | 1255 ExpressionT CheckAndRewriteReferenceExpression( |
1232 ExpressionT expression, int beg_pos, int end_pos, | 1256 ExpressionT expression, int beg_pos, int end_pos, |
1233 MessageTemplate::Template message, bool* ok); | 1257 MessageTemplate::Template message, bool* ok); |
(...skipping 3084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4318 switch (peek()) { | 4342 switch (peek()) { |
4319 case Token::CONTINUE: | 4343 case Token::CONTINUE: |
4320 return ParseContinueStatement(ok); | 4344 return ParseContinueStatement(ok); |
4321 case Token::BREAK: | 4345 case Token::BREAK: |
4322 return ParseBreakStatement(labels, ok); | 4346 return ParseBreakStatement(labels, ok); |
4323 case Token::RETURN: | 4347 case Token::RETURN: |
4324 return ParseReturnStatement(ok); | 4348 return ParseReturnStatement(ok); |
4325 case Token::THROW: | 4349 case Token::THROW: |
4326 return ParseThrowStatement(ok); | 4350 return ParseThrowStatement(ok); |
4327 case Token::TRY: | 4351 case Token::TRY: |
4328 return impl()->ParseTryStatement(ok); | 4352 return ParseTryStatement(ok); |
4329 default: | 4353 default: |
4330 UNREACHABLE(); | 4354 UNREACHABLE(); |
4331 return impl()->NullStatement(); | 4355 return impl()->NullStatement(); |
4332 } | 4356 } |
4333 } | 4357 } |
4334 | 4358 |
4335 template <typename Impl> | 4359 template <typename Impl> |
4336 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( | 4360 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( |
4337 ZoneList<const AstRawString*>* labels, bool* ok) { | 4361 ZoneList<const AstRawString*>* labels, bool* ok) { |
4338 // Block :: | 4362 // Block :: |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4775 cases->Add(clause, zone()); | 4799 cases->Add(clause, zone()); |
4776 } | 4800 } |
4777 Expect(Token::RBRACE, CHECK_OK); | 4801 Expect(Token::RBRACE, CHECK_OK); |
4778 | 4802 |
4779 cases_block_state.set_end_position(scanner()->location().end_pos); | 4803 cases_block_state.set_end_position(scanner()->location().end_pos); |
4780 return impl()->RewriteSwitchStatement( | 4804 return impl()->RewriteSwitchStatement( |
4781 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope()); | 4805 tag, switch_statement, cases, cases_block_state.FinalizedBlockScope()); |
4782 } | 4806 } |
4783 } | 4807 } |
4784 | 4808 |
| 4809 template <typename Impl> |
| 4810 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement( |
| 4811 bool* ok) { |
| 4812 // TryStatement :: |
| 4813 // 'try' Block Catch |
| 4814 // 'try' Block Finally |
| 4815 // 'try' Block Catch Finally |
| 4816 // |
| 4817 // Catch :: |
| 4818 // 'catch' '(' Identifier ')' Block |
| 4819 // |
| 4820 // Finally :: |
| 4821 // 'finally' Block |
| 4822 |
| 4823 Expect(Token::TRY, CHECK_OK); |
| 4824 int pos = position(); |
| 4825 |
| 4826 BlockT try_block = impl()->NullBlock(); |
| 4827 { |
| 4828 ReturnExprScope no_tail_calls(function_state_, |
| 4829 ReturnExprContext::kInsideTryBlock); |
| 4830 try_block = ParseBlock(nullptr, CHECK_OK); |
| 4831 } |
| 4832 |
| 4833 CatchInfo catch_info(this); |
| 4834 catch_info.for_promise_reject = allow_natives() && Check(Token::MOD); |
| 4835 |
| 4836 if (peek() != Token::CATCH && peek() != Token::FINALLY) { |
| 4837 ReportMessage(MessageTemplate::kNoCatchOrFinally); |
| 4838 *ok = false; |
| 4839 return impl()->NullStatement(); |
| 4840 } |
| 4841 |
| 4842 BlockT catch_block = impl()->NullBlock(); |
| 4843 if (Check(Token::CATCH)) { |
| 4844 Expect(Token::LPAREN, CHECK_OK); |
| 4845 catch_info.scope = NewScope(CATCH_SCOPE); |
| 4846 catch_info.scope->set_start_position(scanner()->location().beg_pos); |
| 4847 |
| 4848 { |
| 4849 CollectExpressionsInTailPositionToListScope |
| 4850 collect_tail_call_expressions_scope( |
| 4851 function_state_, &catch_info.tail_call_expressions); |
| 4852 BlockState catch_block_state(&scope_state_, catch_info.scope); |
| 4853 |
| 4854 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); |
| 4855 |
| 4856 // Create a block scope to hold any lexical declarations created |
| 4857 // as part of destructuring the catch parameter. |
| 4858 { |
| 4859 BlockState catch_variable_block_state(&scope_state_); |
| 4860 catch_variable_block_state.set_start_position( |
| 4861 scanner()->location().beg_pos); |
| 4862 typename Types::Target target(this, catch_block); |
| 4863 |
| 4864 // This does not simply call ParsePrimaryExpression to avoid |
| 4865 // ExpressionFromIdentifier from being called in the first |
| 4866 // branch, which would introduce an unresolved symbol and mess |
| 4867 // with arrow function names. |
| 4868 if (peek_any_identifier()) { |
| 4869 catch_info.name = |
| 4870 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 4871 } else { |
| 4872 ExpressionClassifier pattern_classifier(this); |
| 4873 catch_info.pattern = ParsePrimaryExpression(CHECK_OK); |
| 4874 ValidateBindingPattern(CHECK_OK); |
| 4875 } |
| 4876 |
| 4877 Expect(Token::RPAREN, CHECK_OK); |
| 4878 impl()->RewriteCatchPattern(&catch_info, CHECK_OK); |
| 4879 if (!impl()->IsNullStatement(catch_info.init_block)) { |
| 4880 catch_block->statements()->Add(catch_info.init_block, zone()); |
| 4881 } |
| 4882 |
| 4883 catch_info.inner_block = ParseBlock(nullptr, CHECK_OK); |
| 4884 catch_block->statements()->Add(catch_info.inner_block, zone()); |
| 4885 impl()->ValidateCatchBlock(catch_info, CHECK_OK); |
| 4886 catch_variable_block_state.set_end_position( |
| 4887 scanner()->location().end_pos); |
| 4888 catch_block->set_scope( |
| 4889 catch_variable_block_state.FinalizedBlockScope()); |
| 4890 } |
| 4891 } |
| 4892 |
| 4893 catch_info.scope->set_end_position(scanner()->location().end_pos); |
| 4894 } |
| 4895 |
| 4896 BlockT finally_block = impl()->NullBlock(); |
| 4897 DCHECK(peek() == Token::FINALLY || !impl()->IsNullStatement(catch_block)); |
| 4898 if (Check(Token::FINALLY)) { |
| 4899 finally_block = ParseBlock(nullptr, CHECK_OK); |
| 4900 |
| 4901 if (FLAG_harmony_explicit_tailcalls && |
| 4902 catch_info.tail_call_expressions.has_explicit_tail_calls()) { |
| 4903 // TODO(ishell): update chapter number. |
| 4904 // ES8 XX.YY.ZZ |
| 4905 impl()->ReportMessageAt(catch_info.tail_call_expressions.location(), |
| 4906 MessageTemplate::kUnexpectedTailCallInCatchBlock); |
| 4907 *ok = false; |
| 4908 return impl()->NullStatement(); |
| 4909 } |
| 4910 } |
| 4911 |
| 4912 return impl()->RewriteTryStatement(try_block, catch_block, finally_block, |
| 4913 catch_info, pos); |
| 4914 } |
| 4915 |
4785 #undef CHECK_OK | 4916 #undef CHECK_OK |
4786 #undef CHECK_OK_CUSTOM | 4917 #undef CHECK_OK_CUSTOM |
4787 | 4918 |
4788 template <typename Impl> | 4919 template <typename Impl> |
4789 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 4920 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
4790 Token::Value property) { | 4921 Token::Value property) { |
4791 if (property == Token::SMI || property == Token::NUMBER) return; | 4922 if (property == Token::SMI || property == Token::NUMBER) return; |
4792 | 4923 |
4793 if (IsProto()) { | 4924 if (IsProto()) { |
4794 if (has_seen_proto_) { | 4925 if (has_seen_proto_) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4833 has_seen_constructor_ = true; | 4964 has_seen_constructor_ = true; |
4834 return; | 4965 return; |
4835 } | 4966 } |
4836 } | 4967 } |
4837 | 4968 |
4838 | 4969 |
4839 } // namespace internal | 4970 } // namespace internal |
4840 } // namespace v8 | 4971 } // namespace v8 |
4841 | 4972 |
4842 #endif // V8_PARSING_PARSER_BASE_H | 4973 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |