| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 return PreParserIdentifier::Static(); | 46 return PreParserIdentifier::Static(); |
| 47 } else if (scanner->current_token() == Token::YIELD) { | 47 } else if (scanner->current_token() == Token::YIELD) { |
| 48 return PreParserIdentifier::Yield(); | 48 return PreParserIdentifier::Yield(); |
| 49 } | 49 } |
| 50 if (scanner->UnescapedLiteralMatches("eval", 4)) { | 50 if (scanner->UnescapedLiteralMatches("eval", 4)) { |
| 51 return PreParserIdentifier::Eval(); | 51 return PreParserIdentifier::Eval(); |
| 52 } | 52 } |
| 53 if (scanner->UnescapedLiteralMatches("arguments", 9)) { | 53 if (scanner->UnescapedLiteralMatches("arguments", 9)) { |
| 54 return PreParserIdentifier::Arguments(); | 54 return PreParserIdentifier::Arguments(); |
| 55 } | 55 } |
| 56 if (scanner->UnescapedLiteralMatches("undefined", 9)) { |
| 57 return PreParserIdentifier::Undefined(); |
| 58 } |
| 56 if (scanner->LiteralMatches("prototype", 9)) { | 59 if (scanner->LiteralMatches("prototype", 9)) { |
| 57 return PreParserIdentifier::Prototype(); | 60 return PreParserIdentifier::Prototype(); |
| 58 } | 61 } |
| 59 if (scanner->LiteralMatches("constructor", 11)) { | 62 if (scanner->LiteralMatches("constructor", 11)) { |
| 60 return PreParserIdentifier::Constructor(); | 63 return PreParserIdentifier::Constructor(); |
| 61 } | 64 } |
| 62 return PreParserIdentifier::Default(); | 65 return PreParserIdentifier::Default(); |
| 63 } | 66 } |
| 64 | 67 |
| 65 | 68 |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 } | 477 } |
| 475 | 478 |
| 476 // The scope of a var/const declared variable anywhere inside a function | 479 // The scope of a var/const declared variable anywhere inside a function |
| 477 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 480 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 478 // of a let declared variable is the scope of the immediately enclosing | 481 // of a let declared variable is the scope of the immediately enclosing |
| 479 // block. | 482 // block. |
| 480 int nvars = 0; // the number of variables declared | 483 int nvars = 0; // the number of variables declared |
| 481 do { | 484 do { |
| 482 // Parse variable name. | 485 // Parse variable name. |
| 483 if (nvars > 0) Consume(Token::COMMA); | 486 if (nvars > 0) Consume(Token::COMMA); |
| 484 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 487 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 485 Scanner::Location variable_loc = scanner()->location(); | 488 Scanner::Location variable_loc = scanner()->location(); |
| 486 nvars++; | 489 nvars++; |
| 487 if (peek() == Token::ASSIGN || require_initializer || | 490 if (peek() == Token::ASSIGN || require_initializer || |
| 488 // require initializers for multiple consts. | 491 // require initializers for multiple consts. |
| 489 (is_strict_const && peek() == Token::COMMA)) { | 492 (is_strict_const && peek() == Token::COMMA)) { |
| 490 Expect(Token::ASSIGN, CHECK_OK); | 493 Expect(Token::ASSIGN, CHECK_OK); |
| 491 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 494 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 492 | 495 |
| 493 variable_loc.end_pos = scanner()->location().end_pos; | 496 variable_loc.end_pos = scanner()->location().end_pos; |
| 494 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 497 if (first_initializer_loc && !first_initializer_loc->IsValid()) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 // ContinueStatement :: | 577 // ContinueStatement :: |
| 575 // 'continue' [no line terminator] Identifier? ';' | 578 // 'continue' [no line terminator] Identifier? ';' |
| 576 | 579 |
| 577 Expect(Token::CONTINUE, CHECK_OK); | 580 Expect(Token::CONTINUE, CHECK_OK); |
| 578 Token::Value tok = peek(); | 581 Token::Value tok = peek(); |
| 579 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 582 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 580 tok != Token::SEMICOLON && | 583 tok != Token::SEMICOLON && |
| 581 tok != Token::RBRACE && | 584 tok != Token::RBRACE && |
| 582 tok != Token::EOS) { | 585 tok != Token::EOS) { |
| 583 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 586 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 584 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 587 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 585 } | 588 } |
| 586 ExpectSemicolon(CHECK_OK); | 589 ExpectSemicolon(CHECK_OK); |
| 587 return Statement::Default(); | 590 return Statement::Default(); |
| 588 } | 591 } |
| 589 | 592 |
| 590 | 593 |
| 591 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 594 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 592 // BreakStatement :: | 595 // BreakStatement :: |
| 593 // 'break' [no line terminator] Identifier? ';' | 596 // 'break' [no line terminator] Identifier? ';' |
| 594 | 597 |
| 595 Expect(Token::BREAK, CHECK_OK); | 598 Expect(Token::BREAK, CHECK_OK); |
| 596 Token::Value tok = peek(); | 599 Token::Value tok = peek(); |
| 597 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 600 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 598 tok != Token::SEMICOLON && | 601 tok != Token::SEMICOLON && |
| 599 tok != Token::RBRACE && | 602 tok != Token::RBRACE && |
| 600 tok != Token::EOS) { | 603 tok != Token::EOS) { |
| 601 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 604 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 602 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 605 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 603 } | 606 } |
| 604 ExpectSemicolon(CHECK_OK); | 607 ExpectSemicolon(CHECK_OK); |
| 605 return Statement::Default(); | 608 return Statement::Default(); |
| 606 } | 609 } |
| 607 | 610 |
| 608 | 611 |
| 609 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 612 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 610 // ReturnStatement :: | 613 // ReturnStatement :: |
| 611 // 'return' [no line terminator] Expression? ';' | 614 // 'return' [no line terminator] Expression? ';' |
| 612 | 615 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 | 835 |
| 833 Token::Value tok = peek(); | 836 Token::Value tok = peek(); |
| 834 if (tok != Token::CATCH && tok != Token::FINALLY) { | 837 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 835 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); | 838 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); |
| 836 *ok = false; | 839 *ok = false; |
| 837 return Statement::Default(); | 840 return Statement::Default(); |
| 838 } | 841 } |
| 839 if (tok == Token::CATCH) { | 842 if (tok == Token::CATCH) { |
| 840 Consume(Token::CATCH); | 843 Consume(Token::CATCH); |
| 841 Expect(Token::LPAREN, CHECK_OK); | 844 Expect(Token::LPAREN, CHECK_OK); |
| 842 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 845 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 843 Expect(Token::RPAREN, CHECK_OK); | 846 Expect(Token::RPAREN, CHECK_OK); |
| 844 { | 847 { |
| 845 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 848 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
| 846 BlockState block_state(&scope_, with_scope); | 849 BlockState block_state(&scope_, with_scope); |
| 847 ParseBlock(CHECK_OK); | 850 ParseBlock(CHECK_OK); |
| 848 } | 851 } |
| 849 tok = peek(); | 852 tok = peek(); |
| 850 } | 853 } |
| 851 if (tok == Token::FINALLY) { | 854 if (tok == Token::FINALLY) { |
| 852 Consume(Token::FINALLY); | 855 Consume(Token::FINALLY); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 Expect(Token::LPAREN, CHECK_OK); | 899 Expect(Token::LPAREN, CHECK_OK); |
| 897 int start_position = position(); | 900 int start_position = position(); |
| 898 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 901 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 899 // We don't yet know if the function will be strict, so we cannot yet produce | 902 // We don't yet know if the function will be strict, so we cannot yet produce |
| 900 // errors for parameter names or duplicates. However, we remember the | 903 // errors for parameter names or duplicates. However, we remember the |
| 901 // locations of these errors if they occur and produce the errors later. | 904 // locations of these errors if they occur and produce the errors later. |
| 902 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 905 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 903 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 906 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 904 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); | 907 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); |
| 905 | 908 |
| 909 // Similarly for strong mode. |
| 910 Scanner::Location undefined_error_loc = Scanner::Location::invalid(); |
| 911 |
| 906 bool is_rest = false; | 912 bool is_rest = false; |
| 907 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || | 913 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 908 (peek() == Token::RPAREN && | 914 (peek() == Token::RPAREN && |
| 909 arity_restriction != FunctionLiteral::SETTER_ARITY); | 915 arity_restriction != FunctionLiteral::SETTER_ARITY); |
| 910 while (!done) { | 916 while (!done) { |
| 911 bool is_strict_reserved = false; | 917 bool is_strict_reserved = false; |
| 912 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); | 918 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); |
| 913 if (is_rest) { | 919 if (is_rest) { |
| 914 Consume(Token::ELLIPSIS); | 920 Consume(Token::ELLIPSIS); |
| 915 } | 921 } |
| 916 | 922 |
| 917 Identifier param_name = | 923 Identifier param_name = |
| 918 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 924 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 919 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { | 925 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { |
| 920 eval_args_error_loc = scanner()->location(); | 926 eval_args_error_loc = scanner()->location(); |
| 921 } | 927 } |
| 928 if (!undefined_error_loc.IsValid() && param_name.IsUndefined()) { |
| 929 undefined_error_loc = scanner()->location(); |
| 930 } |
| 922 if (!reserved_error_loc.IsValid() && is_strict_reserved) { | 931 if (!reserved_error_loc.IsValid() && is_strict_reserved) { |
| 923 reserved_error_loc = scanner()->location(); | 932 reserved_error_loc = scanner()->location(); |
| 924 } | 933 } |
| 925 | 934 |
| 926 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); | 935 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); |
| 927 | 936 |
| 928 if (!dupe_error_loc.IsValid() && prev_value != 0) { | 937 if (!dupe_error_loc.IsValid() && prev_value != 0) { |
| 929 dupe_error_loc = scanner()->location(); | 938 dupe_error_loc = scanner()->location(); |
| 930 } | 939 } |
| 931 | 940 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 955 ParseStatementList(Token::RBRACE, CHECK_OK); | 964 ParseStatementList(Token::RBRACE, CHECK_OK); |
| 956 } | 965 } |
| 957 Expect(Token::RBRACE, CHECK_OK); | 966 Expect(Token::RBRACE, CHECK_OK); |
| 958 | 967 |
| 959 // Validate name and parameter names. We can do this only after parsing the | 968 // Validate name and parameter names. We can do this only after parsing the |
| 960 // function, since the function can declare itself strict. | 969 // function, since the function can declare itself strict. |
| 961 CheckFunctionName(language_mode(), kind, function_name, | 970 CheckFunctionName(language_mode(), kind, function_name, |
| 962 name_is_strict_reserved, function_name_location, CHECK_OK); | 971 name_is_strict_reserved, function_name_location, CHECK_OK); |
| 963 const bool use_strict_params = is_rest || IsConciseMethod(kind); | 972 const bool use_strict_params = is_rest || IsConciseMethod(kind); |
| 964 CheckFunctionParameterNames(language_mode(), use_strict_params, | 973 CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 965 eval_args_error_loc, dupe_error_loc, | 974 eval_args_error_loc, undefined_error_loc, |
| 966 reserved_error_loc, CHECK_OK); | 975 dupe_error_loc, reserved_error_loc, CHECK_OK); |
| 967 | 976 |
| 968 if (is_strict(language_mode())) { | 977 if (is_strict(language_mode())) { |
| 969 int end_position = scanner()->location().end_pos; | 978 int end_position = scanner()->location().end_pos; |
| 970 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); | 979 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); |
| 971 } | 980 } |
| 972 | 981 |
| 973 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 982 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
| 974 if (!function_state.super_call_location().IsValid()) { | 983 if (!function_state.super_call_location().IsValid()) { |
| 975 ReportMessageAt(function_name_location, "strong_super_call_missing", | 984 ReportMessageAt(function_name_location, "strong_super_call_missing", |
| 976 kReferenceError); | 985 kReferenceError); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1005 if (name_is_strict_reserved) { | 1014 if (name_is_strict_reserved) { |
| 1006 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 1015 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
| 1007 *ok = false; | 1016 *ok = false; |
| 1008 return EmptyExpression(); | 1017 return EmptyExpression(); |
| 1009 } | 1018 } |
| 1010 if (IsEvalOrArguments(name)) { | 1019 if (IsEvalOrArguments(name)) { |
| 1011 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 1020 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
| 1012 *ok = false; | 1021 *ok = false; |
| 1013 return EmptyExpression(); | 1022 return EmptyExpression(); |
| 1014 } | 1023 } |
| 1024 LanguageMode class_language_mode = language_mode(); |
| 1025 if (is_strong(class_language_mode) && IsUndefined(name)) { |
| 1026 ReportMessageAt(class_name_location, "strong_undefined"); |
| 1027 *ok = false; |
| 1028 return EmptyExpression(); |
| 1029 } |
| 1015 | 1030 |
| 1016 Scope* scope = NewScope(scope_, BLOCK_SCOPE); | 1031 Scope* scope = NewScope(scope_, BLOCK_SCOPE); |
| 1017 BlockState block_state(&scope_, scope); | 1032 BlockState block_state(&scope_, scope); |
| 1018 scope_->SetLanguageMode( | 1033 scope_->SetLanguageMode( |
| 1019 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT)); | 1034 static_cast<LanguageMode>(class_language_mode | STRICT_BIT)); |
| 1020 // TODO(marja): Make PreParser use scope names too. | 1035 // TODO(marja): Make PreParser use scope names too. |
| 1021 // scope_->SetScopeName(name); | 1036 // scope_->SetScopeName(name); |
| 1022 | 1037 |
| 1023 bool has_extends = Check(Token::EXTENDS); | 1038 bool has_extends = Check(Token::EXTENDS); |
| 1024 if (has_extends) { | 1039 if (has_extends) { |
| 1025 ParseLeftHandSideExpression(CHECK_OK); | 1040 ParseLeftHandSideExpression(CHECK_OK); |
| 1026 } | 1041 } |
| 1027 | 1042 |
| 1028 ClassLiteralChecker checker(this); | 1043 ClassLiteralChecker checker(this); |
| 1029 bool has_seen_constructor = false; | 1044 bool has_seen_constructor = false; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1047 | 1062 |
| 1048 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1063 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
| 1049 // CallRuntime :: | 1064 // CallRuntime :: |
| 1050 // '%' Identifier Arguments | 1065 // '%' Identifier Arguments |
| 1051 Expect(Token::MOD, CHECK_OK); | 1066 Expect(Token::MOD, CHECK_OK); |
| 1052 if (!allow_natives()) { | 1067 if (!allow_natives()) { |
| 1053 *ok = false; | 1068 *ok = false; |
| 1054 return Expression::Default(); | 1069 return Expression::Default(); |
| 1055 } | 1070 } |
| 1056 // Allow "eval" or "arguments" for backward compatibility. | 1071 // Allow "eval" or "arguments" for backward compatibility. |
| 1057 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1072 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 1058 ParseArguments(ok); | 1073 ParseArguments(ok); |
| 1059 | 1074 |
| 1060 return Expression::Default(); | 1075 return Expression::Default(); |
| 1061 } | 1076 } |
| 1062 | 1077 |
| 1063 #undef CHECK_OK | 1078 #undef CHECK_OK |
| 1064 | 1079 |
| 1065 | 1080 |
| 1066 } } // v8::internal | 1081 } } // v8::internal |
| OLD | NEW |