| 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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 | 479 |
| 477 // The scope of a var/const declared variable anywhere inside a function | 480 // The scope of a var/const declared variable anywhere inside a function |
| 478 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 481 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 479 // of a let declared variable is the scope of the immediately enclosing | 482 // of a let declared variable is the scope of the immediately enclosing |
| 480 // block. | 483 // block. |
| 481 int nvars = 0; // the number of variables declared | 484 int nvars = 0; // the number of variables declared |
| 482 int bindings_start = peek_position(); | 485 int bindings_start = peek_position(); |
| 483 do { | 486 do { |
| 484 // Parse variable name. | 487 // Parse variable name. |
| 485 if (nvars > 0) Consume(Token::COMMA); | 488 if (nvars > 0) Consume(Token::COMMA); |
| 486 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 489 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 487 Scanner::Location variable_loc = scanner()->location(); | 490 Scanner::Location variable_loc = scanner()->location(); |
| 488 nvars++; | 491 nvars++; |
| 489 if (peek() == Token::ASSIGN || require_initializer || | 492 if (peek() == Token::ASSIGN || require_initializer || |
| 490 // require initializers for multiple consts. | 493 // require initializers for multiple consts. |
| 491 (is_strict_const && peek() == Token::COMMA)) { | 494 (is_strict_const && peek() == Token::COMMA)) { |
| 492 Expect(Token::ASSIGN, CHECK_OK); | 495 Expect(Token::ASSIGN, CHECK_OK); |
| 493 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 496 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 494 | 497 |
| 495 variable_loc.end_pos = scanner()->location().end_pos; | 498 variable_loc.end_pos = scanner()->location().end_pos; |
| 496 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 499 if (first_initializer_loc && !first_initializer_loc->IsValid()) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 // ContinueStatement :: | 584 // ContinueStatement :: |
| 582 // 'continue' [no line terminator] Identifier? ';' | 585 // 'continue' [no line terminator] Identifier? ';' |
| 583 | 586 |
| 584 Expect(Token::CONTINUE, CHECK_OK); | 587 Expect(Token::CONTINUE, CHECK_OK); |
| 585 Token::Value tok = peek(); | 588 Token::Value tok = peek(); |
| 586 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 589 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 587 tok != Token::SEMICOLON && | 590 tok != Token::SEMICOLON && |
| 588 tok != Token::RBRACE && | 591 tok != Token::RBRACE && |
| 589 tok != Token::EOS) { | 592 tok != Token::EOS) { |
| 590 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 593 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 591 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 594 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 592 } | 595 } |
| 593 ExpectSemicolon(CHECK_OK); | 596 ExpectSemicolon(CHECK_OK); |
| 594 return Statement::Default(); | 597 return Statement::Default(); |
| 595 } | 598 } |
| 596 | 599 |
| 597 | 600 |
| 598 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 601 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 599 // BreakStatement :: | 602 // BreakStatement :: |
| 600 // 'break' [no line terminator] Identifier? ';' | 603 // 'break' [no line terminator] Identifier? ';' |
| 601 | 604 |
| 602 Expect(Token::BREAK, CHECK_OK); | 605 Expect(Token::BREAK, CHECK_OK); |
| 603 Token::Value tok = peek(); | 606 Token::Value tok = peek(); |
| 604 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 607 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 605 tok != Token::SEMICOLON && | 608 tok != Token::SEMICOLON && |
| 606 tok != Token::RBRACE && | 609 tok != Token::RBRACE && |
| 607 tok != Token::EOS) { | 610 tok != Token::EOS) { |
| 608 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 611 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 609 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 612 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 610 } | 613 } |
| 611 ExpectSemicolon(CHECK_OK); | 614 ExpectSemicolon(CHECK_OK); |
| 612 return Statement::Default(); | 615 return Statement::Default(); |
| 613 } | 616 } |
| 614 | 617 |
| 615 | 618 |
| 616 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 619 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 617 // ReturnStatement :: | 620 // ReturnStatement :: |
| 618 // 'return' [no line terminator] Expression? ';' | 621 // 'return' [no line terminator] Expression? ';' |
| 619 | 622 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 | 849 |
| 847 Token::Value tok = peek(); | 850 Token::Value tok = peek(); |
| 848 if (tok != Token::CATCH && tok != Token::FINALLY) { | 851 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 849 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); | 852 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); |
| 850 *ok = false; | 853 *ok = false; |
| 851 return Statement::Default(); | 854 return Statement::Default(); |
| 852 } | 855 } |
| 853 if (tok == Token::CATCH) { | 856 if (tok == Token::CATCH) { |
| 854 Consume(Token::CATCH); | 857 Consume(Token::CATCH); |
| 855 Expect(Token::LPAREN, CHECK_OK); | 858 Expect(Token::LPAREN, CHECK_OK); |
| 856 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 859 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); |
| 857 Expect(Token::RPAREN, CHECK_OK); | 860 Expect(Token::RPAREN, CHECK_OK); |
| 858 { | 861 { |
| 859 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 862 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
| 860 BlockState block_state(&scope_, with_scope); | 863 BlockState block_state(&scope_, with_scope); |
| 861 ParseBlock(CHECK_OK); | 864 ParseBlock(CHECK_OK); |
| 862 } | 865 } |
| 863 tok = peek(); | 866 tok = peek(); |
| 864 } | 867 } |
| 865 if (tok == Token::FINALLY) { | 868 if (tok == Token::FINALLY) { |
| 866 Consume(Token::FINALLY); | 869 Consume(Token::FINALLY); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 Expect(Token::LPAREN, CHECK_OK); | 913 Expect(Token::LPAREN, CHECK_OK); |
| 911 int start_position = position(); | 914 int start_position = position(); |
| 912 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 915 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 913 // We don't yet know if the function will be strict, so we cannot yet produce | 916 // We don't yet know if the function will be strict, so we cannot yet produce |
| 914 // errors for parameter names or duplicates. However, we remember the | 917 // errors for parameter names or duplicates. However, we remember the |
| 915 // locations of these errors if they occur and produce the errors later. | 918 // locations of these errors if they occur and produce the errors later. |
| 916 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 919 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 917 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 920 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 918 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); | 921 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); |
| 919 | 922 |
| 923 // Similarly for strong mode. |
| 924 Scanner::Location undefined_error_loc = Scanner::Location::invalid(); |
| 925 |
| 920 bool is_rest = false; | 926 bool is_rest = false; |
| 921 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || | 927 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 922 (peek() == Token::RPAREN && | 928 (peek() == Token::RPAREN && |
| 923 arity_restriction != FunctionLiteral::SETTER_ARITY); | 929 arity_restriction != FunctionLiteral::SETTER_ARITY); |
| 924 while (!done) { | 930 while (!done) { |
| 925 bool is_strict_reserved = false; | 931 bool is_strict_reserved = false; |
| 926 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); | 932 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); |
| 927 if (is_rest) { | 933 if (is_rest) { |
| 928 Consume(Token::ELLIPSIS); | 934 Consume(Token::ELLIPSIS); |
| 929 } | 935 } |
| 930 | 936 |
| 931 Identifier param_name = | 937 Identifier param_name = |
| 932 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 938 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 933 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { | 939 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { |
| 934 eval_args_error_loc = scanner()->location(); | 940 eval_args_error_loc = scanner()->location(); |
| 935 } | 941 } |
| 942 if (!undefined_error_loc.IsValid() && param_name.IsUndefined()) { |
| 943 undefined_error_loc = scanner()->location(); |
| 944 } |
| 936 if (!reserved_error_loc.IsValid() && is_strict_reserved) { | 945 if (!reserved_error_loc.IsValid() && is_strict_reserved) { |
| 937 reserved_error_loc = scanner()->location(); | 946 reserved_error_loc = scanner()->location(); |
| 938 } | 947 } |
| 939 | 948 |
| 940 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); | 949 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); |
| 941 | 950 |
| 942 if (!dupe_error_loc.IsValid() && prev_value != 0) { | 951 if (!dupe_error_loc.IsValid() && prev_value != 0) { |
| 943 dupe_error_loc = scanner()->location(); | 952 dupe_error_loc = scanner()->location(); |
| 944 } | 953 } |
| 945 | 954 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 969 ParseStatementList(Token::RBRACE, CHECK_OK); | 978 ParseStatementList(Token::RBRACE, CHECK_OK); |
| 970 } | 979 } |
| 971 Expect(Token::RBRACE, CHECK_OK); | 980 Expect(Token::RBRACE, CHECK_OK); |
| 972 | 981 |
| 973 // Validate name and parameter names. We can do this only after parsing the | 982 // Validate name and parameter names. We can do this only after parsing the |
| 974 // function, since the function can declare itself strict. | 983 // function, since the function can declare itself strict. |
| 975 CheckFunctionName(language_mode(), kind, function_name, | 984 CheckFunctionName(language_mode(), kind, function_name, |
| 976 name_is_strict_reserved, function_name_location, CHECK_OK); | 985 name_is_strict_reserved, function_name_location, CHECK_OK); |
| 977 const bool use_strict_params = is_rest || IsConciseMethod(kind); | 986 const bool use_strict_params = is_rest || IsConciseMethod(kind); |
| 978 CheckFunctionParameterNames(language_mode(), use_strict_params, | 987 CheckFunctionParameterNames(language_mode(), use_strict_params, |
| 979 eval_args_error_loc, dupe_error_loc, | 988 eval_args_error_loc, undefined_error_loc, |
| 980 reserved_error_loc, CHECK_OK); | 989 dupe_error_loc, reserved_error_loc, CHECK_OK); |
| 981 | 990 |
| 982 if (is_strict(language_mode())) { | 991 if (is_strict(language_mode())) { |
| 983 int end_position = scanner()->location().end_pos; | 992 int end_position = scanner()->location().end_pos; |
| 984 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); | 993 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); |
| 985 } | 994 } |
| 986 | 995 |
| 987 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 996 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
| 988 if (!function_state.super_call_location().IsValid()) { | 997 if (!function_state.super_call_location().IsValid()) { |
| 989 ReportMessageAt(function_name_location, "strong_super_call_missing", | 998 ReportMessageAt(function_name_location, "strong_super_call_missing", |
| 990 kReferenceError); | 999 kReferenceError); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1019 if (name_is_strict_reserved) { | 1028 if (name_is_strict_reserved) { |
| 1020 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 1029 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
| 1021 *ok = false; | 1030 *ok = false; |
| 1022 return EmptyExpression(); | 1031 return EmptyExpression(); |
| 1023 } | 1032 } |
| 1024 if (IsEvalOrArguments(name)) { | 1033 if (IsEvalOrArguments(name)) { |
| 1025 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 1034 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
| 1026 *ok = false; | 1035 *ok = false; |
| 1027 return EmptyExpression(); | 1036 return EmptyExpression(); |
| 1028 } | 1037 } |
| 1038 LanguageMode class_language_mode = language_mode(); |
| 1039 if (is_strong(class_language_mode) && IsUndefined(name)) { |
| 1040 ReportMessageAt(class_name_location, "strong_undefined"); |
| 1041 *ok = false; |
| 1042 return EmptyExpression(); |
| 1043 } |
| 1029 | 1044 |
| 1030 Scope* scope = NewScope(scope_, BLOCK_SCOPE); | 1045 Scope* scope = NewScope(scope_, BLOCK_SCOPE); |
| 1031 BlockState block_state(&scope_, scope); | 1046 BlockState block_state(&scope_, scope); |
| 1032 scope_->SetLanguageMode( | 1047 scope_->SetLanguageMode( |
| 1033 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT)); | 1048 static_cast<LanguageMode>(class_language_mode | STRICT_BIT)); |
| 1034 // TODO(marja): Make PreParser use scope names too. | 1049 // TODO(marja): Make PreParser use scope names too. |
| 1035 // scope_->SetScopeName(name); | 1050 // scope_->SetScopeName(name); |
| 1036 | 1051 |
| 1037 bool has_extends = Check(Token::EXTENDS); | 1052 bool has_extends = Check(Token::EXTENDS); |
| 1038 if (has_extends) { | 1053 if (has_extends) { |
| 1039 ParseLeftHandSideExpression(CHECK_OK); | 1054 ParseLeftHandSideExpression(CHECK_OK); |
| 1040 } | 1055 } |
| 1041 | 1056 |
| 1042 ClassLiteralChecker checker(this); | 1057 ClassLiteralChecker checker(this); |
| 1043 bool has_seen_constructor = false; | 1058 bool has_seen_constructor = false; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1061 | 1076 |
| 1062 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1077 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
| 1063 // CallRuntime :: | 1078 // CallRuntime :: |
| 1064 // '%' Identifier Arguments | 1079 // '%' Identifier Arguments |
| 1065 Expect(Token::MOD, CHECK_OK); | 1080 Expect(Token::MOD, CHECK_OK); |
| 1066 if (!allow_natives()) { | 1081 if (!allow_natives()) { |
| 1067 *ok = false; | 1082 *ok = false; |
| 1068 return Expression::Default(); | 1083 return Expression::Default(); |
| 1069 } | 1084 } |
| 1070 // Allow "eval" or "arguments" for backward compatibility. | 1085 // Allow "eval" or "arguments" for backward compatibility. |
| 1071 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1086 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 1072 Scanner::Location spread_pos; | 1087 Scanner::Location spread_pos; |
| 1073 ParseArguments(&spread_pos, ok); | 1088 ParseArguments(&spread_pos, ok); |
| 1074 | 1089 |
| 1075 DCHECK(!spread_pos.IsValid()); | 1090 DCHECK(!spread_pos.IsValid()); |
| 1076 | 1091 |
| 1077 return Expression::Default(); | 1092 return Expression::Default(); |
| 1078 } | 1093 } |
| 1079 | 1094 |
| 1080 #undef CHECK_OK | 1095 #undef CHECK_OK |
| 1081 | 1096 |
| 1082 | 1097 |
| 1083 } } // v8::internal | 1098 } } // v8::internal |
| OLD | NEW |