| 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 | 
|---|