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 |