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