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 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 // of a let declared variable is the scope of the immediately enclosing | 566 // of a let declared variable is the scope of the immediately enclosing |
567 // block. | 567 // block. |
568 int nvars = 0; // the number of variables declared | 568 int nvars = 0; // the number of variables declared |
569 int bindings_start = peek_position(); | 569 int bindings_start = peek_position(); |
570 do { | 570 do { |
571 // Parse binding pattern. | 571 // Parse binding pattern. |
572 if (nvars > 0) Consume(Token::COMMA); | 572 if (nvars > 0) Consume(Token::COMMA); |
573 int decl_pos = peek_position(); | 573 int decl_pos = peek_position(); |
574 PreParserExpression pattern = PreParserExpression::Default(); | 574 PreParserExpression pattern = PreParserExpression::Default(); |
575 { | 575 { |
576 ExpressionClassifier pattern_classifier(this); | 576 ExpressionClassifier pattern_classifier; |
577 Token::Value next = peek(); | 577 Token::Value next = peek(); |
578 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 578 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
579 | 579 |
580 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 580 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
581 if (lexical) { | 581 if (lexical) { |
582 ValidateLetPattern(&pattern_classifier, CHECK_OK); | 582 ValidateLetPattern(&pattern_classifier, CHECK_OK); |
583 } | 583 } |
584 | 584 |
585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { | 585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { |
586 ReportUnexpectedToken(next); | 586 ReportUnexpectedToken(next); |
587 *ok = false; | 587 *ok = false; |
588 return Statement::Default(); | 588 return Statement::Default(); |
589 } | 589 } |
590 } | 590 } |
591 | 591 |
592 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); | 592 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); |
593 | 593 |
594 Scanner::Location variable_loc = scanner()->location(); | 594 Scanner::Location variable_loc = scanner()->location(); |
595 nvars++; | 595 nvars++; |
596 if (Check(Token::ASSIGN)) { | 596 if (Check(Token::ASSIGN)) { |
597 ExpressionClassifier classifier(this); | 597 ExpressionClassifier classifier; |
598 ParseAssignmentExpression(var_context != kForStatement, &classifier, | 598 ParseAssignmentExpression(var_context != kForStatement, &classifier, |
599 CHECK_OK); | 599 CHECK_OK); |
600 ValidateExpression(&classifier, CHECK_OK); | 600 ValidateExpression(&classifier, CHECK_OK); |
601 | 601 |
602 variable_loc.end_pos = scanner()->location().end_pos; | 602 variable_loc.end_pos = scanner()->location().end_pos; |
603 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 603 if (first_initializer_loc && !first_initializer_loc->IsValid()) { |
604 *first_initializer_loc = variable_loc; | 604 *first_initializer_loc = variable_loc; |
605 } | 605 } |
606 } else if ((require_initializer || is_pattern) && | 606 } else if ((require_initializer || is_pattern) && |
607 (var_context != kForStatement || !PeekInOrOf())) { | 607 (var_context != kForStatement || !PeekInOrOf())) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 return Statement::Default(); | 641 return Statement::Default(); |
642 | 642 |
643 case Token::THIS: | 643 case Token::THIS: |
644 if (!FLAG_strong_this) break; | 644 if (!FLAG_strong_this) break; |
645 // Fall through. | 645 // Fall through. |
646 case Token::SUPER: | 646 case Token::SUPER: |
647 if (is_strong(language_mode()) && | 647 if (is_strong(language_mode()) && |
648 IsClassConstructor(function_state_->kind())) { | 648 IsClassConstructor(function_state_->kind())) { |
649 bool is_this = peek() == Token::THIS; | 649 bool is_this = peek() == Token::THIS; |
650 Expression expr = Expression::Default(); | 650 Expression expr = Expression::Default(); |
651 ExpressionClassifier classifier(this); | 651 ExpressionClassifier classifier; |
652 if (is_this) { | 652 if (is_this) { |
653 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); | 653 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); |
654 } else { | 654 } else { |
655 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); | 655 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); |
656 } | 656 } |
657 ValidateExpression(&classifier, CHECK_OK); | 657 ValidateExpression(&classifier, CHECK_OK); |
658 switch (peek()) { | 658 switch (peek()) { |
659 case Token::SEMICOLON: | 659 case Token::SEMICOLON: |
660 Consume(Token::SEMICOLON); | 660 Consume(Token::SEMICOLON); |
661 break; | 661 break; |
(...skipping 15 matching lines...) Expand all Loading... |
677 break; | 677 break; |
678 | 678 |
679 // TODO(arv): Handle `let [` | 679 // TODO(arv): Handle `let [` |
680 // https://code.google.com/p/v8/issues/detail?id=3847 | 680 // https://code.google.com/p/v8/issues/detail?id=3847 |
681 | 681 |
682 default: | 682 default: |
683 break; | 683 break; |
684 } | 684 } |
685 | 685 |
686 bool starts_with_identifier = peek_any_identifier(); | 686 bool starts_with_identifier = peek_any_identifier(); |
687 ExpressionClassifier classifier(this); | 687 ExpressionClassifier classifier; |
688 Expression expr = ParseExpression(true, &classifier, CHECK_OK); | 688 Expression expr = ParseExpression(true, &classifier, CHECK_OK); |
689 ValidateExpression(&classifier, CHECK_OK); | 689 ValidateExpression(&classifier, CHECK_OK); |
690 | 690 |
691 // Even if the expression starts with an identifier, it is not necessarily an | 691 // Even if the expression starts with an identifier, it is not necessarily an |
692 // identifier. For example, "foo + bar" starts with an identifier but is not | 692 // identifier. For example, "foo + bar" starts with an identifier but is not |
693 // an identifier. | 693 // an identifier. |
694 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { | 694 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { |
695 // Expression is a single identifier, and not, e.g., a parenthesized | 695 // Expression is a single identifier, and not, e.g., a parenthesized |
696 // identifier. | 696 // identifier. |
697 DCHECK(!expr.AsIdentifier().IsFutureReserved()); | 697 DCHECK(!expr.AsIdentifier().IsFutureReserved()); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || | 930 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || |
931 is_lexical || is_binding_pattern)) { | 931 is_lexical || is_binding_pattern)) { |
932 PreParserTraits::ReportMessageAt( | 932 PreParserTraits::ReportMessageAt( |
933 first_initializer_loc, MessageTemplate::kForInOfLoopInitializer, | 933 first_initializer_loc, MessageTemplate::kForInOfLoopInitializer, |
934 ForEachStatement::VisitModeString(mode)); | 934 ForEachStatement::VisitModeString(mode)); |
935 *ok = false; | 935 *ok = false; |
936 return Statement::Default(); | 936 return Statement::Default(); |
937 } | 937 } |
938 | 938 |
939 if (mode == ForEachStatement::ITERATE) { | 939 if (mode == ForEachStatement::ITERATE) { |
940 ExpressionClassifier classifier(this); | 940 ExpressionClassifier classifier; |
941 ParseAssignmentExpression(true, &classifier, CHECK_OK); | 941 Expression enumerable = |
942 RewriteNonPattern(&classifier, CHECK_OK); | 942 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
| 943 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); |
943 } else { | 944 } else { |
944 ParseExpression(true, CHECK_OK); | 945 ParseExpression(true, CHECK_OK); |
945 } | 946 } |
946 | 947 |
947 Expect(Token::RPAREN, CHECK_OK); | 948 Expect(Token::RPAREN, CHECK_OK); |
948 ParseSubStatement(CHECK_OK); | 949 ParseSubStatement(CHECK_OK); |
949 return Statement::Default(); | 950 return Statement::Default(); |
950 } | 951 } |
951 } else { | 952 } else { |
952 int lhs_beg_pos = peek_position(); | 953 int lhs_beg_pos = peek_position(); |
953 ExpressionClassifier classifier(this); | 954 ExpressionClassifier classifier; |
954 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); | 955 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); |
955 int lhs_end_pos = scanner()->location().end_pos; | 956 int lhs_end_pos = scanner()->location().end_pos; |
956 is_let_identifier_expression = | 957 is_let_identifier_expression = |
957 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); | 958 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); |
958 bool is_for_each = CheckInOrOf(&mode, ok); | 959 bool is_for_each = CheckInOrOf(&mode, ok); |
959 if (!*ok) return Statement::Default(); | 960 if (!*ok) return Statement::Default(); |
960 bool is_destructuring = is_for_each && | 961 bool is_destructuring = is_for_each && |
961 allow_harmony_destructuring_assignment() && | 962 allow_harmony_destructuring_assignment() && |
962 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); | 963 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); |
963 | 964 |
964 if (is_destructuring) { | 965 if (is_destructuring) { |
965 ValidateAssignmentPattern(&classifier, CHECK_OK); | 966 ValidateAssignmentPattern(&classifier, CHECK_OK); |
966 } else { | 967 } else { |
967 ValidateExpression(&classifier, CHECK_OK); | 968 ValidateExpression(&classifier, CHECK_OK); |
968 } | 969 } |
969 | 970 |
970 if (is_for_each) { | 971 if (is_for_each) { |
971 if (!is_destructuring) { | 972 if (!is_destructuring) { |
972 lhs = CheckAndRewriteReferenceExpression( | 973 lhs = CheckAndRewriteReferenceExpression( |
973 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, | 974 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, |
974 kSyntaxError, CHECK_OK); | 975 kSyntaxError, CHECK_OK); |
975 } | 976 } |
976 | 977 |
977 if (mode == ForEachStatement::ITERATE) { | 978 if (mode == ForEachStatement::ITERATE) { |
978 ExpressionClassifier classifier(this); | 979 ExpressionClassifier classifier; |
979 ParseAssignmentExpression(true, &classifier, CHECK_OK); | 980 Expression enumerable = |
980 RewriteNonPattern(&classifier, CHECK_OK); | 981 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
| 982 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); |
981 } else { | 983 } else { |
982 ParseExpression(true, CHECK_OK); | 984 ParseExpression(true, CHECK_OK); |
983 } | 985 } |
984 | 986 |
985 Expect(Token::RPAREN, CHECK_OK); | 987 Expect(Token::RPAREN, CHECK_OK); |
986 ParseSubStatement(CHECK_OK); | 988 ParseSubStatement(CHECK_OK); |
987 return Statement::Default(); | 989 return Statement::Default(); |
988 } | 990 } |
989 } | 991 } |
990 } | 992 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 | 1050 |
1049 Token::Value tok = peek(); | 1051 Token::Value tok = peek(); |
1050 if (tok != Token::CATCH && tok != Token::FINALLY) { | 1052 if (tok != Token::CATCH && tok != Token::FINALLY) { |
1051 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); | 1053 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); |
1052 *ok = false; | 1054 *ok = false; |
1053 return Statement::Default(); | 1055 return Statement::Default(); |
1054 } | 1056 } |
1055 if (tok == Token::CATCH) { | 1057 if (tok == Token::CATCH) { |
1056 Consume(Token::CATCH); | 1058 Consume(Token::CATCH); |
1057 Expect(Token::LPAREN, CHECK_OK); | 1059 Expect(Token::LPAREN, CHECK_OK); |
1058 ExpressionClassifier pattern_classifier(this); | 1060 ExpressionClassifier pattern_classifier; |
1059 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 1061 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
1060 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 1062 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
1061 Expect(Token::RPAREN, CHECK_OK); | 1063 Expect(Token::RPAREN, CHECK_OK); |
1062 { | 1064 { |
1063 // TODO(adamk): Make this CATCH_SCOPE | 1065 // TODO(adamk): Make this CATCH_SCOPE |
1064 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 1066 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
1065 BlockState block_state(&scope_, with_scope); | 1067 BlockState block_state(&scope_, with_scope); |
1066 ParseBlock(CHECK_OK); | 1068 ParseBlock(CHECK_OK); |
1067 } | 1069 } |
1068 tok = peek(); | 1070 tok = peek(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1107 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
1106 | 1108 |
1107 // Parse function body. | 1109 // Parse function body. |
1108 bool outer_is_script_scope = scope_->is_script_scope(); | 1110 bool outer_is_script_scope = scope_->is_script_scope(); |
1109 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); | 1111 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); |
1110 function_scope->SetLanguageMode(language_mode); | 1112 function_scope->SetLanguageMode(language_mode); |
1111 PreParserFactory factory(NULL); | 1113 PreParserFactory factory(NULL); |
1112 FunctionState function_state(&function_state_, &scope_, function_scope, kind, | 1114 FunctionState function_state(&function_state_, &scope_, function_scope, kind, |
1113 &factory); | 1115 &factory); |
1114 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 1116 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
1115 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 1117 ExpressionClassifier formals_classifier(&duplicate_finder); |
1116 | 1118 |
1117 Expect(Token::LPAREN, CHECK_OK); | 1119 Expect(Token::LPAREN, CHECK_OK); |
1118 int start_position = scanner()->location().beg_pos; | 1120 int start_position = scanner()->location().beg_pos; |
1119 function_scope->set_start_position(start_position); | 1121 function_scope->set_start_position(start_position); |
1120 PreParserFormalParameters formals(function_scope); | 1122 PreParserFormalParameters formals(function_scope); |
1121 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); | 1123 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); |
1122 Expect(Token::RPAREN, CHECK_OK); | 1124 Expect(Token::RPAREN, CHECK_OK); |
1123 int formals_end_position = scanner()->location().end_pos; | 1125 int formals_end_position = scanner()->location().end_pos; |
1124 | 1126 |
1125 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | 1127 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 | 1213 |
1212 Scope* scope = NewScope(scope_, BLOCK_SCOPE); | 1214 Scope* scope = NewScope(scope_, BLOCK_SCOPE); |
1213 BlockState block_state(&scope_, scope); | 1215 BlockState block_state(&scope_, scope); |
1214 scope_->SetLanguageMode( | 1216 scope_->SetLanguageMode( |
1215 static_cast<LanguageMode>(class_language_mode | STRICT)); | 1217 static_cast<LanguageMode>(class_language_mode | STRICT)); |
1216 // TODO(marja): Make PreParser use scope names too. | 1218 // TODO(marja): Make PreParser use scope names too. |
1217 // scope_->SetScopeName(name); | 1219 // scope_->SetScopeName(name); |
1218 | 1220 |
1219 bool has_extends = Check(Token::EXTENDS); | 1221 bool has_extends = Check(Token::EXTENDS); |
1220 if (has_extends) { | 1222 if (has_extends) { |
1221 ExpressionClassifier classifier(this); | 1223 ExpressionClassifier classifier; |
1222 ParseLeftHandSideExpression(&classifier, CHECK_OK); | 1224 ParseLeftHandSideExpression(&classifier, CHECK_OK); |
1223 ValidateExpression(&classifier, CHECK_OK); | 1225 ValidateExpression(&classifier, CHECK_OK); |
1224 } | 1226 } |
1225 | 1227 |
1226 ClassLiteralChecker checker(this); | 1228 ClassLiteralChecker checker(this); |
1227 bool has_seen_constructor = false; | 1229 bool has_seen_constructor = false; |
1228 | 1230 |
1229 Expect(Token::LBRACE, CHECK_OK); | 1231 Expect(Token::LBRACE, CHECK_OK); |
1230 while (peek() != Token::RBRACE) { | 1232 while (peek() != Token::RBRACE) { |
1231 if (Check(Token::SEMICOLON)) continue; | 1233 if (Check(Token::SEMICOLON)) continue; |
1232 const bool in_class = true; | 1234 const bool in_class = true; |
1233 const bool is_static = false; | 1235 const bool is_static = false; |
1234 bool is_computed_name = false; // Classes do not care about computed | 1236 bool is_computed_name = false; // Classes do not care about computed |
1235 // property names here. | 1237 // property names here. |
1236 Identifier name; | 1238 Identifier name; |
1237 ExpressionClassifier classifier(this); | 1239 ExpressionClassifier classifier; |
1238 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, | 1240 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, |
1239 &is_computed_name, &has_seen_constructor, | 1241 &is_computed_name, &has_seen_constructor, |
1240 &classifier, &name, CHECK_OK); | 1242 &classifier, &name, CHECK_OK); |
1241 ValidateExpression(&classifier, CHECK_OK); | 1243 ValidateExpression(&classifier, CHECK_OK); |
1242 } | 1244 } |
1243 | 1245 |
1244 Expect(Token::RBRACE, CHECK_OK); | 1246 Expect(Token::RBRACE, CHECK_OK); |
1245 | 1247 |
1246 return Expression::Default(); | 1248 return Expression::Default(); |
1247 } | 1249 } |
1248 | 1250 |
1249 | 1251 |
1250 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1252 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1251 // CallRuntime :: | 1253 // CallRuntime :: |
1252 // '%' Identifier Arguments | 1254 // '%' Identifier Arguments |
1253 Expect(Token::MOD, CHECK_OK); | 1255 Expect(Token::MOD, CHECK_OK); |
1254 if (!allow_natives()) { | 1256 if (!allow_natives()) { |
1255 *ok = false; | 1257 *ok = false; |
1256 return Expression::Default(); | 1258 return Expression::Default(); |
1257 } | 1259 } |
1258 // Allow "eval" or "arguments" for backward compatibility. | 1260 // Allow "eval" or "arguments" for backward compatibility. |
1259 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 1261 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
1260 Scanner::Location spread_pos; | 1262 Scanner::Location spread_pos; |
1261 ExpressionClassifier classifier(this); | 1263 ExpressionClassifier classifier; |
1262 ParseArguments(&spread_pos, &classifier, ok); | 1264 ParseArguments(&spread_pos, &classifier, ok); |
1263 ValidateExpression(&classifier, CHECK_OK); | 1265 ValidateExpression(&classifier, CHECK_OK); |
1264 | 1266 |
1265 DCHECK(!spread_pos.IsValid()); | 1267 DCHECK(!spread_pos.IsValid()); |
1266 | 1268 |
1267 return Expression::Default(); | 1269 return Expression::Default(); |
1268 } | 1270 } |
1269 | 1271 |
1270 | 1272 |
1271 PreParserExpression PreParser::ParseDoExpression(bool* ok) { | 1273 PreParserExpression PreParser::ParseDoExpression(bool* ok) { |
(...skipping 10 matching lines...) Expand all Loading... |
1282 Expect(Token::RBRACE, CHECK_OK); | 1284 Expect(Token::RBRACE, CHECK_OK); |
1283 return PreParserExpression::Default(); | 1285 return PreParserExpression::Default(); |
1284 } | 1286 } |
1285 } | 1287 } |
1286 | 1288 |
1287 #undef CHECK_OK | 1289 #undef CHECK_OK |
1288 | 1290 |
1289 | 1291 |
1290 } // namespace internal | 1292 } // namespace internal |
1291 } // namespace v8 | 1293 } // namespace v8 |
OLD | NEW |