| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
| 10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
| (...skipping 1865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 | 1876 |
| 1877 default: | 1877 default: |
| 1878 UNREACHABLE(); | 1878 UNREACHABLE(); |
| 1879 return NULL; | 1879 return NULL; |
| 1880 } | 1880 } |
| 1881 } | 1881 } |
| 1882 | 1882 |
| 1883 | 1883 |
| 1884 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1884 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| 1885 VariableMode mode) { | 1885 VariableMode mode) { |
| 1886 // If we are inside a function, a declaration of a var/const variable is a | 1886 // If we are inside a function, a declaration of a 'var' variable is a |
| 1887 // truly local variable, and the scope of the variable is always the function | 1887 // truly local variable, and the scope of the variable is always the function |
| 1888 // scope. | 1888 // scope. |
| 1889 // Let/const variables in harmony mode are always added to the immediately | 1889 // Let/const variables are always added to the immediately enclosing scope. |
| 1890 // enclosing scope. | |
| 1891 Scope* scope = | 1890 Scope* scope = |
| 1892 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); | 1891 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); |
| 1893 return scope->NewUnresolved(factory(), name, Variable::NORMAL, | 1892 return scope->NewUnresolved(factory(), name, Variable::NORMAL, |
| 1894 scanner()->location().beg_pos, | 1893 scanner()->location().beg_pos, |
| 1895 scanner()->location().end_pos); | 1894 scanner()->location().end_pos); |
| 1896 } | 1895 } |
| 1897 | 1896 |
| 1898 | 1897 |
| 1899 Variable* Parser::Declare(Declaration* declaration, | 1898 Variable* Parser::Declare(Declaration* declaration, |
| 1900 DeclarationDescriptor::Kind declaration_kind, | 1899 DeclarationDescriptor::Kind declaration_kind, |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2298 return result; | 2297 return result; |
| 2299 } | 2298 } |
| 2300 | 2299 |
| 2301 | 2300 |
| 2302 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 2301 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 2303 ZoneList<const AstRawString*>* names, | 2302 ZoneList<const AstRawString*>* names, |
| 2304 bool* ok) { | 2303 bool* ok) { |
| 2305 // VariableStatement :: | 2304 // VariableStatement :: |
| 2306 // VariableDeclarations ';' | 2305 // VariableDeclarations ';' |
| 2307 | 2306 |
| 2308 // The scope of a var/const declared variable anywhere inside a function | 2307 // The scope of a var declared variable anywhere inside a function |
| 2309 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 2308 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 2310 // transform a source-level var/const declaration into a (Function) | 2309 // transform a source-level var declaration into a (Function) Scope |
| 2311 // Scope declaration, and rewrite the source-level initialization into an | 2310 // declaration, and rewrite the source-level initialization into an assignment |
| 2312 // assignment statement. We use a block to collect multiple assignments. | 2311 // statement. We use a block to collect multiple assignments. |
| 2313 // | 2312 // |
| 2314 // We mark the block as initializer block because we don't want the | 2313 // We mark the block as initializer block because we don't want the |
| 2315 // rewriter to add a '.result' assignment to such a block (to get compliant | 2314 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 2316 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2315 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 2317 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2316 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 2318 // is inside an initializer block, it is ignored. | 2317 // is inside an initializer block, it is ignored. |
| 2319 | 2318 |
| 2320 DeclarationParsingResult parsing_result; | 2319 DeclarationParsingResult parsing_result; |
| 2321 Block* result = | 2320 Block* result = |
| 2322 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); | 2321 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3000 if (is_simple) { | 2999 if (is_simple) { |
| 3001 auto proxy = pattern->AsVariableProxy(); | 3000 auto proxy = pattern->AsVariableProxy(); |
| 3002 scope_->RemoveUnresolved(proxy); | 3001 scope_->RemoveUnresolved(proxy); |
| 3003 name = proxy->raw_name(); | 3002 name = proxy->raw_name(); |
| 3004 } | 3003 } |
| 3005 catch_variable = catch_scope->DeclareLocal( | 3004 catch_variable = catch_scope->DeclareLocal( |
| 3006 name, VAR, kCreatedInitialized, Variable::NORMAL); | 3005 name, VAR, kCreatedInitialized, Variable::NORMAL); |
| 3007 | 3006 |
| 3008 Expect(Token::RPAREN, CHECK_OK); | 3007 Expect(Token::RPAREN, CHECK_OK); |
| 3009 | 3008 |
| 3009 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 3010 |
| 3010 if (!is_simple) { | 3011 if (!is_simple) { |
| 3011 DeclarationDescriptor descriptor; | 3012 DeclarationDescriptor descriptor; |
| 3012 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 3013 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 3013 descriptor.parser = this; | 3014 descriptor.parser = this; |
| 3014 descriptor.scope = scope_; | 3015 descriptor.scope = scope_; |
| 3015 descriptor.hoist_scope = nullptr; | 3016 descriptor.hoist_scope = nullptr; |
| 3016 descriptor.mode = LET; | 3017 descriptor.mode = LET; |
| 3017 descriptor.declaration_pos = pattern->position(); | 3018 descriptor.declaration_pos = pattern->position(); |
| 3018 descriptor.initialization_pos = pattern->position(); | 3019 descriptor.initialization_pos = pattern->position(); |
| 3019 | 3020 |
| 3020 DeclarationParsingResult::Declaration decl( | 3021 DeclarationParsingResult::Declaration decl( |
| 3021 pattern, pattern->position(), | 3022 pattern, pattern->position(), |
| 3022 factory()->NewVariableProxy(catch_variable)); | 3023 factory()->NewVariableProxy(catch_variable)); |
| 3023 | 3024 |
| 3024 Block* init_block = | 3025 Block* init_block = |
| 3025 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); | 3026 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); |
| 3026 PatternRewriter::DeclareAndInitializeVariables( | 3027 PatternRewriter::DeclareAndInitializeVariables( |
| 3027 init_block, &descriptor, &decl, nullptr, CHECK_OK); | 3028 init_block, &descriptor, &decl, &bound_names, CHECK_OK); |
| 3028 catch_block->statements()->Add(init_block, zone()); | 3029 catch_block->statements()->Add(init_block, zone()); |
| 3030 } else { |
| 3031 bound_names.Add(name, zone()); |
| 3029 } | 3032 } |
| 3030 | 3033 |
| 3031 // TODO(adamk): This should call ParseBlock in order to properly | 3034 Block* inner_block = ParseBlock(nullptr, CHECK_OK); |
| 3032 // add an additional block scope for the catch body. | 3035 catch_block->statements()->Add(inner_block, zone()); |
| 3033 Expect(Token::LBRACE, CHECK_OK); | 3036 |
| 3034 while (peek() != Token::RBRACE) { | 3037 // Check for `catch(e) { let e; }` and similar errors. |
| 3035 Statement* stat = ParseStatementListItem(CHECK_OK); | 3038 Scope* inner_block_scope = inner_block->scope(); |
| 3036 if (stat && !stat->IsEmpty()) { | 3039 if (inner_block_scope != nullptr) { |
| 3037 catch_block->statements()->Add(stat, zone()); | 3040 Declaration* decl = |
| 3041 inner_block_scope->CheckLexDeclarationsConflictingWith( |
| 3042 bound_names); |
| 3043 if (decl != nullptr) { |
| 3044 const AstRawString* name = decl->proxy()->raw_name(); |
| 3045 int position = decl->proxy()->position(); |
| 3046 Scanner::Location location = |
| 3047 position == kNoSourcePosition |
| 3048 ? Scanner::Location::invalid() |
| 3049 : Scanner::Location(position, position + 1); |
| 3050 ParserTraits::ReportMessageAt( |
| 3051 location, MessageTemplate::kVarRedeclaration, name); |
| 3052 *ok = false; |
| 3053 return nullptr; |
| 3038 } | 3054 } |
| 3039 } | 3055 } |
| 3040 Consume(Token::RBRACE); | |
| 3041 } | 3056 } |
| 3042 block_scope->set_end_position(scanner()->location().end_pos); | 3057 block_scope->set_end_position(scanner()->location().end_pos); |
| 3043 block_scope = block_scope->FinalizeBlockScope(); | 3058 block_scope = block_scope->FinalizeBlockScope(); |
| 3044 catch_block->set_scope(block_scope); | 3059 catch_block->set_scope(block_scope); |
| 3045 } | 3060 } |
| 3046 | 3061 |
| 3047 catch_scope->set_end_position(scanner()->location().end_pos); | 3062 catch_scope->set_end_position(scanner()->location().end_pos); |
| 3048 tok = peek(); | 3063 tok = peek(); |
| 3049 } | 3064 } |
| 3050 | 3065 |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3530 body_scope = body_scope->FinalizeBlockScope(); | 3545 body_scope = body_scope->FinalizeBlockScope(); |
| 3531 block->set_scope(body_scope); | 3546 block->set_scope(body_scope); |
| 3532 return block; | 3547 return block; |
| 3533 } | 3548 } |
| 3534 } | 3549 } |
| 3535 | 3550 |
| 3536 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3551 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 3537 bool* ok) { | 3552 bool* ok) { |
| 3538 int stmt_pos = peek_position(); | 3553 int stmt_pos = peek_position(); |
| 3539 Statement* init = NULL; | 3554 Statement* init = NULL; |
| 3540 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3555 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 3556 bool bound_names_are_lexical = false; |
| 3541 | 3557 |
| 3542 // Create an in-between scope for let-bound iteration variables. | 3558 // Create an in-between scope for let-bound iteration variables. |
| 3543 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3559 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3544 | 3560 |
| 3545 BlockState block_state(&scope_, for_scope); | 3561 BlockState block_state(&scope_, for_scope); |
| 3546 Expect(Token::FOR, CHECK_OK); | 3562 Expect(Token::FOR, CHECK_OK); |
| 3547 Expect(Token::LPAREN, CHECK_OK); | 3563 Expect(Token::LPAREN, CHECK_OK); |
| 3548 for_scope->set_start_position(scanner()->location().beg_pos); | 3564 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3549 for_scope->set_is_hidden(); | 3565 for_scope->set_is_hidden(); |
| 3550 DeclarationParsingResult parsing_result; | 3566 DeclarationParsingResult parsing_result; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3581 } | 3597 } |
| 3582 ParserTraits::ReportMessageAt( | 3598 ParserTraits::ReportMessageAt( |
| 3583 parsing_result.first_initializer_loc, | 3599 parsing_result.first_initializer_loc, |
| 3584 MessageTemplate::kForInOfLoopInitializer, | 3600 MessageTemplate::kForInOfLoopInitializer, |
| 3585 ForEachStatement::VisitModeString(mode)); | 3601 ForEachStatement::VisitModeString(mode)); |
| 3586 *ok = false; | 3602 *ok = false; |
| 3587 return nullptr; | 3603 return nullptr; |
| 3588 } | 3604 } |
| 3589 | 3605 |
| 3590 Block* init_block = nullptr; | 3606 Block* init_block = nullptr; |
| 3607 bound_names_are_lexical = |
| 3608 IsLexicalVariableMode(parsing_result.descriptor.mode); |
| 3591 | 3609 |
| 3592 // special case for legacy for (var/const x =.... in) | 3610 // special case for legacy for (var ... = ... in ...) |
| 3593 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && | 3611 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && |
| 3594 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { | 3612 decl.initializer != nullptr) { |
| 3595 DCHECK(!allow_harmony_for_in()); | 3613 DCHECK(!allow_harmony_for_in()); |
| 3596 ++use_counts_[v8::Isolate::kForInInitializer]; | 3614 ++use_counts_[v8::Isolate::kForInInitializer]; |
| 3597 const AstRawString* name = | 3615 const AstRawString* name = |
| 3598 decl.pattern->AsVariableProxy()->raw_name(); | 3616 decl.pattern->AsVariableProxy()->raw_name(); |
| 3599 VariableProxy* single_var = scope_->NewUnresolved( | 3617 VariableProxy* single_var = scope_->NewUnresolved( |
| 3600 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); | 3618 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); |
| 3601 init_block = factory()->NewBlock( | 3619 init_block = factory()->NewBlock( |
| 3602 nullptr, 2, true, parsing_result.descriptor.declaration_pos); | 3620 nullptr, 2, true, parsing_result.descriptor.declaration_pos); |
| 3603 init_block->statements()->Add( | 3621 init_block->statements()->Add( |
| 3604 factory()->NewExpressionStatement( | 3622 factory()->NewExpressionStatement( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3657 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3675 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3658 | 3676 |
| 3659 auto each_initialization_block = | 3677 auto each_initialization_block = |
| 3660 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3678 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
| 3661 { | 3679 { |
| 3662 auto descriptor = parsing_result.descriptor; | 3680 auto descriptor = parsing_result.descriptor; |
| 3663 descriptor.declaration_pos = kNoSourcePosition; | 3681 descriptor.declaration_pos = kNoSourcePosition; |
| 3664 descriptor.initialization_pos = kNoSourcePosition; | 3682 descriptor.initialization_pos = kNoSourcePosition; |
| 3665 decl.initializer = factory()->NewVariableProxy(temp); | 3683 decl.initializer = factory()->NewVariableProxy(temp); |
| 3666 | 3684 |
| 3685 bool is_for_var_of = |
| 3686 mode == ForEachStatement::ITERATE && |
| 3687 parsing_result.descriptor.mode == VariableMode::VAR; |
| 3688 |
| 3667 PatternRewriter::DeclareAndInitializeVariables( | 3689 PatternRewriter::DeclareAndInitializeVariables( |
| 3668 each_initialization_block, &descriptor, &decl, | 3690 each_initialization_block, &descriptor, &decl, |
| 3669 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3691 bound_names_are_lexical || is_for_var_of ? &bound_names |
| 3670 : nullptr, | 3692 : nullptr, |
| 3671 CHECK_OK); | 3693 CHECK_OK); |
| 3694 |
| 3695 // Annex B.3.5 prohibits the form |
| 3696 // `try {} catch(e) { for (var e of {}); }` |
| 3697 // So if we are parsing a statement like `for (var ... of ...)` |
| 3698 // we need to walk up the scope chain and look for catch scopes |
| 3699 // which have a simple binding, then compare their binding against |
| 3700 // all of the names declared in the init of the for-of we're |
| 3701 // parsing. |
| 3702 if (is_for_var_of) { |
| 3703 Scope* catch_scope = scope_; |
| 3704 while (catch_scope != nullptr && |
| 3705 !catch_scope->is_declaration_scope()) { |
| 3706 if (catch_scope->is_catch_scope()) { |
| 3707 auto name = catch_scope->catch_variable_name(); |
| 3708 if (name != |
| 3709 ast_value_factory() |
| 3710 ->dot_catch_string()) { // i.e. is a simple binding |
| 3711 if (bound_names.Contains(name)) { |
| 3712 ParserTraits::ReportMessageAt( |
| 3713 parsing_result.bindings_loc, |
| 3714 MessageTemplate::kVarRedeclaration, name); |
| 3715 *ok = false; |
| 3716 return nullptr; |
| 3717 } |
| 3718 } |
| 3719 } |
| 3720 catch_scope = catch_scope->outer_scope(); |
| 3721 } |
| 3722 } |
| 3672 } | 3723 } |
| 3673 | 3724 |
| 3674 body_block->statements()->Add(each_initialization_block, zone()); | 3725 body_block->statements()->Add(each_initialization_block, zone()); |
| 3675 body_block->statements()->Add(body, zone()); | 3726 body_block->statements()->Add(body, zone()); |
| 3676 VariableProxy* temp_proxy = | 3727 VariableProxy* temp_proxy = |
| 3677 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3728 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| 3678 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, | 3729 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, |
| 3679 each_keyword_position); | 3730 each_keyword_position); |
| 3680 } | 3731 } |
| 3681 body_scope->set_end_position(scanner()->location().end_pos); | 3732 body_scope->set_end_position(scanner()->location().end_pos); |
| 3682 body_scope = body_scope->FinalizeBlockScope(); | 3733 body_scope = body_scope->FinalizeBlockScope(); |
| 3683 body_block->set_scope(body_scope); | 3734 body_block->set_scope(body_scope); |
| 3684 | 3735 |
| 3685 // Create a TDZ for any lexically-bound names. | 3736 // Create a TDZ for any lexically-bound names. |
| 3686 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3737 if (bound_names_are_lexical) { |
| 3687 DCHECK_NULL(init_block); | 3738 DCHECK_NULL(init_block); |
| 3688 | 3739 |
| 3689 init_block = | 3740 init_block = |
| 3690 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3741 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
| 3691 | 3742 |
| 3692 for (int i = 0; i < lexical_bindings.length(); ++i) { | 3743 for (int i = 0; i < bound_names.length(); ++i) { |
| 3693 // TODO(adamk): This needs to be some sort of special | 3744 // TODO(adamk): This needs to be some sort of special |
| 3694 // INTERNAL variable that's invisible to the debugger | 3745 // INTERNAL variable that's invisible to the debugger |
| 3695 // but visible to everything else. | 3746 // but visible to everything else. |
| 3696 VariableProxy* tdz_proxy = | 3747 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET); |
| 3697 NewUnresolved(lexical_bindings[i], LET); | |
| 3698 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3748 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
| 3699 tdz_proxy, LET, scope_, kNoSourcePosition); | 3749 tdz_proxy, LET, scope_, kNoSourcePosition); |
| 3700 Variable* tdz_var = Declare( | 3750 Variable* tdz_var = Declare( |
| 3701 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3751 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 3702 tdz_var->set_initializer_position(position()); | 3752 tdz_var->set_initializer_position(position()); |
| 3703 } | 3753 } |
| 3704 } | 3754 } |
| 3705 | 3755 |
| 3706 Statement* final_loop = | 3756 Statement* final_loop = |
| 3707 loop->IsForOfStatement() | 3757 loop->IsForOfStatement() |
| 3708 ? FinalizeForOfStatement(loop->AsForOfStatement(), | 3758 ? FinalizeForOfStatement(loop->AsForOfStatement(), |
| 3709 kNoSourcePosition) | 3759 kNoSourcePosition) |
| 3710 : loop; | 3760 : loop; |
| 3711 | 3761 |
| 3712 for_scope->set_end_position(scanner()->location().end_pos); | 3762 for_scope->set_end_position(scanner()->location().end_pos); |
| 3713 for_scope = for_scope->FinalizeBlockScope(); | 3763 for_scope = for_scope->FinalizeBlockScope(); |
| 3714 // Parsed for-in loop w/ variable declarations. | 3764 // Parsed for-in loop w/ variable declarations. |
| 3715 if (init_block != nullptr) { | 3765 if (init_block != nullptr) { |
| 3716 init_block->statements()->Add(final_loop, zone()); | 3766 init_block->statements()->Add(final_loop, zone()); |
| 3717 init_block->set_scope(for_scope); | 3767 init_block->set_scope(for_scope); |
| 3718 return init_block; | 3768 return init_block; |
| 3719 } else { | 3769 } else { |
| 3720 DCHECK_NULL(for_scope); | 3770 DCHECK_NULL(for_scope); |
| 3721 return final_loop; | 3771 return final_loop; |
| 3722 } | 3772 } |
| 3723 } else { | 3773 } else { |
| 3774 bound_names_are_lexical = |
| 3775 IsLexicalVariableMode(parsing_result.descriptor.mode); |
| 3724 init = parsing_result.BuildInitializationBlock( | 3776 init = parsing_result.BuildInitializationBlock( |
| 3725 IsLexicalVariableMode(parsing_result.descriptor.mode) | 3777 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); |
| 3726 ? &lexical_bindings | |
| 3727 : nullptr, | |
| 3728 CHECK_OK); | |
| 3729 } | 3778 } |
| 3730 } else { | 3779 } else { |
| 3731 int lhs_beg_pos = peek_position(); | 3780 int lhs_beg_pos = peek_position(); |
| 3732 ExpressionClassifier classifier(this); | 3781 ExpressionClassifier classifier(this); |
| 3733 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | 3782 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); |
| 3734 int lhs_end_pos = scanner()->location().end_pos; | 3783 int lhs_end_pos = scanner()->location().end_pos; |
| 3735 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3784 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
| 3736 | 3785 |
| 3737 bool is_for_each = CheckInOrOf(&mode, ok); | 3786 bool is_for_each = CheckInOrOf(&mode, ok); |
| 3738 if (!*ok) return nullptr; | 3787 if (!*ok) return nullptr; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3799 // Parsed initializer at this point. | 3848 // Parsed initializer at this point. |
| 3800 Expect(Token::SEMICOLON, CHECK_OK); | 3849 Expect(Token::SEMICOLON, CHECK_OK); |
| 3801 | 3850 |
| 3802 Expression* cond = NULL; | 3851 Expression* cond = NULL; |
| 3803 Statement* next = NULL; | 3852 Statement* next = NULL; |
| 3804 Statement* body = NULL; | 3853 Statement* body = NULL; |
| 3805 | 3854 |
| 3806 // If there are let bindings, then condition and the next statement of the | 3855 // If there are let bindings, then condition and the next statement of the |
| 3807 // for loop must be parsed in a new scope. | 3856 // for loop must be parsed in a new scope. |
| 3808 Scope* inner_scope = scope_; | 3857 Scope* inner_scope = scope_; |
| 3809 if (lexical_bindings.length() > 0) { | 3858 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3810 inner_scope = NewScope(for_scope, BLOCK_SCOPE); | 3859 inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
| 3811 inner_scope->set_start_position(scanner()->location().beg_pos); | 3860 inner_scope->set_start_position(scanner()->location().beg_pos); |
| 3812 } | 3861 } |
| 3813 { | 3862 { |
| 3814 BlockState block_state(&scope_, inner_scope); | 3863 BlockState block_state(&scope_, inner_scope); |
| 3815 | 3864 |
| 3816 if (peek() != Token::SEMICOLON) { | 3865 if (peek() != Token::SEMICOLON) { |
| 3817 cond = ParseExpression(true, CHECK_OK); | 3866 cond = ParseExpression(true, CHECK_OK); |
| 3818 } | 3867 } |
| 3819 Expect(Token::SEMICOLON, CHECK_OK); | 3868 Expect(Token::SEMICOLON, CHECK_OK); |
| 3820 | 3869 |
| 3821 if (peek() != Token::RPAREN) { | 3870 if (peek() != Token::RPAREN) { |
| 3822 Expression* exp = ParseExpression(true, CHECK_OK); | 3871 Expression* exp = ParseExpression(true, CHECK_OK); |
| 3823 next = factory()->NewExpressionStatement(exp, exp->position()); | 3872 next = factory()->NewExpressionStatement(exp, exp->position()); |
| 3824 } | 3873 } |
| 3825 Expect(Token::RPAREN, CHECK_OK); | 3874 Expect(Token::RPAREN, CHECK_OK); |
| 3826 | 3875 |
| 3827 body = ParseScopedStatement(NULL, true, CHECK_OK); | 3876 body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3828 } | 3877 } |
| 3829 | 3878 |
| 3830 Statement* result = NULL; | 3879 Statement* result = NULL; |
| 3831 if (lexical_bindings.length() > 0) { | 3880 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3832 BlockState block_state(&scope_, for_scope); | 3881 BlockState block_state(&scope_, for_scope); |
| 3833 result = DesugarLexicalBindingsInForStatement( | 3882 result = DesugarLexicalBindingsInForStatement( |
| 3834 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, | 3883 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, |
| 3835 init, cond, next, body, CHECK_OK); | 3884 cond, next, body, CHECK_OK); |
| 3836 for_scope->set_end_position(scanner()->location().end_pos); | 3885 for_scope->set_end_position(scanner()->location().end_pos); |
| 3837 } else { | 3886 } else { |
| 3838 for_scope->set_end_position(scanner()->location().end_pos); | 3887 for_scope->set_end_position(scanner()->location().end_pos); |
| 3839 for_scope = for_scope->FinalizeBlockScope(); | 3888 for_scope = for_scope->FinalizeBlockScope(); |
| 3840 if (for_scope) { | 3889 if (for_scope) { |
| 3841 // Rewrite a for statement of the form | 3890 // Rewrite a for statement of the form |
| 3842 // for (const x = i; c; n) b | 3891 // for (const x = i; c; n) b |
| 3843 // | 3892 // |
| 3844 // into | 3893 // into |
| 3845 // | 3894 // |
| (...skipping 3151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6997 try_block, target); | 7046 try_block, target); |
| 6998 final_loop = target; | 7047 final_loop = target; |
| 6999 } | 7048 } |
| 7000 | 7049 |
| 7001 return final_loop; | 7050 return final_loop; |
| 7002 } | 7051 } |
| 7003 | 7052 |
| 7004 | 7053 |
| 7005 } // namespace internal | 7054 } // namespace internal |
| 7006 } // namespace v8 | 7055 } // namespace v8 |
| OLD | NEW |