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

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

Issue 1917993004: [es8] Initial set of changes to support syntactic tail calls. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressing comments 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/parser-base.h ('k') | test/message/syntactic-tail-call-in-try.js » ('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"
11 #include "src/globals.h" 11 #include "src/globals.h"
12 #include "src/hashmap.h" 12 #include "src/hashmap.h"
13 #include "src/list.h" 13 #include "src/list.h"
14 #include "src/parsing/parser-base.h" 14 #include "src/parsing/parser-base.h"
15 #include "src/parsing/preparse-data-format.h"
15 #include "src/parsing/preparse-data.h" 16 #include "src/parsing/preparse-data.h"
16 #include "src/parsing/preparse-data-format.h"
17 #include "src/parsing/preparser.h" 17 #include "src/parsing/preparser.h"
18 #include "src/unicode.h" 18 #include "src/unicode.h"
19 #include "src/utils.h" 19 #include "src/utils.h"
20 20
21 namespace v8 { 21 namespace v8 {
22 namespace internal { 22 namespace internal {
23 23
24 void PreParserTraits::ReportMessageAt(Scanner::Location location, 24 void PreParserTraits::ReportMessageAt(Scanner::Location location,
25 MessageTemplate::Template message, 25 MessageTemplate::Template message,
26 const char* arg, 26 const char* arg,
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // reported (underlining). 674 // reported (underlining).
675 Expect(Token::RETURN, CHECK_OK); 675 Expect(Token::RETURN, CHECK_OK);
676 function_state_->set_return_location(scanner()->location()); 676 function_state_->set_return_location(scanner()->location());
677 677
678 // An ECMAScript program is considered syntactically incorrect if it 678 // An ECMAScript program is considered syntactically incorrect if it
679 // contains a return statement that is not within the body of a 679 // contains a return statement that is not within the body of a
680 // function. See ECMA-262, section 12.9, page 67. 680 // function. See ECMA-262, section 12.9, page 67.
681 // This is not handled during preparsing. 681 // This is not handled during preparsing.
682 682
683 Token::Value tok = peek(); 683 Token::Value tok = peek();
684 int tail_call_position = -1;
685 if (FLAG_harmony_explicit_tailcalls && tok == Token::CONTINUE) {
686 Consume(Token::CONTINUE);
687 tail_call_position = position();
688 tok = peek();
689 }
684 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 690 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
685 tok != Token::SEMICOLON && 691 tok != Token::SEMICOLON &&
686 tok != Token::RBRACE && 692 tok != Token::RBRACE &&
687 tok != Token::EOS) { 693 tok != Token::EOS) {
688 ParseExpression(true, CHECK_OK); 694 ParseExpression(true, CHECK_OK);
695 if (tail_call_position >= 0) {
696 if (!function_state_->collect_expressions_in_tail_position()) {
697 Scanner::Location loc(tail_call_position, tail_call_position + 1);
698 ReportMessageAt(loc, MessageTemplate::kTailCallInTryBlock);
699 *ok = false;
700 return Statement::Default();
701 }
702 function_state_->AddExpressionInTailPosition(
703 PreParserExpression::Default(), tail_call_position);
704 }
689 } 705 }
690 ExpectSemicolon(CHECK_OK); 706 ExpectSemicolon(CHECK_OK);
691 return Statement::Jump(); 707 return Statement::Jump();
692 } 708 }
693 709
694 710
695 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 711 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
696 // WithStatement :: 712 // WithStatement ::
697 // 'with' '(' Expression ')' Statement 713 // 'with' '(' Expression ')' Statement
698 Expect(Token::WITH, CHECK_OK); 714 Expect(Token::WITH, CHECK_OK);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 // 'try' Block Catch Finally 945 // 'try' Block Catch Finally
930 // 946 //
931 // Catch :: 947 // Catch ::
932 // 'catch' '(' Identifier ')' Block 948 // 'catch' '(' Identifier ')' Block
933 // 949 //
934 // Finally :: 950 // Finally ::
935 // 'finally' Block 951 // 'finally' Block
936 952
937 Expect(Token::TRY, CHECK_OK); 953 Expect(Token::TRY, CHECK_OK);
938 954
939 ParseBlock(CHECK_OK); 955 {
956 DontCollectExpressionsInTailPositionScope no_tail_calls(function_state_);
957 ParseBlock(CHECK_OK);
958 }
940 959
941 Token::Value tok = peek(); 960 Token::Value tok = peek();
942 if (tok != Token::CATCH && tok != Token::FINALLY) { 961 if (tok != Token::CATCH && tok != Token::FINALLY) {
943 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); 962 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally);
944 *ok = false; 963 *ok = false;
945 return Statement::Default(); 964 return Statement::Default();
946 } 965 }
966 List<TailCallExpression> expressions_in_tail_position_in_catch_block;
967 bool catch_block_exists = false;
947 if (tok == Token::CATCH) { 968 if (tok == Token::CATCH) {
948 Consume(Token::CATCH); 969 Consume(Token::CATCH);
949 Expect(Token::LPAREN, CHECK_OK); 970 Expect(Token::LPAREN, CHECK_OK);
950 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); 971 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE);
951 ExpressionClassifier pattern_classifier(this); 972 ExpressionClassifier pattern_classifier(this);
952 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 973 ParsePrimaryExpression(&pattern_classifier, CHECK_OK);
953 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 974 ValidateBindingPattern(&pattern_classifier, CHECK_OK);
954 Expect(Token::RPAREN, CHECK_OK); 975 Expect(Token::RPAREN, CHECK_OK);
955 { 976 {
977 CollectExpressionsInTailPositionToListScope
978 collect_expressions_in_tail_position_scope(
979 function_state_, &expressions_in_tail_position_in_catch_block);
956 BlockState block_state(&scope_, catch_scope); 980 BlockState block_state(&scope_, catch_scope);
957 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 981 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
958 { 982 {
959 BlockState block_state(&scope_, block_scope); 983 BlockState block_state(&scope_, block_scope);
960 ParseBlock(CHECK_OK); 984 ParseBlock(CHECK_OK);
961 } 985 }
962 } 986 }
987 catch_block_exists = true;
963 tok = peek(); 988 tok = peek();
964 } 989 }
965 if (tok == Token::FINALLY) { 990 if (tok == Token::FINALLY) {
966 Consume(Token::FINALLY); 991 Consume(Token::FINALLY);
967 ParseBlock(CHECK_OK); 992 ParseBlock(CHECK_OK);
993 if (FLAG_harmony_explicit_tailcalls && catch_block_exists &&
994 expressions_in_tail_position_in_catch_block.length() > 0) {
995 // TODO(ishell): update chapter number.
996 // ES8 XX.YY.ZZ
997 int pos = expressions_in_tail_position_in_catch_block[0].pos;
998 ReportMessageAt(Scanner::Location(pos, pos + 1),
999 MessageTemplate::kTailCallInCatchBlock);
1000 *ok = false;
1001 return Statement::Default();
1002 }
968 } 1003 }
969 return Statement::Default(); 1004 return Statement::Default();
970 } 1005 }
971 1006
972 1007
973 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 1008 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
974 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 1009 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
975 // contexts this is used as a statement which invokes the debugger as if a 1010 // contexts this is used as a statement which invokes the debugger as if a
976 // break point is present. 1011 // break point is present.
977 // DebuggerStatement :: 1012 // DebuggerStatement ::
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 } 1192 }
1158 Expect(Token::RBRACE, CHECK_OK); 1193 Expect(Token::RBRACE, CHECK_OK);
1159 return PreParserExpression::Default(); 1194 return PreParserExpression::Default();
1160 } 1195 }
1161 1196
1162 #undef CHECK_OK 1197 #undef CHECK_OK
1163 1198
1164 1199
1165 } // namespace internal 1200 } // namespace internal
1166 } // namespace v8 1201 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser-base.h ('k') | test/message/syntactic-tail-call-in-try.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698