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

Side by Side Diff: src/preparser.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
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/profile-generator-inl.h » ('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
59 void PreParserTraits::CheckStrictModeLValue(PreParserExpression expression,
60 bool* ok) {
61 if (expression.IsIdentifier() &&
62 expression.AsIdentifier().IsEvalOrArguments()) {
63 pre_parser_->ReportMessage("strict_eval_arguments",
64 Vector<const char*>::empty());
65 *ok = false;
66 }
67 }
68
69
58 void PreParserTraits::ReportMessageAt(Scanner::Location location, 70 void PreParserTraits::ReportMessageAt(Scanner::Location location,
59 const char* message, 71 const char* message,
60 Vector<const char*> args) { 72 Vector<const char*> args) {
61 ReportMessageAt(location.beg_pos, 73 ReportMessageAt(location.beg_pos,
62 location.end_pos, 74 location.end_pos,
63 message, 75 message,
64 args.length() > 0 ? args[0] : NULL); 76 args.length() > 0 ? args[0] : NULL);
65 } 77 }
66 78
67 79
(...skipping 16 matching lines...) Expand all
84 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) { 96 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
85 pre_parser_->LogSymbol(); 97 pre_parser_->LogSymbol();
86 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) { 98 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
87 return PreParserIdentifier::FutureReserved(); 99 return PreParserIdentifier::FutureReserved();
88 } else if (scanner->current_token() == 100 } else if (scanner->current_token() ==
89 Token::FUTURE_STRICT_RESERVED_WORD) { 101 Token::FUTURE_STRICT_RESERVED_WORD) {
90 return PreParserIdentifier::FutureStrictReserved(); 102 return PreParserIdentifier::FutureStrictReserved();
91 } else if (scanner->current_token() == Token::YIELD) { 103 } else if (scanner->current_token() == Token::YIELD) {
92 return PreParserIdentifier::Yield(); 104 return PreParserIdentifier::Yield();
93 } 105 }
94 if (scanner->is_literal_ascii()) { 106 if (scanner->UnescapedLiteralMatches("eval", 4)) {
95 // Detect strict-mode poison words. 107 return PreParserIdentifier::Eval();
96 if (scanner->literal_length() == 4 && 108 }
97 !strncmp(scanner->literal_ascii_string().start(), "eval", 4)) { 109 if (scanner->UnescapedLiteralMatches("arguments", 9)) {
98 return PreParserIdentifier::Eval(); 110 return PreParserIdentifier::Arguments();
99 }
100 if (scanner->literal_length() == 9 &&
101 !strncmp(scanner->literal_ascii_string().start(), "arguments", 9)) {
102 return PreParserIdentifier::Arguments();
103 }
104 } 111 }
105 return PreParserIdentifier::Default(); 112 return PreParserIdentifier::Default();
106 } 113 }
107 114
108 115
109 PreParserExpression PreParserTraits::ExpressionFromString( 116 PreParserExpression PreParserTraits::ExpressionFromString(
110 int pos, Scanner* scanner, PreParserFactory* factory) { 117 int pos, Scanner* scanner, PreParserFactory* factory) {
111 const int kUseStrictLength = 10;
112 const char* kUseStrictChars = "use strict";
113 pre_parser_->LogSymbol(); 118 pre_parser_->LogSymbol();
114 if (scanner->is_literal_ascii() && 119 if (scanner->UnescapedLiteralMatches("use strict", 10)) {
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 return PreParserExpression::UseStrictStringLiteral();
120 } 121 }
121 return PreParserExpression::StringLiteral(); 122 return PreParserExpression::StringLiteral();
122 } 123 }
123 124
124 125
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) { 126 PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
137 return pre_parser_->ParseV8Intrinsic(ok); 127 return pre_parser_->ParseV8Intrinsic(ok);
138 } 128 }
139 129
140 130
131 PreParserExpression PreParserTraits::ParseFunctionLiteral(
132 PreParserIdentifier name,
133 Scanner::Location function_name_location,
134 bool name_is_strict_reserved,
135 bool is_generator,
136 int function_token_position,
137 FunctionLiteral::FunctionType type,
138 bool* ok) {
139 return pre_parser_->ParseFunctionLiteral(
140 name, function_name_location, name_is_strict_reserved, is_generator,
141 function_token_position, type, ok);
142 }
143
144
145 PreParserExpression PreParserTraits::ParseConditionalExpression(bool accept_IN,
146 bool* ok) {
147 return pre_parser_->ParseConditionalExpression(accept_IN, ok);
148 }
149
150
141 PreParser::PreParseResult PreParser::PreParseLazyFunction( 151 PreParser::PreParseResult PreParser::PreParseLazyFunction(
142 LanguageMode mode, bool is_generator, ParserRecorder* log) { 152 StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
143 log_ = log; 153 log_ = log;
144 // Lazy functions always have trivial outer scopes (no with/catch scopes). 154 // Lazy functions always have trivial outer scopes (no with/catch scopes).
145 PreParserScope top_scope(scope_, GLOBAL_SCOPE); 155 PreParserScope top_scope(scope_, GLOBAL_SCOPE);
146 FunctionState top_state(&function_state_, &scope_, &top_scope); 156 FunctionState top_state(&function_state_, &scope_, &top_scope);
147 scope_->SetLanguageMode(mode); 157 scope_->SetStrictMode(strict_mode);
148 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 158 PreParserScope function_scope(scope_, FUNCTION_SCOPE);
149 FunctionState function_state(&function_state_, &scope_, &function_scope); 159 FunctionState function_state(&function_state_, &scope_, &function_scope);
150 function_state.set_is_generator(is_generator); 160 function_state.set_is_generator(is_generator);
151 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); 161 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
152 bool ok = true; 162 bool ok = true;
153 int start_position = peek_position(); 163 int start_position = peek_position();
154 ParseLazyFunctionLiteralBody(&ok); 164 ParseLazyFunctionLiteralBody(&ok);
155 if (stack_overflow()) return kPreParseStackOverflow; 165 if (stack_overflow()) return kPreParseStackOverflow;
156 if (!ok) { 166 if (!ok) {
157 ReportUnexpectedToken(scanner()->current_token()); 167 ReportUnexpectedToken(scanner()->current_token());
158 } else { 168 } else {
159 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 169 ASSERT_EQ(Token::RBRACE, scanner()->peek());
160 if (!scope_->is_classic_mode()) { 170 if (scope_->strict_mode() == STRICT) {
161 int end_pos = scanner()->location().end_pos; 171 int end_pos = scanner()->location().end_pos;
162 CheckOctalLiteral(start_position, end_pos, &ok); 172 CheckOctalLiteral(start_position, end_pos, &ok);
163 } 173 }
164 } 174 }
165 return kPreParseSuccess; 175 return kPreParseSuccess;
166 } 176 }
167 177
168 178
169 // Preparsing checks a JavaScript program and emits preparse-data that helps 179 // Preparsing checks a JavaScript program and emits preparse-data that helps
170 // a later parsing to be faster. 180 // a later parsing to be faster.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // (Statement)* <end_token> 227 // (Statement)* <end_token>
218 228
219 bool directive_prologue = true; 229 bool directive_prologue = true;
220 while (peek() != end_token) { 230 while (peek() != end_token) {
221 if (directive_prologue && peek() != Token::STRING) { 231 if (directive_prologue && peek() != Token::STRING) {
222 directive_prologue = false; 232 directive_prologue = false;
223 } 233 }
224 Statement statement = ParseSourceElement(CHECK_OK); 234 Statement statement = ParseSourceElement(CHECK_OK);
225 if (directive_prologue) { 235 if (directive_prologue) {
226 if (statement.IsUseStrictLiteral()) { 236 if (statement.IsUseStrictLiteral()) {
227 scope_->SetLanguageMode(allow_harmony_scoping() ? 237 scope_->SetStrictMode(STRICT);
228 EXTENDED_MODE : STRICT_MODE);
229 } else if (!statement.IsStringLiteral()) { 238 } else if (!statement.IsStringLiteral()) {
230 directive_prologue = false; 239 directive_prologue = false;
231 } 240 }
232 } 241 }
233 } 242 }
234 return kUnknownSourceElements; 243 return kUnknownSourceElements;
235 } 244 }
236 245
237 246
238 #undef CHECK_OK 247 #undef CHECK_OK
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 case Token::THROW: 321 case Token::THROW:
313 return ParseThrowStatement(ok); 322 return ParseThrowStatement(ok);
314 323
315 case Token::TRY: 324 case Token::TRY:
316 return ParseTryStatement(ok); 325 return ParseTryStatement(ok);
317 326
318 case Token::FUNCTION: { 327 case Token::FUNCTION: {
319 Scanner::Location start_location = scanner()->peek_location(); 328 Scanner::Location start_location = scanner()->peek_location();
320 Statement statement = ParseFunctionDeclaration(CHECK_OK); 329 Statement statement = ParseFunctionDeclaration(CHECK_OK);
321 Scanner::Location end_location = scanner()->location(); 330 Scanner::Location end_location = scanner()->location();
322 if (!scope_->is_classic_mode()) { 331 if (strict_mode() == STRICT) {
323 PreParserTraits::ReportMessageAt(start_location.beg_pos, 332 PreParserTraits::ReportMessageAt(start_location.beg_pos,
324 end_location.end_pos, 333 end_location.end_pos,
325 "strict_function", 334 "strict_function",
326 NULL); 335 NULL);
327 *ok = false; 336 *ok = false;
328 return Statement::Default(); 337 return Statement::Default();
329 } else { 338 } else {
330 return statement; 339 return statement;
331 } 340 }
332 } 341 }
333 342
334 case Token::DEBUGGER: 343 case Token::DEBUGGER:
335 return ParseDebuggerStatement(ok); 344 return ParseDebuggerStatement(ok);
336 345
337 default: 346 default:
338 return ParseExpressionOrLabelledStatement(ok); 347 return ParseExpressionOrLabelledStatement(ok);
339 } 348 }
340 } 349 }
341 350
342 351
343 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 352 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
344 // FunctionDeclaration :: 353 // FunctionDeclaration ::
345 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 354 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
346 // GeneratorDeclaration :: 355 // GeneratorDeclaration ::
347 // 'function' '*' Identifier '(' FormalParameterListopt ')' 356 // 'function' '*' Identifier '(' FormalParameterListopt ')'
348 // '{' FunctionBody '}' 357 // '{' FunctionBody '}'
349 Expect(Token::FUNCTION, CHECK_OK); 358 Expect(Token::FUNCTION, CHECK_OK);
350 359 int pos = position();
351 bool is_generator = allow_generators() && Check(Token::MUL); 360 bool is_generator = allow_generators() && Check(Token::MUL);
352 bool is_strict_reserved = false; 361 bool is_strict_reserved = false;
353 Identifier name = ParseIdentifierOrStrictReservedWord( 362 Identifier name = ParseIdentifierOrStrictReservedWord(
354 &is_strict_reserved, CHECK_OK); 363 &is_strict_reserved, CHECK_OK);
355 ParseFunctionLiteral(name, 364 ParseFunctionLiteral(name,
356 scanner()->location(), 365 scanner()->location(),
357 is_strict_reserved, 366 is_strict_reserved,
358 is_generator, 367 is_generator,
368 pos,
369 FunctionLiteral::DECLARATION,
359 CHECK_OK); 370 CHECK_OK);
360 return Statement::FunctionDeclaration(); 371 return Statement::FunctionDeclaration();
361 } 372 }
362 373
363 374
364 PreParser::Statement PreParser::ParseBlock(bool* ok) { 375 PreParser::Statement PreParser::ParseBlock(bool* ok) {
365 // Block :: 376 // Block ::
366 // '{' Statement* '}' 377 // '{' Statement* '}'
367 378
368 // Note that a Block does not introduce a new execution scope! 379 // Note that a Block does not introduce a new execution scope!
369 // (ECMA-262, 3rd, 12.2) 380 // (ECMA-262, 3rd, 12.2)
370 // 381 //
371 Expect(Token::LBRACE, CHECK_OK); 382 Expect(Token::LBRACE, CHECK_OK);
372 while (peek() != Token::RBRACE) { 383 while (peek() != Token::RBRACE) {
373 if (scope_->is_extended_mode()) { 384 if (FLAG_harmony_scoping && strict_mode() == STRICT) {
374 ParseSourceElement(CHECK_OK); 385 ParseSourceElement(CHECK_OK);
375 } else { 386 } else {
376 ParseStatement(CHECK_OK); 387 ParseStatement(CHECK_OK);
377 } 388 }
378 } 389 }
379 Expect(Token::RBRACE, ok); 390 Expect(Token::RBRACE, ok);
380 return Statement::Default(); 391 return Statement::Default();
381 } 392 }
382 393
383 394
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 if (peek() == Token::VAR) { 434 if (peek() == Token::VAR) {
424 Consume(Token::VAR); 435 Consume(Token::VAR);
425 } else if (peek() == Token::CONST) { 436 } else if (peek() == Token::CONST) {
426 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 437 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
427 // 438 //
428 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 439 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
429 // 440 //
430 // * It is a Syntax Error if the code that matches this production is not 441 // * It is a Syntax Error if the code that matches this production is not
431 // contained in extended code. 442 // contained in extended code.
432 // 443 //
433 // However disallowing const in classic mode will break compatibility with 444 // However disallowing const in sloppy mode will break compatibility with
434 // existing pages. Therefore we keep allowing const with the old 445 // existing pages. Therefore we keep allowing const with the old
435 // non-harmony semantics in classic mode. 446 // non-harmony semantics in sloppy mode.
436 Consume(Token::CONST); 447 Consume(Token::CONST);
437 switch (scope_->language_mode()) { 448 if (strict_mode() == STRICT) {
438 case CLASSIC_MODE: 449 if (FLAG_harmony_scoping) {
439 break; 450 if (var_context != kSourceElement && var_context != kForStatement) {
440 case STRICT_MODE: { 451 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
452 *ok = false;
453 return Statement::Default();
454 }
455 require_initializer = true;
456 } else {
441 Scanner::Location location = scanner()->peek_location(); 457 Scanner::Location location = scanner()->peek_location();
442 ReportMessageAt(location, "strict_const"); 458 ReportMessageAt(location, "strict_const");
443 *ok = false; 459 *ok = false;
444 return Statement::Default(); 460 return Statement::Default();
445 } 461 }
446 case EXTENDED_MODE:
447 if (var_context != kSourceElement &&
448 var_context != kForStatement) {
449 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
450 *ok = false;
451 return Statement::Default();
452 }
453 require_initializer = true;
454 break;
455 } 462 }
456 } else if (peek() == Token::LET) { 463 } else if (peek() == Token::LET) {
457 // ES6 Draft Rev4 section 12.2.1: 464 // ES6 Draft Rev4 section 12.2.1:
458 // 465 //
459 // LetDeclaration : let LetBindingList ; 466 // LetDeclaration : let LetBindingList ;
460 // 467 //
461 // * It is a Syntax Error if the code that matches this production is not 468 // * It is a Syntax Error if the code that matches this production is not
462 // contained in extended code. 469 // contained in extended code.
463 if (!scope_->is_extended_mode()) { 470 //
471 // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
472 if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) {
464 ReportMessageAt(scanner()->peek_location(), "illegal_let"); 473 ReportMessageAt(scanner()->peek_location(), "illegal_let");
465 *ok = false; 474 *ok = false;
466 return Statement::Default(); 475 return Statement::Default();
467 } 476 }
468 Consume(Token::LET); 477 Consume(Token::LET);
469 if (var_context != kSourceElement && 478 if (var_context != kSourceElement &&
470 var_context != kForStatement) { 479 var_context != kForStatement) {
471 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 480 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
472 *ok = false; 481 *ok = false;
473 return Statement::Default(); 482 return Statement::Default();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 515
507 bool starts_with_identifier = peek_any_identifier(); 516 bool starts_with_identifier = peek_any_identifier();
508 Expression expr = ParseExpression(true, CHECK_OK); 517 Expression expr = ParseExpression(true, CHECK_OK);
509 // Even if the expression starts with an identifier, it is not necessarily an 518 // Even if the expression starts with an identifier, it is not necessarily an
510 // identifier. For example, "foo + bar" starts with an identifier but is not 519 // identifier. For example, "foo + bar" starts with an identifier but is not
511 // an identifier. 520 // an identifier.
512 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 521 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
513 // Expression is a single identifier, and not, e.g., a parenthesized 522 // Expression is a single identifier, and not, e.g., a parenthesized
514 // identifier. 523 // identifier.
515 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 524 ASSERT(!expr.AsIdentifier().IsFutureReserved());
516 ASSERT(scope_->is_classic_mode() || 525 ASSERT(strict_mode() == SLOPPY ||
517 (!expr.AsIdentifier().IsFutureStrictReserved() && 526 (!expr.AsIdentifier().IsFutureStrictReserved() &&
518 !expr.AsIdentifier().IsYield())); 527 !expr.AsIdentifier().IsYield()));
519 Consume(Token::COLON); 528 Consume(Token::COLON);
520 return ParseStatement(ok); 529 return ParseStatement(ok);
521 // Preparsing is disabled for extensions (because the extension details 530 // Preparsing is disabled for extensions (because the extension details
522 // aren't passed to lazily compiled functions), so we don't 531 // aren't passed to lazily compiled functions), so we don't
523 // accept "native function" in the preparser. 532 // accept "native function" in the preparser.
524 } 533 }
525 // Parsed expression statement. 534 // Parsed expression statement.
526 ExpectSemicolon(CHECK_OK); 535 ExpectSemicolon(CHECK_OK);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 } 613 }
605 ExpectSemicolon(CHECK_OK); 614 ExpectSemicolon(CHECK_OK);
606 return Statement::Default(); 615 return Statement::Default();
607 } 616 }
608 617
609 618
610 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 619 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
611 // WithStatement :: 620 // WithStatement ::
612 // 'with' '(' Expression ')' Statement 621 // 'with' '(' Expression ')' Statement
613 Expect(Token::WITH, CHECK_OK); 622 Expect(Token::WITH, CHECK_OK);
614 if (!scope_->is_classic_mode()) { 623 if (strict_mode() == STRICT) {
615 ReportMessageAt(scanner()->location(), "strict_mode_with"); 624 ReportMessageAt(scanner()->location(), "strict_mode_with");
616 *ok = false; 625 *ok = false;
617 return Statement::Default(); 626 return Statement::Default();
618 } 627 }
619 Expect(Token::LPAREN, CHECK_OK); 628 Expect(Token::LPAREN, CHECK_OK);
620 ParseExpression(true, CHECK_OK); 629 ParseExpression(true, CHECK_OK);
621 Expect(Token::RPAREN, CHECK_OK); 630 Expect(Token::RPAREN, CHECK_OK);
622 631
623 PreParserScope with_scope(scope_, WITH_SCOPE); 632 PreParserScope with_scope(scope_, WITH_SCOPE);
624 BlockState block_state(&scope_, &with_scope); 633 BlockState block_state(&scope_, &with_scope);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 832
824 833
825 #undef CHECK_OK 834 #undef CHECK_OK
826 #define CHECK_OK ok); \ 835 #define CHECK_OK ok); \
827 if (!*ok) return Expression::Default(); \ 836 if (!*ok) return Expression::Default(); \
828 ((void)0 837 ((void)0
829 #define DUMMY ) // to make indentation work 838 #define DUMMY ) // to make indentation work
830 #undef DUMMY 839 #undef DUMMY
831 840
832 841
833 // Precedence = 2
834 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
835 bool* ok) {
836 // AssignmentExpression ::
837 // ConditionalExpression
838 // YieldExpression
839 // LeftHandSideExpression AssignmentOperator AssignmentExpression
840
841 if (function_state_->is_generator() && peek() == Token::YIELD) {
842 return ParseYieldExpression(ok);
843 }
844
845 Scanner::Location before = scanner()->peek_location();
846 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
847
848 if (!Token::IsAssignmentOp(peek())) {
849 // Parsed conditional expression only (no assignment).
850 return expression;
851 }
852
853 if (!scope_->is_classic_mode() &&
854 expression.IsIdentifier() &&
855 expression.AsIdentifier().IsEvalOrArguments()) {
856 Scanner::Location after = scanner()->location();
857 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
858 "strict_eval_arguments", NULL);
859 *ok = false;
860 return Expression::Default();
861 }
862
863 Token::Value op = Next(); // Get assignment operator.
864 ParseAssignmentExpression(accept_IN, CHECK_OK);
865
866 if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
867 function_state_->AddProperty();
868 }
869
870 return Expression::Default();
871 }
872
873
874 // Precedence = 3
875 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
876 // YieldExpression ::
877 // 'yield' '*'? AssignmentExpression
878 Consume(Token::YIELD);
879 Check(Token::MUL);
880
881 ParseAssignmentExpression(false, CHECK_OK);
882
883 return Expression::Default();
884 }
885
886
887 // Precedence = 3 842 // Precedence = 3
888 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, 843 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
889 bool* ok) { 844 bool* ok) {
890 // ConditionalExpression :: 845 // ConditionalExpression ::
891 // LogicalOrExpression 846 // LogicalOrExpression
892 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 847 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
893 848
894 // We start using the binary expression parser for prec >= 4 only! 849 // We start using the binary expression parser for prec >= 4 only!
895 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 850 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
896 if (peek() != Token::CONDITIONAL) return expression; 851 if (peek() != Token::CONDITIONAL) return expression;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 // '~' UnaryExpression 890 // '~' UnaryExpression
936 // '!' UnaryExpression 891 // '!' UnaryExpression
937 892
938 Token::Value op = peek(); 893 Token::Value op = peek();
939 if (Token::IsUnaryOp(op)) { 894 if (Token::IsUnaryOp(op)) {
940 op = Next(); 895 op = Next();
941 ParseUnaryExpression(ok); 896 ParseUnaryExpression(ok);
942 return Expression::Default(); 897 return Expression::Default();
943 } else if (Token::IsCountOp(op)) { 898 } else if (Token::IsCountOp(op)) {
944 op = Next(); 899 op = Next();
945 Scanner::Location before = scanner()->peek_location();
946 Expression expression = ParseUnaryExpression(CHECK_OK); 900 Expression expression = ParseUnaryExpression(CHECK_OK);
947 if (!scope_->is_classic_mode() && 901 if (strict_mode() == STRICT) {
948 expression.IsIdentifier() && 902 CheckStrictModeLValue(expression, CHECK_OK);
949 expression.AsIdentifier().IsEvalOrArguments()) {
950 Scanner::Location after = scanner()->location();
951 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
952 "strict_eval_arguments", NULL);
953 *ok = false;
954 } 903 }
955 return Expression::Default(); 904 return Expression::Default();
956 } else { 905 } else {
957 return ParsePostfixExpression(ok); 906 return ParsePostfixExpression(ok);
958 } 907 }
959 } 908 }
960 909
961 910
962 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 911 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
963 // PostfixExpression :: 912 // PostfixExpression ::
964 // LeftHandSideExpression ('++' | '--')? 913 // LeftHandSideExpression ('++' | '--')?
965 914
966 Scanner::Location before = scanner()->peek_location();
967 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 915 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
968 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 916 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
969 Token::IsCountOp(peek())) { 917 Token::IsCountOp(peek())) {
970 if (!scope_->is_classic_mode() && 918 if (strict_mode() == STRICT) {
971 expression.IsIdentifier() && 919 CheckStrictModeLValue(expression, CHECK_OK);
972 expression.AsIdentifier().IsEvalOrArguments()) {
973 Scanner::Location after = scanner()->location();
974 PreParserTraits::ReportMessageAt(before.beg_pos, after.end_pos,
975 "strict_eval_arguments", NULL);
976 *ok = false;
977 return Expression::Default();
978 } 920 }
979 Next(); 921 Next();
980 return Expression::Default(); 922 return Expression::Default();
981 } 923 }
982 return expression; 924 return expression;
983 } 925 }
984 926
985 927
986 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { 928 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
987 // LeftHandSideExpression :: 929 // LeftHandSideExpression ::
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 // ('[' Expression ']' | '.' Identifier | Arguments)* 998 // ('[' Expression ']' | '.' Identifier | Arguments)*
1057 999
1058 // The '[' Expression ']' and '.' Identifier parts are parsed by 1000 // The '[' Expression ']' and '.' Identifier parts are parsed by
1059 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 1001 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
1060 // caller. 1002 // caller.
1061 1003
1062 // Parse the initial primary or function expression. 1004 // Parse the initial primary or function expression.
1063 Expression result = Expression::Default(); 1005 Expression result = Expression::Default();
1064 if (peek() == Token::FUNCTION) { 1006 if (peek() == Token::FUNCTION) {
1065 Consume(Token::FUNCTION); 1007 Consume(Token::FUNCTION);
1066 1008 int function_token_position = position();
1067 bool is_generator = allow_generators() && Check(Token::MUL); 1009 bool is_generator = allow_generators() && Check(Token::MUL);
1068 Identifier name = Identifier::Default(); 1010 Identifier name = Identifier::Default();
1069 bool is_strict_reserved_name = false; 1011 bool is_strict_reserved_name = false;
1070 Scanner::Location function_name_location = Scanner::Location::invalid(); 1012 Scanner::Location function_name_location = Scanner::Location::invalid();
1013 FunctionLiteral::FunctionType function_type =
1014 FunctionLiteral::ANONYMOUS_EXPRESSION;
1071 if (peek_any_identifier()) { 1015 if (peek_any_identifier()) {
1072 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 1016 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1073 CHECK_OK); 1017 CHECK_OK);
1074 function_name_location = scanner()->location(); 1018 function_name_location = scanner()->location();
1019 function_type = FunctionLiteral::NAMED_EXPRESSION;
1075 } 1020 }
1076 result = ParseFunctionLiteral(name, 1021 result = ParseFunctionLiteral(name,
1077 function_name_location, 1022 function_name_location,
1078 is_strict_reserved_name, 1023 is_strict_reserved_name,
1079 is_generator, 1024 is_generator,
1025 function_token_position,
1026 function_type,
1080 CHECK_OK); 1027 CHECK_OK);
1081 } else { 1028 } else {
1082 result = ParsePrimaryExpression(CHECK_OK); 1029 result = ParsePrimaryExpression(CHECK_OK);
1083 } 1030 }
1084 result = ParseMemberExpressionContinuation(result, CHECK_OK); 1031 result = ParseMemberExpressionContinuation(result, CHECK_OK);
1085 return result; 1032 return result;
1086 } 1033 }
1087 1034
1088 1035
1089 PreParser::Expression PreParser::ParseMemberExpressionContinuation( 1036 PreParser::Expression PreParser::ParseMemberExpressionContinuation(
(...skipping 25 matching lines...) Expand all
1115 } 1062 }
1116 default: 1063 default:
1117 return expression; 1064 return expression;
1118 } 1065 }
1119 } 1066 }
1120 ASSERT(false); 1067 ASSERT(false);
1121 return PreParserExpression::Default(); 1068 return PreParserExpression::Default();
1122 } 1069 }
1123 1070
1124 1071
1125 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1126 // ObjectLiteral ::
1127 // '{' (
1128 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1129 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1130 // )*[','] '}'
1131
1132 ObjectLiteralChecker checker(this, scope_->language_mode());
1133
1134 Expect(Token::LBRACE, CHECK_OK);
1135 while (peek() != Token::RBRACE) {
1136 Token::Value next = peek();
1137 switch (next) {
1138 case Token::IDENTIFIER:
1139 case Token::FUTURE_RESERVED_WORD:
1140 case Token::FUTURE_STRICT_RESERVED_WORD: {
1141 bool is_getter = false;
1142 bool is_setter = false;
1143 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1144 if ((is_getter || is_setter) && peek() != Token::COLON) {
1145 Token::Value name = Next();
1146 bool is_keyword = Token::IsKeyword(name);
1147 if (name != Token::IDENTIFIER &&
1148 name != Token::FUTURE_RESERVED_WORD &&
1149 name != Token::FUTURE_STRICT_RESERVED_WORD &&
1150 name != Token::NUMBER &&
1151 name != Token::STRING &&
1152 !is_keyword) {
1153 *ok = false;
1154 return Expression::Default();
1155 }
1156 if (!is_keyword) {
1157 LogSymbol();
1158 }
1159 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1160 checker.CheckProperty(name, type, CHECK_OK);
1161 ParseFunctionLiteral(Identifier::Default(),
1162 scanner()->location(),
1163 false, // reserved words are allowed here
1164 false, // not a generator
1165 CHECK_OK);
1166 if (peek() != Token::RBRACE) {
1167 Expect(Token::COMMA, CHECK_OK);
1168 }
1169 continue; // restart the while
1170 }
1171 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1172 break;
1173 }
1174 case Token::STRING:
1175 Consume(next);
1176 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1177 LogSymbol();
1178 break;
1179 case Token::NUMBER:
1180 Consume(next);
1181 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1182 break;
1183 default:
1184 if (Token::IsKeyword(next)) {
1185 Consume(next);
1186 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1187 LogSymbol();
1188 } else {
1189 // Unexpected token.
1190 *ok = false;
1191 return Expression::Default();
1192 }
1193 }
1194
1195 Expect(Token::COLON, CHECK_OK);
1196 ParseAssignmentExpression(true, CHECK_OK);
1197
1198 // TODO(1240767): Consider allowing trailing comma.
1199 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1200 }
1201 Expect(Token::RBRACE, CHECK_OK);
1202
1203 function_state_->NextMaterializedLiteralIndex();
1204 return Expression::Default();
1205 }
1206
1207
1208 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1209 // Arguments ::
1210 // '(' (AssignmentExpression)*[','] ')'
1211
1212 Expect(Token::LPAREN, ok);
1213 if (!*ok) return -1;
1214 bool done = (peek() == Token::RPAREN);
1215 int argc = 0;
1216 while (!done) {
1217 ParseAssignmentExpression(true, ok);
1218 if (!*ok) return -1;
1219 argc++;
1220 done = (peek() == Token::RPAREN);
1221 if (!done) {
1222 Expect(Token::COMMA, ok);
1223 if (!*ok) return -1;
1224 }
1225 }
1226 Expect(Token::RPAREN, ok);
1227 return argc;
1228 }
1229
1230 PreParser::Expression PreParser::ParseFunctionLiteral( 1072 PreParser::Expression PreParser::ParseFunctionLiteral(
1231 Identifier function_name, 1073 Identifier function_name,
1232 Scanner::Location function_name_location, 1074 Scanner::Location function_name_location,
1233 bool name_is_strict_reserved, 1075 bool name_is_strict_reserved,
1234 bool is_generator, 1076 bool is_generator,
1077 int function_token_pos,
1078 FunctionLiteral::FunctionType function_type,
1235 bool* ok) { 1079 bool* ok) {
1236 // Function :: 1080 // Function ::
1237 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1081 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1238 1082
1239 // Parse function body. 1083 // Parse function body.
1240 ScopeType outer_scope_type = scope_->type(); 1084 ScopeType outer_scope_type = scope_->type();
1241 bool inside_with = scope_->inside_with(); 1085 bool inside_with = scope_->inside_with();
1242 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 1086 PreParserScope function_scope(scope_, FUNCTION_SCOPE);
1243 FunctionState function_state(&function_state_, &scope_, &function_scope); 1087 FunctionState function_state(&function_state_, &scope_, &function_scope);
1244 function_state.set_is_generator(is_generator); 1088 function_state.set_is_generator(is_generator);
(...skipping 13 matching lines...) Expand all
1258 bool is_strict_reserved = false; 1102 bool is_strict_reserved = false;
1259 Identifier param_name = 1103 Identifier param_name =
1260 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 1104 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1261 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { 1105 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
1262 eval_args_error_loc = scanner()->location(); 1106 eval_args_error_loc = scanner()->location();
1263 } 1107 }
1264 if (!reserved_error_loc.IsValid() && is_strict_reserved) { 1108 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
1265 reserved_error_loc = scanner()->location(); 1109 reserved_error_loc = scanner()->location();
1266 } 1110 }
1267 1111
1268 int prev_value; 1112 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
1269 if (scanner()->is_literal_ascii()) {
1270 prev_value =
1271 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1272 } else {
1273 prev_value =
1274 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1275 }
1276 1113
1277 if (!dupe_error_loc.IsValid() && prev_value != 0) { 1114 if (!dupe_error_loc.IsValid() && prev_value != 0) {
1278 dupe_error_loc = scanner()->location(); 1115 dupe_error_loc = scanner()->location();
1279 } 1116 }
1280 1117
1281 done = (peek() == Token::RPAREN); 1118 done = (peek() == Token::RPAREN);
1282 if (!done) { 1119 if (!done) {
1283 Expect(Token::COMMA, CHECK_OK); 1120 Expect(Token::COMMA, CHECK_OK);
1284 } 1121 }
1285 } 1122 }
1286 Expect(Token::RPAREN, CHECK_OK); 1123 Expect(Token::RPAREN, CHECK_OK);
1287 1124
1288 // See Parser::ParseFunctionLiteral for more information about lazy parsing 1125 // See Parser::ParseFunctionLiteral for more information about lazy parsing
1289 // and lazy compilation. 1126 // and lazy compilation.
1290 bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && 1127 bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE &&
1291 !inside_with && allow_lazy() && 1128 !inside_with && allow_lazy() &&
1292 !parenthesized_function_); 1129 !parenthesized_function_);
1293 parenthesized_function_ = false; 1130 parenthesized_function_ = false;
1294 1131
1295 Expect(Token::LBRACE, CHECK_OK); 1132 Expect(Token::LBRACE, CHECK_OK);
1296 if (is_lazily_parsed) { 1133 if (is_lazily_parsed) {
1297 ParseLazyFunctionLiteralBody(CHECK_OK); 1134 ParseLazyFunctionLiteralBody(CHECK_OK);
1298 } else { 1135 } else {
1299 ParseSourceElements(Token::RBRACE, ok); 1136 ParseSourceElements(Token::RBRACE, ok);
1300 } 1137 }
1301 Expect(Token::RBRACE, CHECK_OK); 1138 Expect(Token::RBRACE, CHECK_OK);
1302 1139
1303 // Validate strict mode. We can do this only after parsing the function, 1140 // Validate strict mode. We can do this only after parsing the function,
1304 // since the function can declare itself strict. 1141 // since the function can declare itself strict.
1305 if (!scope_->is_classic_mode()) { 1142 if (strict_mode() == STRICT) {
1306 if (function_name.IsEvalOrArguments()) { 1143 if (function_name.IsEvalOrArguments()) {
1307 ReportMessageAt(function_name_location, "strict_eval_arguments"); 1144 ReportMessageAt(function_name_location, "strict_eval_arguments");
1308 *ok = false; 1145 *ok = false;
1309 return Expression::Default(); 1146 return Expression::Default();
1310 } 1147 }
1311 if (name_is_strict_reserved) { 1148 if (name_is_strict_reserved) {
1312 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); 1149 ReportMessageAt(function_name_location, "unexpected_strict_reserved");
1313 *ok = false; 1150 *ok = false;
1314 return Expression::Default(); 1151 return Expression::Default();
1315 } 1152 }
(...skipping 17 matching lines...) Expand all
1333 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1170 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1334 return Expression::StrictFunction(); 1171 return Expression::StrictFunction();
1335 } 1172 }
1336 1173
1337 return Expression::Default(); 1174 return Expression::Default();
1338 } 1175 }
1339 1176
1340 1177
1341 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1178 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1342 int body_start = position(); 1179 int body_start = position();
1343 log_->PauseRecording(); 1180 bool is_logging = log_->ShouldLogSymbols();
1181 if (is_logging) log_->PauseRecording();
1344 ParseSourceElements(Token::RBRACE, ok); 1182 ParseSourceElements(Token::RBRACE, ok);
1345 log_->ResumeRecording(); 1183 if (is_logging) log_->ResumeRecording();
1346 if (!*ok) return; 1184 if (!*ok) return;
1347 1185
1348 // Position right after terminal '}'. 1186 // Position right after terminal '}'.
1349 ASSERT_EQ(Token::RBRACE, scanner()->peek()); 1187 ASSERT_EQ(Token::RBRACE, scanner()->peek());
1350 int body_end = scanner()->peek_location().end_pos; 1188 int body_end = scanner()->peek_location().end_pos;
1351 log_->LogFunction(body_start, body_end, 1189 log_->LogFunction(body_start, body_end,
1352 function_state_->materialized_literal_count(), 1190 function_state_->materialized_literal_count(),
1353 function_state_->expected_property_count(), 1191 function_state_->expected_property_count(),
1354 scope_->language_mode()); 1192 strict_mode());
1355 } 1193 }
1356 1194
1357 1195
1358 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1196 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1359 // CallRuntime :: 1197 // CallRuntime ::
1360 // '%' Identifier Arguments 1198 // '%' Identifier Arguments
1361 Expect(Token::MOD, CHECK_OK); 1199 Expect(Token::MOD, CHECK_OK);
1362 if (!allow_natives_syntax()) { 1200 if (!allow_natives_syntax()) {
1363 *ok = false; 1201 *ok = false;
1364 return Expression::Default(); 1202 return Expression::Default();
1365 } 1203 }
1366 // Allow "eval" or "arguments" for backward compatibility. 1204 // Allow "eval" or "arguments" for backward compatibility.
1367 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1205 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1368 ParseArguments(ok); 1206 ParseArguments(ok);
1369 1207
1370 return Expression::Default(); 1208 return Expression::Default();
1371 } 1209 }
1372 1210
1373 #undef CHECK_OK 1211 #undef CHECK_OK
1374 1212
1375 1213
1376 void PreParser::LogSymbol() { 1214 void PreParser::LogSymbol() {
1377 int identifier_pos = position(); 1215 if (log_->ShouldLogSymbols()) {
1378 if (scanner()->is_literal_ascii()) { 1216 scanner()->LogSymbol(log_, position());
1379 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1380 } else {
1381 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1382 } 1217 }
1383 } 1218 }
1384 1219
1385 1220
1386 } } // v8::internal 1221 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/profile-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698