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

Side by Side Diff: src/preparser.cc

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 years, 9 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/promise.js » ('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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 // Usually defined in math.h, but not in MSVC until VS2013+. 48 // Usually defined in math.h, but not in MSVC until VS2013+.
49 // Abstracted to work 49 // Abstracted to work
50 int isfinite(double value); 50 int isfinite(double value);
51 51
52 } // namespace std 52 } // namespace std
53 #endif 53 #endif
54 54
55 namespace v8 { 55 namespace v8 {
56 namespace internal { 56 namespace internal {
57 57
58 void PreParserTraits::ReportMessageAt(Scanner::Location location,
59 const char* message,
60 Vector<const char*> args) {
61 ReportMessageAt(location.beg_pos,
62 location.end_pos,
63 message,
64 args.length() > 0 ? args[0] : NULL);
65 }
66
67
68 void PreParserTraits::ReportMessageAt(Scanner::Location location,
69 const char* type,
70 const char* name_opt) {
71 pre_parser_->log_
72 ->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
73 }
74
75
76 void PreParserTraits::ReportMessageAt(int start_pos,
77 int end_pos,
78 const char* type,
79 const char* name_opt) {
80 pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt);
81 }
82
83
84 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
85 pre_parser_->LogSymbol();
86 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
87 return PreParserIdentifier::FutureReserved();
88 } else if (scanner->current_token() ==
89 Token::FUTURE_STRICT_RESERVED_WORD) {
90 return PreParserIdentifier::FutureStrictReserved();
91 } else if (scanner->current_token() == Token::YIELD) {
92 return PreParserIdentifier::Yield();
93 }
94 if (scanner->is_literal_ascii()) {
95 // Detect strict-mode poison words.
96 if (scanner->literal_length() == 4 &&
97 !strncmp(scanner->literal_ascii_string().start(), "eval", 4)) {
98 return PreParserIdentifier::Eval();
99 }
100 if (scanner->literal_length() == 9 &&
101 !strncmp(scanner->literal_ascii_string().start(), "arguments", 9)) {
102 return PreParserIdentifier::Arguments();
103 }
104 }
105 return PreParserIdentifier::Default();
106 }
107
108
109 PreParserExpression PreParserTraits::ExpressionFromString(
110 int pos, Scanner* scanner, PreParserFactory* factory) {
111 const int kUseStrictLength = 10;
112 const char* kUseStrictChars = "use strict";
113 pre_parser_->LogSymbol();
114 if (scanner->is_literal_ascii() &&
115 scanner->literal_length() == kUseStrictLength &&
116 !scanner->literal_contains_escapes() &&
117 !strncmp(scanner->literal_ascii_string().start(), kUseStrictChars,
118 kUseStrictLength)) {
119 return PreParserExpression::UseStrictStringLiteral();
120 }
121 return PreParserExpression::StringLiteral();
122 }
123
124
125 PreParserExpression PreParserTraits::ParseObjectLiteral(bool* ok) {
126 return pre_parser_->ParseObjectLiteral(ok);
127 }
128
129
130 PreParserExpression PreParserTraits::ParseAssignmentExpression(bool accept_IN,
131 bool* ok) {
132 return pre_parser_->ParseAssignmentExpression(accept_IN, ok);
133 }
134
135
136 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
137 return pre_parser_->ParseV8Intrinsic(ok);
138 }
139
140
141 PreParser::PreParseResult PreParser::PreParseLazyFunction( 58 PreParser::PreParseResult PreParser::PreParseLazyFunction(
142 LanguageMode mode, bool is_generator, ParserRecorder* log) { 59 LanguageMode mode, bool is_generator, ParserRecorder* log) {
143 log_ = log; 60 log_ = log;
144 // Lazy functions always have trivial outer scopes (no with/catch scopes). 61 // Lazy functions always have trivial outer scopes (no with/catch scopes).
145 PreParserScope top_scope(scope_, GLOBAL_SCOPE); 62 Scope top_scope(&scope_, kTopLevelScope);
146 FunctionState top_state(&function_state_, &scope_, &top_scope); 63 set_language_mode(mode);
147 scope_->SetLanguageMode(mode); 64 Scope function_scope(&scope_, kFunctionScope);
148 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 65 function_scope.set_is_generator(is_generator);
149 FunctionState function_state(&function_state_, &scope_, &function_scope);
150 function_state.set_is_generator(is_generator);
151 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); 66 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
152 bool ok = true; 67 bool ok = true;
153 int start_position = peek_position(); 68 int start_position = peek_position();
154 ParseLazyFunctionLiteralBody(&ok); 69 ParseLazyFunctionLiteralBody(&ok);
155 if (stack_overflow()) return kPreParseStackOverflow; 70 if (stack_overflow()) return kPreParseStackOverflow;
156 if (!ok) { 71 if (!ok) {
157 ReportUnexpectedToken(scanner()->current_token()); 72 ReportUnexpectedToken(scanner()->current_token());
158 } else { 73 } else {
159 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 74 ASSERT_EQ(Token::RBRACE, scanner()->peek());
160 if (!scope_->is_classic_mode()) { 75 if (!scope_->is_classic_mode()) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // (Statement)* <end_token> 132 // (Statement)* <end_token>
218 133
219 bool directive_prologue = true; 134 bool directive_prologue = true;
220 while (peek() != end_token) { 135 while (peek() != end_token) {
221 if (directive_prologue && peek() != Token::STRING) { 136 if (directive_prologue && peek() != Token::STRING) {
222 directive_prologue = false; 137 directive_prologue = false;
223 } 138 }
224 Statement statement = ParseSourceElement(CHECK_OK); 139 Statement statement = ParseSourceElement(CHECK_OK);
225 if (directive_prologue) { 140 if (directive_prologue) {
226 if (statement.IsUseStrictLiteral()) { 141 if (statement.IsUseStrictLiteral()) {
227 scope_->SetLanguageMode(allow_harmony_scoping() ? 142 set_language_mode(allow_harmony_scoping() ?
228 EXTENDED_MODE : STRICT_MODE); 143 EXTENDED_MODE : STRICT_MODE);
229 } else if (!statement.IsStringLiteral()) { 144 } else if (!statement.IsStringLiteral()) {
230 directive_prologue = false; 145 directive_prologue = false;
231 } 146 }
232 } 147 }
233 } 148 }
234 return kUnknownSourceElements; 149 return kUnknownSourceElements;
235 } 150 }
236 151
237 152
238 #undef CHECK_OK 153 #undef CHECK_OK
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 return ParseThrowStatement(ok); 228 return ParseThrowStatement(ok);
314 229
315 case Token::TRY: 230 case Token::TRY:
316 return ParseTryStatement(ok); 231 return ParseTryStatement(ok);
317 232
318 case Token::FUNCTION: { 233 case Token::FUNCTION: {
319 Scanner::Location start_location = scanner()->peek_location(); 234 Scanner::Location start_location = scanner()->peek_location();
320 Statement statement = ParseFunctionDeclaration(CHECK_OK); 235 Statement statement = ParseFunctionDeclaration(CHECK_OK);
321 Scanner::Location end_location = scanner()->location(); 236 Scanner::Location end_location = scanner()->location();
322 if (!scope_->is_classic_mode()) { 237 if (!scope_->is_classic_mode()) {
323 PreParserTraits::ReportMessageAt(start_location.beg_pos, 238 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
324 end_location.end_pos, 239 "strict_function", NULL);
325 "strict_function",
326 NULL);
327 *ok = false; 240 *ok = false;
328 return Statement::Default(); 241 return Statement::Default();
329 } else { 242 } else {
330 return statement; 243 return statement;
331 } 244 }
332 } 245 }
333 246
334 case Token::DEBUGGER: 247 case Token::DEBUGGER:
335 return ParseDebuggerStatement(ok); 248 return ParseDebuggerStatement(ok);
336 249
(...skipping 26 matching lines...) Expand all
363 276
364 PreParser::Statement PreParser::ParseBlock(bool* ok) { 277 PreParser::Statement PreParser::ParseBlock(bool* ok) {
365 // Block :: 278 // Block ::
366 // '{' Statement* '}' 279 // '{' Statement* '}'
367 280
368 // Note that a Block does not introduce a new execution scope! 281 // Note that a Block does not introduce a new execution scope!
369 // (ECMA-262, 3rd, 12.2) 282 // (ECMA-262, 3rd, 12.2)
370 // 283 //
371 Expect(Token::LBRACE, CHECK_OK); 284 Expect(Token::LBRACE, CHECK_OK);
372 while (peek() != Token::RBRACE) { 285 while (peek() != Token::RBRACE) {
373 if (scope_->is_extended_mode()) { 286 if (is_extended_mode()) {
374 ParseSourceElement(CHECK_OK); 287 ParseSourceElement(CHECK_OK);
375 } else { 288 } else {
376 ParseStatement(CHECK_OK); 289 ParseStatement(CHECK_OK);
377 } 290 }
378 } 291 }
379 Expect(Token::RBRACE, ok); 292 Expect(Token::RBRACE, ok);
380 return Statement::Default(); 293 return Statement::Default();
381 } 294 }
382 295
383 296
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 // 340 //
428 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 341 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
429 // 342 //
430 // * It is a Syntax Error if the code that matches this production is not 343 // * It is a Syntax Error if the code that matches this production is not
431 // contained in extended code. 344 // contained in extended code.
432 // 345 //
433 // However disallowing const in classic mode will break compatibility with 346 // However disallowing const in classic mode will break compatibility with
434 // existing pages. Therefore we keep allowing const with the old 347 // existing pages. Therefore we keep allowing const with the old
435 // non-harmony semantics in classic mode. 348 // non-harmony semantics in classic mode.
436 Consume(Token::CONST); 349 Consume(Token::CONST);
437 switch (scope_->language_mode()) { 350 switch (language_mode()) {
438 case CLASSIC_MODE: 351 case CLASSIC_MODE:
439 break; 352 break;
440 case STRICT_MODE: { 353 case STRICT_MODE: {
441 Scanner::Location location = scanner()->peek_location(); 354 Scanner::Location location = scanner()->peek_location();
442 ReportMessageAt(location, "strict_const"); 355 ReportMessageAt(location, "strict_const", NULL);
443 *ok = false; 356 *ok = false;
444 return Statement::Default(); 357 return Statement::Default();
445 } 358 }
446 case EXTENDED_MODE: 359 case EXTENDED_MODE:
447 if (var_context != kSourceElement && 360 if (var_context != kSourceElement &&
448 var_context != kForStatement) { 361 var_context != kForStatement) {
449 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); 362 Scanner::Location location = scanner()->peek_location();
363 ReportMessageAt(location.beg_pos, location.end_pos,
364 "unprotected_const", NULL);
450 *ok = false; 365 *ok = false;
451 return Statement::Default(); 366 return Statement::Default();
452 } 367 }
453 require_initializer = true; 368 require_initializer = true;
454 break; 369 break;
455 } 370 }
456 } else if (peek() == Token::LET) { 371 } else if (peek() == Token::LET) {
457 // ES6 Draft Rev4 section 12.2.1: 372 // ES6 Draft Rev4 section 12.2.1:
458 // 373 //
459 // LetDeclaration : let LetBindingList ; 374 // LetDeclaration : let LetBindingList ;
460 // 375 //
461 // * It is a Syntax Error if the code that matches this production is not 376 // * It is a Syntax Error if the code that matches this production is not
462 // contained in extended code. 377 // contained in extended code.
463 if (!scope_->is_extended_mode()) { 378 if (!is_extended_mode()) {
464 ReportMessageAt(scanner()->peek_location(), "illegal_let"); 379 Scanner::Location location = scanner()->peek_location();
380 ReportMessageAt(location.beg_pos, location.end_pos,
381 "illegal_let", NULL);
465 *ok = false; 382 *ok = false;
466 return Statement::Default(); 383 return Statement::Default();
467 } 384 }
468 Consume(Token::LET); 385 Consume(Token::LET);
469 if (var_context != kSourceElement && 386 if (var_context != kSourceElement &&
470 var_context != kForStatement) { 387 var_context != kForStatement) {
471 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 388 Scanner::Location location = scanner()->peek_location();
389 ReportMessageAt(location.beg_pos, location.end_pos,
390 "unprotected_let", NULL);
472 *ok = false; 391 *ok = false;
473 return Statement::Default(); 392 return Statement::Default();
474 } 393 }
475 } else { 394 } else {
476 *ok = false; 395 *ok = false;
477 return Statement::Default(); 396 return Statement::Default();
478 } 397 }
479 398
480 // 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
481 // 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
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 ExpectSemicolon(CHECK_OK); 524 ExpectSemicolon(CHECK_OK);
606 return Statement::Default(); 525 return Statement::Default();
607 } 526 }
608 527
609 528
610 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 529 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
611 // WithStatement :: 530 // WithStatement ::
612 // 'with' '(' Expression ')' Statement 531 // 'with' '(' Expression ')' Statement
613 Expect(Token::WITH, CHECK_OK); 532 Expect(Token::WITH, CHECK_OK);
614 if (!scope_->is_classic_mode()) { 533 if (!scope_->is_classic_mode()) {
615 ReportMessageAt(scanner()->location(), "strict_mode_with"); 534 Scanner::Location location = scanner()->location();
535 ReportMessageAt(location, "strict_mode_with", NULL);
616 *ok = false; 536 *ok = false;
617 return Statement::Default(); 537 return Statement::Default();
618 } 538 }
619 Expect(Token::LPAREN, CHECK_OK); 539 Expect(Token::LPAREN, CHECK_OK);
620 ParseExpression(true, CHECK_OK); 540 ParseExpression(true, CHECK_OK);
621 Expect(Token::RPAREN, CHECK_OK); 541 Expect(Token::RPAREN, CHECK_OK);
622 542
623 PreParserScope with_scope(scope_, WITH_SCOPE); 543 Scope::InsideWith iw(scope_);
624 BlockState block_state(&scope_, &with_scope);
625 ParseStatement(CHECK_OK); 544 ParseStatement(CHECK_OK);
626 return Statement::Default(); 545 return Statement::Default();
627 } 546 }
628 547
629 548
630 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 549 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
631 // SwitchStatement :: 550 // SwitchStatement ::
632 // 'switch' '(' Expression ')' '{' CaseClause* '}' 551 // 'switch' '(' Expression ')' '{' CaseClause* '}'
633 552
634 Expect(Token::SWITCH, CHECK_OK); 553 Expect(Token::SWITCH, CHECK_OK);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 return Statement::Default(); 669 return Statement::Default();
751 } 670 }
752 671
753 672
754 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 673 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
755 // ThrowStatement :: 674 // ThrowStatement ::
756 // 'throw' [no line terminator] Expression ';' 675 // 'throw' [no line terminator] Expression ';'
757 676
758 Expect(Token::THROW, CHECK_OK); 677 Expect(Token::THROW, CHECK_OK);
759 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 678 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
760 ReportMessageAt(scanner()->location(), "newline_after_throw"); 679 Scanner::Location pos = scanner()->location();
680 ReportMessageAt(pos, "newline_after_throw", NULL);
761 *ok = false; 681 *ok = false;
762 return Statement::Default(); 682 return Statement::Default();
763 } 683 }
764 ParseExpression(true, CHECK_OK); 684 ParseExpression(true, CHECK_OK);
765 ExpectSemicolon(ok); 685 ExpectSemicolon(ok);
766 return Statement::Default(); 686 return Statement::Default();
767 } 687 }
768 688
769 689
770 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { 690 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
771 // TryStatement :: 691 // TryStatement ::
772 // 'try' Block Catch 692 // 'try' Block Catch
773 // 'try' Block Finally 693 // 'try' Block Finally
774 // 'try' Block Catch Finally 694 // 'try' Block Catch Finally
775 // 695 //
776 // Catch :: 696 // Catch ::
777 // 'catch' '(' Identifier ')' Block 697 // 'catch' '(' Identifier ')' Block
778 // 698 //
779 // Finally :: 699 // Finally ::
780 // 'finally' Block 700 // 'finally' Block
781 701
782 Expect(Token::TRY, CHECK_OK); 702 Expect(Token::TRY, CHECK_OK);
783 703
784 ParseBlock(CHECK_OK); 704 ParseBlock(CHECK_OK);
785 705
786 Token::Value tok = peek(); 706 Token::Value tok = peek();
787 if (tok != Token::CATCH && tok != Token::FINALLY) { 707 if (tok != Token::CATCH && tok != Token::FINALLY) {
788 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); 708 ReportMessageAt(scanner()->location(), "no_catch_or_finally", NULL);
789 *ok = false; 709 *ok = false;
790 return Statement::Default(); 710 return Statement::Default();
791 } 711 }
792 if (tok == Token::CATCH) { 712 if (tok == Token::CATCH) {
793 Consume(Token::CATCH); 713 Consume(Token::CATCH);
794 Expect(Token::LPAREN, CHECK_OK); 714 Expect(Token::LPAREN, CHECK_OK);
795 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 715 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
796 Expect(Token::RPAREN, CHECK_OK); 716 Expect(Token::RPAREN, CHECK_OK);
797 { 717 { Scope::InsideWith iw(scope_);
798 PreParserScope with_scope(scope_, WITH_SCOPE);
799 BlockState block_state(&scope_, &with_scope);
800 ParseBlock(CHECK_OK); 718 ParseBlock(CHECK_OK);
801 } 719 }
802 tok = peek(); 720 tok = peek();
803 } 721 }
804 if (tok == Token::FINALLY) { 722 if (tok == Token::FINALLY) {
805 Consume(Token::FINALLY); 723 Consume(Token::FINALLY);
806 ParseBlock(CHECK_OK); 724 ParseBlock(CHECK_OK);
807 } 725 }
808 return Statement::Default(); 726 return Statement::Default();
809 } 727 }
(...skipping 13 matching lines...) Expand all
823 741
824 742
825 #undef CHECK_OK 743 #undef CHECK_OK
826 #define CHECK_OK ok); \ 744 #define CHECK_OK ok); \
827 if (!*ok) return Expression::Default(); \ 745 if (!*ok) return Expression::Default(); \
828 ((void)0 746 ((void)0
829 #define DUMMY ) // to make indentation work 747 #define DUMMY ) // to make indentation work
830 #undef DUMMY 748 #undef DUMMY
831 749
832 750
751 // Precedence = 1
752 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
753 // Expression ::
754 // AssignmentExpression
755 // Expression ',' AssignmentExpression
756
757 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
758 while (peek() == Token::COMMA) {
759 Expect(Token::COMMA, CHECK_OK);
760 ParseAssignmentExpression(accept_IN, CHECK_OK);
761 result = Expression::Default();
762 }
763 return result;
764 }
765
766
833 // Precedence = 2 767 // Precedence = 2
834 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, 768 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
835 bool* ok) { 769 bool* ok) {
836 // AssignmentExpression :: 770 // AssignmentExpression ::
837 // ConditionalExpression 771 // ConditionalExpression
838 // YieldExpression 772 // YieldExpression
839 // LeftHandSideExpression AssignmentOperator AssignmentExpression 773 // LeftHandSideExpression AssignmentOperator AssignmentExpression
840 774
841 if (function_state_->is_generator() && peek() == Token::YIELD) { 775 if (scope_->is_generator() && peek() == Token::YIELD) {
842 return ParseYieldExpression(ok); 776 return ParseYieldExpression(ok);
843 } 777 }
844 778
845 Scanner::Location before = scanner()->peek_location(); 779 Scanner::Location before = scanner()->peek_location();
846 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 780 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
847 781
848 if (!Token::IsAssignmentOp(peek())) { 782 if (!Token::IsAssignmentOp(peek())) {
849 // Parsed conditional expression only (no assignment). 783 // Parsed conditional expression only (no assignment).
850 return expression; 784 return expression;
851 } 785 }
852 786
853 if (!scope_->is_classic_mode() && 787 if (!scope_->is_classic_mode() &&
854 expression.IsIdentifier() && 788 expression.IsIdentifier() &&
855 expression.AsIdentifier().IsEvalOrArguments()) { 789 expression.AsIdentifier().IsEvalOrArguments()) {
856 Scanner::Location after = scanner()->location(); 790 Scanner::Location after = scanner()->location();
857 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos, 791 ReportMessageAt(before.beg_pos, after.end_pos,
858 "strict_eval_arguments", NULL); 792 "strict_eval_arguments", NULL);
859 *ok = false; 793 *ok = false;
860 return Expression::Default(); 794 return Expression::Default();
861 } 795 }
862 796
863 Token::Value op = Next(); // Get assignment operator. 797 Token::Value op = Next(); // Get assignment operator.
864 ParseAssignmentExpression(accept_IN, CHECK_OK); 798 ParseAssignmentExpression(accept_IN, CHECK_OK);
865 799
866 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { 800 if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
867 function_state_->AddProperty(); 801 scope_->AddProperty();
868 } 802 }
869 803
870 return Expression::Default(); 804 return Expression::Default();
871 } 805 }
872 806
873 807
874 // Precedence = 3 808 // Precedence = 3
875 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { 809 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
876 // YieldExpression :: 810 // YieldExpression ::
877 // 'yield' '*'? AssignmentExpression 811 // 'yield' '*'? AssignmentExpression
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 ParseUnaryExpression(ok); 875 ParseUnaryExpression(ok);
942 return Expression::Default(); 876 return Expression::Default();
943 } else if (Token::IsCountOp(op)) { 877 } else if (Token::IsCountOp(op)) {
944 op = Next(); 878 op = Next();
945 Scanner::Location before = scanner()->peek_location(); 879 Scanner::Location before = scanner()->peek_location();
946 Expression expression = ParseUnaryExpression(CHECK_OK); 880 Expression expression = ParseUnaryExpression(CHECK_OK);
947 if (!scope_->is_classic_mode() && 881 if (!scope_->is_classic_mode() &&
948 expression.IsIdentifier() && 882 expression.IsIdentifier() &&
949 expression.AsIdentifier().IsEvalOrArguments()) { 883 expression.AsIdentifier().IsEvalOrArguments()) {
950 Scanner::Location after = scanner()->location(); 884 Scanner::Location after = scanner()->location();
951 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos, 885 ReportMessageAt(before.beg_pos, after.end_pos,
952 "strict_eval_arguments", NULL); 886 "strict_eval_arguments", NULL);
953 *ok = false; 887 *ok = false;
954 } 888 }
955 return Expression::Default(); 889 return Expression::Default();
956 } else { 890 } else {
957 return ParsePostfixExpression(ok); 891 return ParsePostfixExpression(ok);
958 } 892 }
959 } 893 }
960 894
961 895
962 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 896 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
963 // PostfixExpression :: 897 // PostfixExpression ::
964 // LeftHandSideExpression ('++' | '--')? 898 // LeftHandSideExpression ('++' | '--')?
965 899
966 Scanner::Location before = scanner()->peek_location(); 900 Scanner::Location before = scanner()->peek_location();
967 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 901 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
968 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 902 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
969 Token::IsCountOp(peek())) { 903 Token::IsCountOp(peek())) {
970 if (!scope_->is_classic_mode() && 904 if (!scope_->is_classic_mode() &&
971 expression.IsIdentifier() && 905 expression.IsIdentifier() &&
972 expression.AsIdentifier().IsEvalOrArguments()) { 906 expression.AsIdentifier().IsEvalOrArguments()) {
973 Scanner::Location after = scanner()->location(); 907 Scanner::Location after = scanner()->location();
974 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos, 908 ReportMessageAt(before.beg_pos, after.end_pos,
975 "strict_eval_arguments", NULL); 909 "strict_eval_arguments", NULL);
976 *ok = false; 910 *ok = false;
977 return Expression::Default(); 911 return Expression::Default();
978 } 912 }
979 Next(); 913 Next();
980 return Expression::Default(); 914 return Expression::Default();
981 } 915 }
982 return expression; 916 return expression;
983 } 917 }
984 918
985 919
986 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { 920 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
987 // LeftHandSideExpression :: 921 // LeftHandSideExpression ::
988 // (NewExpression | MemberExpression) ... 922 // (NewExpression | MemberExpression) ...
989 923
990 Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK); 924 Expression result = Expression::Default();
925 if (peek() == Token::NEW) {
926 result = ParseNewExpression(CHECK_OK);
927 } else {
928 result = ParseMemberExpression(CHECK_OK);
929 }
991 930
992 while (true) { 931 while (true) {
993 switch (peek()) { 932 switch (peek()) {
994 case Token::LBRACK: { 933 case Token::LBRACK: {
995 Consume(Token::LBRACK); 934 Consume(Token::LBRACK);
996 ParseExpression(true, CHECK_OK); 935 ParseExpression(true, CHECK_OK);
997 Expect(Token::RBRACK, CHECK_OK); 936 Expect(Token::RBRACK, CHECK_OK);
998 if (result.IsThis()) { 937 if (result.IsThis()) {
999 result = Expression::ThisProperty(); 938 result = Expression::ThisProperty();
1000 } else { 939 } else {
(...skipping 19 matching lines...) Expand all
1020 break; 959 break;
1021 } 960 }
1022 961
1023 default: 962 default:
1024 return result; 963 return result;
1025 } 964 }
1026 } 965 }
1027 } 966 }
1028 967
1029 968
969 PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
970 // NewExpression ::
971 // ('new')+ MemberExpression
972
973 // The grammar for new expressions is pretty warped. The keyword
974 // 'new' can either be a part of the new expression (where it isn't
975 // followed by an argument list) or a part of the member expression,
976 // where it must be followed by an argument list. To accommodate
977 // this, we parse the 'new' keywords greedily and keep track of how
978 // many we have parsed. This information is then passed on to the
979 // member expression parser, which is only allowed to match argument
980 // lists as long as it has 'new' prefixes left
981 unsigned new_count = 0;
982 do {
983 Consume(Token::NEW);
984 new_count++;
985 } while (peek() == Token::NEW);
986
987 return ParseMemberWithNewPrefixesExpression(new_count, ok);
988 }
989
990
991 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
992 return ParseMemberWithNewPrefixesExpression(0, ok);
993 }
994
995
1030 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( 996 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1031 bool* ok) { 997 unsigned new_count, bool* ok) {
1032 // NewExpression ::
1033 // ('new')+ MemberExpression
1034
1035 // See Parser::ParseNewExpression.
1036
1037 if (peek() == Token::NEW) {
1038 Consume(Token::NEW);
1039 ParseMemberWithNewPrefixesExpression(CHECK_OK);
1040 if (peek() == Token::LPAREN) {
1041 // NewExpression with arguments.
1042 ParseArguments(CHECK_OK);
1043 // The expression can still continue with . or [ after the arguments.
1044 ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK);
1045 }
1046 return Expression::Default();
1047 }
1048 // No 'new' keyword.
1049 return ParseMemberExpression(ok);
1050 }
1051
1052
1053 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1054 // MemberExpression :: 998 // MemberExpression ::
1055 // (PrimaryExpression | FunctionLiteral) 999 // (PrimaryExpression | FunctionLiteral)
1056 // ('[' Expression ']' | '.' Identifier | Arguments)* 1000 // ('[' Expression ']' | '.' Identifier | Arguments)*
1057 1001
1058 // The '[' Expression ']' and '.' Identifier parts are parsed by
1059 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
1060 // caller.
1061
1062 // Parse the initial primary or function expression. 1002 // Parse the initial primary or function expression.
1063 Expression result = Expression::Default(); 1003 Expression result = Expression::Default();
1064 if (peek() == Token::FUNCTION) { 1004 if (peek() == Token::FUNCTION) {
1065 Consume(Token::FUNCTION); 1005 Consume(Token::FUNCTION);
1066 1006
1067 bool is_generator = allow_generators() && Check(Token::MUL); 1007 bool is_generator = allow_generators() && Check(Token::MUL);
1068 Identifier name = Identifier::Default(); 1008 Identifier name = Identifier::Default();
1069 bool is_strict_reserved_name = false; 1009 bool is_strict_reserved_name = false;
1070 Scanner::Location function_name_location = Scanner::Location::invalid(); 1010 Scanner::Location function_name_location = Scanner::Location::invalid();
1071 if (peek_any_identifier()) { 1011 if (peek_any_identifier()) {
1072 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 1012 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1073 CHECK_OK); 1013 CHECK_OK);
1074 function_name_location = scanner()->location(); 1014 function_name_location = scanner()->location();
1075 } 1015 }
1076 result = ParseFunctionLiteral(name, 1016 result = ParseFunctionLiteral(name,
1077 function_name_location, 1017 function_name_location,
1078 is_strict_reserved_name, 1018 is_strict_reserved_name,
1079 is_generator, 1019 is_generator,
1080 CHECK_OK); 1020 CHECK_OK);
1081 } else { 1021 } else {
1082 result = ParsePrimaryExpression(CHECK_OK); 1022 result = ParsePrimaryExpression(CHECK_OK);
1083 } 1023 }
1084 result = ParseMemberExpressionContinuation(result, CHECK_OK);
1085 return result;
1086 }
1087 1024
1088
1089 PreParser::Expression PreParser::ParseMemberExpressionContinuation(
1090 PreParserExpression expression, bool* ok) {
1091 // Parses this part of MemberExpression:
1092 // ('[' Expression ']' | '.' Identifier)*
1093 while (true) { 1025 while (true) {
1094 switch (peek()) { 1026 switch (peek()) {
1095 case Token::LBRACK: { 1027 case Token::LBRACK: {
1096 Consume(Token::LBRACK); 1028 Consume(Token::LBRACK);
1097 ParseExpression(true, CHECK_OK); 1029 ParseExpression(true, CHECK_OK);
1098 Expect(Token::RBRACK, CHECK_OK); 1030 Expect(Token::RBRACK, CHECK_OK);
1099 if (expression.IsThis()) { 1031 if (result.IsThis()) {
1100 expression = Expression::ThisProperty(); 1032 result = Expression::ThisProperty();
1101 } else { 1033 } else {
1102 expression = Expression::Default(); 1034 result = Expression::Default();
1103 } 1035 }
1104 break; 1036 break;
1105 } 1037 }
1106 case Token::PERIOD: { 1038 case Token::PERIOD: {
1107 Consume(Token::PERIOD); 1039 Consume(Token::PERIOD);
1108 ParseIdentifierName(CHECK_OK); 1040 ParseIdentifierName(CHECK_OK);
1109 if (expression.IsThis()) { 1041 if (result.IsThis()) {
1110 expression = Expression::ThisProperty(); 1042 result = Expression::ThisProperty();
1111 } else { 1043 } else {
1112 expression = Expression::Default(); 1044 result = Expression::Default();
1113 } 1045 }
1114 break; 1046 break;
1115 } 1047 }
1048 case Token::LPAREN: {
1049 if (new_count == 0) return result;
1050 // Consume one of the new prefixes (already parsed).
1051 ParseArguments(CHECK_OK);
1052 new_count--;
1053 result = Expression::Default();
1054 break;
1055 }
1116 default: 1056 default:
1117 return expression; 1057 return result;
1118 } 1058 }
1119 } 1059 }
1120 ASSERT(false);
1121 return PreParserExpression::Default();
1122 } 1060 }
1123 1061
1124 1062
1063 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
1064 // PrimaryExpression ::
1065 // 'this'
1066 // 'null'
1067 // 'true'
1068 // 'false'
1069 // Identifier
1070 // Number
1071 // String
1072 // ArrayLiteral
1073 // ObjectLiteral
1074 // RegExpLiteral
1075 // '(' Expression ')'
1076
1077 Expression result = Expression::Default();
1078 switch (peek()) {
1079 case Token::THIS: {
1080 Next();
1081 result = Expression::This();
1082 break;
1083 }
1084
1085 case Token::FUTURE_RESERVED_WORD:
1086 case Token::FUTURE_STRICT_RESERVED_WORD:
1087 case Token::YIELD:
1088 case Token::IDENTIFIER: {
1089 // Using eval or arguments in this context is OK even in strict mode.
1090 Identifier id = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1091 result = Expression::FromIdentifier(id);
1092 break;
1093 }
1094
1095 case Token::NULL_LITERAL:
1096 case Token::TRUE_LITERAL:
1097 case Token::FALSE_LITERAL:
1098 case Token::NUMBER: {
1099 Next();
1100 break;
1101 }
1102 case Token::STRING: {
1103 Next();
1104 result = GetStringSymbol();
1105 break;
1106 }
1107
1108 case Token::ASSIGN_DIV:
1109 result = ParseRegExpLiteral(true, CHECK_OK);
1110 break;
1111
1112 case Token::DIV:
1113 result = ParseRegExpLiteral(false, CHECK_OK);
1114 break;
1115
1116 case Token::LBRACK:
1117 result = ParseArrayLiteral(CHECK_OK);
1118 break;
1119
1120 case Token::LBRACE:
1121 result = ParseObjectLiteral(CHECK_OK);
1122 break;
1123
1124 case Token::LPAREN:
1125 Consume(Token::LPAREN);
1126 parenthesized_function_ = (peek() == Token::FUNCTION);
1127 result = ParseExpression(true, CHECK_OK);
1128 Expect(Token::RPAREN, CHECK_OK);
1129 break;
1130
1131 case Token::MOD:
1132 result = ParseV8Intrinsic(CHECK_OK);
1133 break;
1134
1135 default: {
1136 Token::Value next = Next();
1137 ReportUnexpectedToken(next);
1138 *ok = false;
1139 return Expression::Default();
1140 }
1141 }
1142
1143 return result;
1144 }
1145
1146
1147 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1148 // ArrayLiteral ::
1149 // '[' Expression? (',' Expression?)* ']'
1150 Expect(Token::LBRACK, CHECK_OK);
1151 while (peek() != Token::RBRACK) {
1152 if (peek() != Token::COMMA) {
1153 ParseAssignmentExpression(true, CHECK_OK);
1154 }
1155 if (peek() != Token::RBRACK) {
1156 Expect(Token::COMMA, CHECK_OK);
1157 }
1158 }
1159 Expect(Token::RBRACK, CHECK_OK);
1160
1161 scope_->NextMaterializedLiteralIndex();
1162 return Expression::Default();
1163 }
1164
1165
1125 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { 1166 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1126 // ObjectLiteral :: 1167 // ObjectLiteral ::
1127 // '{' ( 1168 // '{' (
1128 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1169 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1129 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1170 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1130 // )*[','] '}' 1171 // )*[','] '}'
1131 1172
1132 ObjectLiteralChecker checker(this, scope_->language_mode()); 1173 ObjectLiteralChecker checker(this, language_mode());
1133 1174
1134 Expect(Token::LBRACE, CHECK_OK); 1175 Expect(Token::LBRACE, CHECK_OK);
1135 while (peek() != Token::RBRACE) { 1176 while (peek() != Token::RBRACE) {
1136 Token::Value next = peek(); 1177 Token::Value next = peek();
1137 switch (next) { 1178 switch (next) {
1138 case Token::IDENTIFIER: 1179 case Token::IDENTIFIER:
1139 case Token::FUTURE_RESERVED_WORD: 1180 case Token::FUTURE_RESERVED_WORD:
1140 case Token::FUTURE_STRICT_RESERVED_WORD: { 1181 case Token::FUTURE_STRICT_RESERVED_WORD: {
1141 bool is_getter = false; 1182 bool is_getter = false;
1142 bool is_setter = false; 1183 bool is_setter = false;
(...skipping 24 matching lines...) Expand all
1167 Expect(Token::COMMA, CHECK_OK); 1208 Expect(Token::COMMA, CHECK_OK);
1168 } 1209 }
1169 continue; // restart the while 1210 continue; // restart the while
1170 } 1211 }
1171 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1212 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1172 break; 1213 break;
1173 } 1214 }
1174 case Token::STRING: 1215 case Token::STRING:
1175 Consume(next); 1216 Consume(next);
1176 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1217 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1177 LogSymbol(); 1218 GetStringSymbol();
1178 break; 1219 break;
1179 case Token::NUMBER: 1220 case Token::NUMBER:
1180 Consume(next); 1221 Consume(next);
1181 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1222 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1182 break; 1223 break;
1183 default: 1224 default:
1184 if (Token::IsKeyword(next)) { 1225 if (Token::IsKeyword(next)) {
1185 Consume(next); 1226 Consume(next);
1186 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1227 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1187 LogSymbol();
1188 } else { 1228 } else {
1189 // Unexpected token. 1229 // Unexpected token.
1190 *ok = false; 1230 *ok = false;
1191 return Expression::Default(); 1231 return Expression::Default();
1192 } 1232 }
1193 } 1233 }
1194 1234
1195 Expect(Token::COLON, CHECK_OK); 1235 Expect(Token::COLON, CHECK_OK);
1196 ParseAssignmentExpression(true, CHECK_OK); 1236 ParseAssignmentExpression(true, CHECK_OK);
1197 1237
1198 // TODO(1240767): Consider allowing trailing comma. 1238 // TODO(1240767): Consider allowing trailing comma.
1199 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 1239 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1200 } 1240 }
1201 Expect(Token::RBRACE, CHECK_OK); 1241 Expect(Token::RBRACE, CHECK_OK);
1202 1242
1203 function_state_->NextMaterializedLiteralIndex(); 1243 scope_->NextMaterializedLiteralIndex();
1204 return Expression::Default(); 1244 return Expression::Default();
1205 } 1245 }
1206 1246
1247
1248 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1249 bool* ok) {
1250 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1251 Next();
1252 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
1253 *ok = false;
1254 return Expression::Default();
1255 }
1256
1257 scope_->NextMaterializedLiteralIndex();
1258
1259 if (!scanner()->ScanRegExpFlags()) {
1260 Next();
1261 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
1262 *ok = false;
1263 return Expression::Default();
1264 }
1265 Next();
1266 return Expression::Default();
1267 }
1268
1207 1269
1208 PreParser::Arguments PreParser::ParseArguments(bool* ok) { 1270 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1209 // Arguments :: 1271 // Arguments ::
1210 // '(' (AssignmentExpression)*[','] ')' 1272 // '(' (AssignmentExpression)*[','] ')'
1211 1273
1212 Expect(Token::LPAREN, ok); 1274 Expect(Token::LPAREN, ok);
1213 if (!*ok) return -1; 1275 if (!*ok) return -1;
1214 bool done = (peek() == Token::RPAREN); 1276 bool done = (peek() == Token::RPAREN);
1215 int argc = 0; 1277 int argc = 0;
1216 while (!done) { 1278 while (!done) {
(...skipping 14 matching lines...) Expand all
1231 Identifier function_name, 1293 Identifier function_name,
1232 Scanner::Location function_name_location, 1294 Scanner::Location function_name_location,
1233 bool name_is_strict_reserved, 1295 bool name_is_strict_reserved,
1234 bool is_generator, 1296 bool is_generator,
1235 bool* ok) { 1297 bool* ok) {
1236 // Function :: 1298 // Function ::
1237 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1299 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1238 1300
1239 // Parse function body. 1301 // Parse function body.
1240 ScopeType outer_scope_type = scope_->type(); 1302 ScopeType outer_scope_type = scope_->type();
1241 bool inside_with = scope_->inside_with(); 1303 bool inside_with = scope_->IsInsideWith();
1242 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 1304 Scope function_scope(&scope_, kFunctionScope);
1243 FunctionState function_state(&function_state_, &scope_, &function_scope); 1305 function_scope.set_is_generator(is_generator);
1244 function_state.set_is_generator(is_generator);
1245 // FormalParameterList :: 1306 // FormalParameterList ::
1246 // '(' (Identifier)*[','] ')' 1307 // '(' (Identifier)*[','] ')'
1247 Expect(Token::LPAREN, CHECK_OK); 1308 Expect(Token::LPAREN, CHECK_OK);
1248 int start_position = position(); 1309 int start_position = position();
1249 bool done = (peek() == Token::RPAREN); 1310 bool done = (peek() == Token::RPAREN);
1250 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1311 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1251 // We don't yet know if the function will be strict, so we cannot yet produce 1312 // We don't yet know if the function will be strict, so we cannot yet produce
1252 // errors for parameter names or duplicates. However, we remember the 1313 // errors for parameter names or duplicates. However, we remember the
1253 // locations of these errors if they occur and produce the errors later. 1314 // locations of these errors if they occur and produce the errors later.
1254 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 1315 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
(...skipping 23 matching lines...) Expand all
1278 dupe_error_loc = scanner()->location(); 1339 dupe_error_loc = scanner()->location();
1279 } 1340 }
1280 1341
1281 done = (peek() == Token::RPAREN); 1342 done = (peek() == Token::RPAREN);
1282 if (!done) { 1343 if (!done) {
1283 Expect(Token::COMMA, CHECK_OK); 1344 Expect(Token::COMMA, CHECK_OK);
1284 } 1345 }
1285 } 1346 }
1286 Expect(Token::RPAREN, CHECK_OK); 1347 Expect(Token::RPAREN, CHECK_OK);
1287 1348
1288 // See Parser::ParseFunctionLiteral for more information about lazy parsing 1349 // Determine if the function will be lazily compiled.
1289 // and lazy compilation. 1350 // Currently only happens to top-level functions.
1290 bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && 1351 // Optimistically assume that all top-level functions are lazily compiled.
1291 !inside_with && allow_lazy() && 1352 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1292 !parenthesized_function_); 1353 !inside_with && allow_lazy() &&
1354 !parenthesized_function_);
1293 parenthesized_function_ = false; 1355 parenthesized_function_ = false;
1294 1356
1295 Expect(Token::LBRACE, CHECK_OK); 1357 Expect(Token::LBRACE, CHECK_OK);
1296 if (is_lazily_parsed) { 1358 if (is_lazily_compiled) {
1297 ParseLazyFunctionLiteralBody(CHECK_OK); 1359 ParseLazyFunctionLiteralBody(CHECK_OK);
1298 } else { 1360 } else {
1299 ParseSourceElements(Token::RBRACE, ok); 1361 ParseSourceElements(Token::RBRACE, ok);
1300 } 1362 }
1301 Expect(Token::RBRACE, CHECK_OK); 1363 Expect(Token::RBRACE, CHECK_OK);
1302 1364
1303 // Validate strict mode. We can do this only after parsing the function, 1365 // Validate strict mode. We can do this only after parsing the function,
1304 // since the function can declare itself strict. 1366 // since the function can declare itself strict.
1305 if (!scope_->is_classic_mode()) { 1367 if (!scope_->is_classic_mode()) {
1306 if (function_name.IsEvalOrArguments()) { 1368 if (function_name.IsEvalOrArguments()) {
1307 ReportMessageAt(function_name_location, "strict_eval_arguments"); 1369 ReportMessageAt(function_name_location, "strict_eval_arguments", NULL);
1308 *ok = false; 1370 *ok = false;
1309 return Expression::Default(); 1371 return Expression::Default();
1310 } 1372 }
1311 if (name_is_strict_reserved) { 1373 if (name_is_strict_reserved) {
1312 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); 1374 ReportMessageAt(
1375 function_name_location, "unexpected_strict_reserved", NULL);
1313 *ok = false; 1376 *ok = false;
1314 return Expression::Default(); 1377 return Expression::Default();
1315 } 1378 }
1316 if (eval_args_error_loc.IsValid()) { 1379 if (eval_args_error_loc.IsValid()) {
1317 ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); 1380 ReportMessageAt(eval_args_error_loc, "strict_eval_arguments",
1381 Vector<const char*>::empty());
1318 *ok = false; 1382 *ok = false;
1319 return Expression::Default(); 1383 return Expression::Default();
1320 } 1384 }
1321 if (dupe_error_loc.IsValid()) { 1385 if (dupe_error_loc.IsValid()) {
1322 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); 1386 ReportMessageAt(dupe_error_loc, "strict_param_dupe",
1387 Vector<const char*>::empty());
1323 *ok = false; 1388 *ok = false;
1324 return Expression::Default(); 1389 return Expression::Default();
1325 } 1390 }
1326 if (reserved_error_loc.IsValid()) { 1391 if (reserved_error_loc.IsValid()) {
1327 ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved"); 1392 ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved",
1393 Vector<const char*>::empty());
1328 *ok = false; 1394 *ok = false;
1329 return Expression::Default(); 1395 return Expression::Default();
1330 } 1396 }
1331 1397
1332 int end_position = scanner()->location().end_pos; 1398 int end_position = scanner()->location().end_pos;
1333 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1399 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1334 return Expression::StrictFunction(); 1400 return Expression::StrictFunction();
1335 } 1401 }
1336 1402
1337 return Expression::Default(); 1403 return Expression::Default();
1338 } 1404 }
1339 1405
1340 1406
1341 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1407 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1342 int body_start = position(); 1408 int body_start = position();
1343 log_->PauseRecording(); 1409 log_->PauseRecording();
1344 ParseSourceElements(Token::RBRACE, ok); 1410 ParseSourceElements(Token::RBRACE, ok);
1345 log_->ResumeRecording(); 1411 log_->ResumeRecording();
1346 if (!*ok) return; 1412 if (!*ok) return;
1347 1413
1348 // Position right after terminal '}'. 1414 // Position right after terminal '}'.
1349 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 1415 ASSERT_EQ(Token::RBRACE, scanner()->peek());
1350 int body_end = scanner()->peek_location().end_pos; 1416 int body_end = scanner()->peek_location().end_pos;
1351 log_->LogFunction(body_start, body_end, 1417 log_->LogFunction(body_start, body_end,
1352 function_state_->materialized_literal_count(), 1418 scope_->materialized_literal_count(),
1353 function_state_->expected_property_count(), 1419 scope_->expected_properties(),
1354 scope_->language_mode()); 1420 language_mode());
1355 } 1421 }
1356 1422
1357 1423
1358 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1424 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1359 // CallRuntime :: 1425 // CallRuntime ::
1360 // '%' Identifier Arguments 1426 // '%' Identifier Arguments
1361 Expect(Token::MOD, CHECK_OK); 1427 Expect(Token::MOD, CHECK_OK);
1362 if (!allow_natives_syntax()) { 1428 if (!allow_natives_syntax()) {
1363 *ok = false; 1429 *ok = false;
1364 return Expression::Default(); 1430 return Expression::Default();
(...skipping 11 matching lines...) Expand all
1376 void PreParser::LogSymbol() { 1442 void PreParser::LogSymbol() {
1377 int identifier_pos = position(); 1443 int identifier_pos = position();
1378 if (scanner()->is_literal_ascii()) { 1444 if (scanner()->is_literal_ascii()) {
1379 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); 1445 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1380 } else { 1446 } else {
1381 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); 1447 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1382 } 1448 }
1383 } 1449 }
1384 1450
1385 1451
1452 PreParser::Expression PreParser::GetStringSymbol() {
1453 const int kUseStrictLength = 10;
1454 const char* kUseStrictChars = "use strict";
1455 LogSymbol();
1456 if (scanner()->is_literal_ascii() &&
1457 scanner()->literal_length() == kUseStrictLength &&
1458 !scanner()->literal_contains_escapes() &&
1459 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1460 kUseStrictLength)) {
1461 return Expression::UseStrictStringLiteral();
1462 }
1463 return Expression::StringLiteral();
1464 }
1465
1466
1467 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1468 LogSymbol();
1469 if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
1470 return Identifier::FutureReserved();
1471 } else if (scanner()->current_token() ==
1472 Token::FUTURE_STRICT_RESERVED_WORD) {
1473 return Identifier::FutureStrictReserved();
1474 } else if (scanner()->current_token() == Token::YIELD) {
1475 return Identifier::Yield();
1476 }
1477 if (scanner()->is_literal_ascii()) {
1478 // Detect strict-mode poison words.
1479 if (scanner()->literal_length() == 4 &&
1480 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1481 return Identifier::Eval();
1482 }
1483 if (scanner()->literal_length() == 9 &&
1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485 return Identifier::Arguments();
1486 }
1487 }
1488 return Identifier::Default();
1489 }
1490
1491
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) {
1500 Token::Value next = Next();
1501 if (next == Token::IDENTIFIER) {
1502 PreParser::Identifier name = GetIdentifierSymbol();
1503 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
1504 !scope_->is_classic_mode() && name.IsEvalOrArguments()) {
1505 ReportMessageAt(scanner()->location(), "strict_eval_arguments", NULL);
1506 *ok = false;
1507 }
1508 return name;
1509 } else if (scope_->is_classic_mode() &&
1510 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1511 (next == Token::YIELD && !scope_->is_generator()))) {
1512 return GetIdentifierSymbol();
1513 } else {
1514 ReportUnexpectedToken(next);
1515 *ok = false;
1516 return Identifier::Default();
1517 }
1518 }
1519
1520
1521 // Parses and identifier or a strict mode future reserved word, and indicate
1522 // whether it is strict mode future reserved.
1523 PreParser::Identifier PreParser::ParseIdentifierOrStrictReservedWord(
1524 bool* is_strict_reserved, bool* ok) {
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);
1533 *ok = false;
1534 return Identifier::Default();
1535 }
1536 return GetIdentifierSymbol();
1537 }
1538
1539
1540 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1541 Token::Value next = Next();
1542 if (next != Token::IDENTIFIER &&
1543 next != Token::FUTURE_RESERVED_WORD &&
1544 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1545 !Token::IsKeyword(next)) {
1546 ReportUnexpectedToken(next);
1547 *ok = false;
1548 return Identifier::Default();
1549 }
1550 return GetIdentifierSymbol();
1551 }
1552
1553 #undef CHECK_OK
1554
1555
1556 // This function reads an identifier and determines whether or not it
1557 // is 'get' or 'set'.
1558 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1559 bool* is_set,
1560 bool* ok) {
1561 Identifier result = ParseIdentifierName(ok);
1562 if (!*ok) return Identifier::Default();
1563 if (scanner()->is_literal_ascii() &&
1564 scanner()->literal_length() == 3) {
1565 const char* token = scanner()->literal_ascii_string().start();
1566 *is_get = strncmp(token, "get", 3) == 0;
1567 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1568 }
1569 return result;
1570 }
1571
1572
1573 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property,
1574 PropertyKind type,
1575 bool* ok) {
1576 int old;
1577 if (property == Token::NUMBER) {
1578 old = finder_.AddNumber(scanner()->literal_ascii_string(), type);
1579 } else if (scanner()->is_literal_ascii()) {
1580 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
1581 } else {
1582 old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type);
1583 }
1584 PropertyKind old_type = static_cast<PropertyKind>(old);
1585 if (HasConflict(old_type, type)) {
1586 if (IsDataDataConflict(old_type, type)) {
1587 // Both are data properties.
1588 if (language_mode_ == CLASSIC_MODE) return;
1589 parser()->ReportMessageAt(scanner()->location(),
1590 "strict_duplicate_property");
1591 } else if (IsDataAccessorConflict(old_type, type)) {
1592 // Both a data and an accessor property with the same name.
1593 parser()->ReportMessageAt(scanner()->location(),
1594 "accessor_data_property");
1595 } else {
1596 ASSERT(IsAccessorAccessorConflict(old_type, type));
1597 // Both accessors of the same type.
1598 parser()->ReportMessageAt(scanner()->location(),
1599 "accessor_get_set");
1600 }
1601 *ok = false;
1602 }
1603 }
1604
1386 } } // v8::internal 1605 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/promise.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698