Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: src/preparser.cc

Issue 153743006: Merge Parser::ReportUnexpectedToken and PreParser::ReportUnexpectedToken. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 function_scope.set_is_generator(is_generator); 65 function_scope.set_is_generator(is_generator);
66 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); 66 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
67 bool ok = true; 67 bool ok = true;
68 int start_position = peek_position(); 68 int start_position = peek_position();
69 ParseLazyFunctionLiteralBody(&ok); 69 ParseLazyFunctionLiteralBody(&ok);
70 if (stack_overflow()) return kPreParseStackOverflow; 70 if (stack_overflow()) return kPreParseStackOverflow;
71 if (!ok) { 71 if (!ok) {
72 ReportUnexpectedToken(scanner()->current_token()); 72 ReportUnexpectedToken(scanner()->current_token());
73 } else { 73 } else {
74 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 74 ASSERT_EQ(Token::RBRACE, scanner()->peek());
75 if (!is_classic_mode()) { 75 if (!scope_->is_classic_mode()) {
76 int end_pos = scanner()->location().end_pos; 76 int end_pos = scanner()->location().end_pos;
77 CheckOctalLiteral(start_position, end_pos, &ok); 77 CheckOctalLiteral(start_position, end_pos, &ok);
78 if (ok) { 78 if (ok) {
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80 } 80 }
81 } 81 }
82 } 82 }
83 return kPreParseSuccess; 83 return kPreParseSuccess;
84 } 84 }
85 85
86 86
87 // Preparsing checks a JavaScript program and emits preparse-data that helps 87 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster. 88 // a later parsing to be faster.
89 // See preparser-data.h for the data. 89 // See preparser-data.h for the data.
90 90
91 // The PreParser checks that the syntax follows the grammar for JavaScript, 91 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way. 92 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program 93 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used 94 // sufficiently to deduce some information about it, that can be used
95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
96 // rather it is to speed up properly written and correct programs. 96 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where 97 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted. 98 // it is used) are generally omitted.
99 99
100 void PreParser::ReportUnexpectedToken(Token::Value token) {
101 // We don't report stack overflows here, to avoid increasing the
102 // stack depth even further. Instead we report it after parsing is
103 // over, in ParseProgram.
104 if (token == Token::ILLEGAL && stack_overflow()) {
105 return;
106 }
107 Scanner::Location source_location = scanner()->location();
108
109 // Four of the tokens are treated specially
110 switch (token) {
111 case Token::EOS:
112 return ReportMessageAt(source_location, "unexpected_eos", NULL);
113 case Token::NUMBER:
114 return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115 case Token::STRING:
116 return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117 case Token::IDENTIFIER:
118 return ReportMessageAt(source_location,
119 "unexpected_token_identifier", NULL);
120 case Token::FUTURE_RESERVED_WORD:
121 return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122 case Token::YIELD:
123 case Token::FUTURE_STRICT_RESERVED_WORD:
124 return ReportMessageAt(source_location,
125 is_classic_mode() ? "unexpected_token_identifier"
126 : "unexpected_strict_reserved",
127 NULL);
128 default:
129 const char* name = Token::String(token);
130 ReportMessageAt(source_location, "unexpected_token", name);
131 }
132 }
133
134 100
135 #define CHECK_OK ok); \ 101 #define CHECK_OK ok); \
136 if (!*ok) return kUnknownSourceElements; \ 102 if (!*ok) return kUnknownSourceElements; \
137 ((void)0 103 ((void)0
138 #define DUMMY ) // to make indentation work 104 #define DUMMY ) // to make indentation work
139 #undef DUMMY 105 #undef DUMMY
140 106
141 107
142 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 108 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
143 // (Ecma 262 5th Edition, clause 14): 109 // (Ecma 262 5th Edition, clause 14):
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 case Token::THROW: 230 case Token::THROW:
265 return ParseThrowStatement(ok); 231 return ParseThrowStatement(ok);
266 232
267 case Token::TRY: 233 case Token::TRY:
268 return ParseTryStatement(ok); 234 return ParseTryStatement(ok);
269 235
270 case Token::FUNCTION: { 236 case Token::FUNCTION: {
271 Scanner::Location start_location = scanner()->peek_location(); 237 Scanner::Location start_location = scanner()->peek_location();
272 Statement statement = ParseFunctionDeclaration(CHECK_OK); 238 Statement statement = ParseFunctionDeclaration(CHECK_OK);
273 Scanner::Location end_location = scanner()->location(); 239 Scanner::Location end_location = scanner()->location();
274 if (!is_classic_mode()) { 240 if (!scope_->is_classic_mode()) {
275 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 241 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
276 "strict_function", NULL); 242 "strict_function", NULL);
277 *ok = false; 243 *ok = false;
278 return Statement::Default(); 244 return Statement::Default();
279 } else { 245 } else {
280 return statement; 246 return statement;
281 } 247 }
282 } 248 }
283 249
284 case Token::DEBUGGER: 250 case Token::DEBUGGER:
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 439
474 bool starts_with_identifier = peek_any_identifier(); 440 bool starts_with_identifier = peek_any_identifier();
475 Expression expr = ParseExpression(true, CHECK_OK); 441 Expression expr = ParseExpression(true, CHECK_OK);
476 // Even if the expression starts with an identifier, it is not necessarily an 442 // Even if the expression starts with an identifier, it is not necessarily an
477 // identifier. For example, "foo + bar" starts with an identifier but is not 443 // identifier. For example, "foo + bar" starts with an identifier but is not
478 // an identifier. 444 // an identifier.
479 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 445 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
480 // Expression is a single identifier, and not, e.g., a parenthesized 446 // Expression is a single identifier, and not, e.g., a parenthesized
481 // identifier. 447 // identifier.
482 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 448 ASSERT(!expr.AsIdentifier().IsFutureReserved());
483 ASSERT(is_classic_mode() || 449 ASSERT(scope_->is_classic_mode() ||
484 (!expr.AsIdentifier().IsFutureStrictReserved() && 450 (!expr.AsIdentifier().IsFutureStrictReserved() &&
485 !expr.AsIdentifier().IsYield())); 451 !expr.AsIdentifier().IsYield()));
486 Consume(Token::COLON); 452 Consume(Token::COLON);
487 return ParseStatement(ok); 453 return ParseStatement(ok);
488 // Preparsing is disabled for extensions (because the extension details 454 // Preparsing is disabled for extensions (because the extension details
489 // aren't passed to lazily compiled functions), so we don't 455 // aren't passed to lazily compiled functions), so we don't
490 // accept "native function" in the preparser. 456 // accept "native function" in the preparser.
491 } 457 }
492 // Parsed expression statement. 458 // Parsed expression statement.
493 ExpectSemicolon(CHECK_OK); 459 ExpectSemicolon(CHECK_OK);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 } 537 }
572 ExpectSemicolon(CHECK_OK); 538 ExpectSemicolon(CHECK_OK);
573 return Statement::Default(); 539 return Statement::Default();
574 } 540 }
575 541
576 542
577 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 543 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
578 // WithStatement :: 544 // WithStatement ::
579 // 'with' '(' Expression ')' Statement 545 // 'with' '(' Expression ')' Statement
580 Expect(Token::WITH, CHECK_OK); 546 Expect(Token::WITH, CHECK_OK);
581 if (!is_classic_mode()) { 547 if (!scope_->is_classic_mode()) {
582 Scanner::Location location = scanner()->location(); 548 Scanner::Location location = scanner()->location();
583 ReportMessageAt(location, "strict_mode_with", NULL); 549 ReportMessageAt(location, "strict_mode_with", NULL);
584 *ok = false; 550 *ok = false;
585 return Statement::Default(); 551 return Statement::Default();
586 } 552 }
587 Expect(Token::LPAREN, CHECK_OK); 553 Expect(Token::LPAREN, CHECK_OK);
588 ParseExpression(true, CHECK_OK); 554 ParseExpression(true, CHECK_OK);
589 Expect(Token::RPAREN, CHECK_OK); 555 Expect(Token::RPAREN, CHECK_OK);
590 556
591 Scope::InsideWith iw(scope_); 557 Scope::InsideWith iw(scope_);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } 793 }
828 794
829 Scanner::Location before = scanner()->peek_location(); 795 Scanner::Location before = scanner()->peek_location();
830 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 796 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
831 797
832 if (!Token::IsAssignmentOp(peek())) { 798 if (!Token::IsAssignmentOp(peek())) {
833 // Parsed conditional expression only (no assignment). 799 // Parsed conditional expression only (no assignment).
834 return expression; 800 return expression;
835 } 801 }
836 802
837 if (!is_classic_mode() && 803 if (!scope_->is_classic_mode() &&
838 expression.IsIdentifier() && 804 expression.IsIdentifier() &&
839 expression.AsIdentifier().IsEvalOrArguments()) { 805 expression.AsIdentifier().IsEvalOrArguments()) {
840 Scanner::Location after = scanner()->location(); 806 Scanner::Location after = scanner()->location();
841 ReportMessageAt(before.beg_pos, after.end_pos, 807 ReportMessageAt(before.beg_pos, after.end_pos,
842 "strict_eval_arguments", NULL); 808 "strict_eval_arguments", NULL);
843 *ok = false; 809 *ok = false;
844 return Expression::Default(); 810 return Expression::Default();
845 } 811 }
846 812
847 Token::Value op = Next(); // Get assignment operator. 813 Token::Value op = Next(); // Get assignment operator.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 887
922 Token::Value op = peek(); 888 Token::Value op = peek();
923 if (Token::IsUnaryOp(op)) { 889 if (Token::IsUnaryOp(op)) {
924 op = Next(); 890 op = Next();
925 ParseUnaryExpression(ok); 891 ParseUnaryExpression(ok);
926 return Expression::Default(); 892 return Expression::Default();
927 } else if (Token::IsCountOp(op)) { 893 } else if (Token::IsCountOp(op)) {
928 op = Next(); 894 op = Next();
929 Scanner::Location before = scanner()->peek_location(); 895 Scanner::Location before = scanner()->peek_location();
930 Expression expression = ParseUnaryExpression(CHECK_OK); 896 Expression expression = ParseUnaryExpression(CHECK_OK);
931 if (!is_classic_mode() && 897 if (!scope_->is_classic_mode() &&
932 expression.IsIdentifier() && 898 expression.IsIdentifier() &&
933 expression.AsIdentifier().IsEvalOrArguments()) { 899 expression.AsIdentifier().IsEvalOrArguments()) {
934 Scanner::Location after = scanner()->location(); 900 Scanner::Location after = scanner()->location();
935 ReportMessageAt(before.beg_pos, after.end_pos, 901 ReportMessageAt(before.beg_pos, after.end_pos,
936 "strict_eval_arguments", NULL); 902 "strict_eval_arguments", NULL);
937 *ok = false; 903 *ok = false;
938 } 904 }
939 return Expression::Default(); 905 return Expression::Default();
940 } else { 906 } else {
941 return ParsePostfixExpression(ok); 907 return ParsePostfixExpression(ok);
942 } 908 }
943 } 909 }
944 910
945 911
946 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 912 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
947 // PostfixExpression :: 913 // PostfixExpression ::
948 // LeftHandSideExpression ('++' | '--')? 914 // LeftHandSideExpression ('++' | '--')?
949 915
950 Scanner::Location before = scanner()->peek_location(); 916 Scanner::Location before = scanner()->peek_location();
951 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 917 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
952 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 918 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
953 Token::IsCountOp(peek())) { 919 Token::IsCountOp(peek())) {
954 if (!is_classic_mode() && 920 if (!scope_->is_classic_mode() &&
955 expression.IsIdentifier() && 921 expression.IsIdentifier() &&
956 expression.AsIdentifier().IsEvalOrArguments()) { 922 expression.AsIdentifier().IsEvalOrArguments()) {
957 Scanner::Location after = scanner()->location(); 923 Scanner::Location after = scanner()->location();
958 ReportMessageAt(before.beg_pos, after.end_pos, 924 ReportMessageAt(before.beg_pos, after.end_pos,
959 "strict_eval_arguments", NULL); 925 "strict_eval_arguments", NULL);
960 *ok = false; 926 *ok = false;
961 return Expression::Default(); 927 return Expression::Default();
962 } 928 }
963 Next(); 929 Next();
964 return Expression::Default(); 930 return Expression::Default();
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 parenthesized_function_ = false; 1351 parenthesized_function_ = false;
1386 1352
1387 Expect(Token::LBRACE, CHECK_OK); 1353 Expect(Token::LBRACE, CHECK_OK);
1388 if (is_lazily_compiled) { 1354 if (is_lazily_compiled) {
1389 ParseLazyFunctionLiteralBody(CHECK_OK); 1355 ParseLazyFunctionLiteralBody(CHECK_OK);
1390 } else { 1356 } else {
1391 ParseSourceElements(Token::RBRACE, ok); 1357 ParseSourceElements(Token::RBRACE, ok);
1392 } 1358 }
1393 Expect(Token::RBRACE, CHECK_OK); 1359 Expect(Token::RBRACE, CHECK_OK);
1394 1360
1395 if (!is_classic_mode()) { 1361 if (!scope_->is_classic_mode()) {
1396 int end_position = scanner()->location().end_pos; 1362 int end_position = scanner()->location().end_pos;
1397 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1363 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1398 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); 1364 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1399 return Expression::StrictFunction(); 1365 return Expression::StrictFunction();
1400 } 1366 }
1401 1367
1402 return Expression::Default(); 1368 return Expression::Default();
1403 } 1369 }
1404 1370
1405 1371
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 1459 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
1494 // "arguments" as identifier even in strict mode (this is needed in cases like 1460 // "arguments" as identifier even in strict mode (this is needed in cases like
1495 // "var foo = eval;"). 1461 // "var foo = eval;").
1496 PreParser::Identifier PreParser::ParseIdentifier( 1462 PreParser::Identifier PreParser::ParseIdentifier(
1497 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1463 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1498 bool* ok) { 1464 bool* ok) {
1499 Token::Value next = Next(); 1465 Token::Value next = Next();
1500 if (next == Token::IDENTIFIER) { 1466 if (next == Token::IDENTIFIER) {
1501 PreParser::Identifier name = GetIdentifierSymbol(); 1467 PreParser::Identifier name = GetIdentifierSymbol();
1502 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1468 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1503 !is_classic_mode() && name.IsEvalOrArguments()) { 1469 !scope_->is_classic_mode() && name.IsEvalOrArguments()) {
1504 StrictModeIdentifierViolation(scanner()->location(), name, ok); 1470 StrictModeIdentifierViolation(scanner()->location(), name, ok);
1505 } 1471 }
1506 return name; 1472 return name;
1507 } else if (is_classic_mode() && 1473 } else if (scope_->is_classic_mode() &&
1508 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1474 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1509 (next == Token::YIELD && !scope_->is_generator()))) { 1475 (next == Token::YIELD && !scope_->is_generator()))) {
1510 return GetIdentifierSymbol(); 1476 return GetIdentifierSymbol();
1511 } else { 1477 } else {
1512 ReportUnexpectedToken(next); 1478 ReportUnexpectedToken(next);
1513 *ok = false; 1479 *ok = false;
1514 return Identifier::Default(); 1480 return Identifier::Default();
1515 } 1481 }
1516 } 1482 }
1517 1483
1518 1484
1519 void PreParser::SetStrictModeViolation(Scanner::Location location, 1485 void PreParser::SetStrictModeViolation(Scanner::Location location,
1520 const char* type, 1486 const char* type,
1521 bool* ok) { 1487 bool* ok) {
1522 if (!is_classic_mode()) { 1488 if (!scope_->is_classic_mode()) {
1523 ReportMessageAt(location, type, NULL); 1489 ReportMessageAt(location, type, NULL);
1524 *ok = false; 1490 *ok = false;
1525 return; 1491 return;
1526 } 1492 }
1527 // Delay report in case this later turns out to be strict code 1493 // Delay report in case this later turns out to be strict code
1528 // (i.e., for function names and parameters prior to a "use strict" 1494 // (i.e., for function names and parameters prior to a "use strict"
1529 // directive). 1495 // directive).
1530 // It's safe to overwrite an existing violation. 1496 // It's safe to overwrite an existing violation.
1531 // It's either from a function that turned out to be non-strict, 1497 // It's either from a function that turned out to be non-strict,
1532 // or it's in the current function (and we just need to report 1498 // or it's in the current function (and we just need to report
(...skipping 18 matching lines...) Expand all
1551 1517
1552 void PreParser::StrictModeIdentifierViolation(Scanner::Location location, 1518 void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
1553 Identifier identifier, 1519 Identifier identifier,
1554 bool* ok) { 1520 bool* ok) {
1555 const char* type = "strict_eval_arguments"; 1521 const char* type = "strict_eval_arguments";
1556 if (identifier.IsFutureReserved()) { 1522 if (identifier.IsFutureReserved()) {
1557 type = "unexpected_reserved"; 1523 type = "unexpected_reserved";
1558 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { 1524 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1559 type = "unexpected_strict_reserved"; 1525 type = "unexpected_strict_reserved";
1560 } 1526 }
1561 if (!is_classic_mode()) { 1527 if (!scope_->is_classic_mode()) {
1562 ReportMessageAt(location, type, NULL); 1528 ReportMessageAt(location, type, NULL);
1563 *ok = false; 1529 *ok = false;
1564 return; 1530 return;
1565 } 1531 }
1566 strict_mode_violation_location_ = location; 1532 strict_mode_violation_location_ = location;
1567 strict_mode_violation_type_ = type; 1533 strict_mode_violation_type_ = type;
1568 } 1534 }
1569 1535
1570 1536
1571 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1537 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 ASSERT(IsAccessorAccessorConflict(old_type, type)); 1597 ASSERT(IsAccessorAccessorConflict(old_type, type));
1632 // Both accessors of the same type. 1598 // Both accessors of the same type.
1633 parser()->ReportMessageAt(scanner()->location(), 1599 parser()->ReportMessageAt(scanner()->location(),
1634 "accessor_get_set"); 1600 "accessor_get_set");
1635 } 1601 }
1636 *ok = false; 1602 *ok = false;
1637 } 1603 }
1638 } 1604 }
1639 1605
1640 } } // v8::internal 1606 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698