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

Side by Side Diff: src/preparser.cc

Issue 641283003: Support lazy parsing of inner functions (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: Actually track variable declarations in the preparser Created 6 years, 1 month 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
« no previous file with comments | « src/preparser.h ('k') | src/vector.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
11 #include "src/globals.h" 11 #include "src/globals.h"
12 #include "src/hashmap.h" 12 #include "src/hashmap.h"
13 #include "src/list.h" 13 #include "src/list.h"
14 #include "src/parser.h"
14 #include "src/preparse-data.h" 15 #include "src/preparse-data.h"
15 #include "src/preparse-data-format.h" 16 #include "src/preparse-data-format.h"
16 #include "src/preparser.h" 17 #include "src/preparser.h"
17 #include "src/unicode.h" 18 #include "src/unicode.h"
18 #include "src/utils.h" 19 #include "src/utils.h"
19 20
20 namespace v8 { 21 namespace v8 {
21 namespace internal { 22 namespace internal {
22 23
24 PreParserScope::~PreParserScope() {
25 if (unbound_variables_ && outer_scope_) {
26 for (ZoneHashMap::Entry* p = unbound_variables_->Start(); p != NULL;
27 p = unbound_variables_->Next(p)) {
28 AstRawString* identifier = static_cast<AstRawString*>(p->key);
29 if (!declared_variables_->Lookup(identifier, identifier->hash(), false,
30 ZoneAllocationPolicy(zone_))) {
31 outer_scope_->RecordVariableUsage(identifier);
32 }
33 }
34 }
35 }
36
37
38 PreParserScope* PreParserScope::DeclarationScope() {
39 PreParserScope* scope = this;
40 while (!scope->is_declaration_scope()) {
41 scope = scope->outer_scope();
42 }
43 return scope;
44 }
45
46
47 void PreParserScope::RecordVariableUsage(const AstRawString* identifier) {
48 ZoneAllocationPolicy allocator(zone_);
49 if (!declared_variables_->Lookup(const_cast<AstRawString*>(identifier),
50 identifier->hash(), false, allocator)) {
51 unbound_variables_->Lookup(const_cast<AstRawString*>(identifier),
52 identifier->hash(), true, allocator);
53 }
54 }
55
56
57 void PreParserScope::LogUnboundVariables(ParserRecorder* recorder) {
58 for (ZoneHashMap::Entry* p = unbound_variables_->Start(); p != NULL;
59 p = unbound_variables_->Next(p)) {
60 AstRawString* identifier = static_cast<AstRawString*>(p->key);
61 if (!declared_variables_->Lookup(identifier, identifier->hash(), false,
62 ZoneAllocationPolicy(zone_))) {
63 recorder->LogIdentifier(identifier);
64 }
65 }
66 unbound_variables_->Clear();
67 }
68
69
70 void PreParserScope::Declare(const AstRawString* identifier, bool lexical) {
71 if (lexical || is_declaration_scope()) {
72 DCHECK(declared_variables_);
73 declared_variables_->Lookup(const_cast<AstRawString*>(identifier),
74 identifier->hash(), true,
75 ZoneAllocationPolicy(zone_));
76 } else {
77 DeclarationScope()->Declare(identifier, lexical);
78 }
79 }
80
81
82 void PreParserTraits::RecordCurrentSymbolAsIdentifierExpression() {
83 if (pre_parser_->log_ != NULL && pre_parser_->log_identifiers_) {
84 DCHECK(pre_parser_->ast_value_factory_ != NULL);
85 const AstRawString* identifier =
86 pre_parser_->scanner()->CurrentSymbol(pre_parser_->ast_value_factory_);
87 pre_parser_->scope_->RecordVariableUsage(identifier);
88 }
89 }
90
91
23 void PreParserTraits::ReportMessageAt(Scanner::Location location, 92 void PreParserTraits::ReportMessageAt(Scanner::Location location,
24 const char* message, 93 const char* message,
25 const char* arg, 94 const char* arg,
26 bool is_reference_error) { 95 bool is_reference_error) {
27 ReportMessageAt(location.beg_pos, 96 ReportMessageAt(location.beg_pos,
28 location.end_pos, 97 location.end_pos,
29 message, 98 message,
30 arg, 99 arg,
31 is_reference_error); 100 is_reference_error);
32 } 101 }
33 102
34 103
35 void PreParserTraits::ReportMessageAt(int start_pos, 104 void PreParserTraits::ReportMessageAt(int start_pos,
36 int end_pos, 105 int end_pos,
37 const char* message, 106 const char* message,
38 const char* arg, 107 const char* arg,
39 bool is_reference_error) { 108 bool is_reference_error) {
40 pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg, 109 pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg,
41 is_reference_error); 110 is_reference_error);
42 } 111 }
43 112
44 113
114 void PreParserTraits::CheckPossibleEvalCall(PreParserExpression expression,
115 PreParserScope* scope) {
116 if (pre_parser_->log_ != NULL && pre_parser_->log_identifiers_ &&
117 expression.IsIdentifier() && expression.AsIdentifier().IsEval()) {
118 pre_parser_->log_->LogEvalCall();
119 }
120 }
121
122
45 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) { 123 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
46 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) { 124 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
47 return PreParserIdentifier::FutureReserved(); 125 return PreParserIdentifier::FutureReserved();
48 } else if (scanner->current_token() == 126 } else if (scanner->current_token() ==
49 Token::FUTURE_STRICT_RESERVED_WORD) { 127 Token::FUTURE_STRICT_RESERVED_WORD) {
50 return PreParserIdentifier::FutureStrictReserved(); 128 return PreParserIdentifier::FutureStrictReserved();
51 } else if (scanner->current_token() == Token::LET) { 129 } else if (scanner->current_token() == Token::LET) {
52 return PreParserIdentifier::Let(); 130 return PreParserIdentifier::Let();
53 } else if (scanner->current_token() == Token::YIELD) { 131 } else if (scanner->current_token() == Token::YIELD) {
54 return PreParserIdentifier::Yield(); 132 return PreParserIdentifier::Yield();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 bool name_is_strict_reserved, FunctionKind kind, 171 bool name_is_strict_reserved, FunctionKind kind,
94 int function_token_position, FunctionLiteral::FunctionType type, 172 int function_token_position, FunctionLiteral::FunctionType type,
95 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 173 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
96 return pre_parser_->ParseFunctionLiteral( 174 return pre_parser_->ParseFunctionLiteral(
97 name, function_name_location, name_is_strict_reserved, kind, 175 name, function_name_location, name_is_strict_reserved, kind,
98 function_token_position, type, arity_restriction, ok); 176 function_token_position, type, arity_restriction, ok);
99 } 177 }
100 178
101 179
102 PreParser::PreParseResult PreParser::PreParseLazyFunction( 180 PreParser::PreParseResult PreParser::PreParseLazyFunction(
103 StrictMode strict_mode, bool is_generator, ParserRecorder* log) { 181 StrictMode strict_mode, bool is_generator, bool log_identifiers,
182 ParserRecorder* log) {
183 log_identifiers_ = log_identifiers;
104 log_ = log; 184 log_ = log;
105 // Lazy functions always have trivial outer scopes (no with/catch scopes). 185 // Lazy functions always have trivial outer scopes (no with/catch scopes).
106 PreParserScope top_scope(scope_, GLOBAL_SCOPE); 186 PreParserScope top_scope = NewScope(NULL, GLOBAL_SCOPE);
107 PreParserFactory top_factory(NULL); 187 PreParserFactory top_factory(NULL);
108 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory); 188 FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
109 scope_->SetStrictMode(strict_mode); 189 scope_->SetStrictMode(strict_mode);
110 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 190 PreParserScope function_scope = NewScope(scope_, FUNCTION_SCOPE);
111 PreParserFactory function_factory(NULL); 191 PreParserFactory function_factory(NULL);
112 FunctionState function_state(&function_state_, &scope_, &function_scope, 192 FunctionState function_state(&function_state_, &scope_, &function_scope,
113 &function_factory); 193 &function_factory);
114 function_state.set_is_generator(is_generator); 194 function_state.set_is_generator(is_generator);
115 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 195 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
116 bool ok = true; 196 bool ok = true;
117 int start_position = peek_position(); 197 int start_position = peek_position();
118 ParseLazyFunctionLiteralBody(&ok); 198 ParseLazyFunctionLiteralBody(&ok);
119 if (stack_overflow()) return kPreParseStackOverflow; 199 if (stack_overflow()) return kPreParseStackOverflow;
120 if (!ok) { 200 if (!ok) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 402 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
323 // GeneratorDeclaration :: 403 // GeneratorDeclaration ::
324 // 'function' '*' Identifier '(' FormalParameterListopt ')' 404 // 'function' '*' Identifier '(' FormalParameterListopt ')'
325 // '{' FunctionBody '}' 405 // '{' FunctionBody '}'
326 Expect(Token::FUNCTION, CHECK_OK); 406 Expect(Token::FUNCTION, CHECK_OK);
327 int pos = position(); 407 int pos = position();
328 bool is_generator = Check(Token::MUL); 408 bool is_generator = Check(Token::MUL);
329 bool is_strict_reserved = false; 409 bool is_strict_reserved = false;
330 Identifier name = ParseIdentifierOrStrictReservedWord( 410 Identifier name = ParseIdentifierOrStrictReservedWord(
331 &is_strict_reserved, CHECK_OK); 411 &is_strict_reserved, CHECK_OK);
412 if (log_identifiers_) {
413 DCHECK(ast_value_factory_);
414 const AstRawString* identifier =
415 scanner()->CurrentSymbol(ast_value_factory_);
416 scope_->Declare(identifier);
417 }
332 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved, 418 ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
333 is_generator ? FunctionKind::kGeneratorFunction 419 is_generator ? FunctionKind::kGeneratorFunction
334 : FunctionKind::kNormalFunction, 420 : FunctionKind::kNormalFunction,
335 pos, FunctionLiteral::DECLARATION, 421 pos, FunctionLiteral::DECLARATION,
336 FunctionLiteral::NORMAL_ARITY, CHECK_OK); 422 FunctionLiteral::NORMAL_ARITY, CHECK_OK);
337 return Statement::FunctionDeclaration(); 423 return Statement::FunctionDeclaration();
338 } 424 }
339 425
340 426
341 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 427 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
342 Expect(Token::CLASS, CHECK_OK); 428 Expect(Token::CLASS, CHECK_OK);
343 int pos = position(); 429 int pos = position();
344 bool is_strict_reserved = false; 430 bool is_strict_reserved = false;
345 Identifier name = 431 Identifier name =
346 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 432 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
433 if (log_identifiers_) {
434 DCHECK(ast_value_factory_);
435 const AstRawString* identifier =
436 scanner()->CurrentSymbol(ast_value_factory_);
437 scope_->Declare(identifier);
438 }
347 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, 439 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
348 CHECK_OK); 440 CHECK_OK);
349 return Statement::Default(); 441 return Statement::Default();
350 } 442 }
351 443
352 444
353 PreParser::Statement PreParser::ParseBlock(bool* ok) { 445 PreParser::Statement PreParser::ParseBlock(bool* ok) {
354 // Block :: 446 // Block ::
355 // '{' Statement* '}' 447 // '{' Statement* '}'
356 448
357 // Note that a Block does not introduce a new execution scope! 449 // Note that a Block does not introduce a new execution scope!
358 // (ECMA-262, 3rd, 12.2) 450 // (ECMA-262, 3rd, 12.2)
359 // 451 //
360 Expect(Token::LBRACE, CHECK_OK); 452 Expect(Token::LBRACE, CHECK_OK);
361 while (peek() != Token::RBRACE) { 453 if (allow_harmony_scoping() && strict_mode() == STRICT) {
362 if (allow_harmony_scoping() && strict_mode() == STRICT) { 454 PreParserScope block_scope = NewScope(scope_, BLOCK_SCOPE);
455 BlockState block_state(&scope_, &block_scope);
456 while (peek() != Token::RBRACE) {
363 ParseSourceElement(CHECK_OK); 457 ParseSourceElement(CHECK_OK);
364 } else { 458 }
459 } else {
460 while (peek() != Token::RBRACE) {
365 ParseStatement(CHECK_OK); 461 ParseStatement(CHECK_OK);
366 } 462 }
367 } 463 }
368 Expect(Token::RBRACE, ok); 464 Expect(Token::RBRACE, ok);
369 return Statement::Default(); 465 return Statement::Default();
370 } 466 }
371 467
372 468
373 PreParser::Statement PreParser::ParseVariableStatement( 469 PreParser::Statement PreParser::ParseVariableStatement(
374 VariableDeclarationContext var_context, 470 VariableDeclarationContext var_context,
(...skipping 27 matching lines...) Expand all
402 // 498 //
403 // ConstDeclaration :: 499 // ConstDeclaration ::
404 // const ConstBinding (',' ConstBinding)* ';' 500 // const ConstBinding (',' ConstBinding)* ';'
405 // ConstBinding :: 501 // ConstBinding ::
406 // Identifier '=' AssignmentExpression 502 // Identifier '=' AssignmentExpression
407 // 503 //
408 // TODO(ES6): 504 // TODO(ES6):
409 // ConstBinding :: 505 // ConstBinding ::
410 // BindingPattern '=' AssignmentExpression 506 // BindingPattern '=' AssignmentExpression
411 bool require_initializer = false; 507 bool require_initializer = false;
508 bool lexical = false;
412 if (peek() == Token::VAR) { 509 if (peek() == Token::VAR) {
413 Consume(Token::VAR); 510 Consume(Token::VAR);
414 } else if (peek() == Token::CONST) { 511 } else if (peek() == Token::CONST) {
415 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 512 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
416 // 513 //
417 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 514 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
418 // 515 //
419 // * It is a Syntax Error if the code that matches this production is not 516 // * It is a Syntax Error if the code that matches this production is not
420 // contained in extended code. 517 // contained in extended code.
421 // 518 //
422 // However disallowing const in sloppy mode will break compatibility with 519 // However disallowing const in sloppy mode will break compatibility with
423 // existing pages. Therefore we keep allowing const with the old 520 // existing pages. Therefore we keep allowing const with the old
424 // non-harmony semantics in sloppy mode. 521 // non-harmony semantics in sloppy mode.
425 Consume(Token::CONST); 522 Consume(Token::CONST);
426 if (strict_mode() == STRICT) { 523 if (strict_mode() == STRICT) {
427 if (allow_harmony_scoping()) { 524 if (allow_harmony_scoping()) {
428 if (var_context != kSourceElement && var_context != kForStatement) { 525 if (var_context != kSourceElement && var_context != kForStatement) {
429 ReportMessageAt(scanner()->peek_location(), "unprotected_const"); 526 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
430 *ok = false; 527 *ok = false;
431 return Statement::Default(); 528 return Statement::Default();
432 } 529 }
433 require_initializer = true; 530 require_initializer = true;
531 lexical = true;
434 } else { 532 } else {
435 Scanner::Location location = scanner()->peek_location(); 533 Scanner::Location location = scanner()->peek_location();
436 ReportMessageAt(location, "strict_const"); 534 ReportMessageAt(location, "strict_const");
437 *ok = false; 535 *ok = false;
438 return Statement::Default(); 536 return Statement::Default();
439 } 537 }
440 } 538 }
441 } else if (peek() == Token::LET && strict_mode() == STRICT) { 539 } else if (peek() == Token::LET && strict_mode() == STRICT) {
442 Consume(Token::LET); 540 Consume(Token::LET);
443 if (var_context != kSourceElement && var_context != kForStatement) { 541 if (var_context != kSourceElement && var_context != kForStatement) {
444 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 542 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
445 *ok = false; 543 *ok = false;
446 return Statement::Default(); 544 return Statement::Default();
447 } 545 }
546 lexical = true;
448 } else { 547 } else {
449 *ok = false; 548 *ok = false;
450 return Statement::Default(); 549 return Statement::Default();
451 } 550 }
452 551
453 // The scope of a var/const declared variable anywhere inside a function 552 // The scope of a var/const declared variable anywhere inside a function
454 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 553 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
455 // of a let declared variable is the scope of the immediately enclosing 554 // of a let declared variable is the scope of the immediately enclosing
456 // block. 555 // block.
457 int nvars = 0; // the number of variables declared 556 int nvars = 0; // the number of variables declared
458 do { 557 do {
459 // Parse variable name. 558 // Parse variable name.
460 if (nvars > 0) Consume(Token::COMMA); 559 if (nvars > 0) Consume(Token::COMMA);
461 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 560 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
561 if (log_identifiers_) {
562 DCHECK(ast_value_factory_);
563 const AstRawString* identifier =
564 scanner()->CurrentSymbol(ast_value_factory_);
565 scope_->Declare(identifier, lexical);
566 }
462 nvars++; 567 nvars++;
463 if (peek() == Token::ASSIGN || require_initializer) { 568 if (peek() == Token::ASSIGN || require_initializer) {
464 Expect(Token::ASSIGN, CHECK_OK); 569 Expect(Token::ASSIGN, CHECK_OK);
465 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 570 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
466 if (decl_props != NULL) *decl_props = kHasInitializers; 571 if (decl_props != NULL) *decl_props = kHasInitializers;
467 } 572 }
468 } while (peek() == Token::COMMA); 573 } while (peek() == Token::COMMA);
469 574
470 if (num_decl != NULL) *num_decl = nvars; 575 if (num_decl != NULL) *num_decl = nvars;
471 return Statement::Default(); 576 return Statement::Default();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 Expect(Token::WITH, CHECK_OK); 691 Expect(Token::WITH, CHECK_OK);
587 if (strict_mode() == STRICT) { 692 if (strict_mode() == STRICT) {
588 ReportMessageAt(scanner()->location(), "strict_mode_with"); 693 ReportMessageAt(scanner()->location(), "strict_mode_with");
589 *ok = false; 694 *ok = false;
590 return Statement::Default(); 695 return Statement::Default();
591 } 696 }
592 Expect(Token::LPAREN, CHECK_OK); 697 Expect(Token::LPAREN, CHECK_OK);
593 ParseExpression(true, CHECK_OK); 698 ParseExpression(true, CHECK_OK);
594 Expect(Token::RPAREN, CHECK_OK); 699 Expect(Token::RPAREN, CHECK_OK);
595 700
596 PreParserScope with_scope(scope_, WITH_SCOPE); 701 PreParserScope with_scope = NewScope(scope_, WITH_SCOPE);
597 BlockState block_state(&scope_, &with_scope); 702 BlockState block_state(&scope_, &with_scope);
598 ParseStatement(CHECK_OK); 703 ParseStatement(CHECK_OK);
599 return Statement::Default(); 704 return Statement::Default();
600 } 705 }
601 706
602 707
603 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 708 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
604 // SwitchStatement :: 709 // SwitchStatement ::
605 // 'switch' '(' Expression ')' '{' CaseClause* '}' 710 // 'switch' '(' Expression ')' '{' CaseClause* '}'
606 711
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 return true; 771 return true;
667 } 772 }
668 return false; 773 return false;
669 } 774 }
670 775
671 776
672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 777 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
673 // ForStatement :: 778 // ForStatement ::
674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 779 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
675 780
781 // Create an in-between scope for let-bound iteration variables.
782 PreParserScope* saved_scope = scope_;
783 PreParserScope for_scope = NewScope(scope_, BLOCK_SCOPE);
784 scope_ = &for_scope;
785
676 Expect(Token::FOR, CHECK_OK); 786 Expect(Token::FOR, CHECK_OK);
677 Expect(Token::LPAREN, CHECK_OK); 787 Expect(Token::LPAREN, CHECK_OK);
678 if (peek() != Token::SEMICOLON) { 788 if (peek() != Token::SEMICOLON) {
679 if (peek() == Token::VAR || peek() == Token::CONST || 789 if (peek() == Token::VAR || peek() == Token::CONST ||
680 (peek() == Token::LET && strict_mode() == STRICT)) { 790 (peek() == Token::LET && strict_mode() == STRICT)) {
681 bool is_let = peek() == Token::LET; 791 bool is_let = peek() == Token::LET;
682 int decl_count; 792 int decl_count;
683 VariableDeclarationProperties decl_props = kHasNoInitializers; 793 VariableDeclarationProperties decl_props = kHasNoInitializers;
684 ParseVariableDeclarations( 794 ParseVariableDeclarations(
685 kForStatement, &decl_props, &decl_count, CHECK_OK); 795 kForStatement, &decl_props, &decl_count, CHECK_OK);
686 bool has_initializers = decl_props == kHasInitializers; 796 bool has_initializers = decl_props == kHasInitializers;
687 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 797 bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
688 bool accept_OF = !has_initializers; 798 bool accept_OF = !has_initializers;
689 if (accept_IN && CheckInOrOf(accept_OF)) { 799 if (accept_IN && CheckInOrOf(accept_OF)) {
800 // The expression does not see the loop variable.
801 scope_ = saved_scope;
690 ParseExpression(true, CHECK_OK); 802 ParseExpression(true, CHECK_OK);
803 scope_ = &for_scope;
691 Expect(Token::RPAREN, CHECK_OK); 804 Expect(Token::RPAREN, CHECK_OK);
692 805
693 ParseStatement(CHECK_OK); 806 ParseStatement(CHECK_OK);
807 scope_ = saved_scope;
694 return Statement::Default(); 808 return Statement::Default();
695 } 809 }
696 } else { 810 } else {
697 Expression lhs = ParseExpression(false, CHECK_OK); 811 Expression lhs = ParseExpression(false, CHECK_OK);
698 if (CheckInOrOf(lhs.IsIdentifier())) { 812 if (CheckInOrOf(lhs.IsIdentifier())) {
699 ParseExpression(true, CHECK_OK); 813 ParseExpression(true, CHECK_OK);
700 Expect(Token::RPAREN, CHECK_OK); 814 Expect(Token::RPAREN, CHECK_OK);
701 815
702 ParseStatement(CHECK_OK); 816 ParseStatement(CHECK_OK);
817 scope_ = saved_scope;
703 return Statement::Default(); 818 return Statement::Default();
704 } 819 }
705 } 820 }
706 } 821 }
707 822
708 // Parsed initializer at this point. 823 // Parsed initializer at this point.
709 Expect(Token::SEMICOLON, CHECK_OK); 824 Expect(Token::SEMICOLON, CHECK_OK);
710 825
711 if (peek() != Token::SEMICOLON) { 826 if (peek() != Token::SEMICOLON) {
712 ParseExpression(true, CHECK_OK); 827 ParseExpression(true, CHECK_OK);
713 } 828 }
714 Expect(Token::SEMICOLON, CHECK_OK); 829 Expect(Token::SEMICOLON, CHECK_OK);
715 830
716 if (peek() != Token::RPAREN) { 831 if (peek() != Token::RPAREN) {
717 ParseExpression(true, CHECK_OK); 832 ParseExpression(true, CHECK_OK);
718 } 833 }
719 Expect(Token::RPAREN, CHECK_OK); 834 Expect(Token::RPAREN, CHECK_OK);
720 835
721 ParseStatement(ok); 836 ParseStatement(ok);
837 scope_ = saved_scope;
722 return Statement::Default(); 838 return Statement::Default();
723 } 839 }
724 840
725 841
726 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 842 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
727 // ThrowStatement :: 843 // ThrowStatement ::
728 // 'throw' [no line terminator] Expression ';' 844 // 'throw' [no line terminator] Expression ';'
729 845
730 Expect(Token::THROW, CHECK_OK); 846 Expect(Token::THROW, CHECK_OK);
731 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 847 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
(...skipping 26 matching lines...) Expand all
758 Token::Value tok = peek(); 874 Token::Value tok = peek();
759 if (tok != Token::CATCH && tok != Token::FINALLY) { 875 if (tok != Token::CATCH && tok != Token::FINALLY) {
760 ReportMessageAt(scanner()->location(), "no_catch_or_finally"); 876 ReportMessageAt(scanner()->location(), "no_catch_or_finally");
761 *ok = false; 877 *ok = false;
762 return Statement::Default(); 878 return Statement::Default();
763 } 879 }
764 if (tok == Token::CATCH) { 880 if (tok == Token::CATCH) {
765 Consume(Token::CATCH); 881 Consume(Token::CATCH);
766 Expect(Token::LPAREN, CHECK_OK); 882 Expect(Token::LPAREN, CHECK_OK);
767 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 883 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
884 if (log_identifiers_) {
885 DCHECK(ast_value_factory_);
886 const AstRawString* identifier =
887 scanner()->CurrentSymbol(ast_value_factory_);
888 scope_->Declare(identifier);
889 }
768 Expect(Token::RPAREN, CHECK_OK); 890 Expect(Token::RPAREN, CHECK_OK);
769 { 891 {
770 PreParserScope with_scope(scope_, WITH_SCOPE); 892 PreParserScope with_scope = NewScope(scope_, WITH_SCOPE);
771 BlockState block_state(&scope_, &with_scope); 893 BlockState block_state(&scope_, &with_scope);
772 ParseBlock(CHECK_OK); 894 ParseBlock(CHECK_OK);
773 } 895 }
774 tok = peek(); 896 tok = peek();
775 } 897 }
776 if (tok == Token::FINALLY) { 898 if (tok == Token::FINALLY) {
777 Consume(Token::FINALLY); 899 Consume(Token::FINALLY);
778 ParseBlock(CHECK_OK); 900 ParseBlock(CHECK_OK);
779 } 901 }
780 return Statement::Default(); 902 return Statement::Default();
(...skipping 24 matching lines...) Expand all
805 PreParser::Expression PreParser::ParseFunctionLiteral( 927 PreParser::Expression PreParser::ParseFunctionLiteral(
806 Identifier function_name, Scanner::Location function_name_location, 928 Identifier function_name, Scanner::Location function_name_location,
807 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, 929 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
808 FunctionLiteral::FunctionType function_type, 930 FunctionLiteral::FunctionType function_type,
809 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) { 931 FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
810 // Function :: 932 // Function ::
811 // '(' FormalParameterList? ')' '{' FunctionBody '}' 933 // '(' FormalParameterList? ')' '{' FunctionBody '}'
812 934
813 // Parse function body. 935 // Parse function body.
814 ScopeType outer_scope_type = scope_->type(); 936 ScopeType outer_scope_type = scope_->type();
815 PreParserScope function_scope(scope_, FUNCTION_SCOPE); 937 PreParserScope function_scope = NewScope(scope_, FUNCTION_SCOPE);
816 PreParserFactory factory(NULL); 938 PreParserFactory factory(NULL);
817 FunctionState function_state(&function_state_, &scope_, &function_scope, 939 FunctionState function_state(&function_state_, &scope_, &function_scope,
818 &factory); 940 &factory);
819 function_state.set_is_generator(IsGeneratorFunction(kind)); 941 function_state.set_is_generator(IsGeneratorFunction(kind));
820 // FormalParameterList :: 942 // FormalParameterList ::
821 // '(' (Identifier)*[','] ')' 943 // '(' (Identifier)*[','] ')'
822 Expect(Token::LPAREN, CHECK_OK); 944 Expect(Token::LPAREN, CHECK_OK);
823 int start_position = position(); 945 int start_position = position();
824 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 946 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
825 // We don't yet know if the function will be strict, so we cannot yet produce 947 // We don't yet know if the function will be strict, so we cannot yet produce
826 // errors for parameter names or duplicates. However, we remember the 948 // errors for parameter names or duplicates. However, we remember the
827 // locations of these errors if they occur and produce the errors later. 949 // locations of these errors if they occur and produce the errors later.
828 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 950 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
829 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); 951 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
830 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); 952 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
831 953
832 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || 954 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
833 (peek() == Token::RPAREN && 955 (peek() == Token::RPAREN &&
834 arity_restriction != FunctionLiteral::SETTER_ARITY); 956 arity_restriction != FunctionLiteral::SETTER_ARITY);
835 while (!done) { 957 while (!done) {
836 bool is_strict_reserved = false; 958 bool is_strict_reserved = false;
837 Identifier param_name = 959 Identifier param_name =
838 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 960 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
961 if (log_identifiers_) {
962 DCHECK(ast_value_factory_);
963 const AstRawString* identifier =
964 scanner()->CurrentSymbol(ast_value_factory_);
965 scope_->Declare(identifier);
966 }
839 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) { 967 if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
840 eval_args_error_loc = scanner()->location(); 968 eval_args_error_loc = scanner()->location();
841 } 969 }
842 if (!reserved_error_loc.IsValid() && is_strict_reserved) { 970 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
843 reserved_error_loc = scanner()->location(); 971 reserved_error_loc = scanner()->location();
844 } 972 }
845 973
846 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1); 974 int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
847 975
848 if (!dupe_error_loc.IsValid() && prev_value != 0) { 976 if (!dupe_error_loc.IsValid() && prev_value != 0) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 1036
909 1037
910 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1038 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
911 int body_start = position(); 1039 int body_start = position();
912 ParseSourceElements(Token::RBRACE, ok); 1040 ParseSourceElements(Token::RBRACE, ok);
913 if (!*ok) return; 1041 if (!*ok) return;
914 1042
915 // Position right after terminal '}'. 1043 // Position right after terminal '}'.
916 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 1044 DCHECK_EQ(Token::RBRACE, scanner()->peek());
917 int body_end = scanner()->peek_location().end_pos; 1045 int body_end = scanner()->peek_location().end_pos;
1046 if (log_identifiers_) {
1047 scope_->LogUnboundVariables(log_);
1048 }
918 log_->LogFunction(body_start, body_end, 1049 log_->LogFunction(body_start, body_end,
919 function_state_->materialized_literal_count(), 1050 function_state_->materialized_literal_count(),
920 function_state_->expected_property_count(), 1051 function_state_->expected_property_count(),
921 strict_mode()); 1052 strict_mode());
922 } 1053 }
923 1054
924 1055
925 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1056 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
926 // CallRuntime :: 1057 // CallRuntime ::
927 // '%' Identifier Arguments 1058 // '%' Identifier Arguments
928 Expect(Token::MOD, CHECK_OK); 1059 Expect(Token::MOD, CHECK_OK);
929 if (!allow_natives_syntax()) { 1060 if (!allow_natives_syntax()) {
930 *ok = false; 1061 *ok = false;
931 return Expression::Default(); 1062 return Expression::Default();
932 } 1063 }
933 // Allow "eval" or "arguments" for backward compatibility. 1064 // Allow "eval" or "arguments" for backward compatibility.
934 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1065 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
935 ParseArguments(ok); 1066 ParseArguments(ok);
936 1067
937 return Expression::Default(); 1068 return Expression::Default();
938 } 1069 }
939 1070
940 #undef CHECK_OK 1071 #undef CHECK_OK
941 1072
942 1073
943 } } // v8::internal 1074 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/vector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698