| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 #include <cmath> | 5 #include <cmath> |
| 6 | 6 |
| 7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
| 8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
| 9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
| 10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 // reported (underlining). | 694 // reported (underlining). |
| 695 Expect(Token::RETURN, CHECK_OK); | 695 Expect(Token::RETURN, CHECK_OK); |
| 696 function_state_->set_return_location(scanner()->location()); | 696 function_state_->set_return_location(scanner()->location()); |
| 697 | 697 |
| 698 // An ECMAScript program is considered syntactically incorrect if it | 698 // An ECMAScript program is considered syntactically incorrect if it |
| 699 // contains a return statement that is not within the body of a | 699 // contains a return statement that is not within the body of a |
| 700 // function. See ECMA-262, section 12.9, page 67. | 700 // function. See ECMA-262, section 12.9, page 67. |
| 701 // This is not handled during preparsing. | 701 // This is not handled during preparsing. |
| 702 | 702 |
| 703 Token::Value tok = peek(); | 703 Token::Value tok = peek(); |
| 704 int tail_call_position = -1; | |
| 705 if (FLAG_harmony_explicit_tailcalls && tok == Token::CONTINUE) { | |
| 706 Consume(Token::CONTINUE); | |
| 707 tail_call_position = position(); | |
| 708 tok = peek(); | |
| 709 } | |
| 710 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 704 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 711 tok != Token::SEMICOLON && | 705 tok != Token::SEMICOLON && |
| 712 tok != Token::RBRACE && | 706 tok != Token::RBRACE && |
| 713 tok != Token::EOS) { | 707 tok != Token::EOS) { |
| 708 // Because of the return code rewriting that happens in case of a subclass |
| 709 // constructor we don't want to accept tail calls, therefore we don't set |
| 710 // ReturnExprScope to kInsideValidReturnStatement here. |
| 711 ReturnExprContext return_expr_context = |
| 712 IsSubclassConstructor(function_state_->kind()) |
| 713 ? function_state_->return_expr_context() |
| 714 : ReturnExprContext::kInsideValidReturnStatement; |
| 715 |
| 716 ReturnExprScope maybe_allow_tail_calls(function_state_, |
| 717 return_expr_context); |
| 714 ParseExpression(true, CHECK_OK); | 718 ParseExpression(true, CHECK_OK); |
| 715 if (tail_call_position >= 0) { | |
| 716 ReturnExprContext return_expr_context = | |
| 717 function_state_->return_expr_context(); | |
| 718 if (return_expr_context != ReturnExprContext::kNormal) { | |
| 719 ReportIllegalTailCallAt(tail_call_position, return_expr_context); | |
| 720 *ok = false; | |
| 721 return Statement::Default(); | |
| 722 } | |
| 723 function_state_->AddExpressionInTailPosition( | |
| 724 PreParserExpression::Default(), tail_call_position); | |
| 725 } | |
| 726 } | 719 } |
| 727 ExpectSemicolon(CHECK_OK); | 720 ExpectSemicolon(CHECK_OK); |
| 728 return Statement::Jump(); | 721 return Statement::Jump(); |
| 729 } | 722 } |
| 730 | 723 |
| 731 | 724 |
| 732 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 725 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 733 // WithStatement :: | 726 // WithStatement :: |
| 734 // 'with' '(' Expression ')' Statement | 727 // 'with' '(' Expression ')' Statement |
| 735 Expect(Token::WITH, CHECK_OK); | 728 Expect(Token::WITH, CHECK_OK); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 ReturnExprContext::kInsideTryBlock); | 975 ReturnExprContext::kInsideTryBlock); |
| 983 ParseBlock(CHECK_OK); | 976 ParseBlock(CHECK_OK); |
| 984 } | 977 } |
| 985 | 978 |
| 986 Token::Value tok = peek(); | 979 Token::Value tok = peek(); |
| 987 if (tok != Token::CATCH && tok != Token::FINALLY) { | 980 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 988 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); | 981 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); |
| 989 *ok = false; | 982 *ok = false; |
| 990 return Statement::Default(); | 983 return Statement::Default(); |
| 991 } | 984 } |
| 992 List<TailCallExpression> expressions_in_tail_position_in_catch_block; | 985 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); |
| 993 bool catch_block_exists = false; | 986 bool catch_block_exists = false; |
| 994 if (tok == Token::CATCH) { | 987 if (tok == Token::CATCH) { |
| 995 Consume(Token::CATCH); | 988 Consume(Token::CATCH); |
| 996 Expect(Token::LPAREN, CHECK_OK); | 989 Expect(Token::LPAREN, CHECK_OK); |
| 997 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); | 990 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 998 ExpressionClassifier pattern_classifier(this); | 991 ExpressionClassifier pattern_classifier(this); |
| 999 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 992 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
| 1000 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 993 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
| 1001 Expect(Token::RPAREN, CHECK_OK); | 994 Expect(Token::RPAREN, CHECK_OK); |
| 1002 { | 995 { |
| 1003 CollectExpressionsInTailPositionToListScope | 996 CollectExpressionsInTailPositionToListScope |
| 1004 collect_expressions_in_tail_position_scope( | 997 collect_tail_call_expressions_scope( |
| 1005 function_state_, &expressions_in_tail_position_in_catch_block); | 998 function_state_, &tail_call_expressions_in_catch_block); |
| 1006 BlockState block_state(&scope_, catch_scope); | 999 BlockState block_state(&scope_, catch_scope); |
| 1007 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1000 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
| 1008 { | 1001 { |
| 1009 BlockState block_state(&scope_, block_scope); | 1002 BlockState block_state(&scope_, block_scope); |
| 1010 ParseBlock(CHECK_OK); | 1003 ParseBlock(CHECK_OK); |
| 1011 } | 1004 } |
| 1012 } | 1005 } |
| 1013 catch_block_exists = true; | 1006 catch_block_exists = true; |
| 1014 tok = peek(); | 1007 tok = peek(); |
| 1015 } | 1008 } |
| 1016 if (tok == Token::FINALLY) { | 1009 if (tok == Token::FINALLY) { |
| 1017 Consume(Token::FINALLY); | 1010 Consume(Token::FINALLY); |
| 1018 ParseBlock(CHECK_OK); | 1011 ParseBlock(CHECK_OK); |
| 1019 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && | 1012 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && |
| 1020 expressions_in_tail_position_in_catch_block.length() > 0) { | 1013 !tail_call_expressions_in_catch_block.is_empty()) { |
| 1021 // TODO(ishell): update chapter number. | 1014 // TODO(ishell): update chapter number. |
| 1022 // ES8 XX.YY.ZZ | 1015 // ES8 XX.YY.ZZ |
| 1023 int pos = expressions_in_tail_position_in_catch_block[0].pos; | 1016 ReportMessageAt(tail_call_expressions_in_catch_block.location(), |
| 1024 ReportMessageAt(Scanner::Location(pos, pos + 1), | 1017 MessageTemplate::kUnexpectedTailCallInCatchBlock); |
| 1025 MessageTemplate::kTailCallInCatchBlock); | |
| 1026 *ok = false; | 1018 *ok = false; |
| 1027 return Statement::Default(); | 1019 return Statement::Default(); |
| 1028 } | 1020 } |
| 1029 } | 1021 } |
| 1030 return Statement::Default(); | 1022 return Statement::Default(); |
| 1031 } | 1023 } |
| 1032 | 1024 |
| 1033 | 1025 |
| 1034 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { | 1026 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { |
| 1035 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 1027 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 Scope* scope = NewScope(scope_, BLOCK_SCOPE); | 1144 Scope* scope = NewScope(scope_, BLOCK_SCOPE); |
| 1153 BlockState block_state(&scope_, scope); | 1145 BlockState block_state(&scope_, scope); |
| 1154 scope_->SetLanguageMode( | 1146 scope_->SetLanguageMode( |
| 1155 static_cast<LanguageMode>(class_language_mode | STRICT)); | 1147 static_cast<LanguageMode>(class_language_mode | STRICT)); |
| 1156 // TODO(marja): Make PreParser use scope names too. | 1148 // TODO(marja): Make PreParser use scope names too. |
| 1157 // scope_->SetScopeName(name); | 1149 // scope_->SetScopeName(name); |
| 1158 | 1150 |
| 1159 bool has_extends = Check(Token::EXTENDS); | 1151 bool has_extends = Check(Token::EXTENDS); |
| 1160 if (has_extends) { | 1152 if (has_extends) { |
| 1161 ExpressionClassifier classifier(this); | 1153 ExpressionClassifier classifier(this); |
| 1162 ParseLeftHandSideExpression(&classifier, CHECK_OK); | 1154 ParseLeftHandSideExpression(kDontAcceptTCE, &classifier, CHECK_OK); |
| 1163 ValidateExpression(&classifier, CHECK_OK); | 1155 ValidateExpression(&classifier, CHECK_OK); |
| 1164 } | 1156 } |
| 1165 | 1157 |
| 1166 ClassLiteralChecker checker(this); | 1158 ClassLiteralChecker checker(this); |
| 1167 bool has_seen_constructor = false; | 1159 bool has_seen_constructor = false; |
| 1168 | 1160 |
| 1169 Expect(Token::LBRACE, CHECK_OK); | 1161 Expect(Token::LBRACE, CHECK_OK); |
| 1170 while (peek() != Token::RBRACE) { | 1162 while (peek() != Token::RBRACE) { |
| 1171 if (Check(Token::SEMICOLON)) continue; | 1163 if (Check(Token::SEMICOLON)) continue; |
| 1172 const bool in_class = true; | 1164 const bool in_class = true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 } | 1210 } |
| 1219 Expect(Token::RBRACE, CHECK_OK); | 1211 Expect(Token::RBRACE, CHECK_OK); |
| 1220 return PreParserExpression::Default(); | 1212 return PreParserExpression::Default(); |
| 1221 } | 1213 } |
| 1222 | 1214 |
| 1223 #undef CHECK_OK | 1215 #undef CHECK_OK |
| 1224 | 1216 |
| 1225 | 1217 |
| 1226 } // namespace internal | 1218 } // namespace internal |
| 1227 } // namespace v8 | 1219 } // namespace v8 |
| OLD | NEW |