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; | 576 ExpressionClassifier pattern_classifier(this); |
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; | 597 ExpressionClassifier classifier(this); |
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; | 651 ExpressionClassifier classifier(this); |
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; | 687 ExpressionClassifier classifier(this); |
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; | 940 ExpressionClassifier classifier(this); |
941 Expression enumerable = | 941 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
942 ParseAssignmentExpression(true, &classifier, CHECK_OK); | 942 RewriteNonPattern(&classifier, CHECK_OK); |
943 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); | |
944 } else { | 943 } else { |
945 ParseExpression(true, CHECK_OK); | 944 ParseExpression(true, CHECK_OK); |
946 } | 945 } |
947 | 946 |
948 Expect(Token::RPAREN, CHECK_OK); | 947 Expect(Token::RPAREN, CHECK_OK); |
949 ParseSubStatement(CHECK_OK); | 948 ParseSubStatement(CHECK_OK); |
950 return Statement::Default(); | 949 return Statement::Default(); |
951 } | 950 } |
952 } else { | 951 } else { |
953 int lhs_beg_pos = peek_position(); | 952 int lhs_beg_pos = peek_position(); |
954 ExpressionClassifier classifier; | 953 ExpressionClassifier classifier(this); |
955 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); | 954 Expression lhs = ParseExpression(false, &classifier, CHECK_OK); |
956 int lhs_end_pos = scanner()->location().end_pos; | 955 int lhs_end_pos = scanner()->location().end_pos; |
957 is_let_identifier_expression = | 956 is_let_identifier_expression = |
958 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); | 957 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); |
959 bool is_for_each = CheckInOrOf(&mode, ok); | 958 bool is_for_each = CheckInOrOf(&mode, ok); |
960 if (!*ok) return Statement::Default(); | 959 if (!*ok) return Statement::Default(); |
961 bool is_destructuring = is_for_each && | 960 bool is_destructuring = is_for_each && |
962 allow_harmony_destructuring_assignment() && | 961 allow_harmony_destructuring_assignment() && |
963 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); | 962 (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()); |
964 | 963 |
965 if (is_destructuring) { | 964 if (is_destructuring) { |
966 ValidateAssignmentPattern(&classifier, CHECK_OK); | 965 ValidateAssignmentPattern(&classifier, CHECK_OK); |
967 } else { | 966 } else { |
968 ValidateExpression(&classifier, CHECK_OK); | 967 ValidateExpression(&classifier, CHECK_OK); |
969 } | 968 } |
970 | 969 |
971 if (is_for_each) { | 970 if (is_for_each) { |
972 if (!is_destructuring) { | 971 if (!is_destructuring) { |
973 lhs = CheckAndRewriteReferenceExpression( | 972 lhs = CheckAndRewriteReferenceExpression( |
974 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, | 973 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, |
975 kSyntaxError, CHECK_OK); | 974 kSyntaxError, CHECK_OK); |
976 } | 975 } |
977 | 976 |
978 if (mode == ForEachStatement::ITERATE) { | 977 if (mode == ForEachStatement::ITERATE) { |
979 ExpressionClassifier classifier; | 978 ExpressionClassifier classifier(this); |
980 Expression enumerable = | 979 ParseAssignmentExpression(true, &classifier, CHECK_OK); |
981 ParseAssignmentExpression(true, &classifier, CHECK_OK); | 980 RewriteNonPattern(&classifier, CHECK_OK); |
982 PreParserTraits::RewriteNonPattern(enumerable, &classifier, CHECK_OK); | |
983 } else { | 981 } else { |
984 ParseExpression(true, CHECK_OK); | 982 ParseExpression(true, CHECK_OK); |
985 } | 983 } |
986 | 984 |
987 Expect(Token::RPAREN, CHECK_OK); | 985 Expect(Token::RPAREN, CHECK_OK); |
988 ParseSubStatement(CHECK_OK); | 986 ParseSubStatement(CHECK_OK); |
989 return Statement::Default(); | 987 return Statement::Default(); |
990 } | 988 } |
991 } | 989 } |
992 } | 990 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 | 1048 |
1051 Token::Value tok = peek(); | 1049 Token::Value tok = peek(); |
1052 if (tok != Token::CATCH && tok != Token::FINALLY) { | 1050 if (tok != Token::CATCH && tok != Token::FINALLY) { |
1053 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); | 1051 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); |
1054 *ok = false; | 1052 *ok = false; |
1055 return Statement::Default(); | 1053 return Statement::Default(); |
1056 } | 1054 } |
1057 if (tok == Token::CATCH) { | 1055 if (tok == Token::CATCH) { |
1058 Consume(Token::CATCH); | 1056 Consume(Token::CATCH); |
1059 Expect(Token::LPAREN, CHECK_OK); | 1057 Expect(Token::LPAREN, CHECK_OK); |
1060 ExpressionClassifier pattern_classifier; | 1058 ExpressionClassifier pattern_classifier(this); |
1061 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 1059 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); |
1062 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 1060 ValidateBindingPattern(&pattern_classifier, CHECK_OK); |
1063 Expect(Token::RPAREN, CHECK_OK); | 1061 Expect(Token::RPAREN, CHECK_OK); |
1064 { | 1062 { |
1065 // TODO(adamk): Make this CATCH_SCOPE | 1063 // TODO(adamk): Make this CATCH_SCOPE |
1066 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 1064 Scope* with_scope = NewScope(scope_, WITH_SCOPE); |
1067 BlockState block_state(&scope_, with_scope); | 1065 BlockState block_state(&scope_, with_scope); |
1068 ParseBlock(CHECK_OK); | 1066 ParseBlock(CHECK_OK); |
1069 } | 1067 } |
1070 tok = peek(); | 1068 tok = peek(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1105 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
1108 | 1106 |
1109 // Parse function body. | 1107 // Parse function body. |
1110 bool outer_is_script_scope = scope_->is_script_scope(); | 1108 bool outer_is_script_scope = scope_->is_script_scope(); |
1111 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); | 1109 Scope* function_scope = NewScope(scope_, FUNCTION_SCOPE, kind); |
1112 function_scope->SetLanguageMode(language_mode); | 1110 function_scope->SetLanguageMode(language_mode); |
1113 PreParserFactory factory(NULL); | 1111 PreParserFactory factory(NULL); |
1114 FunctionState function_state(&function_state_, &scope_, function_scope, kind, | 1112 FunctionState function_state(&function_state_, &scope_, function_scope, kind, |
1115 &factory); | 1113 &factory); |
1116 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 1114 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
1117 ExpressionClassifier formals_classifier(&duplicate_finder); | 1115 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
1118 | 1116 |
1119 Expect(Token::LPAREN, CHECK_OK); | 1117 Expect(Token::LPAREN, CHECK_OK); |
1120 int start_position = scanner()->location().beg_pos; | 1118 int start_position = scanner()->location().beg_pos; |
1121 function_scope->set_start_position(start_position); | 1119 function_scope->set_start_position(start_position); |
1122 PreParserFormalParameters formals(function_scope); | 1120 PreParserFormalParameters formals(function_scope); |
1123 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); | 1121 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); |
1124 Expect(Token::RPAREN, CHECK_OK); | 1122 Expect(Token::RPAREN, CHECK_OK); |
1125 int formals_end_position = scanner()->location().end_pos; | 1123 int formals_end_position = scanner()->location().end_pos; |
1126 | 1124 |
1127 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | 1125 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 | 1211 |
1214 Scope* scope = NewScope(scope_, BLOCK_SCOPE); | 1212 Scope* scope = NewScope(scope_, BLOCK_SCOPE); |
1215 BlockState block_state(&scope_, scope); | 1213 BlockState block_state(&scope_, scope); |
1216 scope_->SetLanguageMode( | 1214 scope_->SetLanguageMode( |
1217 static_cast<LanguageMode>(class_language_mode | STRICT)); | 1215 static_cast<LanguageMode>(class_language_mode | STRICT)); |
1218 // TODO(marja): Make PreParser use scope names too. | 1216 // TODO(marja): Make PreParser use scope names too. |
1219 // scope_->SetScopeName(name); | 1217 // scope_->SetScopeName(name); |
1220 | 1218 |
1221 bool has_extends = Check(Token::EXTENDS); | 1219 bool has_extends = Check(Token::EXTENDS); |
1222 if (has_extends) { | 1220 if (has_extends) { |
1223 ExpressionClassifier classifier; | 1221 ExpressionClassifier classifier(this); |
1224 ParseLeftHandSideExpression(&classifier, CHECK_OK); | 1222 ParseLeftHandSideExpression(&classifier, CHECK_OK); |
1225 ValidateExpression(&classifier, CHECK_OK); | 1223 ValidateExpression(&classifier, CHECK_OK); |
1226 } | 1224 } |
1227 | 1225 |
1228 ClassLiteralChecker checker(this); | 1226 ClassLiteralChecker checker(this); |
1229 bool has_seen_constructor = false; | 1227 bool has_seen_constructor = false; |
1230 | 1228 |
1231 Expect(Token::LBRACE, CHECK_OK); | 1229 Expect(Token::LBRACE, CHECK_OK); |
1232 while (peek() != Token::RBRACE) { | 1230 while (peek() != Token::RBRACE) { |
1233 if (Check(Token::SEMICOLON)) continue; | 1231 if (Check(Token::SEMICOLON)) continue; |
1234 const bool in_class = true; | 1232 const bool in_class = true; |
1235 const bool is_static = false; | 1233 const bool is_static = false; |
1236 bool is_computed_name = false; // Classes do not care about computed | 1234 bool is_computed_name = false; // Classes do not care about computed |
1237 // property names here. | 1235 // property names here. |
1238 Identifier name; | 1236 Identifier name; |
1239 ExpressionClassifier classifier; | 1237 ExpressionClassifier classifier(this); |
1240 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, | 1238 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, |
1241 &is_computed_name, &has_seen_constructor, | 1239 &is_computed_name, &has_seen_constructor, |
1242 &classifier, &name, CHECK_OK); | 1240 &classifier, &name, CHECK_OK); |
1243 ValidateExpression(&classifier, CHECK_OK); | 1241 ValidateExpression(&classifier, CHECK_OK); |
1244 } | 1242 } |
1245 | 1243 |
1246 Expect(Token::RBRACE, CHECK_OK); | 1244 Expect(Token::RBRACE, CHECK_OK); |
1247 | 1245 |
1248 return Expression::Default(); | 1246 return Expression::Default(); |
1249 } | 1247 } |
1250 | 1248 |
1251 | 1249 |
1252 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1250 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1253 // CallRuntime :: | 1251 // CallRuntime :: |
1254 // '%' Identifier Arguments | 1252 // '%' Identifier Arguments |
1255 Expect(Token::MOD, CHECK_OK); | 1253 Expect(Token::MOD, CHECK_OK); |
1256 if (!allow_natives()) { | 1254 if (!allow_natives()) { |
1257 *ok = false; | 1255 *ok = false; |
1258 return Expression::Default(); | 1256 return Expression::Default(); |
1259 } | 1257 } |
1260 // Allow "eval" or "arguments" for backward compatibility. | 1258 // Allow "eval" or "arguments" for backward compatibility. |
1261 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 1259 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
1262 Scanner::Location spread_pos; | 1260 Scanner::Location spread_pos; |
1263 ExpressionClassifier classifier; | 1261 ExpressionClassifier classifier(this); |
1264 ParseArguments(&spread_pos, &classifier, ok); | 1262 ParseArguments(&spread_pos, &classifier, ok); |
1265 ValidateExpression(&classifier, CHECK_OK); | 1263 ValidateExpression(&classifier, CHECK_OK); |
1266 | 1264 |
1267 DCHECK(!spread_pos.IsValid()); | 1265 DCHECK(!spread_pos.IsValid()); |
1268 | 1266 |
1269 return Expression::Default(); | 1267 return Expression::Default(); |
1270 } | 1268 } |
1271 | 1269 |
1272 | 1270 |
1273 PreParserExpression PreParser::ParseDoExpression(bool* ok) { | 1271 PreParserExpression PreParser::ParseDoExpression(bool* ok) { |
(...skipping 10 matching lines...) Expand all Loading... |
1284 Expect(Token::RBRACE, CHECK_OK); | 1282 Expect(Token::RBRACE, CHECK_OK); |
1285 return PreParserExpression::Default(); | 1283 return PreParserExpression::Default(); |
1286 } | 1284 } |
1287 } | 1285 } |
1288 | 1286 |
1289 #undef CHECK_OK | 1287 #undef CHECK_OK |
1290 | 1288 |
1291 | 1289 |
1292 } // namespace internal | 1290 } // namespace internal |
1293 } // namespace v8 | 1291 } // namespace v8 |
OLD | NEW |