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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |