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 1757543003: Restrict FunctionDeclarations in Statement position (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: git cl format Created 4 years, 9 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') | test/cctest/test-parsing.cc » ('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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 // EmptyStatement 316 // EmptyStatement
317 // ... 317 // ...
318 318
319 if (peek() == Token::SEMICOLON) { 319 if (peek() == Token::SEMICOLON) {
320 Next(); 320 Next();
321 return Statement::Default(); 321 return Statement::Default();
322 } 322 }
323 return ParseSubStatement(ok); 323 return ParseSubStatement(ok);
324 } 324 }
325 325
326 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
327 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
328 (legacy && allow_harmony_restrictive_declarations())) {
329 return ParseSubStatement(ok);
330 } else {
331 return ParseFunctionDeclaration(CHECK_OK);
332 }
333 }
326 334
327 PreParser::Statement PreParser::ParseSubStatement(bool* ok) { 335 PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
328 // Statement :: 336 // Statement ::
329 // Block 337 // Block
330 // VariableStatement 338 // VariableStatement
331 // EmptyStatement 339 // EmptyStatement
332 // ExpressionStatement 340 // ExpressionStatement
333 // IfStatement 341 // IfStatement
334 // IterationStatement 342 // IterationStatement
335 // ContinueStatement 343 // ContinueStatement
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 398
391 case Token::SWITCH: 399 case Token::SWITCH:
392 return ParseSwitchStatement(ok); 400 return ParseSwitchStatement(ok);
393 401
394 case Token::THROW: 402 case Token::THROW:
395 return ParseThrowStatement(ok); 403 return ParseThrowStatement(ok);
396 404
397 case Token::TRY: 405 case Token::TRY:
398 return ParseTryStatement(ok); 406 return ParseTryStatement(ok);
399 407
400 case Token::FUNCTION: { 408 case Token::FUNCTION:
401 Scanner::Location start_location = scanner()->peek_location(); 409 // FunctionDeclaration only allowed as a StatementListItem, not in
402 Statement statement = ParseFunctionDeclaration(CHECK_OK); 410 // an arbitrary Statement position. Exceptions such as
403 Scanner::Location end_location = scanner()->location(); 411 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
404 if (is_strict(language_mode())) { 412 // are handled by calling ParseScopedStatement rather than
405 PreParserTraits::ReportMessageAt(start_location.beg_pos, 413 // ParseSubStatement directly.
406 end_location.end_pos, 414 ReportMessageAt(scanner()->peek_location(),
407 MessageTemplate::kStrictFunction); 415 is_strict(language_mode())
408 *ok = false; 416 ? MessageTemplate::kStrictFunction
409 return Statement::Default(); 417 : MessageTemplate::kSloppyFunction);
410 } else { 418 *ok = false;
411 return statement; 419 return Statement::Default();
412 }
413 }
414 420
415 case Token::DEBUGGER: 421 case Token::DEBUGGER:
416 return ParseDebuggerStatement(ok); 422 return ParseDebuggerStatement(ok);
417 423
418 case Token::VAR: 424 case Token::VAR:
419 return ParseVariableStatement(kStatement, ok); 425 return ParseVariableStatement(kStatement, ok);
420 426
421 case Token::CONST: 427 case Token::CONST:
422 // In ES6 CONST is not allowed as a Statement, only as a 428 // In ES6 CONST is not allowed as a Statement, only as a
423 // LexicalDeclaration, however we continue to allow it in sloppy mode for 429 // LexicalDeclaration, however we continue to allow it in sloppy mode for
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 // Even if the expression starts with an identifier, it is not necessarily an 697 // Even if the expression starts with an identifier, it is not necessarily an
692 // identifier. For example, "foo + bar" starts with an identifier but is not 698 // identifier. For example, "foo + bar" starts with an identifier but is not
693 // an identifier. 699 // an identifier.
694 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 700 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
695 // Expression is a single identifier, and not, e.g., a parenthesized 701 // Expression is a single identifier, and not, e.g., a parenthesized
696 // identifier. 702 // identifier.
697 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 703 DCHECK(!expr.AsIdentifier().IsFutureReserved());
698 DCHECK(is_sloppy(language_mode()) || 704 DCHECK(is_sloppy(language_mode()) ||
699 !IsFutureStrictReserved(expr.AsIdentifier())); 705 !IsFutureStrictReserved(expr.AsIdentifier()));
700 Consume(Token::COLON); 706 Consume(Token::COLON);
707 // ES#sec-labelled-function-declarations Labelled Function Declarations
708 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
709 return ParseFunctionDeclaration(ok);
710 }
701 Statement statement = ParseStatement(ok); 711 Statement statement = ParseStatement(ok);
702 return statement.IsJumpStatement() ? Statement::Default() : statement; 712 return statement.IsJumpStatement() ? Statement::Default() : statement;
703 // Preparsing is disabled for extensions (because the extension details 713 // Preparsing is disabled for extensions (because the extension details
704 // aren't passed to lazily compiled functions), so we don't 714 // aren't passed to lazily compiled functions), so we don't
705 // accept "native function" in the preparser. 715 // accept "native function" in the preparser.
706 } 716 }
707 // Parsed expression statement. 717 // Parsed expression statement.
708 // Detect attempts at 'let' declarations in sloppy mode. 718 // Detect attempts at 'let' declarations in sloppy mode.
709 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && 719 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
710 is_sloppy(language_mode()) && expr.IsIdentifier() && 720 is_sloppy(language_mode()) && expr.IsIdentifier() &&
711 expr.AsIdentifier().IsLet()) { 721 expr.AsIdentifier().IsLet()) {
712 ReportMessage(MessageTemplate::kSloppyLexical, NULL); 722 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
713 *ok = false; 723 *ok = false;
714 return Statement::Default(); 724 return Statement::Default();
715 } 725 }
716 ExpectSemicolon(CHECK_OK); 726 ExpectSemicolon(CHECK_OK);
717 return Statement::ExpressionStatement(expr); 727 return Statement::ExpressionStatement(expr);
718 } 728 }
719 729
720 730
721 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 731 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
722 // IfStatement :: 732 // IfStatement ::
723 // 'if' '(' Expression ')' Statement ('else' Statement)? 733 // 'if' '(' Expression ')' Statement ('else' Statement)?
724 734
725 Expect(Token::IF, CHECK_OK); 735 Expect(Token::IF, CHECK_OK);
726 Expect(Token::LPAREN, CHECK_OK); 736 Expect(Token::LPAREN, CHECK_OK);
727 ParseExpression(true, CHECK_OK); 737 ParseExpression(true, CHECK_OK);
728 Expect(Token::RPAREN, CHECK_OK); 738 Expect(Token::RPAREN, CHECK_OK);
729 Statement stat = ParseSubStatement(CHECK_OK); 739 Statement stat = ParseScopedStatement(false, CHECK_OK);
730 if (peek() == Token::ELSE) { 740 if (peek() == Token::ELSE) {
731 Next(); 741 Next();
732 Statement else_stat = ParseSubStatement(CHECK_OK); 742 Statement else_stat = ParseScopedStatement(false, CHECK_OK);
733 stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ? 743 stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ?
734 Statement::Jump() : Statement::Default(); 744 Statement::Jump() : Statement::Default();
735 } else { 745 } else {
736 stat = Statement::Default(); 746 stat = Statement::Default();
737 } 747 }
738 return stat; 748 return stat;
739 } 749 }
740 750
741 751
742 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 752 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith); 828 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
819 *ok = false; 829 *ok = false;
820 return Statement::Default(); 830 return Statement::Default();
821 } 831 }
822 Expect(Token::LPAREN, CHECK_OK); 832 Expect(Token::LPAREN, CHECK_OK);
823 ParseExpression(true, CHECK_OK); 833 ParseExpression(true, CHECK_OK);
824 Expect(Token::RPAREN, CHECK_OK); 834 Expect(Token::RPAREN, CHECK_OK);
825 835
826 Scope* with_scope = NewScope(scope_, WITH_SCOPE); 836 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
827 BlockState block_state(&scope_, with_scope); 837 BlockState block_state(&scope_, with_scope);
828 ParseSubStatement(CHECK_OK); 838 ParseScopedStatement(true, CHECK_OK);
829 return Statement::Default(); 839 return Statement::Default();
830 } 840 }
831 841
832 842
833 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 843 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
834 // SwitchStatement :: 844 // SwitchStatement ::
835 // 'switch' '(' Expression ')' '{' CaseClause* '}' 845 // 'switch' '(' Expression ')' '{' CaseClause* '}'
836 846
837 Expect(Token::SWITCH, CHECK_OK); 847 Expect(Token::SWITCH, CHECK_OK);
838 Expect(Token::LPAREN, CHECK_OK); 848 Expect(Token::LPAREN, CHECK_OK);
(...skipping 29 matching lines...) Expand all
868 Expect(Token::RBRACE, ok); 878 Expect(Token::RBRACE, ok);
869 return Statement::Default(); 879 return Statement::Default();
870 } 880 }
871 881
872 882
873 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 883 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
874 // DoStatement :: 884 // DoStatement ::
875 // 'do' Statement 'while' '(' Expression ')' ';' 885 // 'do' Statement 'while' '(' Expression ')' ';'
876 886
877 Expect(Token::DO, CHECK_OK); 887 Expect(Token::DO, CHECK_OK);
878 ParseSubStatement(CHECK_OK); 888 ParseScopedStatement(true, CHECK_OK);
879 Expect(Token::WHILE, CHECK_OK); 889 Expect(Token::WHILE, CHECK_OK);
880 Expect(Token::LPAREN, CHECK_OK); 890 Expect(Token::LPAREN, CHECK_OK);
881 ParseExpression(true, CHECK_OK); 891 ParseExpression(true, CHECK_OK);
882 Expect(Token::RPAREN, ok); 892 Expect(Token::RPAREN, ok);
883 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 893 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
884 return Statement::Default(); 894 return Statement::Default();
885 } 895 }
886 896
887 897
888 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { 898 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
889 // WhileStatement :: 899 // WhileStatement ::
890 // 'while' '(' Expression ')' Statement 900 // 'while' '(' Expression ')' Statement
891 901
892 Expect(Token::WHILE, CHECK_OK); 902 Expect(Token::WHILE, CHECK_OK);
893 Expect(Token::LPAREN, CHECK_OK); 903 Expect(Token::LPAREN, CHECK_OK);
894 ParseExpression(true, CHECK_OK); 904 ParseExpression(true, CHECK_OK);
895 Expect(Token::RPAREN, CHECK_OK); 905 Expect(Token::RPAREN, CHECK_OK);
896 ParseSubStatement(ok); 906 ParseScopedStatement(true, ok);
897 return Statement::Default(); 907 return Statement::Default();
898 } 908 }
899 909
900 910
901 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 911 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
902 // ForStatement :: 912 // ForStatement ::
903 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 913 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
904 914
905 Expect(Token::FOR, CHECK_OK); 915 Expect(Token::FOR, CHECK_OK);
906 Expect(Token::LPAREN, CHECK_OK); 916 Expect(Token::LPAREN, CHECK_OK);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 948
939 if (mode == ForEachStatement::ITERATE) { 949 if (mode == ForEachStatement::ITERATE) {
940 ExpressionClassifier classifier(this); 950 ExpressionClassifier classifier(this);
941 ParseAssignmentExpression(true, &classifier, CHECK_OK); 951 ParseAssignmentExpression(true, &classifier, CHECK_OK);
942 RewriteNonPattern(&classifier, CHECK_OK); 952 RewriteNonPattern(&classifier, CHECK_OK);
943 } else { 953 } else {
944 ParseExpression(true, CHECK_OK); 954 ParseExpression(true, CHECK_OK);
945 } 955 }
946 956
947 Expect(Token::RPAREN, CHECK_OK); 957 Expect(Token::RPAREN, CHECK_OK);
948 ParseSubStatement(CHECK_OK); 958 ParseScopedStatement(true, CHECK_OK);
949 return Statement::Default(); 959 return Statement::Default();
950 } 960 }
951 } else { 961 } else {
952 int lhs_beg_pos = peek_position(); 962 int lhs_beg_pos = peek_position();
953 ExpressionClassifier classifier(this); 963 ExpressionClassifier classifier(this);
954 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); 964 Expression lhs = ParseExpression(false, &classifier, CHECK_OK);
955 int lhs_end_pos = scanner()->location().end_pos; 965 int lhs_end_pos = scanner()->location().end_pos;
956 is_let_identifier_expression = 966 is_let_identifier_expression =
957 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); 967 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
958 bool is_for_each = CheckInOrOf(&mode, ok); 968 bool is_for_each = CheckInOrOf(&mode, ok);
(...skipping 17 matching lines...) Expand all
976 986
977 if (mode == ForEachStatement::ITERATE) { 987 if (mode == ForEachStatement::ITERATE) {
978 ExpressionClassifier classifier(this); 988 ExpressionClassifier classifier(this);
979 ParseAssignmentExpression(true, &classifier, CHECK_OK); 989 ParseAssignmentExpression(true, &classifier, CHECK_OK);
980 RewriteNonPattern(&classifier, CHECK_OK); 990 RewriteNonPattern(&classifier, CHECK_OK);
981 } else { 991 } else {
982 ParseExpression(true, CHECK_OK); 992 ParseExpression(true, CHECK_OK);
983 } 993 }
984 994
985 Expect(Token::RPAREN, CHECK_OK); 995 Expect(Token::RPAREN, CHECK_OK);
986 ParseSubStatement(CHECK_OK); 996 ParseScopedStatement(true, CHECK_OK);
987 return Statement::Default(); 997 return Statement::Default();
988 } 998 }
989 } 999 }
990 } 1000 }
991 1001
992 // Parsed initializer at this point. 1002 // Parsed initializer at this point.
993 // Detect attempts at 'let' declarations in sloppy mode. 1003 // Detect attempts at 'let' declarations in sloppy mode.
994 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && 1004 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
995 is_sloppy(language_mode()) && is_let_identifier_expression) { 1005 is_sloppy(language_mode()) && is_let_identifier_expression) {
996 ReportMessage(MessageTemplate::kSloppyLexical, NULL); 1006 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
997 *ok = false; 1007 *ok = false;
998 return Statement::Default(); 1008 return Statement::Default();
999 } 1009 }
1000 Expect(Token::SEMICOLON, CHECK_OK); 1010 Expect(Token::SEMICOLON, CHECK_OK);
1001 1011
1002 if (peek() != Token::SEMICOLON) { 1012 if (peek() != Token::SEMICOLON) {
1003 ParseExpression(true, CHECK_OK); 1013 ParseExpression(true, CHECK_OK);
1004 } 1014 }
1005 Expect(Token::SEMICOLON, CHECK_OK); 1015 Expect(Token::SEMICOLON, CHECK_OK);
1006 1016
1007 if (peek() != Token::RPAREN) { 1017 if (peek() != Token::RPAREN) {
1008 ParseExpression(true, CHECK_OK); 1018 ParseExpression(true, CHECK_OK);
1009 } 1019 }
1010 Expect(Token::RPAREN, CHECK_OK); 1020 Expect(Token::RPAREN, CHECK_OK);
1011 1021
1012 ParseSubStatement(ok); 1022 ParseScopedStatement(true, ok);
1013 return Statement::Default(); 1023 return Statement::Default();
1014 } 1024 }
1015 1025
1016 1026
1017 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 1027 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
1018 // ThrowStatement :: 1028 // ThrowStatement ::
1019 // 'throw' [no line terminator] Expression ';' 1029 // 'throw' [no line terminator] Expression ';'
1020 1030
1021 Expect(Token::THROW, CHECK_OK); 1031 Expect(Token::THROW, CHECK_OK);
1022 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 1032 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 Expect(Token::RBRACE, CHECK_OK); 1292 Expect(Token::RBRACE, CHECK_OK);
1283 return PreParserExpression::Default(); 1293 return PreParserExpression::Default();
1284 } 1294 }
1285 } 1295 }
1286 1296
1287 #undef CHECK_OK 1297 #undef CHECK_OK
1288 1298
1289 1299
1290 } // namespace internal 1300 } // namespace internal
1291 } // namespace v8 1301 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698