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 4684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4695 bool* ok) { | 4695 bool* ok) { |
4696 // ReturnStatement :: | 4696 // ReturnStatement :: |
4697 // 'return' [no line terminator] Expression? ';' | 4697 // 'return' [no line terminator] Expression? ';' |
4698 | 4698 |
4699 // Consume the return token. It is necessary to do that before | 4699 // Consume the return token. It is necessary to do that before |
4700 // reporting any errors on it, because of the way errors are | 4700 // reporting any errors on it, because of the way errors are |
4701 // reported (underlining). | 4701 // reported (underlining). |
4702 Expect(Token::RETURN, CHECK_OK); | 4702 Expect(Token::RETURN, CHECK_OK); |
4703 Scanner::Location loc = scanner()->location(); | 4703 Scanner::Location loc = scanner()->location(); |
4704 | 4704 |
| 4705 switch (GetDeclarationScope()->scope_type()) { |
| 4706 case SCRIPT_SCOPE: |
| 4707 case EVAL_SCOPE: |
| 4708 case MODULE_SCOPE: |
| 4709 impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn); |
| 4710 *ok = false; |
| 4711 return impl()->NullStatement(); |
| 4712 default: |
| 4713 break; |
| 4714 } |
| 4715 |
4705 Token::Value tok = peek(); | 4716 Token::Value tok = peek(); |
4706 ExpressionT return_value = impl()->EmptyExpression(); | 4717 ExpressionT return_value = impl()->EmptyExpression(); |
4707 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON || | 4718 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON || |
4708 tok == Token::RBRACE || tok == Token::EOS) { | 4719 tok == Token::RBRACE || tok == Token::EOS) { |
4709 if (IsSubclassConstructor(function_state_->kind())) { | 4720 if (IsSubclassConstructor(function_state_->kind())) { |
4710 return_value = impl()->ThisExpression(loc.beg_pos); | 4721 return_value = impl()->ThisExpression(loc.beg_pos); |
4711 } else { | 4722 } else { |
4712 return_value = impl()->GetLiteralUndefined(position()); | 4723 return_value = impl()->GetLiteralUndefined(position()); |
4713 } | 4724 } |
4714 } else { | 4725 } else { |
4715 if (IsSubclassConstructor(function_state_->kind())) { | 4726 if (IsSubclassConstructor(function_state_->kind())) { |
4716 // Because of the return code rewriting that happens in case of a subclass | 4727 // Because of the return code rewriting that happens in case of a subclass |
4717 // constructor we don't want to accept tail calls, therefore we don't set | 4728 // constructor we don't want to accept tail calls, therefore we don't set |
4718 // ReturnExprScope to kInsideValidReturnStatement here. | 4729 // ReturnExprScope to kInsideValidReturnStatement here. |
4719 return_value = ParseExpression(true, CHECK_OK); | 4730 return_value = ParseExpression(true, CHECK_OK); |
4720 } else { | 4731 } else { |
4721 ReturnExprScope maybe_allow_tail_calls( | 4732 ReturnExprScope maybe_allow_tail_calls( |
4722 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 4733 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
4723 return_value = ParseExpression(true, CHECK_OK); | 4734 return_value = ParseExpression(true, CHECK_OK); |
4724 | 4735 |
4725 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) { | 4736 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) { |
4726 // ES6 14.6.1 Static Semantics: IsInTailPosition | 4737 // ES6 14.6.1 Static Semantics: IsInTailPosition |
4727 function_state_->AddImplicitTailCallExpression(return_value); | 4738 function_state_->AddImplicitTailCallExpression(return_value); |
4728 } | 4739 } |
4729 } | 4740 } |
4730 } | 4741 } |
4731 ExpectSemicolon(CHECK_OK); | 4742 ExpectSemicolon(CHECK_OK); |
4732 return_value = impl()->RewriteReturn(return_value, loc.beg_pos); | 4743 return_value = impl()->RewriteReturn(return_value, loc.beg_pos); |
4733 | |
4734 DeclarationScope* decl_scope = GetDeclarationScope(); | |
4735 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { | |
4736 impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn); | |
4737 *ok = false; | |
4738 return impl()->NullStatement(); | |
4739 } | |
4740 return factory()->NewReturnStatement(return_value, loc.beg_pos); | 4744 return factory()->NewReturnStatement(return_value, loc.beg_pos); |
4741 } | 4745 } |
4742 | 4746 |
4743 template <typename Impl> | 4747 template <typename Impl> |
4744 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement( | 4748 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement( |
4745 ZoneList<const AstRawString*>* labels, bool* ok) { | 4749 ZoneList<const AstRawString*>* labels, bool* ok) { |
4746 // WithStatement :: | 4750 // WithStatement :: |
4747 // 'with' '(' Expression ')' Statement | 4751 // 'with' '(' Expression ')' Statement |
4748 | 4752 |
4749 Expect(Token::WITH, CHECK_OK); | 4753 Expect(Token::WITH, CHECK_OK); |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5317 has_seen_constructor_ = true; | 5321 has_seen_constructor_ = true; |
5318 return; | 5322 return; |
5319 } | 5323 } |
5320 } | 5324 } |
5321 | 5325 |
5322 | 5326 |
5323 } // namespace internal | 5327 } // namespace internal |
5324 } // namespace v8 | 5328 } // namespace v8 |
5325 | 5329 |
5326 #endif // V8_PARSING_PARSER_BASE_H | 5330 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |