Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Side by Side Diff: src/parsing/preparser.cc

Issue 1928203002: [es8] More spec compliant syntactic tail calls implementation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Some STC tests ported for PTC Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 // reported (underlining). 699 // reported (underlining).
700 Expect(Token::RETURN, CHECK_OK); 700 Expect(Token::RETURN, CHECK_OK);
701 function_state_->set_return_location(scanner()->location()); 701 function_state_->set_return_location(scanner()->location());
702 702
703 // An ECMAScript program is considered syntactically incorrect if it 703 // An ECMAScript program is considered syntactically incorrect if it
704 // contains a return statement that is not within the body of a 704 // contains a return statement that is not within the body of a
705 // function. See ECMA-262, section 12.9, page 67. 705 // function. See ECMA-262, section 12.9, page 67.
706 // This is not handled during preparsing. 706 // This is not handled during preparsing.
707 707
708 Token::Value tok = peek(); 708 Token::Value tok = peek();
709 int tail_call_position = -1;
710 if (FLAG_harmony_explicit_tailcalls && tok == Token::CONTINUE) {
711 Consume(Token::CONTINUE);
712 tail_call_position = position();
713 tok = peek();
714 }
715 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 709 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
716 tok != Token::SEMICOLON && 710 tok != Token::SEMICOLON &&
717 tok != Token::RBRACE && 711 tok != Token::RBRACE &&
718 tok != Token::EOS) { 712 tok != Token::EOS) {
713 // Because of the return code rewriting that happens in case of a subclass
714 // constructor we don't want to accept tail calls, therefore we don't set
715 // ReturnExprScope to kInsideValidReturnStatement here.
716 ReturnExprContext return_expr_context =
717 IsSubclassConstructor(function_state_->kind())
718 ? function_state_->return_expr_context()
719 : ReturnExprContext::kInsideValidReturnStatement;
720
721 ReturnExprScope maybe_allow_tail_calls(function_state_,
722 return_expr_context);
719 ParseExpression(true, CHECK_OK); 723 ParseExpression(true, CHECK_OK);
720 if (tail_call_position >= 0) {
721 ReturnExprContext return_expr_context =
722 function_state_->return_expr_context();
723 if (return_expr_context != ReturnExprContext::kNormal) {
724 ReportIllegalTailCallAt(tail_call_position, return_expr_context);
725 *ok = false;
726 return Statement::Default();
727 }
728 function_state_->AddExpressionInTailPosition(
729 PreParserExpression::Default(), tail_call_position);
730 }
731 } 724 }
732 ExpectSemicolon(CHECK_OK); 725 ExpectSemicolon(CHECK_OK);
733 return Statement::Jump(); 726 return Statement::Jump();
734 } 727 }
735 728
736 729
737 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 730 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
738 // WithStatement :: 731 // WithStatement ::
739 // 'with' '(' Expression ')' Statement 732 // 'with' '(' Expression ')' Statement
740 Expect(Token::WITH, CHECK_OK); 733 Expect(Token::WITH, CHECK_OK);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 ReturnExprContext::kInsideTryBlock); 980 ReturnExprContext::kInsideTryBlock);
988 ParseBlock(CHECK_OK); 981 ParseBlock(CHECK_OK);
989 } 982 }
990 983
991 Token::Value tok = peek(); 984 Token::Value tok = peek();
992 if (tok != Token::CATCH && tok != Token::FINALLY) { 985 if (tok != Token::CATCH && tok != Token::FINALLY) {
993 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); 986 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
994 *ok = false; 987 *ok = false;
995 return Statement::Default(); 988 return Statement::Default();
996 } 989 }
997 List<TailCallExpression> expressions_in_tail_position_in_catch_block; 990 TailCallExpressionList tail_call_expressions_in_catch_block(zone());
998 bool catch_block_exists = false; 991 bool catch_block_exists = false;
999 if (tok == Token::CATCH) { 992 if (tok == Token::CATCH) {
1000 Consume(Token::CATCH); 993 Consume(Token::CATCH);
1001 Expect(Token::LPAREN, CHECK_OK); 994 Expect(Token::LPAREN, CHECK_OK);
1002 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); 995 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
1003 ExpressionClassifier pattern_classifier(this); 996 ExpressionClassifier pattern_classifier(this);
1004 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 997 ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
1005 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 998 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
1006 Expect(Token::RPAREN, CHECK_OK); 999 Expect(Token::RPAREN, CHECK_OK);
1007 { 1000 {
1008 CollectExpressionsInTailPositionToListScope 1001 CollectExpressionsInTailPositionToListScope
1009 collect_expressions_in_tail_position_scope( 1002 collect_tail_call_expressions_scope(
1010 function_state_, &expressions_in_tail_position_in_catch_block); 1003 function_state_, &tail_call_expressions_in_catch_block);
1011 BlockState block_state(&scope_, catch_scope); 1004 BlockState block_state(&scope_, catch_scope);
1012 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 1005 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
1013 { 1006 {
1014 BlockState block_state(&scope_, block_scope); 1007 BlockState block_state(&scope_, block_scope);
1015 ParseBlock(CHECK_OK); 1008 ParseBlock(CHECK_OK);
1016 } 1009 }
1017 } 1010 }
1018 catch_block_exists = true; 1011 catch_block_exists = true;
1019 tok = peek(); 1012 tok = peek();
1020 } 1013 }
1021 if (tok == Token::FINALLY) { 1014 if (tok == Token::FINALLY) {
1022 Consume(Token::FINALLY); 1015 Consume(Token::FINALLY);
1023 ParseBlock(CHECK_OK); 1016 ParseBlock(CHECK_OK);
1024 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && 1017 if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
1025 expressions_in_tail_position_in_catch_block.length() > 0) { 1018 !tail_call_expressions_in_catch_block.is_empty()) {
1026 // TODO(ishell): update chapter number. 1019 // TODO(ishell): update chapter number.
1027 // ES8 XX.YY.ZZ 1020 // ES8 XX.YY.ZZ
1028 int pos = expressions_in_tail_position_in_catch_block[0].pos; 1021 ReportMessageAt(tail_call_expressions_in_catch_block.location(),
1029 ReportMessageAt(Scanner::Location(pos, pos + 1), 1022 MessageTemplate::kUnexpectedTailCallInCatchBlock);
1030 MessageTemplate::kTailCallInCatchBlock);
1031 *ok = false; 1023 *ok = false;
1032 return Statement::Default(); 1024 return Statement::Default();
1033 } 1025 }
1034 } 1026 }
1035 return Statement::Default(); 1027 return Statement::Default();
1036 } 1028 }
1037 1029
1038 1030
1039 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 1031 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
1040 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 1032 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 BlockState block_state(&scope_, scope); 1150 BlockState block_state(&scope_, scope);
1159 scope_->SetLanguageMode( 1151 scope_->SetLanguageMode(
1160 static_cast<LanguageMode>(class_language_mode | STRICT)); 1152 static_cast<LanguageMode>(class_language_mode | STRICT));
1161 // TODO(marja): Make PreParser use scope names too. 1153 // TODO(marja): Make PreParser use scope names too.
1162 // scope_->SetScopeName(name); 1154 // scope_->SetScopeName(name);
1163 1155
1164 bool has_extends = Check(Token::EXTENDS); 1156 bool has_extends = Check(Token::EXTENDS);
1165 if (has_extends) { 1157 if (has_extends) {
1166 ExpressionClassifier extends_classifier(this); 1158 ExpressionClassifier extends_classifier(this);
1167 ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); 1159 ParseLeftHandSideExpression(&extends_classifier, CHECK_OK);
1160 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK);
1168 ValidateExpression(&extends_classifier, CHECK_OK); 1161 ValidateExpression(&extends_classifier, CHECK_OK);
1169 if (classifier != nullptr) { 1162 if (classifier != nullptr) {
1170 classifier->Accumulate(&extends_classifier, 1163 classifier->Accumulate(&extends_classifier,
1171 ExpressionClassifier::ExpressionProductions); 1164 ExpressionClassifier::ExpressionProductions);
1172 } 1165 }
1173 } 1166 }
1174 1167
1175 ClassLiteralChecker checker(this); 1168 ClassLiteralChecker checker(this);
1176 bool has_seen_constructor = false; 1169 bool has_seen_constructor = false;
1177 1170
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1220 }
1228 Expect(Token::RBRACE, CHECK_OK); 1221 Expect(Token::RBRACE, CHECK_OK);
1229 return PreParserExpression::Default(); 1222 return PreParserExpression::Default();
1230 } 1223 }
1231 1224
1232 #undef CHECK_OK 1225 #undef CHECK_OK
1233 1226
1234 1227
1235 } // namespace internal 1228 } // namespace internal
1236 } // namespace v8 1229 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698