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" |
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 Loading... | |
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 Loading... | |
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 && | |
rossberg
2016/04/26 14:56:57
Same question here, where is the corresponding log
Igor Sheludko
2016/04/26 16:48:17
Implicit tail calls does not produce any errors, t
| |
994 expressions_in_tail_position_in_catch_block.length() > 0) { | |
995 // TODO(ishell): update chapter number. | |
996 // ES7 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 Loading... | |
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 |
OLD | NEW |