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

Side by Side Diff: src/preparser.cc

Issue 149403003: A64: Synchronize with r19234. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
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') | src/runtime.cc » ('j') | 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) {
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80 }
81 } 78 }
82 } 79 }
83 return kPreParseSuccess; 80 return kPreParseSuccess;
84 } 81 }
85 82
86 83
87 // Preparsing checks a JavaScript program and emits preparse-data that helps 84 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster. 85 // a later parsing to be faster.
89 // See preparser-data.h for the data. 86 // See preparser-data.h for the data.
90 87
91 // The PreParser checks that the syntax follows the grammar for JavaScript, 88 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way. 89 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program 90 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used 91 // 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, 92 // 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. 93 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where 94 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted. 95 // it is used) are generally omitted.
99 96
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::FUTURE_STRICT_RESERVED_WORD:
123 return ReportMessageAt(source_location,
124 "unexpected_strict_reserved", NULL);
125 default:
126 const char* name = Token::String(token);
127 ReportMessageAt(source_location, "unexpected_token", name);
128 }
129 }
130
131 97
132 #define CHECK_OK ok); \ 98 #define CHECK_OK ok); \
133 if (!*ok) return kUnknownSourceElements; \ 99 if (!*ok) return kUnknownSourceElements; \
134 ((void)0 100 ((void)0
135 #define DUMMY ) // to make indentation work 101 #define DUMMY ) // to make indentation work
136 #undef DUMMY 102 #undef DUMMY
137 103
138 104
139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 105 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
140 // (Ecma 262 5th Edition, clause 14): 106 // (Ecma 262 5th Edition, clause 14):
(...skipping 17 matching lines...) Expand all
158 return ParseStatement(ok); 124 return ParseStatement(ok);
159 } 125 }
160 } 126 }
161 127
162 128
163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 129 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
164 bool* ok) { 130 bool* ok) {
165 // SourceElements :: 131 // SourceElements ::
166 // (Statement)* <end_token> 132 // (Statement)* <end_token>
167 133
168 bool allow_directive_prologue = true; 134 bool directive_prologue = true;
169 while (peek() != end_token) { 135 while (peek() != end_token) {
136 if (directive_prologue && peek() != Token::STRING) {
137 directive_prologue = false;
138 }
170 Statement statement = ParseSourceElement(CHECK_OK); 139 Statement statement = ParseSourceElement(CHECK_OK);
171 if (allow_directive_prologue) { 140 if (directive_prologue) {
172 if (statement.IsUseStrictLiteral()) { 141 if (statement.IsUseStrictLiteral()) {
173 set_language_mode(allow_harmony_scoping() ? 142 set_language_mode(allow_harmony_scoping() ?
174 EXTENDED_MODE : STRICT_MODE); 143 EXTENDED_MODE : STRICT_MODE);
175 } else if (!statement.IsStringLiteral()) { 144 } else if (!statement.IsStringLiteral()) {
176 allow_directive_prologue = false; 145 directive_prologue = false;
177 } 146 }
178 } 147 }
179 } 148 }
180 return kUnknownSourceElements; 149 return kUnknownSourceElements;
181 } 150 }
182 151
183 152
184 #undef CHECK_OK 153 #undef CHECK_OK
185 #define CHECK_OK ok); \ 154 #define CHECK_OK ok); \
186 if (!*ok) return Statement::Default(); \ 155 if (!*ok) return Statement::Default(); \
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 case Token::THROW: 227 case Token::THROW:
259 return ParseThrowStatement(ok); 228 return ParseThrowStatement(ok);
260 229
261 case Token::TRY: 230 case Token::TRY:
262 return ParseTryStatement(ok); 231 return ParseTryStatement(ok);
263 232
264 case Token::FUNCTION: { 233 case Token::FUNCTION: {
265 Scanner::Location start_location = scanner()->peek_location(); 234 Scanner::Location start_location = scanner()->peek_location();
266 Statement statement = ParseFunctionDeclaration(CHECK_OK); 235 Statement statement = ParseFunctionDeclaration(CHECK_OK);
267 Scanner::Location end_location = scanner()->location(); 236 Scanner::Location end_location = scanner()->location();
268 if (!is_classic_mode()) { 237 if (!scope_->is_classic_mode()) {
269 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 238 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
270 "strict_function", NULL); 239 "strict_function", NULL);
271 *ok = false; 240 *ok = false;
272 return Statement::Default(); 241 return Statement::Default();
273 } else { 242 } else {
274 return statement; 243 return statement;
275 } 244 }
276 } 245 }
277 246
278 case Token::DEBUGGER: 247 case Token::DEBUGGER:
279 return ParseDebuggerStatement(ok); 248 return ParseDebuggerStatement(ok);
280 249
281 default: 250 default:
282 return ParseExpressionOrLabelledStatement(ok); 251 return ParseExpressionOrLabelledStatement(ok);
283 } 252 }
284 } 253 }
285 254
286 255
287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 256 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
288 // FunctionDeclaration :: 257 // FunctionDeclaration ::
289 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 258 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
290 // GeneratorDeclaration :: 259 // GeneratorDeclaration ::
291 // 'function' '*' Identifier '(' FormalParameterListopt ')' 260 // 'function' '*' Identifier '(' FormalParameterListopt ')'
292 // '{' FunctionBody '}' 261 // '{' FunctionBody '}'
293 Expect(Token::FUNCTION, CHECK_OK); 262 Expect(Token::FUNCTION, CHECK_OK);
294 263
295 bool is_generator = allow_generators() && Check(Token::MUL); 264 bool is_generator = allow_generators() && Check(Token::MUL);
296 Identifier identifier = ParseIdentifier(CHECK_OK); 265 bool is_strict_reserved = false;
297 Scanner::Location location = scanner()->location(); 266 Identifier name = ParseIdentifierOrStrictReservedWord(
298 267 &is_strict_reserved, CHECK_OK);
299 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); 268 ParseFunctionLiteral(name,
300 269 scanner()->location(),
301 if (function_value.IsStrictFunction() && 270 is_strict_reserved,
302 !identifier.IsValidStrictVariable()) { 271 is_generator,
303 // Strict mode violation, using either reserved word or eval/arguments 272 CHECK_OK);
304 // as name of strict function.
305 const char* type = "strict_function_name";
306 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
307 type = "strict_reserved_word";
308 }
309 ReportMessageAt(location, type, NULL);
310 *ok = false;
311 }
312 return Statement::FunctionDeclaration(); 273 return Statement::FunctionDeclaration();
313 } 274 }
314 275
315 276
316 PreParser::Statement PreParser::ParseBlock(bool* ok) { 277 PreParser::Statement PreParser::ParseBlock(bool* ok) {
317 // Block :: 278 // Block ::
318 // '{' Statement* '}' 279 // '{' Statement* '}'
319 280
320 // Note that a Block does not introduce a new execution scope! 281 // Note that a Block does not introduce a new execution scope!
321 // (ECMA-262, 3rd, 12.2) 282 // (ECMA-262, 3rd, 12.2)
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 } 397 }
437 398
438 // The scope of a var/const declared variable anywhere inside a function 399 // The scope of a var/const declared variable anywhere inside a function
439 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 400 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
440 // of a let declared variable is the scope of the immediately enclosing 401 // of a let declared variable is the scope of the immediately enclosing
441 // block. 402 // block.
442 int nvars = 0; // the number of variables declared 403 int nvars = 0; // the number of variables declared
443 do { 404 do {
444 // Parse variable name. 405 // Parse variable name.
445 if (nvars > 0) Consume(Token::COMMA); 406 if (nvars > 0) Consume(Token::COMMA);
446 Identifier identifier = ParseIdentifier(CHECK_OK); 407 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
447 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
448 StrictModeIdentifierViolation(scanner()->location(),
449 "strict_var_name",
450 identifier,
451 ok);
452 return Statement::Default();
453 }
454 nvars++; 408 nvars++;
455 if (peek() == Token::ASSIGN || require_initializer) { 409 if (peek() == Token::ASSIGN || require_initializer) {
456 Expect(Token::ASSIGN, CHECK_OK); 410 Expect(Token::ASSIGN, CHECK_OK);
457 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 411 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
458 if (decl_props != NULL) *decl_props = kHasInitializers; 412 if (decl_props != NULL) *decl_props = kHasInitializers;
459 } 413 }
460 } while (peek() == Token::COMMA); 414 } while (peek() == Token::COMMA);
461 415
462 if (num_decl != NULL) *num_decl = nvars; 416 if (num_decl != NULL) *num_decl = nvars;
463 return Statement::Default(); 417 return Statement::Default();
464 } 418 }
465 419
466 420
467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 421 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
468 // ExpressionStatement | LabelledStatement :: 422 // ExpressionStatement | LabelledStatement ::
469 // Expression ';' 423 // Expression ';'
470 // Identifier ':' Statement 424 // Identifier ':' Statement
471 425
426 bool starts_with_identifier = peek_any_identifier();
472 Expression expr = ParseExpression(true, CHECK_OK); 427 Expression expr = ParseExpression(true, CHECK_OK);
473 if (expr.IsRawIdentifier()) { 428 // Even if the expression starts with an identifier, it is not necessarily an
429 // identifier. For example, "foo + bar" starts with an identifier but is not
430 // an identifier.
431 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
432 // Expression is a single identifier, and not, e.g., a parenthesized
433 // identifier.
474 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 434 ASSERT(!expr.AsIdentifier().IsFutureReserved());
475 ASSERT(is_classic_mode() || 435 ASSERT(scope_->is_classic_mode() ||
476 (!expr.AsIdentifier().IsFutureStrictReserved() && 436 (!expr.AsIdentifier().IsFutureStrictReserved() &&
477 !expr.AsIdentifier().IsYield())); 437 !expr.AsIdentifier().IsYield()));
478 if (peek() == Token::COLON) { 438 Consume(Token::COLON);
479 Consume(Token::COLON); 439 return ParseStatement(ok);
480 return ParseStatement(ok);
481 }
482 // Preparsing is disabled for extensions (because the extension details 440 // Preparsing is disabled for extensions (because the extension details
483 // aren't passed to lazily compiled functions), so we don't 441 // aren't passed to lazily compiled functions), so we don't
484 // accept "native function" in the preparser. 442 // accept "native function" in the preparser.
485 } 443 }
486 // Parsed expression statement. 444 // Parsed expression statement.
487 ExpectSemicolon(CHECK_OK); 445 ExpectSemicolon(CHECK_OK);
488 return Statement::ExpressionStatement(expr); 446 return Statement::ExpressionStatement(expr);
489 } 447 }
490 448
491 449
(...skipping 17 matching lines...) Expand all
509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 467 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
510 // ContinueStatement :: 468 // ContinueStatement ::
511 // 'continue' [no line terminator] Identifier? ';' 469 // 'continue' [no line terminator] Identifier? ';'
512 470
513 Expect(Token::CONTINUE, CHECK_OK); 471 Expect(Token::CONTINUE, CHECK_OK);
514 Token::Value tok = peek(); 472 Token::Value tok = peek();
515 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 473 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
516 tok != Token::SEMICOLON && 474 tok != Token::SEMICOLON &&
517 tok != Token::RBRACE && 475 tok != Token::RBRACE &&
518 tok != Token::EOS) { 476 tok != Token::EOS) {
519 ParseIdentifier(CHECK_OK); 477 // ECMA allows "eval" or "arguments" as labels even in strict mode.
478 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
520 } 479 }
521 ExpectSemicolon(CHECK_OK); 480 ExpectSemicolon(CHECK_OK);
522 return Statement::Default(); 481 return Statement::Default();
523 } 482 }
524 483
525 484
526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 485 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
527 // BreakStatement :: 486 // BreakStatement ::
528 // 'break' [no line terminator] Identifier? ';' 487 // 'break' [no line terminator] Identifier? ';'
529 488
530 Expect(Token::BREAK, CHECK_OK); 489 Expect(Token::BREAK, CHECK_OK);
531 Token::Value tok = peek(); 490 Token::Value tok = peek();
532 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 491 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
533 tok != Token::SEMICOLON && 492 tok != Token::SEMICOLON &&
534 tok != Token::RBRACE && 493 tok != Token::RBRACE &&
535 tok != Token::EOS) { 494 tok != Token::EOS) {
536 ParseIdentifier(CHECK_OK); 495 // ECMA allows "eval" or "arguments" as labels even in strict mode.
496 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
537 } 497 }
538 ExpectSemicolon(CHECK_OK); 498 ExpectSemicolon(CHECK_OK);
539 return Statement::Default(); 499 return Statement::Default();
540 } 500 }
541 501
542 502
543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 503 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
544 // ReturnStatement :: 504 // ReturnStatement ::
545 // 'return' [no line terminator] Expression? ';' 505 // 'return' [no line terminator] Expression? ';'
546 506
(...skipping 16 matching lines...) Expand all
563 } 523 }
564 ExpectSemicolon(CHECK_OK); 524 ExpectSemicolon(CHECK_OK);
565 return Statement::Default(); 525 return Statement::Default();
566 } 526 }
567 527
568 528
569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 529 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
570 // WithStatement :: 530 // WithStatement ::
571 // 'with' '(' Expression ')' Statement 531 // 'with' '(' Expression ')' Statement
572 Expect(Token::WITH, CHECK_OK); 532 Expect(Token::WITH, CHECK_OK);
573 if (!is_classic_mode()) { 533 if (!scope_->is_classic_mode()) {
574 Scanner::Location location = scanner()->location(); 534 Scanner::Location location = scanner()->location();
575 ReportMessageAt(location, "strict_mode_with", NULL); 535 ReportMessageAt(location, "strict_mode_with", NULL);
576 *ok = false; 536 *ok = false;
577 return Statement::Default(); 537 return Statement::Default();
578 } 538 }
579 Expect(Token::LPAREN, CHECK_OK); 539 Expect(Token::LPAREN, CHECK_OK);
580 ParseExpression(true, CHECK_OK); 540 ParseExpression(true, CHECK_OK);
581 Expect(Token::RPAREN, CHECK_OK); 541 Expect(Token::RPAREN, CHECK_OK);
582 542
583 Scope::InsideWith iw(scope_); 543 Scope::InsideWith iw(scope_);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 // 'try' Block Catch 692 // 'try' Block Catch
733 // 'try' Block Finally 693 // 'try' Block Finally
734 // 'try' Block Catch Finally 694 // 'try' Block Catch Finally
735 // 695 //
736 // Catch :: 696 // Catch ::
737 // 'catch' '(' Identifier ')' Block 697 // 'catch' '(' Identifier ')' Block
738 // 698 //
739 // Finally :: 699 // Finally ::
740 // 'finally' Block 700 // 'finally' Block
741 701
742 // In preparsing, allow any number of catch/finally blocks, including zero
743 // of both.
744
745 Expect(Token::TRY, CHECK_OK); 702 Expect(Token::TRY, CHECK_OK);
746 703
747 ParseBlock(CHECK_OK); 704 ParseBlock(CHECK_OK);
748 705
749 bool catch_or_finally_seen = false; 706 Token::Value tok = peek();
750 if (peek() == Token::CATCH) { 707 if (tok != Token::CATCH && tok != Token::FINALLY) {
708 ReportMessageAt(scanner()->location(), "no_catch_or_finally", NULL);
709 *ok = false;
710 return Statement::Default();
711 }
712 if (tok == Token::CATCH) {
751 Consume(Token::CATCH); 713 Consume(Token::CATCH);
752 Expect(Token::LPAREN, CHECK_OK); 714 Expect(Token::LPAREN, CHECK_OK);
753 Identifier id = ParseIdentifier(CHECK_OK); 715 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
754 if (!is_classic_mode() && !id.IsValidStrictVariable()) {
755 StrictModeIdentifierViolation(scanner()->location(),
756 "strict_catch_variable",
757 id,
758 ok);
759 return Statement::Default();
760 }
761 Expect(Token::RPAREN, CHECK_OK); 716 Expect(Token::RPAREN, CHECK_OK);
762 { Scope::InsideWith iw(scope_); 717 { Scope::InsideWith iw(scope_);
763 ParseBlock(CHECK_OK); 718 ParseBlock(CHECK_OK);
764 } 719 }
765 catch_or_finally_seen = true; 720 tok = peek();
766 } 721 }
767 if (peek() == Token::FINALLY) { 722 if (tok == Token::FINALLY) {
768 Consume(Token::FINALLY); 723 Consume(Token::FINALLY);
769 ParseBlock(CHECK_OK); 724 ParseBlock(CHECK_OK);
770 catch_or_finally_seen = true;
771 }
772 if (!catch_or_finally_seen) {
773 *ok = false;
774 } 725 }
775 return Statement::Default(); 726 return Statement::Default();
776 } 727 }
777 728
778 729
779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 730 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
780 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 731 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
781 // contexts this is used as a statement which invokes the debugger as if a 732 // contexts this is used as a statement which invokes the debugger as if a
782 // break point is present. 733 // break point is present.
783 // DebuggerStatement :: 734 // DebuggerStatement ::
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 } 777 }
827 778
828 Scanner::Location before = scanner()->peek_location(); 779 Scanner::Location before = scanner()->peek_location();
829 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 780 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
830 781
831 if (!Token::IsAssignmentOp(peek())) { 782 if (!Token::IsAssignmentOp(peek())) {
832 // Parsed conditional expression only (no assignment). 783 // Parsed conditional expression only (no assignment).
833 return expression; 784 return expression;
834 } 785 }
835 786
836 if (!is_classic_mode() && 787 if (!scope_->is_classic_mode() &&
837 expression.IsIdentifier() && 788 expression.IsIdentifier() &&
838 expression.AsIdentifier().IsEvalOrArguments()) { 789 expression.AsIdentifier().IsEvalOrArguments()) {
839 Scanner::Location after = scanner()->location(); 790 Scanner::Location after = scanner()->location();
840 ReportMessageAt(before.beg_pos, after.end_pos, 791 ReportMessageAt(before.beg_pos, after.end_pos,
841 "strict_lhs_assignment", NULL); 792 "strict_eval_arguments", NULL);
842 *ok = false; 793 *ok = false;
843 return Expression::Default(); 794 return Expression::Default();
844 } 795 }
845 796
846 Token::Value op = Next(); // Get assignment operator. 797 Token::Value op = Next(); // Get assignment operator.
847 ParseAssignmentExpression(accept_IN, CHECK_OK); 798 ParseAssignmentExpression(accept_IN, CHECK_OK);
848 799
849 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { 800 if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
850 scope_->AddProperty(); 801 scope_->AddProperty();
851 } 802 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 871
921 Token::Value op = peek(); 872 Token::Value op = peek();
922 if (Token::IsUnaryOp(op)) { 873 if (Token::IsUnaryOp(op)) {
923 op = Next(); 874 op = Next();
924 ParseUnaryExpression(ok); 875 ParseUnaryExpression(ok);
925 return Expression::Default(); 876 return Expression::Default();
926 } else if (Token::IsCountOp(op)) { 877 } else if (Token::IsCountOp(op)) {
927 op = Next(); 878 op = Next();
928 Scanner::Location before = scanner()->peek_location(); 879 Scanner::Location before = scanner()->peek_location();
929 Expression expression = ParseUnaryExpression(CHECK_OK); 880 Expression expression = ParseUnaryExpression(CHECK_OK);
930 if (!is_classic_mode() && 881 if (!scope_->is_classic_mode() &&
931 expression.IsIdentifier() && 882 expression.IsIdentifier() &&
932 expression.AsIdentifier().IsEvalOrArguments()) { 883 expression.AsIdentifier().IsEvalOrArguments()) {
933 Scanner::Location after = scanner()->location(); 884 Scanner::Location after = scanner()->location();
934 ReportMessageAt(before.beg_pos, after.end_pos, 885 ReportMessageAt(before.beg_pos, after.end_pos,
935 "strict_lhs_prefix", NULL); 886 "strict_eval_arguments", NULL);
936 *ok = false; 887 *ok = false;
937 } 888 }
938 return Expression::Default(); 889 return Expression::Default();
939 } else { 890 } else {
940 return ParsePostfixExpression(ok); 891 return ParsePostfixExpression(ok);
941 } 892 }
942 } 893 }
943 894
944 895
945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 896 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
946 // PostfixExpression :: 897 // PostfixExpression ::
947 // LeftHandSideExpression ('++' | '--')? 898 // LeftHandSideExpression ('++' | '--')?
948 899
949 Scanner::Location before = scanner()->peek_location(); 900 Scanner::Location before = scanner()->peek_location();
950 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 901 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
951 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 902 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
952 Token::IsCountOp(peek())) { 903 Token::IsCountOp(peek())) {
953 if (!is_classic_mode() && 904 if (!scope_->is_classic_mode() &&
954 expression.IsIdentifier() && 905 expression.IsIdentifier() &&
955 expression.AsIdentifier().IsEvalOrArguments()) { 906 expression.AsIdentifier().IsEvalOrArguments()) {
956 Scanner::Location after = scanner()->location(); 907 Scanner::Location after = scanner()->location();
957 ReportMessageAt(before.beg_pos, after.end_pos, 908 ReportMessageAt(before.beg_pos, after.end_pos,
958 "strict_lhs_postfix", NULL); 909 "strict_eval_arguments", NULL);
959 *ok = false; 910 *ok = false;
960 return Expression::Default(); 911 return Expression::Default();
961 } 912 }
962 Next(); 913 Next();
963 return Expression::Default(); 914 return Expression::Default();
964 } 915 }
965 return expression; 916 return expression;
966 } 917 }
967 918
968 919
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 // MemberExpression :: 998 // MemberExpression ::
1048 // (PrimaryExpression | FunctionLiteral) 999 // (PrimaryExpression | FunctionLiteral)
1049 // ('[' Expression ']' | '.' Identifier | Arguments)* 1000 // ('[' Expression ']' | '.' Identifier | Arguments)*
1050 1001
1051 // Parse the initial primary or function expression. 1002 // Parse the initial primary or function expression.
1052 Expression result = Expression::Default(); 1003 Expression result = Expression::Default();
1053 if (peek() == Token::FUNCTION) { 1004 if (peek() == Token::FUNCTION) {
1054 Consume(Token::FUNCTION); 1005 Consume(Token::FUNCTION);
1055 1006
1056 bool is_generator = allow_generators() && Check(Token::MUL); 1007 bool is_generator = allow_generators() && Check(Token::MUL);
1057 Identifier identifier = Identifier::Default(); 1008 Identifier name = Identifier::Default();
1009 bool is_strict_reserved_name = false;
1010 Scanner::Location function_name_location = Scanner::Location::invalid();
1058 if (peek_any_identifier()) { 1011 if (peek_any_identifier()) {
1059 identifier = ParseIdentifier(CHECK_OK); 1012 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1013 CHECK_OK);
1014 function_name_location = scanner()->location();
1060 } 1015 }
1061 result = ParseFunctionLiteral(is_generator, CHECK_OK); 1016 result = ParseFunctionLiteral(name,
1062 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { 1017 function_name_location,
1063 StrictModeIdentifierViolation(scanner()->location(), 1018 is_strict_reserved_name,
1064 "strict_function_name", 1019 is_generator,
1065 identifier, 1020 CHECK_OK);
1066 ok);
1067 return Expression::Default();
1068 }
1069 } else { 1021 } else {
1070 result = ParsePrimaryExpression(CHECK_OK); 1022 result = ParsePrimaryExpression(CHECK_OK);
1071 } 1023 }
1072 1024
1073 while (true) { 1025 while (true) {
1074 switch (peek()) { 1026 switch (peek()) {
1075 case Token::LBRACK: { 1027 case Token::LBRACK: {
1076 Consume(Token::LBRACK); 1028 Consume(Token::LBRACK);
1077 ParseExpression(true, CHECK_OK); 1029 ParseExpression(true, CHECK_OK);
1078 Expect(Token::RBRACK, CHECK_OK); 1030 Expect(Token::RBRACK, CHECK_OK);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 case Token::THIS: { 1079 case Token::THIS: {
1128 Next(); 1080 Next();
1129 result = Expression::This(); 1081 result = Expression::This();
1130 break; 1082 break;
1131 } 1083 }
1132 1084
1133 case Token::FUTURE_RESERVED_WORD: 1085 case Token::FUTURE_RESERVED_WORD:
1134 case Token::FUTURE_STRICT_RESERVED_WORD: 1086 case Token::FUTURE_STRICT_RESERVED_WORD:
1135 case Token::YIELD: 1087 case Token::YIELD:
1136 case Token::IDENTIFIER: { 1088 case Token::IDENTIFIER: {
1137 Identifier id = ParseIdentifier(CHECK_OK); 1089 // Using eval or arguments in this context is OK even in strict mode.
1090 Identifier id = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1138 result = Expression::FromIdentifier(id); 1091 result = Expression::FromIdentifier(id);
1139 break; 1092 break;
1140 } 1093 }
1141 1094
1142 case Token::NULL_LITERAL: 1095 case Token::NULL_LITERAL:
1143 case Token::TRUE_LITERAL: 1096 case Token::TRUE_LITERAL:
1144 case Token::FALSE_LITERAL: 1097 case Token::FALSE_LITERAL:
1145 case Token::NUMBER: { 1098 case Token::NUMBER: {
1146 Next(); 1099 Next();
1147 break; 1100 break;
(...skipping 18 matching lines...) Expand all
1166 1119
1167 case Token::LBRACE: 1120 case Token::LBRACE:
1168 result = ParseObjectLiteral(CHECK_OK); 1121 result = ParseObjectLiteral(CHECK_OK);
1169 break; 1122 break;
1170 1123
1171 case Token::LPAREN: 1124 case Token::LPAREN:
1172 Consume(Token::LPAREN); 1125 Consume(Token::LPAREN);
1173 parenthesized_function_ = (peek() == Token::FUNCTION); 1126 parenthesized_function_ = (peek() == Token::FUNCTION);
1174 result = ParseExpression(true, CHECK_OK); 1127 result = ParseExpression(true, CHECK_OK);
1175 Expect(Token::RPAREN, CHECK_OK); 1128 Expect(Token::RPAREN, CHECK_OK);
1176 result = result.Parenthesize();
1177 break; 1129 break;
1178 1130
1179 case Token::MOD: 1131 case Token::MOD:
1180 result = ParseV8Intrinsic(CHECK_OK); 1132 result = ParseV8Intrinsic(CHECK_OK);
1181 break; 1133 break;
1182 1134
1183 default: { 1135 default: {
1184 Next(); 1136 Token::Value next = Next();
1137 ReportUnexpectedToken(next);
1185 *ok = false; 1138 *ok = false;
1186 return Expression::Default(); 1139 return Expression::Default();
1187 } 1140 }
1188 } 1141 }
1189 1142
1190 return result; 1143 return result;
1191 } 1144 }
1192 1145
1193 1146
1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { 1147 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 name != Token::STRING && 1192 name != Token::STRING &&
1240 !is_keyword) { 1193 !is_keyword) {
1241 *ok = false; 1194 *ok = false;
1242 return Expression::Default(); 1195 return Expression::Default();
1243 } 1196 }
1244 if (!is_keyword) { 1197 if (!is_keyword) {
1245 LogSymbol(); 1198 LogSymbol();
1246 } 1199 }
1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1200 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1248 checker.CheckProperty(name, type, CHECK_OK); 1201 checker.CheckProperty(name, type, CHECK_OK);
1249 ParseFunctionLiteral(false, CHECK_OK); 1202 ParseFunctionLiteral(Identifier::Default(),
1203 scanner()->location(),
1204 false, // reserved words are allowed here
1205 false, // not a generator
1206 CHECK_OK);
1250 if (peek() != Token::RBRACE) { 1207 if (peek() != Token::RBRACE) {
1251 Expect(Token::COMMA, CHECK_OK); 1208 Expect(Token::COMMA, CHECK_OK);
1252 } 1209 }
1253 continue; // restart the while 1210 continue; // restart the while
1254 } 1211 }
1255 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1212 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1256 break; 1213 break;
1257 } 1214 }
1258 case Token::STRING: 1215 case Token::STRING:
1259 Consume(next); 1216 Consume(next);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 done = (peek() == Token::RPAREN); 1282 done = (peek() == Token::RPAREN);
1326 if (!done) { 1283 if (!done) {
1327 Expect(Token::COMMA, ok); 1284 Expect(Token::COMMA, ok);
1328 if (!*ok) return -1; 1285 if (!*ok) return -1;
1329 } 1286 }
1330 } 1287 }
1331 Expect(Token::RPAREN, ok); 1288 Expect(Token::RPAREN, ok);
1332 return argc; 1289 return argc;
1333 } 1290 }
1334 1291
1335 1292 PreParser::Expression PreParser::ParseFunctionLiteral(
1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, 1293 Identifier function_name,
1337 bool* ok) { 1294 Scanner::Location function_name_location,
1295 bool name_is_strict_reserved,
1296 bool is_generator,
1297 bool* ok) {
1338 // Function :: 1298 // Function ::
1339 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1299 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1340 1300
1341 // Parse function body. 1301 // Parse function body.
1342 ScopeType outer_scope_type = scope_->type(); 1302 ScopeType outer_scope_type = scope_->type();
1343 bool inside_with = scope_->IsInsideWith(); 1303 bool inside_with = scope_->IsInsideWith();
1344 Scope function_scope(&scope_, kFunctionScope); 1304 Scope function_scope(&scope_, kFunctionScope);
1345 function_scope.set_is_generator(is_generator); 1305 function_scope.set_is_generator(is_generator);
1346 // FormalParameterList :: 1306 // FormalParameterList ::
1347 // '(' (Identifier)*[','] ')' 1307 // '(' (Identifier)*[','] ')'
1348 Expect(Token::LPAREN, CHECK_OK); 1308 Expect(Token::LPAREN, CHECK_OK);
1349 int start_position = position(); 1309 int start_position = position();
1350 bool done = (peek() == Token::RPAREN); 1310 bool done = (peek() == Token::RPAREN);
1351 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1311 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1312 // We don't yet know if the function will be strict, so we cannot yet produce
1313 // errors for parameter names or duplicates. However, we remember the
1314 // locations of these errors if they occur and produce the errors later.
1315 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
1316 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
1317 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
1352 while (!done) { 1318 while (!done) {
1353 Identifier id = ParseIdentifier(CHECK_OK); 1319 bool is_strict_reserved = false;
1354 if (!id.IsValidStrictVariable()) { 1320 Identifier param_name =
1355 StrictModeIdentifierViolation(scanner()->location(), 1321 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1356 "strict_param_name", 1322 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
1357 id, 1323 eval_args_error_loc = scanner()->location();
1358 CHECK_OK);
1359 } 1324 }
1325 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
1326 reserved_error_loc = scanner()->location();
1327 }
1328
1360 int prev_value; 1329 int prev_value;
1361 if (scanner()->is_literal_ascii()) { 1330 if (scanner()->is_literal_ascii()) {
1362 prev_value = 1331 prev_value =
1363 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); 1332 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1364 } else { 1333 } else {
1365 prev_value = 1334 prev_value =
1366 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); 1335 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1367 } 1336 }
1368 1337
1369 if (prev_value != 0) { 1338 if (!dupe_error_loc.IsValid() && prev_value != 0) {
1370 SetStrictModeViolation(scanner()->location(), 1339 dupe_error_loc = scanner()->location();
1371 "strict_param_dupe",
1372 CHECK_OK);
1373 } 1340 }
1341
1374 done = (peek() == Token::RPAREN); 1342 done = (peek() == Token::RPAREN);
1375 if (!done) { 1343 if (!done) {
1376 Expect(Token::COMMA, CHECK_OK); 1344 Expect(Token::COMMA, CHECK_OK);
1377 } 1345 }
1378 } 1346 }
1379 Expect(Token::RPAREN, CHECK_OK); 1347 Expect(Token::RPAREN, CHECK_OK);
1380 1348
1381 // Determine if the function will be lazily compiled. 1349 // Determine if the function will be lazily compiled.
1382 // Currently only happens to top-level functions. 1350 // Currently only happens to top-level functions.
1383 // Optimistically assume that all top-level functions are lazily compiled. 1351 // Optimistically assume that all top-level functions are lazily compiled.
1384 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && 1352 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1385 !inside_with && allow_lazy() && 1353 !inside_with && allow_lazy() &&
1386 !parenthesized_function_); 1354 !parenthesized_function_);
1387 parenthesized_function_ = false; 1355 parenthesized_function_ = false;
1388 1356
1389 Expect(Token::LBRACE, CHECK_OK); 1357 Expect(Token::LBRACE, CHECK_OK);
1390 if (is_lazily_compiled) { 1358 if (is_lazily_compiled) {
1391 ParseLazyFunctionLiteralBody(CHECK_OK); 1359 ParseLazyFunctionLiteralBody(CHECK_OK);
1392 } else { 1360 } else {
1393 ParseSourceElements(Token::RBRACE, ok); 1361 ParseSourceElements(Token::RBRACE, ok);
1394 } 1362 }
1395 Expect(Token::RBRACE, CHECK_OK); 1363 Expect(Token::RBRACE, CHECK_OK);
1396 1364
1397 if (!is_classic_mode()) { 1365 // Validate strict mode. We can do this only after parsing the function,
1366 // since the function can declare itself strict.
1367 if (!scope_->is_classic_mode()) {
1368 if (function_name.IsEvalOrArguments()) {
1369 ReportMessageAt(function_name_location, "strict_eval_arguments", NULL);
1370 *ok = false;
1371 return Expression::Default();
1372 }
1373 if (name_is_strict_reserved) {
1374 ReportMessageAt(
1375 function_name_location, "unexpected_strict_reserved", NULL);
1376 *ok = false;
1377 return Expression::Default();
1378 }
1379 if (eval_args_error_loc.IsValid()) {
1380 ReportMessageAt(eval_args_error_loc, "strict_eval_arguments",
1381 Vector<const char*>::empty());
1382 *ok = false;
1383 return Expression::Default();
1384 }
1385 if (dupe_error_loc.IsValid()) {
1386 ReportMessageAt(dupe_error_loc, "strict_param_dupe",
1387 Vector<const char*>::empty());
1388 *ok = false;
1389 return Expression::Default();
1390 }
1391 if (reserved_error_loc.IsValid()) {
1392 ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved",
1393 Vector<const char*>::empty());
1394 *ok = false;
1395 return Expression::Default();
1396 }
1397
1398 int end_position = scanner()->location().end_pos; 1398 int end_position = scanner()->location().end_pos;
1399 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1399 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1401 return Expression::StrictFunction(); 1400 return Expression::StrictFunction();
1402 } 1401 }
1403 1402
1404 return Expression::Default(); 1403 return Expression::Default();
1405 } 1404 }
1406 1405
1407 1406
1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1407 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1409 int body_start = position(); 1408 int body_start = position();
1410 log_->PauseRecording(); 1409 log_->PauseRecording();
(...skipping 12 matching lines...) Expand all
1423 1422
1424 1423
1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1424 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1426 // CallRuntime :: 1425 // CallRuntime ::
1427 // '%' Identifier Arguments 1426 // '%' Identifier Arguments
1428 Expect(Token::MOD, CHECK_OK); 1427 Expect(Token::MOD, CHECK_OK);
1429 if (!allow_natives_syntax()) { 1428 if (!allow_natives_syntax()) {
1430 *ok = false; 1429 *ok = false;
1431 return Expression::Default(); 1430 return Expression::Default();
1432 } 1431 }
1433 ParseIdentifier(CHECK_OK); 1432 // Allow "eval" or "arguments" for backward compatibility.
1433 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1434 ParseArguments(ok); 1434 ParseArguments(ok);
1435 1435
1436 return Expression::Default(); 1436 return Expression::Default();
1437 } 1437 }
1438 1438
1439 #undef CHECK_OK 1439 #undef CHECK_OK
1440 1440
1441 1441
1442 void PreParser::LogSymbol() { 1442 void PreParser::LogSymbol() {
1443 int identifier_pos = position(); 1443 int identifier_pos = position();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 } 1482 }
1483 if (scanner()->literal_length() == 9 && 1483 if (scanner()->literal_length() == 9 &&
1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { 1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485 return Identifier::Arguments(); 1485 return Identifier::Arguments();
1486 } 1486 }
1487 } 1487 }
1488 return Identifier::Default(); 1488 return Identifier::Default();
1489 } 1489 }
1490 1490
1491 1491
1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1492 // Parses an identifier that is valid for the current scope, in particular it
1493 // fails on strict mode future reserved keywords in a strict scope. If
1494 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
1495 // "arguments" as identifier even in strict mode (this is needed in cases like
1496 // "var foo = eval;").
1497 PreParser::Identifier PreParser::ParseIdentifier(
1498 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
1499 bool* ok) {
1493 Token::Value next = Next(); 1500 Token::Value next = Next();
1494 switch (next) { 1501 if (next == Token::IDENTIFIER) {
1495 case Token::FUTURE_RESERVED_WORD: { 1502 PreParser::Identifier name = GetIdentifierSymbol();
1496 Scanner::Location location = scanner()->location(); 1503 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1497 ReportMessageAt(location.beg_pos, location.end_pos, 1504 !scope_->is_classic_mode() && name.IsEvalOrArguments()) {
1498 "reserved_word", NULL); 1505 ReportMessageAt(scanner()->location(), "strict_eval_arguments", NULL);
1499 *ok = false; 1506 *ok = false;
1500 return GetIdentifierSymbol();
1501 } 1507 }
1502 case Token::YIELD: 1508 return name;
1503 if (scope_->is_generator()) { 1509 } else if (scope_->is_classic_mode() &&
1504 // 'yield' in a generator is only valid as part of a YieldExpression. 1510 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1505 ReportMessageAt(scanner()->location(), "unexpected_token", "yield"); 1511 (next == Token::YIELD && !scope_->is_generator()))) {
1506 *ok = false; 1512 return GetIdentifierSymbol();
1507 return Identifier::Yield(); 1513 } else {
1508 } 1514 ReportUnexpectedToken(next);
1509 // FALLTHROUGH 1515 *ok = false;
1510 case Token::FUTURE_STRICT_RESERVED_WORD: 1516 return Identifier::Default();
1511 if (!is_classic_mode()) {
1512 Scanner::Location location = scanner()->location();
1513 ReportMessageAt(location.beg_pos, location.end_pos,
1514 "strict_reserved_word", NULL);
1515 *ok = false;
1516 }
1517 // FALLTHROUGH
1518 case Token::IDENTIFIER:
1519 return GetIdentifierSymbol();
1520 default:
1521 *ok = false;
1522 return Identifier::Default();
1523 } 1517 }
1524 } 1518 }
1525 1519
1526 1520
1527 void PreParser::SetStrictModeViolation(Scanner::Location location, 1521 // Parses and identifier or a strict mode future reserved word, and indicate
1528 const char* type, 1522 // whether it is strict mode future reserved.
1529 bool* ok) { 1523 PreParser::Identifier PreParser::ParseIdentifierOrStrictReservedWord(
1530 if (!is_classic_mode()) { 1524 bool* is_strict_reserved, bool* ok) {
1531 ReportMessageAt(location, type, NULL); 1525 Token::Value next = Next();
1526 if (next == Token::IDENTIFIER) {
1527 *is_strict_reserved = false;
1528 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1529 (next == Token::YIELD && !scope_->is_generator())) {
1530 *is_strict_reserved = true;
1531 } else {
1532 ReportUnexpectedToken(next);
1532 *ok = false; 1533 *ok = false;
1533 return; 1534 return Identifier::Default();
1534 } 1535 }
1535 // Delay report in case this later turns out to be strict code 1536 return GetIdentifierSymbol();
1536 // (i.e., for function names and parameters prior to a "use strict"
1537 // directive).
1538 // It's safe to overwrite an existing violation.
1539 // It's either from a function that turned out to be non-strict,
1540 // or it's in the current function (and we just need to report
1541 // one error), or it's in a unclosed nesting function that wasn't
1542 // strict (otherwise we would already be in strict mode).
1543 strict_mode_violation_location_ = location;
1544 strict_mode_violation_type_ = type;
1545 }
1546
1547
1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1549 int end_pos,
1550 bool* ok) {
1551 Scanner::Location location = strict_mode_violation_location_;
1552 if (location.IsValid() &&
1553 location.beg_pos > beg_pos && location.end_pos < end_pos) {
1554 ReportMessageAt(location, strict_mode_violation_type_, NULL);
1555 *ok = false;
1556 }
1557 }
1558
1559
1560 void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
1561 const char* eval_args_type,
1562 Identifier identifier,
1563 bool* ok) {
1564 const char* type = eval_args_type;
1565 if (identifier.IsFutureReserved()) {
1566 type = "reserved_word";
1567 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1568 type = "strict_reserved_word";
1569 }
1570 if (!is_classic_mode()) {
1571 ReportMessageAt(location, type, NULL);
1572 *ok = false;
1573 return;
1574 }
1575 strict_mode_violation_location_ = location;
1576 strict_mode_violation_type_ = type;
1577 } 1537 }
1578 1538
1579 1539
1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1540 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1581 Token::Value next = Next(); 1541 Token::Value next = Next();
1582 if (Token::IsKeyword(next)) { 1542 if (next != Token::IDENTIFIER &&
1583 int pos = position(); 1543 next != Token::FUTURE_RESERVED_WORD &&
1584 const char* keyword = Token::String(next); 1544 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1585 log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword))); 1545 !Token::IsKeyword(next)) {
1546 ReportUnexpectedToken(next);
1547 *ok = false;
1586 return Identifier::Default(); 1548 return Identifier::Default();
1587 } 1549 }
1588 if (next == Token::IDENTIFIER || 1550 return GetIdentifierSymbol();
1589 next == Token::FUTURE_RESERVED_WORD ||
1590 next == Token::FUTURE_STRICT_RESERVED_WORD) {
1591 return GetIdentifierSymbol();
1592 }
1593 *ok = false;
1594 return Identifier::Default();
1595 } 1551 }
1596 1552
1597 #undef CHECK_OK 1553 #undef CHECK_OK
1598 1554
1599 1555
1600 // This function reads an identifier and determines whether or not it 1556 // This function reads an identifier and determines whether or not it
1601 // is 'get' or 'set'. 1557 // is 'get' or 'set'.
1602 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, 1558 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1603 bool* is_set, 1559 bool* is_set,
1604 bool* ok) { 1560 bool* ok) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 ASSERT(IsAccessorAccessorConflict(old_type, type)); 1596 ASSERT(IsAccessorAccessorConflict(old_type, type));
1641 // Both accessors of the same type. 1597 // Both accessors of the same type.
1642 parser()->ReportMessageAt(scanner()->location(), 1598 parser()->ReportMessageAt(scanner()->location(),
1643 "accessor_get_set"); 1599 "accessor_get_set");
1644 } 1600 }
1645 *ok = false; 1601 *ok = false;
1646 } 1602 }
1647 } 1603 }
1648 1604
1649 } } // v8::internal 1605 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698