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

Side by Side Diff: src/preparser.cc

Issue 27182002: Introduce ParserBase for common code between parser and pre-parser. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 namespace internal { 56 namespace internal {
57 57
58 PreParser::PreParseResult PreParser::PreParseLazyFunction( 58 PreParser::PreParseResult PreParser::PreParseLazyFunction(
59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) {
60 log_ = log; 60 log_ = log;
61 // Lazy functions always have trivial outer scopes (no with/catch scopes). 61 // Lazy functions always have trivial outer scopes (no with/catch scopes).
62 Scope top_scope(&scope_, kTopLevelScope); 62 Scope top_scope(&scope_, kTopLevelScope);
63 set_language_mode(mode); 63 set_language_mode(mode);
64 Scope function_scope(&scope_, kFunctionScope); 64 Scope function_scope(&scope_, kFunctionScope);
65 function_scope.set_is_generator(is_generator); 65 function_scope.set_is_generator(is_generator);
66 ASSERT_EQ(i::Token::LBRACE, scanner_->current_token()); 66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token());
67 bool ok = true; 67 bool ok = true;
68 int start_position = scanner_->peek_location().beg_pos; 68 int start_position = scanner()->peek_location().beg_pos;
69 ParseLazyFunctionLiteralBody(&ok); 69 ParseLazyFunctionLiteralBody(&ok);
70 if (stack_overflow_) return kPreParseStackOverflow; 70 if (stack_overflow()) return kPreParseStackOverflow;
71 if (!ok) { 71 if (!ok) {
72 ReportUnexpectedToken(scanner_->current_token()); 72 ReportUnexpectedToken(scanner()->current_token());
73 } else { 73 } else {
74 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); 74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
75 if (!is_classic_mode()) { 75 if (!is_classic_mode()) {
76 int end_pos = scanner_->location().end_pos; 76 int end_pos = scanner()->location().end_pos;
77 CheckOctalLiteral(start_position, end_pos, &ok); 77 CheckOctalLiteral(start_position, end_pos, &ok);
78 if (ok) { 78 if (ok) {
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80 } 80 }
81 } 81 }
82 } 82 }
83 return kPreParseSuccess; 83 return kPreParseSuccess;
84 } 84 }
85 85
86 86
87 // Preparsing checks a JavaScript program and emits preparse-data that helps 87 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster. 88 // a later parsing to be faster.
89 // See preparser-data.h for the data. 89 // See preparser-data.h for the data.
90 90
91 // The PreParser checks that the syntax follows the grammar for JavaScript, 91 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way. 92 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program 93 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used 94 // sufficiently to deduce some information about it, that can be used
95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
96 // rather it is to speed up properly written and correct programs. 96 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where 97 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted. 98 // it is used) are generally omitted.
99 99
100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { 100 void PreParser::ReportUnexpectedToken(i::Token::Value token) {
101 // We don't report stack overflows here, to avoid increasing the 101 // We don't report stack overflows here, to avoid increasing the
102 // stack depth even further. Instead we report it after parsing is 102 // stack depth even further. Instead we report it after parsing is
103 // over, in ParseProgram. 103 // over, in ParseProgram.
104 if (token == i::Token::ILLEGAL && stack_overflow_) { 104 if (token == i::Token::ILLEGAL && stack_overflow()) {
105 return; 105 return;
106 } 106 }
107 i::Scanner::Location source_location = scanner_->location(); 107 i::Scanner::Location source_location = scanner()->location();
108 108
109 // Four of the tokens are treated specially 109 // Four of the tokens are treated specially
110 switch (token) { 110 switch (token) {
111 case i::Token::EOS: 111 case i::Token::EOS:
112 return ReportMessageAt(source_location, "unexpected_eos", NULL); 112 return ReportMessageAt(source_location, "unexpected_eos", NULL);
113 case i::Token::NUMBER: 113 case i::Token::NUMBER:
114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115 case i::Token::STRING: 115 case i::Token::STRING:
116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117 case i::Token::IDENTIFIER: 117 case i::Token::IDENTIFIER:
118 return ReportMessageAt(source_location, 118 return ReportMessageAt(source_location,
119 "unexpected_token_identifier", NULL); 119 "unexpected_token_identifier", NULL);
120 case i::Token::FUTURE_RESERVED_WORD: 120 case i::Token::FUTURE_RESERVED_WORD:
121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122 case i::Token::FUTURE_STRICT_RESERVED_WORD: 122 case i::Token::FUTURE_STRICT_RESERVED_WORD:
123 return ReportMessageAt(source_location, 123 return ReportMessageAt(source_location,
124 "unexpected_strict_reserved", NULL); 124 "unexpected_strict_reserved", NULL);
125 default: 125 default:
126 const char* name = i::Token::String(token); 126 const char* name = i::Token::String(token);
127 ReportMessageAt(source_location, "unexpected_token", name); 127 ReportMessageAt(source_location, "unexpected_token", name);
128 } 128 }
129 } 129 }
130 130
131 131
132 // Checks whether octal literal last seen is between beg_pos and end_pos. 132 // Checks whether octal literal last seen is between beg_pos and end_pos.
133 // If so, reports an error. 133 // If so, reports an error.
134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
135 i::Scanner::Location octal = scanner_->octal_position(); 135 i::Scanner::Location octal = scanner()->octal_position();
136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { 136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
137 ReportMessageAt(octal, "strict_octal_literal", NULL); 137 ReportMessageAt(octal, "strict_octal_literal", NULL);
138 scanner_->clear_octal_position(); 138 scanner()->clear_octal_position();
139 *ok = false; 139 *ok = false;
140 } 140 }
141 } 141 }
142 142
143 143
144 #define CHECK_OK ok); \ 144 #define CHECK_OK ok); \
145 if (!*ok) return kUnknownSourceElements; \ 145 if (!*ok) return kUnknownSourceElements; \
146 ((void)0 146 ((void)0
147 #define DUMMY ) // to make indentation work 147 #define DUMMY ) // to make indentation work
148 #undef DUMMY 148 #undef DUMMY
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 case i::Token::SWITCH: 267 case i::Token::SWITCH:
268 return ParseSwitchStatement(ok); 268 return ParseSwitchStatement(ok);
269 269
270 case i::Token::THROW: 270 case i::Token::THROW:
271 return ParseThrowStatement(ok); 271 return ParseThrowStatement(ok);
272 272
273 case i::Token::TRY: 273 case i::Token::TRY:
274 return ParseTryStatement(ok); 274 return ParseTryStatement(ok);
275 275
276 case i::Token::FUNCTION: { 276 case i::Token::FUNCTION: {
277 i::Scanner::Location start_location = scanner_->peek_location(); 277 i::Scanner::Location start_location = scanner()->peek_location();
278 Statement statement = ParseFunctionDeclaration(CHECK_OK); 278 Statement statement = ParseFunctionDeclaration(CHECK_OK);
279 i::Scanner::Location end_location = scanner_->location(); 279 i::Scanner::Location end_location = scanner()->location();
280 if (!is_classic_mode()) { 280 if (!is_classic_mode()) {
281 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 281 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
282 "strict_function", NULL); 282 "strict_function", NULL);
283 *ok = false; 283 *ok = false;
284 return Statement::Default(); 284 return Statement::Default();
285 } else { 285 } else {
286 return statement; 286 return statement;
287 } 287 }
288 } 288 }
289 289
290 case i::Token::DEBUGGER: 290 case i::Token::DEBUGGER:
291 return ParseDebuggerStatement(ok); 291 return ParseDebuggerStatement(ok);
292 292
293 default: 293 default:
294 return ParseExpressionOrLabelledStatement(ok); 294 return ParseExpressionOrLabelledStatement(ok);
295 } 295 }
296 } 296 }
297 297
298 298
299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 299 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
300 // FunctionDeclaration :: 300 // FunctionDeclaration ::
301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 301 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
302 // GeneratorDeclaration :: 302 // GeneratorDeclaration ::
303 // 'function' '*' Identifier '(' FormalParameterListopt ')' 303 // 'function' '*' Identifier '(' FormalParameterListopt ')'
304 // '{' FunctionBody '}' 304 // '{' FunctionBody '}'
305 Expect(i::Token::FUNCTION, CHECK_OK); 305 Expect(i::Token::FUNCTION, CHECK_OK);
306 306
307 bool is_generator = allow_generators_ && Check(i::Token::MUL); 307 bool is_generator = allow_generators() && Check(i::Token::MUL);
308 Identifier identifier = ParseIdentifier(CHECK_OK); 308 Identifier identifier = ParseIdentifier(CHECK_OK);
309 i::Scanner::Location location = scanner_->location(); 309 i::Scanner::Location location = scanner()->location();
310 310
311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); 311 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
312 312
313 if (function_value.IsStrictFunction() && 313 if (function_value.IsStrictFunction() &&
314 !identifier.IsValidStrictVariable()) { 314 !identifier.IsValidStrictVariable()) {
315 // Strict mode violation, using either reserved word or eval/arguments 315 // Strict mode violation, using either reserved word or eval/arguments
316 // as name of strict function. 316 // as name of strict function.
317 const char* type = "strict_function_name"; 317 const char* type = "strict_function_name";
318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { 318 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
319 type = "strict_reserved_word"; 319 type = "strict_reserved_word";
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // contained in extended code. 395 // contained in extended code.
396 // 396 //
397 // However disallowing const in classic mode will break compatibility with 397 // However disallowing const in classic mode will break compatibility with
398 // existing pages. Therefore we keep allowing const with the old 398 // existing pages. Therefore we keep allowing const with the old
399 // non-harmony semantics in classic mode. 399 // non-harmony semantics in classic mode.
400 Consume(i::Token::CONST); 400 Consume(i::Token::CONST);
401 switch (language_mode()) { 401 switch (language_mode()) {
402 case i::CLASSIC_MODE: 402 case i::CLASSIC_MODE:
403 break; 403 break;
404 case i::STRICT_MODE: { 404 case i::STRICT_MODE: {
405 i::Scanner::Location location = scanner_->peek_location(); 405 i::Scanner::Location location = scanner()->peek_location();
406 ReportMessageAt(location, "strict_const", NULL); 406 ReportMessageAt(location, "strict_const", NULL);
407 *ok = false; 407 *ok = false;
408 return Statement::Default(); 408 return Statement::Default();
409 } 409 }
410 case i::EXTENDED_MODE: 410 case i::EXTENDED_MODE:
411 if (var_context != kSourceElement && 411 if (var_context != kSourceElement &&
412 var_context != kForStatement) { 412 var_context != kForStatement) {
413 i::Scanner::Location location = scanner_->peek_location(); 413 i::Scanner::Location location = scanner()->peek_location();
414 ReportMessageAt(location.beg_pos, location.end_pos, 414 ReportMessageAt(location.beg_pos, location.end_pos,
415 "unprotected_const", NULL); 415 "unprotected_const", NULL);
416 *ok = false; 416 *ok = false;
417 return Statement::Default(); 417 return Statement::Default();
418 } 418 }
419 require_initializer = true; 419 require_initializer = true;
420 break; 420 break;
421 } 421 }
422 } else if (peek() == i::Token::LET) { 422 } else if (peek() == i::Token::LET) {
423 // ES6 Draft Rev4 section 12.2.1: 423 // ES6 Draft Rev4 section 12.2.1:
424 // 424 //
425 // LetDeclaration : let LetBindingList ; 425 // LetDeclaration : let LetBindingList ;
426 // 426 //
427 // * It is a Syntax Error if the code that matches this production is not 427 // * It is a Syntax Error if the code that matches this production is not
428 // contained in extended code. 428 // contained in extended code.
429 if (!is_extended_mode()) { 429 if (!is_extended_mode()) {
430 i::Scanner::Location location = scanner_->peek_location(); 430 i::Scanner::Location location = scanner()->peek_location();
431 ReportMessageAt(location.beg_pos, location.end_pos, 431 ReportMessageAt(location.beg_pos, location.end_pos,
432 "illegal_let", NULL); 432 "illegal_let", NULL);
433 *ok = false; 433 *ok = false;
434 return Statement::Default(); 434 return Statement::Default();
435 } 435 }
436 Consume(i::Token::LET); 436 Consume(i::Token::LET);
437 if (var_context != kSourceElement && 437 if (var_context != kSourceElement &&
438 var_context != kForStatement) { 438 var_context != kForStatement) {
439 i::Scanner::Location location = scanner_->peek_location(); 439 i::Scanner::Location location = scanner()->peek_location();
440 ReportMessageAt(location.beg_pos, location.end_pos, 440 ReportMessageAt(location.beg_pos, location.end_pos,
441 "unprotected_let", NULL); 441 "unprotected_let", NULL);
442 *ok = false; 442 *ok = false;
443 return Statement::Default(); 443 return Statement::Default();
444 } 444 }
445 } else { 445 } else {
446 *ok = false; 446 *ok = false;
447 return Statement::Default(); 447 return Statement::Default();
448 } 448 }
449 449
450 // The scope of a var/const declared variable anywhere inside a function 450 // The scope of a var/const declared variable anywhere inside a function
451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 451 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
452 // of a let declared variable is the scope of the immediately enclosing 452 // of a let declared variable is the scope of the immediately enclosing
453 // block. 453 // block.
454 int nvars = 0; // the number of variables declared 454 int nvars = 0; // the number of variables declared
455 do { 455 do {
456 // Parse variable name. 456 // Parse variable name.
457 if (nvars > 0) Consume(i::Token::COMMA); 457 if (nvars > 0) Consume(i::Token::COMMA);
458 Identifier identifier = ParseIdentifier(CHECK_OK); 458 Identifier identifier = ParseIdentifier(CHECK_OK);
459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { 459 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
460 StrictModeIdentifierViolation(scanner_->location(), 460 StrictModeIdentifierViolation(scanner()->location(),
461 "strict_var_name", 461 "strict_var_name",
462 identifier, 462 identifier,
463 ok); 463 ok);
464 return Statement::Default(); 464 return Statement::Default();
465 } 465 }
466 nvars++; 466 nvars++;
467 if (peek() == i::Token::ASSIGN || require_initializer) { 467 if (peek() == i::Token::ASSIGN || require_initializer) {
468 Expect(i::Token::ASSIGN, CHECK_OK); 468 Expect(i::Token::ASSIGN, CHECK_OK);
469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 469 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
470 if (decl_props != NULL) *decl_props = kHasInitializers; 470 if (decl_props != NULL) *decl_props = kHasInitializers;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 return Statement::Default(); 517 return Statement::Default();
518 } 518 }
519 519
520 520
521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 521 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
522 // ContinueStatement :: 522 // ContinueStatement ::
523 // 'continue' [no line terminator] Identifier? ';' 523 // 'continue' [no line terminator] Identifier? ';'
524 524
525 Expect(i::Token::CONTINUE, CHECK_OK); 525 Expect(i::Token::CONTINUE, CHECK_OK);
526 i::Token::Value tok = peek(); 526 i::Token::Value tok = peek();
527 if (!scanner_->HasAnyLineTerminatorBeforeNext() && 527 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
528 tok != i::Token::SEMICOLON && 528 tok != i::Token::SEMICOLON &&
529 tok != i::Token::RBRACE && 529 tok != i::Token::RBRACE &&
530 tok != i::Token::EOS) { 530 tok != i::Token::EOS) {
531 ParseIdentifier(CHECK_OK); 531 ParseIdentifier(CHECK_OK);
532 } 532 }
533 ExpectSemicolon(CHECK_OK); 533 ExpectSemicolon(CHECK_OK);
534 return Statement::Default(); 534 return Statement::Default();
535 } 535 }
536 536
537 537
538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 538 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
539 // BreakStatement :: 539 // BreakStatement ::
540 // 'break' [no line terminator] Identifier? ';' 540 // 'break' [no line terminator] Identifier? ';'
541 541
542 Expect(i::Token::BREAK, CHECK_OK); 542 Expect(i::Token::BREAK, CHECK_OK);
543 i::Token::Value tok = peek(); 543 i::Token::Value tok = peek();
544 if (!scanner_->HasAnyLineTerminatorBeforeNext() && 544 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
545 tok != i::Token::SEMICOLON && 545 tok != i::Token::SEMICOLON &&
546 tok != i::Token::RBRACE && 546 tok != i::Token::RBRACE &&
547 tok != i::Token::EOS) { 547 tok != i::Token::EOS) {
548 ParseIdentifier(CHECK_OK); 548 ParseIdentifier(CHECK_OK);
549 } 549 }
550 ExpectSemicolon(CHECK_OK); 550 ExpectSemicolon(CHECK_OK);
551 return Statement::Default(); 551 return Statement::Default();
552 } 552 }
553 553
554 554
555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 555 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
556 // ReturnStatement :: 556 // ReturnStatement ::
557 // 'return' [no line terminator] Expression? ';' 557 // 'return' [no line terminator] Expression? ';'
558 558
559 // Consume the return token. It is necessary to do the before 559 // Consume the return token. It is necessary to do the before
560 // reporting any errors on it, because of the way errors are 560 // reporting any errors on it, because of the way errors are
561 // reported (underlining). 561 // reported (underlining).
562 Expect(i::Token::RETURN, CHECK_OK); 562 Expect(i::Token::RETURN, CHECK_OK);
563 563
564 // An ECMAScript program is considered syntactically incorrect if it 564 // An ECMAScript program is considered syntactically incorrect if it
565 // contains a return statement that is not within the body of a 565 // contains a return statement that is not within the body of a
566 // function. See ECMA-262, section 12.9, page 67. 566 // function. See ECMA-262, section 12.9, page 67.
567 // This is not handled during preparsing. 567 // This is not handled during preparsing.
568 568
569 i::Token::Value tok = peek(); 569 i::Token::Value tok = peek();
570 if (!scanner_->HasAnyLineTerminatorBeforeNext() && 570 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
571 tok != i::Token::SEMICOLON && 571 tok != i::Token::SEMICOLON &&
572 tok != i::Token::RBRACE && 572 tok != i::Token::RBRACE &&
573 tok != i::Token::EOS) { 573 tok != i::Token::EOS) {
574 ParseExpression(true, CHECK_OK); 574 ParseExpression(true, CHECK_OK);
575 } 575 }
576 ExpectSemicolon(CHECK_OK); 576 ExpectSemicolon(CHECK_OK);
577 return Statement::Default(); 577 return Statement::Default();
578 } 578 }
579 579
580 580
581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 581 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
582 // WithStatement :: 582 // WithStatement ::
583 // 'with' '(' Expression ')' Statement 583 // 'with' '(' Expression ')' Statement
584 Expect(i::Token::WITH, CHECK_OK); 584 Expect(i::Token::WITH, CHECK_OK);
585 if (!is_classic_mode()) { 585 if (!is_classic_mode()) {
586 i::Scanner::Location location = scanner_->location(); 586 i::Scanner::Location location = scanner()->location();
587 ReportMessageAt(location, "strict_mode_with", NULL); 587 ReportMessageAt(location, "strict_mode_with", NULL);
588 *ok = false; 588 *ok = false;
589 return Statement::Default(); 589 return Statement::Default();
590 } 590 }
591 Expect(i::Token::LPAREN, CHECK_OK); 591 Expect(i::Token::LPAREN, CHECK_OK);
592 ParseExpression(true, CHECK_OK); 592 ParseExpression(true, CHECK_OK);
593 Expect(i::Token::RPAREN, CHECK_OK); 593 Expect(i::Token::RPAREN, CHECK_OK);
594 594
595 Scope::InsideWith iw(scope_); 595 Scope::InsideWith iw(scope_);
596 ParseStatement(CHECK_OK); 596 ParseStatement(CHECK_OK);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 ParseExpression(true, CHECK_OK); 654 ParseExpression(true, CHECK_OK);
655 Expect(i::Token::RPAREN, CHECK_OK); 655 Expect(i::Token::RPAREN, CHECK_OK);
656 ParseStatement(ok); 656 ParseStatement(ok);
657 return Statement::Default(); 657 return Statement::Default();
658 } 658 }
659 659
660 660
661 bool PreParser::CheckInOrOf(bool accept_OF) { 661 bool PreParser::CheckInOrOf(bool accept_OF) {
662 if (peek() == i::Token::IN || 662 if (peek() == i::Token::IN ||
663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && 663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER &&
664 scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { 664 scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) {
665 Next(); 665 Next();
666 return true; 666 return true;
667 } 667 }
668 return false; 668 return false;
669 } 669 }
670 670
671 671
672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 672 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
673 // ForStatement :: 673 // ForStatement ::
674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 ParseStatement(ok); 721 ParseStatement(ok);
722 return Statement::Default(); 722 return Statement::Default();
723 } 723 }
724 724
725 725
726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
727 // ThrowStatement :: 727 // ThrowStatement ::
728 // 'throw' [no line terminator] Expression ';' 728 // 'throw' [no line terminator] Expression ';'
729 729
730 Expect(i::Token::THROW, CHECK_OK); 730 Expect(i::Token::THROW, CHECK_OK);
731 if (scanner_->HasAnyLineTerminatorBeforeNext()) { 731 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
732 i::Scanner::Location pos = scanner_->location(); 732 i::Scanner::Location pos = scanner()->location();
733 ReportMessageAt(pos, "newline_after_throw", NULL); 733 ReportMessageAt(pos, "newline_after_throw", NULL);
734 *ok = false; 734 *ok = false;
735 return Statement::Default(); 735 return Statement::Default();
736 } 736 }
737 ParseExpression(true, CHECK_OK); 737 ParseExpression(true, CHECK_OK);
738 ExpectSemicolon(ok); 738 ExpectSemicolon(ok);
739 return Statement::Default(); 739 return Statement::Default();
740 } 740 }
741 741
742 742
(...skipping 15 matching lines...) Expand all
758 Expect(i::Token::TRY, CHECK_OK); 758 Expect(i::Token::TRY, CHECK_OK);
759 759
760 ParseBlock(CHECK_OK); 760 ParseBlock(CHECK_OK);
761 761
762 bool catch_or_finally_seen = false; 762 bool catch_or_finally_seen = false;
763 if (peek() == i::Token::CATCH) { 763 if (peek() == i::Token::CATCH) {
764 Consume(i::Token::CATCH); 764 Consume(i::Token::CATCH);
765 Expect(i::Token::LPAREN, CHECK_OK); 765 Expect(i::Token::LPAREN, CHECK_OK);
766 Identifier id = ParseIdentifier(CHECK_OK); 766 Identifier id = ParseIdentifier(CHECK_OK);
767 if (!is_classic_mode() && !id.IsValidStrictVariable()) { 767 if (!is_classic_mode() && !id.IsValidStrictVariable()) {
768 StrictModeIdentifierViolation(scanner_->location(), 768 StrictModeIdentifierViolation(scanner()->location(),
769 "strict_catch_variable", 769 "strict_catch_variable",
770 id, 770 id,
771 ok); 771 ok);
772 return Statement::Default(); 772 return Statement::Default();
773 } 773 }
774 Expect(i::Token::RPAREN, CHECK_OK); 774 Expect(i::Token::RPAREN, CHECK_OK);
775 { Scope::InsideWith iw(scope_); 775 { Scope::InsideWith iw(scope_);
776 ParseBlock(CHECK_OK); 776 ParseBlock(CHECK_OK);
777 } 777 }
778 catch_or_finally_seen = true; 778 catch_or_finally_seen = true;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 bool* ok) { 831 bool* ok) {
832 // AssignmentExpression :: 832 // AssignmentExpression ::
833 // ConditionalExpression 833 // ConditionalExpression
834 // YieldExpression 834 // YieldExpression
835 // LeftHandSideExpression AssignmentOperator AssignmentExpression 835 // LeftHandSideExpression AssignmentOperator AssignmentExpression
836 836
837 if (scope_->is_generator() && peek() == i::Token::YIELD) { 837 if (scope_->is_generator() && peek() == i::Token::YIELD) {
838 return ParseYieldExpression(ok); 838 return ParseYieldExpression(ok);
839 } 839 }
840 840
841 i::Scanner::Location before = scanner_->peek_location(); 841 i::Scanner::Location before = scanner()->peek_location();
842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 842 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
843 843
844 if (!i::Token::IsAssignmentOp(peek())) { 844 if (!i::Token::IsAssignmentOp(peek())) {
845 // Parsed conditional expression only (no assignment). 845 // Parsed conditional expression only (no assignment).
846 return expression; 846 return expression;
847 } 847 }
848 848
849 if (!is_classic_mode() && 849 if (!is_classic_mode() &&
850 expression.IsIdentifier() && 850 expression.IsIdentifier() &&
851 expression.AsIdentifier().IsEvalOrArguments()) { 851 expression.AsIdentifier().IsEvalOrArguments()) {
852 i::Scanner::Location after = scanner_->location(); 852 i::Scanner::Location after = scanner()->location();
853 ReportMessageAt(before.beg_pos, after.end_pos, 853 ReportMessageAt(before.beg_pos, after.end_pos,
854 "strict_lhs_assignment", NULL); 854 "strict_lhs_assignment", NULL);
855 *ok = false; 855 *ok = false;
856 return Expression::Default(); 856 return Expression::Default();
857 } 857 }
858 858
859 i::Token::Value op = Next(); // Get assignment operator. 859 i::Token::Value op = Next(); // Get assignment operator.
860 ParseAssignmentExpression(accept_IN, CHECK_OK); 860 ParseAssignmentExpression(accept_IN, CHECK_OK);
861 861
862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { 862 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 // '~' UnaryExpression 939 // '~' UnaryExpression
940 // '!' UnaryExpression 940 // '!' UnaryExpression
941 941
942 i::Token::Value op = peek(); 942 i::Token::Value op = peek();
943 if (i::Token::IsUnaryOp(op)) { 943 if (i::Token::IsUnaryOp(op)) {
944 op = Next(); 944 op = Next();
945 ParseUnaryExpression(ok); 945 ParseUnaryExpression(ok);
946 return Expression::Default(); 946 return Expression::Default();
947 } else if (i::Token::IsCountOp(op)) { 947 } else if (i::Token::IsCountOp(op)) {
948 op = Next(); 948 op = Next();
949 i::Scanner::Location before = scanner_->peek_location(); 949 i::Scanner::Location before = scanner()->peek_location();
950 Expression expression = ParseUnaryExpression(CHECK_OK); 950 Expression expression = ParseUnaryExpression(CHECK_OK);
951 if (!is_classic_mode() && 951 if (!is_classic_mode() &&
952 expression.IsIdentifier() && 952 expression.IsIdentifier() &&
953 expression.AsIdentifier().IsEvalOrArguments()) { 953 expression.AsIdentifier().IsEvalOrArguments()) {
954 i::Scanner::Location after = scanner_->location(); 954 i::Scanner::Location after = scanner()->location();
955 ReportMessageAt(before.beg_pos, after.end_pos, 955 ReportMessageAt(before.beg_pos, after.end_pos,
956 "strict_lhs_prefix", NULL); 956 "strict_lhs_prefix", NULL);
957 *ok = false; 957 *ok = false;
958 } 958 }
959 return Expression::Default(); 959 return Expression::Default();
960 } else { 960 } else {
961 return ParsePostfixExpression(ok); 961 return ParsePostfixExpression(ok);
962 } 962 }
963 } 963 }
964 964
965 965
966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 966 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
967 // PostfixExpression :: 967 // PostfixExpression ::
968 // LeftHandSideExpression ('++' | '--')? 968 // LeftHandSideExpression ('++' | '--')?
969 969
970 i::Scanner::Location before = scanner_->peek_location(); 970 i::Scanner::Location before = scanner()->peek_location();
971 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 971 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
972 if (!scanner_->HasAnyLineTerminatorBeforeNext() && 972 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
973 i::Token::IsCountOp(peek())) { 973 i::Token::IsCountOp(peek())) {
974 if (!is_classic_mode() && 974 if (!is_classic_mode() &&
975 expression.IsIdentifier() && 975 expression.IsIdentifier() &&
976 expression.AsIdentifier().IsEvalOrArguments()) { 976 expression.AsIdentifier().IsEvalOrArguments()) {
977 i::Scanner::Location after = scanner_->location(); 977 i::Scanner::Location after = scanner()->location();
978 ReportMessageAt(before.beg_pos, after.end_pos, 978 ReportMessageAt(before.beg_pos, after.end_pos,
979 "strict_lhs_postfix", NULL); 979 "strict_lhs_postfix", NULL);
980 *ok = false; 980 *ok = false;
981 return Expression::Default(); 981 return Expression::Default();
982 } 982 }
983 Next(); 983 Next();
984 return Expression::Default(); 984 return Expression::Default();
985 } 985 }
986 return expression; 986 return expression;
987 } 987 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 unsigned new_count, bool* ok) { 1067 unsigned new_count, bool* ok) {
1068 // MemberExpression :: 1068 // MemberExpression ::
1069 // (PrimaryExpression | FunctionLiteral) 1069 // (PrimaryExpression | FunctionLiteral)
1070 // ('[' Expression ']' | '.' Identifier | Arguments)* 1070 // ('[' Expression ']' | '.' Identifier | Arguments)*
1071 1071
1072 // Parse the initial primary or function expression. 1072 // Parse the initial primary or function expression.
1073 Expression result = Expression::Default(); 1073 Expression result = Expression::Default();
1074 if (peek() == i::Token::FUNCTION) { 1074 if (peek() == i::Token::FUNCTION) {
1075 Consume(i::Token::FUNCTION); 1075 Consume(i::Token::FUNCTION);
1076 1076
1077 bool is_generator = allow_generators_ && Check(i::Token::MUL); 1077 bool is_generator = allow_generators() && Check(i::Token::MUL);
1078 Identifier identifier = Identifier::Default(); 1078 Identifier identifier = Identifier::Default();
1079 if (peek_any_identifier()) { 1079 if (peek_any_identifier()) {
1080 identifier = ParseIdentifier(CHECK_OK); 1080 identifier = ParseIdentifier(CHECK_OK);
1081 } 1081 }
1082 result = ParseFunctionLiteral(is_generator, CHECK_OK); 1082 result = ParseFunctionLiteral(is_generator, CHECK_OK);
1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { 1083 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1084 StrictModeIdentifierViolation(scanner_->location(), 1084 StrictModeIdentifierViolation(scanner()->location(),
1085 "strict_function_name", 1085 "strict_function_name",
1086 identifier, 1086 identifier,
1087 ok); 1087 ok);
1088 return Expression::Default(); 1088 return Expression::Default();
1089 } 1089 }
1090 } else { 1090 } else {
1091 result = ParsePrimaryExpression(CHECK_OK); 1091 result = ParsePrimaryExpression(CHECK_OK);
1092 } 1092 }
1093 1093
1094 while (true) { 1094 while (true) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 } 1231 }
1232 1232
1233 1233
1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { 1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1235 // ObjectLiteral :: 1235 // ObjectLiteral ::
1236 // '{' ( 1236 // '{' (
1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1237 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1239 // )*[','] '}' 1239 // )*[','] '}'
1240 1240
1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); 1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode());
1242 1242
1243 Expect(i::Token::LBRACE, CHECK_OK); 1243 Expect(i::Token::LBRACE, CHECK_OK);
1244 while (peek() != i::Token::RBRACE) { 1244 while (peek() != i::Token::RBRACE) {
1245 i::Token::Value next = peek(); 1245 i::Token::Value next = peek();
1246 switch (next) { 1246 switch (next) {
1247 case i::Token::IDENTIFIER: 1247 case i::Token::IDENTIFIER:
1248 case i::Token::FUTURE_RESERVED_WORD: 1248 case i::Token::FUTURE_RESERVED_WORD:
1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { 1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1250 bool is_getter = false; 1250 bool is_getter = false;
1251 bool is_setter = false; 1251 bool is_setter = false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 } 1305 }
1306 Expect(i::Token::RBRACE, CHECK_OK); 1306 Expect(i::Token::RBRACE, CHECK_OK);
1307 1307
1308 scope_->NextMaterializedLiteralIndex(); 1308 scope_->NextMaterializedLiteralIndex();
1309 return Expression::Default(); 1309 return Expression::Default();
1310 } 1310 }
1311 1311
1312 1312
1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, 1313 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1314 bool* ok) { 1314 bool* ok) {
1315 if (!scanner_->ScanRegExpPattern(seen_equal)) { 1315 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1316 Next(); 1316 Next();
1317 ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL); 1317 ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
1318 *ok = false; 1318 *ok = false;
1319 return Expression::Default(); 1319 return Expression::Default();
1320 } 1320 }
1321 1321
1322 scope_->NextMaterializedLiteralIndex(); 1322 scope_->NextMaterializedLiteralIndex();
1323 1323
1324 if (!scanner_->ScanRegExpFlags()) { 1324 if (!scanner()->ScanRegExpFlags()) {
1325 Next(); 1325 Next();
1326 ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL); 1326 ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
1327 *ok = false; 1327 *ok = false;
1328 return Expression::Default(); 1328 return Expression::Default();
1329 } 1329 }
1330 Next(); 1330 Next();
1331 return Expression::Default(); 1331 return Expression::Default();
1332 } 1332 }
1333 1333
1334 1334
1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) { 1335 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1336 // Arguments :: 1336 // Arguments ::
(...skipping 24 matching lines...) Expand all
1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1361 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1362 1362
1363 // Parse function body. 1363 // Parse function body.
1364 ScopeType outer_scope_type = scope_->type(); 1364 ScopeType outer_scope_type = scope_->type();
1365 bool inside_with = scope_->IsInsideWith(); 1365 bool inside_with = scope_->IsInsideWith();
1366 Scope function_scope(&scope_, kFunctionScope); 1366 Scope function_scope(&scope_, kFunctionScope);
1367 function_scope.set_is_generator(is_generator); 1367 function_scope.set_is_generator(is_generator);
1368 // FormalParameterList :: 1368 // FormalParameterList ::
1369 // '(' (Identifier)*[','] ')' 1369 // '(' (Identifier)*[','] ')'
1370 Expect(i::Token::LPAREN, CHECK_OK); 1370 Expect(i::Token::LPAREN, CHECK_OK);
1371 int start_position = scanner_->location().beg_pos; 1371 int start_position = scanner()->location().beg_pos;
1372 bool done = (peek() == i::Token::RPAREN); 1372 bool done = (peek() == i::Token::RPAREN);
1373 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); 1373 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1374 while (!done) { 1374 while (!done) {
1375 Identifier id = ParseIdentifier(CHECK_OK); 1375 Identifier id = ParseIdentifier(CHECK_OK);
1376 if (!id.IsValidStrictVariable()) { 1376 if (!id.IsValidStrictVariable()) {
1377 StrictModeIdentifierViolation(scanner_->location(), 1377 StrictModeIdentifierViolation(scanner()->location(),
1378 "strict_param_name", 1378 "strict_param_name",
1379 id, 1379 id,
1380 CHECK_OK); 1380 CHECK_OK);
1381 } 1381 }
1382 int prev_value; 1382 int prev_value;
1383 if (scanner_->is_literal_ascii()) { 1383 if (scanner()->is_literal_ascii()) {
1384 prev_value = 1384 prev_value =
1385 duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1); 1385 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1386 } else { 1386 } else {
1387 prev_value = 1387 prev_value =
1388 duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1); 1388 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1389 } 1389 }
1390 1390
1391 if (prev_value != 0) { 1391 if (prev_value != 0) {
1392 SetStrictModeViolation(scanner_->location(), 1392 SetStrictModeViolation(scanner()->location(),
1393 "strict_param_dupe", 1393 "strict_param_dupe",
1394 CHECK_OK); 1394 CHECK_OK);
1395 } 1395 }
1396 done = (peek() == i::Token::RPAREN); 1396 done = (peek() == i::Token::RPAREN);
1397 if (!done) { 1397 if (!done) {
1398 Expect(i::Token::COMMA, CHECK_OK); 1398 Expect(i::Token::COMMA, CHECK_OK);
1399 } 1399 }
1400 } 1400 }
1401 Expect(i::Token::RPAREN, CHECK_OK); 1401 Expect(i::Token::RPAREN, CHECK_OK);
1402 1402
1403 // Determine if the function will be lazily compiled. 1403 // Determine if the function will be lazily compiled.
1404 // Currently only happens to top-level functions. 1404 // Currently only happens to top-level functions.
1405 // Optimistically assume that all top-level functions are lazily compiled. 1405 // Optimistically assume that all top-level functions are lazily compiled.
1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && 1406 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1407 !inside_with && allow_lazy_ && 1407 !inside_with && allow_lazy() &&
1408 !parenthesized_function_); 1408 !parenthesized_function_);
1409 parenthesized_function_ = false; 1409 parenthesized_function_ = false;
1410 1410
1411 Expect(i::Token::LBRACE, CHECK_OK); 1411 Expect(i::Token::LBRACE, CHECK_OK);
1412 if (is_lazily_compiled) { 1412 if (is_lazily_compiled) {
1413 ParseLazyFunctionLiteralBody(CHECK_OK); 1413 ParseLazyFunctionLiteralBody(CHECK_OK);
1414 } else { 1414 } else {
1415 ParseSourceElements(i::Token::RBRACE, ok); 1415 ParseSourceElements(i::Token::RBRACE, ok);
1416 } 1416 }
1417 Expect(i::Token::RBRACE, CHECK_OK); 1417 Expect(i::Token::RBRACE, CHECK_OK);
1418 1418
1419 if (!is_classic_mode()) { 1419 if (!is_classic_mode()) {
1420 int end_position = scanner_->location().end_pos; 1420 int end_position = scanner()->location().end_pos;
1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1421 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); 1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1423 return Expression::StrictFunction(); 1423 return Expression::StrictFunction();
1424 } 1424 }
1425 1425
1426 return Expression::Default(); 1426 return Expression::Default();
1427 } 1427 }
1428 1428
1429 1429
1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1431 int body_start = scanner_->location().beg_pos; 1431 int body_start = scanner()->location().beg_pos;
1432 log_->PauseRecording(); 1432 log_->PauseRecording();
1433 ParseSourceElements(i::Token::RBRACE, ok); 1433 ParseSourceElements(i::Token::RBRACE, ok);
1434 log_->ResumeRecording(); 1434 log_->ResumeRecording();
1435 if (!*ok) return; 1435 if (!*ok) return;
1436 1436
1437 // Position right after terminal '}'. 1437 // Position right after terminal '}'.
1438 ASSERT_EQ(i::Token::RBRACE, scanner_->peek()); 1438 ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
1439 int body_end = scanner_->peek_location().end_pos; 1439 int body_end = scanner()->peek_location().end_pos;
1440 log_->LogFunction(body_start, body_end, 1440 log_->LogFunction(body_start, body_end,
1441 scope_->materialized_literal_count(), 1441 scope_->materialized_literal_count(),
1442 scope_->expected_properties(), 1442 scope_->expected_properties(),
1443 language_mode()); 1443 language_mode());
1444 } 1444 }
1445 1445
1446 1446
1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1447 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1448 // CallRuntime :: 1448 // CallRuntime ::
1449 // '%' Identifier Arguments 1449 // '%' Identifier Arguments
1450 Expect(i::Token::MOD, CHECK_OK); 1450 Expect(i::Token::MOD, CHECK_OK);
1451 if (!allow_natives_syntax_) { 1451 if (!allow_natives_syntax()) {
1452 *ok = false; 1452 *ok = false;
1453 return Expression::Default(); 1453 return Expression::Default();
1454 } 1454 }
1455 ParseIdentifier(CHECK_OK); 1455 ParseIdentifier(CHECK_OK);
1456 ParseArguments(ok); 1456 ParseArguments(ok);
1457 1457
1458 return Expression::Default(); 1458 return Expression::Default();
1459 } 1459 }
1460 1460
1461 #undef CHECK_OK 1461 #undef CHECK_OK
1462 1462
1463 1463
1464 void PreParser::ExpectSemicolon(bool* ok) {
1465 // Check for automatic semicolon insertion according to
1466 // the rules given in ECMA-262, section 7.9, page 21.
1467 i::Token::Value tok = peek();
1468 if (tok == i::Token::SEMICOLON) {
1469 Next();
1470 return;
1471 }
1472 if (scanner_->HasAnyLineTerminatorBeforeNext() ||
1473 tok == i::Token::RBRACE ||
1474 tok == i::Token::EOS) {
1475 return;
1476 }
1477 Expect(i::Token::SEMICOLON, ok);
1478 }
1479
1480
1481 void PreParser::LogSymbol() { 1464 void PreParser::LogSymbol() {
1482 int identifier_pos = scanner_->location().beg_pos; 1465 int identifier_pos = scanner()->location().beg_pos;
1483 if (scanner_->is_literal_ascii()) { 1466 if (scanner()->is_literal_ascii()) {
1484 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); 1467 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
1485 } else { 1468 } else {
1486 log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string()); 1469 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
1487 } 1470 }
1488 } 1471 }
1489 1472
1490 1473
1491 PreParser::Expression PreParser::GetStringSymbol() { 1474 PreParser::Expression PreParser::GetStringSymbol() {
1492 const int kUseStrictLength = 10; 1475 const int kUseStrictLength = 10;
1493 const char* kUseStrictChars = "use strict"; 1476 const char* kUseStrictChars = "use strict";
1494 LogSymbol(); 1477 LogSymbol();
1495 if (scanner_->is_literal_ascii() && 1478 if (scanner()->is_literal_ascii() &&
1496 scanner_->literal_length() == kUseStrictLength && 1479 scanner()->literal_length() == kUseStrictLength &&
1497 !scanner_->literal_contains_escapes() && 1480 !scanner()->literal_contains_escapes() &&
1498 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, 1481 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1499 kUseStrictLength)) { 1482 kUseStrictLength)) {
1500 return Expression::UseStrictStringLiteral(); 1483 return Expression::UseStrictStringLiteral();
1501 } 1484 }
1502 return Expression::StringLiteral(); 1485 return Expression::StringLiteral();
1503 } 1486 }
1504 1487
1505 1488
1506 PreParser::Identifier PreParser::GetIdentifierSymbol() { 1489 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1507 LogSymbol(); 1490 LogSymbol();
1508 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { 1491 if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1509 return Identifier::FutureReserved(); 1492 return Identifier::FutureReserved();
1510 } else if (scanner_->current_token() == 1493 } else if (scanner()->current_token() ==
1511 i::Token::FUTURE_STRICT_RESERVED_WORD) { 1494 i::Token::FUTURE_STRICT_RESERVED_WORD) {
1512 return Identifier::FutureStrictReserved(); 1495 return Identifier::FutureStrictReserved();
1513 } else if (scanner_->current_token() == i::Token::YIELD) { 1496 } else if (scanner()->current_token() == i::Token::YIELD) {
1514 return Identifier::Yield(); 1497 return Identifier::Yield();
1515 } 1498 }
1516 if (scanner_->is_literal_ascii()) { 1499 if (scanner()->is_literal_ascii()) {
1517 // Detect strict-mode poison words. 1500 // Detect strict-mode poison words.
1518 if (scanner_->literal_length() == 4 && 1501 if (scanner()->literal_length() == 4 &&
1519 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { 1502 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1520 return Identifier::Eval(); 1503 return Identifier::Eval();
1521 } 1504 }
1522 if (scanner_->literal_length() == 9 && 1505 if (scanner()->literal_length() == 9 &&
1523 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { 1506 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1524 return Identifier::Arguments(); 1507 return Identifier::Arguments();
1525 } 1508 }
1526 } 1509 }
1527 return Identifier::Default(); 1510 return Identifier::Default();
1528 } 1511 }
1529 1512
1530 1513
1531 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1514 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1532 i::Token::Value next = Next(); 1515 i::Token::Value next = Next();
1533 switch (next) { 1516 switch (next) {
1534 case i::Token::FUTURE_RESERVED_WORD: { 1517 case i::Token::FUTURE_RESERVED_WORD: {
1535 i::Scanner::Location location = scanner_->location(); 1518 i::Scanner::Location location = scanner()->location();
1536 ReportMessageAt(location.beg_pos, location.end_pos, 1519 ReportMessageAt(location.beg_pos, location.end_pos,
1537 "reserved_word", NULL); 1520 "reserved_word", NULL);
1538 *ok = false; 1521 *ok = false;
1539 return GetIdentifierSymbol(); 1522 return GetIdentifierSymbol();
1540 } 1523 }
1541 case i::Token::YIELD: 1524 case i::Token::YIELD:
1542 if (scope_->is_generator()) { 1525 if (scope_->is_generator()) {
1543 // 'yield' in a generator is only valid as part of a YieldExpression. 1526 // 'yield' in a generator is only valid as part of a YieldExpression.
1544 ReportMessageAt(scanner_->location(), "unexpected_token", "yield"); 1527 ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
1545 *ok = false; 1528 *ok = false;
1546 return Identifier::Yield(); 1529 return Identifier::Yield();
1547 } 1530 }
1548 // FALLTHROUGH 1531 // FALLTHROUGH
1549 case i::Token::FUTURE_STRICT_RESERVED_WORD: 1532 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1550 if (!is_classic_mode()) { 1533 if (!is_classic_mode()) {
1551 i::Scanner::Location location = scanner_->location(); 1534 i::Scanner::Location location = scanner()->location();
1552 ReportMessageAt(location.beg_pos, location.end_pos, 1535 ReportMessageAt(location.beg_pos, location.end_pos,
1553 "strict_reserved_word", NULL); 1536 "strict_reserved_word", NULL);
1554 *ok = false; 1537 *ok = false;
1555 } 1538 }
1556 // FALLTHROUGH 1539 // FALLTHROUGH
1557 case i::Token::IDENTIFIER: 1540 case i::Token::IDENTIFIER:
1558 return GetIdentifierSymbol(); 1541 return GetIdentifierSymbol();
1559 default: 1542 default:
1560 *ok = false; 1543 *ok = false;
1561 return Identifier::Default(); 1544 return Identifier::Default();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 return; 1595 return;
1613 } 1596 }
1614 strict_mode_violation_location_ = location; 1597 strict_mode_violation_location_ = location;
1615 strict_mode_violation_type_ = type; 1598 strict_mode_violation_type_ = type;
1616 } 1599 }
1617 1600
1618 1601
1619 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1602 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1620 i::Token::Value next = Next(); 1603 i::Token::Value next = Next();
1621 if (i::Token::IsKeyword(next)) { 1604 if (i::Token::IsKeyword(next)) {
1622 int pos = scanner_->location().beg_pos; 1605 int pos = scanner()->location().beg_pos;
1623 const char* keyword = i::Token::String(next); 1606 const char* keyword = i::Token::String(next);
1624 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, 1607 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
1625 i::StrLength(keyword))); 1608 i::StrLength(keyword)));
1626 return Identifier::Default(); 1609 return Identifier::Default();
1627 } 1610 }
1628 if (next == i::Token::IDENTIFIER || 1611 if (next == i::Token::IDENTIFIER ||
1629 next == i::Token::FUTURE_RESERVED_WORD || 1612 next == i::Token::FUTURE_RESERVED_WORD ||
1630 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { 1613 next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1631 return GetIdentifierSymbol(); 1614 return GetIdentifierSymbol();
1632 } 1615 }
1633 *ok = false; 1616 *ok = false;
1634 return Identifier::Default(); 1617 return Identifier::Default();
1635 } 1618 }
1636 1619
1637 #undef CHECK_OK 1620 #undef CHECK_OK
1638 1621
1639 1622
1640 // This function reads an identifier and determines whether or not it 1623 // This function reads an identifier and determines whether or not it
1641 // is 'get' or 'set'. 1624 // is 'get' or 'set'.
1642 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get, 1625 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1643 bool* is_set, 1626 bool* is_set,
1644 bool* ok) { 1627 bool* ok) {
1645 Identifier result = ParseIdentifierName(ok); 1628 Identifier result = ParseIdentifierName(ok);
1646 if (!*ok) return Identifier::Default(); 1629 if (!*ok) return Identifier::Default();
1647 if (scanner_->is_literal_ascii() && 1630 if (scanner()->is_literal_ascii() &&
1648 scanner_->literal_length() == 3) { 1631 scanner()->literal_length() == 3) {
1649 const char* token = scanner_->literal_ascii_string().start(); 1632 const char* token = scanner()->literal_ascii_string().start();
1650 *is_get = strncmp(token, "get", 3) == 0; 1633 *is_get = strncmp(token, "get", 3) == 0;
1651 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 1634 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1652 } 1635 }
1653 return result; 1636 return result;
1654 } 1637 }
1655 1638
1656 1639
1657 bool PreParser::peek_any_identifier() {
1658 i::Token::Value next = peek();
1659 return next == i::Token::IDENTIFIER ||
1660 next == i::Token::FUTURE_RESERVED_WORD ||
1661 next == i::Token::FUTURE_STRICT_RESERVED_WORD ||
1662 next == i::Token::YIELD;
1663 }
1664
1665 } } // v8::internal 1640 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698