| 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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 // | 175 // |
| 176 // LexicalDeclaration[In, Yield] : | 176 // LexicalDeclaration[In, Yield] : |
| 177 // LetOrConst BindingList[?In, ?Yield] ; | 177 // LetOrConst BindingList[?In, ?Yield] ; |
| 178 | 178 |
| 179 switch (peek()) { | 179 switch (peek()) { |
| 180 case Token::FUNCTION: | 180 case Token::FUNCTION: |
| 181 return ParseFunctionDeclaration(ok); | 181 return ParseFunctionDeclaration(ok); |
| 182 case Token::CLASS: | 182 case Token::CLASS: |
| 183 return ParseClassDeclaration(ok); | 183 return ParseClassDeclaration(ok); |
| 184 case Token::CONST: | 184 case Token::CONST: |
| 185 if (allow_const()) { | 185 return ParseVariableStatement(kStatementListItem, ok); |
| 186 return ParseVariableStatement(kStatementListItem, ok); | |
| 187 } | |
| 188 break; | |
| 189 case Token::LET: | 186 case Token::LET: |
| 190 if (IsNextLetKeyword()) { | 187 if (IsNextLetKeyword()) { |
| 191 return ParseVariableStatement(kStatementListItem, ok); | 188 return ParseVariableStatement(kStatementListItem, ok); |
| 192 } | 189 } |
| 193 break; | 190 break; |
| 194 default: | 191 default: |
| 195 break; | 192 break; |
| 196 } | 193 } |
| 197 return ParseStatement(kAllowLabelledFunctionStatement, ok); | 194 return ParseStatement(kAllowLabelledFunctionStatement, ok); |
| 198 } | 195 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 is_generator ? FunctionKind::kGeneratorFunction | 393 is_generator ? FunctionKind::kGeneratorFunction |
| 397 : FunctionKind::kNormalFunction, | 394 : FunctionKind::kNormalFunction, |
| 398 pos, FunctionLiteral::kDeclaration, language_mode(), | 395 pos, FunctionLiteral::kDeclaration, language_mode(), |
| 399 CHECK_OK); | 396 CHECK_OK); |
| 400 return Statement::FunctionDeclaration(); | 397 return Statement::FunctionDeclaration(); |
| 401 } | 398 } |
| 402 | 399 |
| 403 | 400 |
| 404 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { | 401 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { |
| 405 Expect(Token::CLASS, CHECK_OK); | 402 Expect(Token::CLASS, CHECK_OK); |
| 406 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | |
| 407 ReportMessage(MessageTemplate::kSloppyLexical); | |
| 408 *ok = false; | |
| 409 return Statement::Default(); | |
| 410 } | |
| 411 | 403 |
| 412 int pos = position(); | 404 int pos = position(); |
| 413 bool is_strict_reserved = false; | 405 bool is_strict_reserved = false; |
| 414 Identifier name = | 406 Identifier name = |
| 415 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 407 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 416 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, | 408 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, |
| 417 CHECK_OK); | 409 CHECK_OK); |
| 418 return Statement::Default(); | 410 return Statement::Default(); |
| 419 } | 411 } |
| 420 | 412 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 // Identifier '=' AssignmentExpression | 458 // Identifier '=' AssignmentExpression |
| 467 // | 459 // |
| 468 // TODO(ES6): | 460 // TODO(ES6): |
| 469 // ConstBinding :: | 461 // ConstBinding :: |
| 470 // BindingPattern '=' AssignmentExpression | 462 // BindingPattern '=' AssignmentExpression |
| 471 bool require_initializer = false; | 463 bool require_initializer = false; |
| 472 bool lexical = false; | 464 bool lexical = false; |
| 473 bool is_pattern = false; | 465 bool is_pattern = false; |
| 474 if (peek() == Token::VAR) { | 466 if (peek() == Token::VAR) { |
| 475 Consume(Token::VAR); | 467 Consume(Token::VAR); |
| 476 } else if (peek() == Token::CONST && allow_const()) { | 468 } else if (peek() == Token::CONST) { |
| 477 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: | 469 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
| 478 // | 470 // |
| 479 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 471 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 480 // | 472 // |
| 481 // * It is a Syntax Error if the code that matches this production is not | 473 // * It is a Syntax Error if the code that matches this production is not |
| 482 // contained in extended code. | 474 // contained in extended code. |
| 483 // | 475 // |
| 484 // However disallowing const in sloppy mode will break compatibility with | 476 // However disallowing const in sloppy mode will break compatibility with |
| 485 // existing pages. Therefore we keep allowing const with the old | 477 // existing pages. Therefore we keep allowing const with the old |
| 486 // non-harmony semantics in sloppy mode. | 478 // non-harmony semantics in sloppy mode. |
| 487 Consume(Token::CONST); | 479 Consume(Token::CONST); |
| 488 if (is_strict(language_mode()) || allow_harmony_sloppy()) { | 480 DCHECK(var_context != kStatement); |
| 489 DCHECK(var_context != kStatement); | 481 require_initializer = true; |
| 490 require_initializer = true; | 482 lexical = true; |
| 491 lexical = true; | 483 } else if (peek() == Token::LET) { |
| 492 } | |
| 493 } else if (peek() == Token::LET && allow_let()) { | |
| 494 Consume(Token::LET); | 484 Consume(Token::LET); |
| 495 DCHECK(var_context != kStatement); | 485 DCHECK(var_context != kStatement); |
| 496 lexical = true; | 486 lexical = true; |
| 497 } else { | 487 } else { |
| 498 *ok = false; | 488 *ok = false; |
| 499 return Statement::Default(); | 489 return Statement::Default(); |
| 500 } | 490 } |
| 501 | 491 |
| 502 // The scope of a var/const declared variable anywhere inside a function | 492 // The scope of a var/const declared variable anywhere inside a function |
| 503 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 493 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 } | 589 } |
| 600 } | 590 } |
| 601 Statement statement = | 591 Statement statement = |
| 602 ParseStatement(kDisallowLabelledFunctionStatement, ok); | 592 ParseStatement(kDisallowLabelledFunctionStatement, ok); |
| 603 return statement.IsJumpStatement() ? Statement::Default() : statement; | 593 return statement.IsJumpStatement() ? Statement::Default() : statement; |
| 604 // Preparsing is disabled for extensions (because the extension details | 594 // Preparsing is disabled for extensions (because the extension details |
| 605 // aren't passed to lazily compiled functions), so we don't | 595 // aren't passed to lazily compiled functions), so we don't |
| 606 // accept "native function" in the preparser. | 596 // accept "native function" in the preparser. |
| 607 } | 597 } |
| 608 // Parsed expression statement. | 598 // Parsed expression statement. |
| 609 // Detect attempts at 'let' declarations in sloppy mode. | |
| 610 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && | |
| 611 is_sloppy(language_mode()) && expr.IsIdentifier() && | |
| 612 expr.AsIdentifier().IsLet()) { | |
| 613 ReportMessage(MessageTemplate::kSloppyLexical, NULL); | |
| 614 *ok = false; | |
| 615 return Statement::Default(); | |
| 616 } | |
| 617 ExpectSemicolon(CHECK_OK); | 599 ExpectSemicolon(CHECK_OK); |
| 618 return Statement::ExpressionStatement(expr); | 600 return Statement::ExpressionStatement(expr); |
| 619 } | 601 } |
| 620 | 602 |
| 621 | 603 |
| 622 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 604 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
| 623 // IfStatement :: | 605 // IfStatement :: |
| 624 // 'if' '(' Expression ')' Statement ('else' Statement)? | 606 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 625 | 607 |
| 626 Expect(Token::IF, CHECK_OK); | 608 Expect(Token::IF, CHECK_OK); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 return Statement::Default(); | 765 return Statement::Default(); |
| 784 } | 766 } |
| 785 | 767 |
| 786 | 768 |
| 787 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 769 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 788 // ForStatement :: | 770 // ForStatement :: |
| 789 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 771 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 790 | 772 |
| 791 Expect(Token::FOR, CHECK_OK); | 773 Expect(Token::FOR, CHECK_OK); |
| 792 Expect(Token::LPAREN, CHECK_OK); | 774 Expect(Token::LPAREN, CHECK_OK); |
| 793 bool is_let_identifier_expression = false; | |
| 794 if (peek() != Token::SEMICOLON) { | 775 if (peek() != Token::SEMICOLON) { |
| 795 ForEachStatement::VisitMode mode; | 776 ForEachStatement::VisitMode mode; |
| 796 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || | 777 if (peek() == Token::VAR || peek() == Token::CONST || |
| 797 (peek() == Token::LET && IsNextLetKeyword())) { | 778 (peek() == Token::LET && IsNextLetKeyword())) { |
| 798 int decl_count; | 779 int decl_count; |
| 799 bool is_lexical; | 780 bool is_lexical; |
| 800 bool is_binding_pattern; | 781 bool is_binding_pattern; |
| 801 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); | 782 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); |
| 802 Scanner::Location bindings_loc = Scanner::Location::invalid(); | 783 Scanner::Location bindings_loc = Scanner::Location::invalid(); |
| 803 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, | 784 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, |
| 804 &is_binding_pattern, &first_initializer_loc, | 785 &is_binding_pattern, &first_initializer_loc, |
| 805 &bindings_loc, CHECK_OK); | 786 &bindings_loc, CHECK_OK); |
| 806 if (CheckInOrOf(&mode, ok)) { | 787 if (CheckInOrOf(&mode, ok)) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 832 | 813 |
| 833 Expect(Token::RPAREN, CHECK_OK); | 814 Expect(Token::RPAREN, CHECK_OK); |
| 834 ParseScopedStatement(true, CHECK_OK); | 815 ParseScopedStatement(true, CHECK_OK); |
| 835 return Statement::Default(); | 816 return Statement::Default(); |
| 836 } | 817 } |
| 837 } else { | 818 } else { |
| 838 int lhs_beg_pos = peek_position(); | 819 int lhs_beg_pos = peek_position(); |
| 839 ExpressionClassifier classifier(this); | 820 ExpressionClassifier classifier(this); |
| 840 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); | 821 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); |
| 841 int lhs_end_pos = scanner()->location().end_pos; | 822 int lhs_end_pos = scanner()->location().end_pos; |
| 842 is_let_identifier_expression = | |
| 843 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); | |
| 844 bool is_for_each = CheckInOrOf(&mode, ok); | 823 bool is_for_each = CheckInOrOf(&mode, ok); |
| 845 if (!*ok) return Statement::Default(); | 824 if (!*ok) return Statement::Default(); |
| 846 bool is_destructuring = is_for_each && | 825 bool is_destructuring = is_for_each && |
| 847 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); | 826 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); |
| 848 | 827 |
| 849 if (is_destructuring) { | 828 if (is_destructuring) { |
| 850 ValidateAssignmentPattern(&classifier, CHECK_OK); | 829 ValidateAssignmentPattern(&classifier, CHECK_OK); |
| 851 } else { | 830 } else { |
| 852 ValidateExpression(&classifier, CHECK_OK); | 831 ValidateExpression(&classifier, CHECK_OK); |
| 853 } | 832 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 868 } | 847 } |
| 869 | 848 |
| 870 Expect(Token::RPAREN, CHECK_OK); | 849 Expect(Token::RPAREN, CHECK_OK); |
| 871 ParseScopedStatement(true, CHECK_OK); | 850 ParseScopedStatement(true, CHECK_OK); |
| 872 return Statement::Default(); | 851 return Statement::Default(); |
| 873 } | 852 } |
| 874 } | 853 } |
| 875 } | 854 } |
| 876 | 855 |
| 877 // Parsed initializer at this point. | 856 // Parsed initializer at this point. |
| 878 // Detect attempts at 'let' declarations in sloppy mode. | |
| 879 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER && | |
| 880 is_sloppy(language_mode()) && is_let_identifier_expression) { | |
| 881 ReportMessage(MessageTemplate::kSloppyLexical, NULL); | |
| 882 *ok = false; | |
| 883 return Statement::Default(); | |
| 884 } | |
| 885 Expect(Token::SEMICOLON, CHECK_OK); | 857 Expect(Token::SEMICOLON, CHECK_OK); |
| 886 | 858 |
| 887 if (peek() != Token::SEMICOLON) { | 859 if (peek() != Token::SEMICOLON) { |
| 888 ParseExpression(true, CHECK_OK); | 860 ParseExpression(true, CHECK_OK); |
| 889 } | 861 } |
| 890 Expect(Token::SEMICOLON, CHECK_OK); | 862 Expect(Token::SEMICOLON, CHECK_OK); |
| 891 | 863 |
| 892 if (peek() != Token::RPAREN) { | 864 if (peek() != Token::RPAREN) { |
| 893 ParseExpression(true, CHECK_OK); | 865 ParseExpression(true, CHECK_OK); |
| 894 } | 866 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 Expect(Token::RBRACE, CHECK_OK); | 1124 Expect(Token::RBRACE, CHECK_OK); |
| 1153 return PreParserExpression::Default(); | 1125 return PreParserExpression::Default(); |
| 1154 } | 1126 } |
| 1155 } | 1127 } |
| 1156 | 1128 |
| 1157 #undef CHECK_OK | 1129 #undef CHECK_OK |
| 1158 | 1130 |
| 1159 | 1131 |
| 1160 } // namespace internal | 1132 } // namespace internal |
| 1161 } // namespace v8 | 1133 } // namespace v8 |
| OLD | NEW |