Chromium Code Reviews| 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 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1922 | 1922 |
| 1923 default: | 1923 default: |
| 1924 UNREACHABLE(); | 1924 UNREACHABLE(); |
| 1925 return NULL; | 1925 return NULL; |
| 1926 } | 1926 } |
| 1927 } | 1927 } |
| 1928 | 1928 |
| 1929 | 1929 |
| 1930 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1930 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| 1931 VariableMode mode) { | 1931 VariableMode mode) { |
| 1932 // If we are inside a function, a declaration of a var/const variable is a | 1932 // If we are inside a function, a declaration of a 'var' variable is a |
| 1933 // truly local variable, and the scope of the variable is always the function | 1933 // truly local variable, and the scope of the variable is always the function |
| 1934 // scope. | 1934 // scope. |
| 1935 // Let/const variables in harmony mode are always added to the immediately | 1935 // Let/const variables are always added to the immediately enclosing scope. |
| 1936 // enclosing scope. | |
| 1937 Scope* scope = | 1936 Scope* scope = |
| 1938 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); | 1937 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); |
| 1939 return scope->NewUnresolved(factory(), name, Variable::NORMAL, | 1938 return scope->NewUnresolved(factory(), name, Variable::NORMAL, |
| 1940 scanner()->location().beg_pos, | 1939 scanner()->location().beg_pos, |
| 1941 scanner()->location().end_pos); | 1940 scanner()->location().end_pos); |
| 1942 } | 1941 } |
| 1943 | 1942 |
| 1944 | 1943 |
| 1945 Variable* Parser::Declare(Declaration* declaration, | 1944 Variable* Parser::Declare(Declaration* declaration, |
| 1946 DeclarationDescriptor::Kind declaration_kind, | 1945 DeclarationDescriptor::Kind declaration_kind, |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2319 return result; | 2318 return result; |
| 2320 } | 2319 } |
| 2321 | 2320 |
| 2322 | 2321 |
| 2323 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 2322 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 2324 ZoneList<const AstRawString*>* names, | 2323 ZoneList<const AstRawString*>* names, |
| 2325 bool* ok) { | 2324 bool* ok) { |
| 2326 // VariableStatement :: | 2325 // VariableStatement :: |
| 2327 // VariableDeclarations ';' | 2326 // VariableDeclarations ';' |
| 2328 | 2327 |
| 2329 // The scope of a var/const declared variable anywhere inside a function | 2328 // The scope of a var declared variable anywhere inside a function |
| 2330 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 2329 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 2331 // transform a source-level var/const declaration into a (Function) | 2330 // transform a source-level var declaration into a (Function) Scope |
| 2332 // Scope declaration, and rewrite the source-level initialization into an | 2331 // declaration, and rewrite the source-level initialization into an assignment |
| 2333 // assignment statement. We use a block to collect multiple assignments. | 2332 // statement. We use a block to collect multiple assignments. |
| 2334 // | 2333 // |
| 2335 // We mark the block as initializer block because we don't want the | 2334 // We mark the block as initializer block because we don't want the |
| 2336 // rewriter to add a '.result' assignment to such a block (to get compliant | 2335 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 2337 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 2336 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 2338 // reasons when pretty-printing. Also, unless an assignment (initialization) | 2337 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 2339 // is inside an initializer block, it is ignored. | 2338 // is inside an initializer block, it is ignored. |
| 2340 | 2339 |
| 2341 DeclarationParsingResult parsing_result; | 2340 DeclarationParsingResult parsing_result; |
| 2342 Block* result = | 2341 Block* result = |
| 2343 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); | 2342 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 if (is_simple) { | 3020 if (is_simple) { |
| 3022 auto proxy = pattern->AsVariableProxy(); | 3021 auto proxy = pattern->AsVariableProxy(); |
| 3023 scope_->RemoveUnresolved(proxy); | 3022 scope_->RemoveUnresolved(proxy); |
| 3024 name = proxy->raw_name(); | 3023 name = proxy->raw_name(); |
| 3025 } | 3024 } |
| 3026 catch_variable = catch_scope->DeclareLocal( | 3025 catch_variable = catch_scope->DeclareLocal( |
| 3027 name, VAR, kCreatedInitialized, Variable::NORMAL); | 3026 name, VAR, kCreatedInitialized, Variable::NORMAL); |
| 3028 | 3027 |
| 3029 Expect(Token::RPAREN, CHECK_OK); | 3028 Expect(Token::RPAREN, CHECK_OK); |
| 3030 | 3029 |
| 3030 ZoneList<const AstRawString*> bound_names(1, zone()); | |
| 3031 | |
| 3031 if (!is_simple) { | 3032 if (!is_simple) { |
| 3032 DeclarationDescriptor descriptor; | 3033 DeclarationDescriptor descriptor; |
| 3033 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 3034 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 3034 descriptor.parser = this; | 3035 descriptor.parser = this; |
| 3035 descriptor.scope = scope_; | 3036 descriptor.scope = scope_; |
| 3036 descriptor.hoist_scope = nullptr; | 3037 descriptor.hoist_scope = nullptr; |
| 3037 descriptor.mode = LET; | 3038 descriptor.mode = LET; |
| 3038 descriptor.declaration_pos = pattern->position(); | 3039 descriptor.declaration_pos = pattern->position(); |
| 3039 descriptor.initialization_pos = pattern->position(); | 3040 descriptor.initialization_pos = pattern->position(); |
| 3040 | 3041 |
| 3041 DeclarationParsingResult::Declaration decl( | 3042 DeclarationParsingResult::Declaration decl( |
| 3042 pattern, pattern->position(), | 3043 pattern, pattern->position(), |
| 3043 factory()->NewVariableProxy(catch_variable)); | 3044 factory()->NewVariableProxy(catch_variable)); |
| 3044 | 3045 |
| 3045 Block* init_block = | 3046 Block* init_block = |
| 3046 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); | 3047 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); |
| 3047 PatternRewriter::DeclareAndInitializeVariables( | 3048 PatternRewriter::DeclareAndInitializeVariables( |
| 3048 init_block, &descriptor, &decl, nullptr, CHECK_OK); | 3049 init_block, &descriptor, &decl, &bound_names, CHECK_OK); |
| 3049 catch_block->statements()->Add(init_block, zone()); | 3050 catch_block->statements()->Add(init_block, zone()); |
| 3051 } else { | |
| 3052 bound_names.Add(name, zone()); | |
| 3050 } | 3053 } |
| 3051 | 3054 |
| 3052 // TODO(adamk): This should call ParseBlock in order to properly | 3055 Block* inner_block = ParseBlock(nullptr, CHECK_OK); |
| 3053 // add an additional block scope for the catch body. | 3056 catch_block->statements()->Add(inner_block, zone()); |
| 3054 Expect(Token::LBRACE, CHECK_OK); | 3057 |
| 3055 while (peek() != Token::RBRACE) { | 3058 // Check for `catch(e) { let e; }` and similar errors. |
| 3056 Statement* stat = ParseStatementListItem(CHECK_OK); | 3059 Scope* inner_block_scope = inner_block->scope(); |
| 3057 if (stat && !stat->IsEmpty()) { | 3060 if (inner_block_scope != nullptr) { |
| 3058 catch_block->statements()->Add(stat, zone()); | 3061 Declaration* decl = |
| 3062 inner_block_scope->CheckLexDeclarationsConflictingWith( | |
| 3063 &bound_names); | |
| 3064 if (decl != nullptr) { | |
| 3065 const AstRawString* name = decl->proxy()->raw_name(); | |
| 3066 int position = decl->proxy()->position(); | |
| 3067 Scanner::Location location = | |
| 3068 position == kNoSourcePosition | |
|
adamk
2016/07/01 19:14:04
When does this hold?
| |
| 3069 ? Scanner::Location::invalid() | |
| 3070 : Scanner::Location(position, position + 1); | |
| 3071 ParserTraits::ReportMessageAt( | |
| 3072 location, MessageTemplate::kVarRedeclaration, name); | |
| 3073 *ok = false; | |
| 3074 return nullptr; | |
| 3059 } | 3075 } |
| 3060 } | 3076 } |
| 3061 Consume(Token::RBRACE); | |
| 3062 } | 3077 } |
| 3063 block_scope->set_end_position(scanner()->location().end_pos); | 3078 block_scope->set_end_position(scanner()->location().end_pos); |
| 3064 block_scope = block_scope->FinalizeBlockScope(); | 3079 block_scope = block_scope->FinalizeBlockScope(); |
| 3065 catch_block->set_scope(block_scope); | 3080 catch_block->set_scope(block_scope); |
| 3066 } | 3081 } |
| 3067 | 3082 |
| 3068 catch_scope->set_end_position(scanner()->location().end_pos); | 3083 catch_scope->set_end_position(scanner()->location().end_pos); |
| 3069 tok = peek(); | 3084 tok = peek(); |
| 3070 } | 3085 } |
| 3071 | 3086 |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3551 body_scope = body_scope->FinalizeBlockScope(); | 3566 body_scope = body_scope->FinalizeBlockScope(); |
| 3552 block->set_scope(body_scope); | 3567 block->set_scope(body_scope); |
| 3553 return block; | 3568 return block; |
| 3554 } | 3569 } |
| 3555 } | 3570 } |
| 3556 | 3571 |
| 3557 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3572 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
| 3558 bool* ok) { | 3573 bool* ok) { |
| 3559 int stmt_pos = peek_position(); | 3574 int stmt_pos = peek_position(); |
| 3560 Statement* init = NULL; | 3575 Statement* init = NULL; |
| 3561 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3576 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 3577 bool bound_names_are_lexical = false; | |
| 3562 | 3578 |
| 3563 // Create an in-between scope for let-bound iteration variables. | 3579 // Create an in-between scope for let-bound iteration variables. |
| 3564 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3580 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
| 3565 | 3581 |
| 3566 BlockState block_state(&scope_, for_scope); | 3582 BlockState block_state(&scope_, for_scope); |
| 3567 Expect(Token::FOR, CHECK_OK); | 3583 Expect(Token::FOR, CHECK_OK); |
| 3568 Expect(Token::LPAREN, CHECK_OK); | 3584 Expect(Token::LPAREN, CHECK_OK); |
| 3569 for_scope->set_start_position(scanner()->location().beg_pos); | 3585 for_scope->set_start_position(scanner()->location().beg_pos); |
| 3570 for_scope->set_is_hidden(); | 3586 for_scope->set_is_hidden(); |
| 3571 DeclarationParsingResult parsing_result; | 3587 DeclarationParsingResult parsing_result; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 3602 } | 3618 } |
| 3603 ParserTraits::ReportMessageAt( | 3619 ParserTraits::ReportMessageAt( |
| 3604 parsing_result.first_initializer_loc, | 3620 parsing_result.first_initializer_loc, |
| 3605 MessageTemplate::kForInOfLoopInitializer, | 3621 MessageTemplate::kForInOfLoopInitializer, |
| 3606 ForEachStatement::VisitModeString(mode)); | 3622 ForEachStatement::VisitModeString(mode)); |
| 3607 *ok = false; | 3623 *ok = false; |
| 3608 return nullptr; | 3624 return nullptr; |
| 3609 } | 3625 } |
| 3610 | 3626 |
| 3611 Block* init_block = nullptr; | 3627 Block* init_block = nullptr; |
| 3628 bound_names_are_lexical = | |
| 3629 IsLexicalVariableMode(parsing_result.descriptor.mode); | |
| 3612 | 3630 |
| 3613 // special case for legacy for (var/const x =.... in) | 3631 // special case for legacy for (var ... = ... in ...) |
| 3614 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && | 3632 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && |
| 3615 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { | 3633 decl.initializer != nullptr) { |
| 3616 DCHECK(!allow_harmony_for_in()); | 3634 DCHECK(!allow_harmony_for_in()); |
| 3617 ++use_counts_[v8::Isolate::kForInInitializer]; | 3635 ++use_counts_[v8::Isolate::kForInInitializer]; |
| 3618 const AstRawString* name = | 3636 const AstRawString* name = |
| 3619 decl.pattern->AsVariableProxy()->raw_name(); | 3637 decl.pattern->AsVariableProxy()->raw_name(); |
| 3620 VariableProxy* single_var = scope_->NewUnresolved( | 3638 VariableProxy* single_var = scope_->NewUnresolved( |
| 3621 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); | 3639 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); |
| 3622 init_block = factory()->NewBlock( | 3640 init_block = factory()->NewBlock( |
| 3623 nullptr, 2, true, parsing_result.descriptor.declaration_pos); | 3641 nullptr, 2, true, parsing_result.descriptor.declaration_pos); |
| 3624 init_block->statements()->Add( | 3642 init_block->statements()->Add( |
| 3625 factory()->NewExpressionStatement( | 3643 factory()->NewExpressionStatement( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3678 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); | 3696 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3679 | 3697 |
| 3680 auto each_initialization_block = | 3698 auto each_initialization_block = |
| 3681 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); | 3699 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); |
| 3682 { | 3700 { |
| 3683 auto descriptor = parsing_result.descriptor; | 3701 auto descriptor = parsing_result.descriptor; |
| 3684 descriptor.declaration_pos = kNoSourcePosition; | 3702 descriptor.declaration_pos = kNoSourcePosition; |
| 3685 descriptor.initialization_pos = kNoSourcePosition; | 3703 descriptor.initialization_pos = kNoSourcePosition; |
| 3686 decl.initializer = factory()->NewVariableProxy(temp); | 3704 decl.initializer = factory()->NewVariableProxy(temp); |
| 3687 | 3705 |
| 3706 bool is_for_var_of = | |
| 3707 mode == ForEachStatement::ITERATE && | |
| 3708 parsing_result.descriptor.mode == VariableMode::VAR; | |
| 3709 | |
| 3688 PatternRewriter::DeclareAndInitializeVariables( | 3710 PatternRewriter::DeclareAndInitializeVariables( |
| 3689 each_initialization_block, &descriptor, &decl, | 3711 each_initialization_block, &descriptor, &decl, |
| 3690 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3712 bound_names_are_lexical || is_for_var_of ? &bound_names |
| 3691 : nullptr, | 3713 : nullptr, |
| 3692 CHECK_OK); | 3714 CHECK_OK); |
| 3715 | |
| 3716 // Annex B.3.5 prohibits the form | |
| 3717 // `try {} catch(e) { for (var e of {}); }` | |
| 3718 // So if we are parsing a statement like `for (var ... of ...)` | |
| 3719 // we need to walk up the scope chain and look for catch scopes | |
| 3720 // which have a simple binding, then compare their binding against | |
| 3721 // all of the names declared in the init of the for-of we're | |
| 3722 // parsing. | |
| 3723 if (is_for_var_of) { | |
| 3724 Scope* catch_scope = scope_; | |
| 3725 while (catch_scope != nullptr && | |
| 3726 !catch_scope->is_declaration_scope()) { | |
| 3727 if (catch_scope->is_catch_scope()) { | |
| 3728 auto name = catch_scope->catch_variable_name(); | |
| 3729 if (name != | |
| 3730 ast_value_factory() | |
| 3731 ->dot_catch_string()) { // i.e. is a simple binding | |
| 3732 if (bound_names.Contains(name)) { | |
| 3733 ParserTraits::ReportMessageAt( | |
| 3734 parsing_result.bindings_loc, | |
| 3735 MessageTemplate::kVarRedeclaration, name); | |
| 3736 *ok = false; | |
| 3737 return nullptr; | |
| 3738 } | |
| 3739 } | |
| 3740 } | |
| 3741 catch_scope = catch_scope->outer_scope(); | |
| 3742 } | |
| 3743 } | |
| 3693 } | 3744 } |
| 3694 | 3745 |
| 3695 body_block->statements()->Add(each_initialization_block, zone()); | 3746 body_block->statements()->Add(each_initialization_block, zone()); |
| 3696 body_block->statements()->Add(body, zone()); | 3747 body_block->statements()->Add(body, zone()); |
| 3697 VariableProxy* temp_proxy = | 3748 VariableProxy* temp_proxy = |
| 3698 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3749 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| 3699 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, | 3750 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, |
| 3700 each_keyword_position); | 3751 each_keyword_position); |
| 3701 } | 3752 } |
| 3702 body_scope->set_end_position(scanner()->location().end_pos); | 3753 body_scope->set_end_position(scanner()->location().end_pos); |
| 3703 body_scope = body_scope->FinalizeBlockScope(); | 3754 body_scope = body_scope->FinalizeBlockScope(); |
| 3704 body_block->set_scope(body_scope); | 3755 body_block->set_scope(body_scope); |
| 3705 | 3756 |
| 3706 // Create a TDZ for any lexically-bound names. | 3757 // Create a TDZ for any lexically-bound names. |
| 3707 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3758 if (bound_names_are_lexical) { |
| 3708 DCHECK_NULL(init_block); | 3759 DCHECK_NULL(init_block); |
| 3709 | 3760 |
| 3710 init_block = | 3761 init_block = |
| 3711 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3762 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
| 3712 | 3763 |
| 3713 for (int i = 0; i < lexical_bindings.length(); ++i) { | 3764 for (int i = 0; i < bound_names.length(); ++i) { |
| 3714 // TODO(adamk): This needs to be some sort of special | 3765 // TODO(adamk): This needs to be some sort of special |
| 3715 // INTERNAL variable that's invisible to the debugger | 3766 // INTERNAL variable that's invisible to the debugger |
| 3716 // but visible to everything else. | 3767 // but visible to everything else. |
| 3717 VariableProxy* tdz_proxy = | 3768 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET); |
| 3718 NewUnresolved(lexical_bindings[i], LET); | |
| 3719 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3769 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
| 3720 tdz_proxy, LET, scope_, kNoSourcePosition); | 3770 tdz_proxy, LET, scope_, kNoSourcePosition); |
| 3721 Variable* tdz_var = Declare( | 3771 Variable* tdz_var = Declare( |
| 3722 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3772 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 3723 tdz_var->set_initializer_position(position()); | 3773 tdz_var->set_initializer_position(position()); |
| 3724 } | 3774 } |
| 3725 } | 3775 } |
| 3726 | 3776 |
| 3727 Statement* final_loop = | 3777 Statement* final_loop = |
| 3728 loop->IsForOfStatement() | 3778 loop->IsForOfStatement() |
| 3729 ? FinalizeForOfStatement(loop->AsForOfStatement(), | 3779 ? FinalizeForOfStatement(loop->AsForOfStatement(), |
| 3730 kNoSourcePosition) | 3780 kNoSourcePosition) |
| 3731 : loop; | 3781 : loop; |
| 3732 | 3782 |
| 3733 for_scope->set_end_position(scanner()->location().end_pos); | 3783 for_scope->set_end_position(scanner()->location().end_pos); |
| 3734 for_scope = for_scope->FinalizeBlockScope(); | 3784 for_scope = for_scope->FinalizeBlockScope(); |
| 3735 // Parsed for-in loop w/ variable declarations. | 3785 // Parsed for-in loop w/ variable declarations. |
| 3736 if (init_block != nullptr) { | 3786 if (init_block != nullptr) { |
| 3737 init_block->statements()->Add(final_loop, zone()); | 3787 init_block->statements()->Add(final_loop, zone()); |
| 3738 init_block->set_scope(for_scope); | 3788 init_block->set_scope(for_scope); |
| 3739 return init_block; | 3789 return init_block; |
| 3740 } else { | 3790 } else { |
| 3741 DCHECK_NULL(for_scope); | 3791 DCHECK_NULL(for_scope); |
| 3742 return final_loop; | 3792 return final_loop; |
| 3743 } | 3793 } |
| 3744 } else { | 3794 } else { |
| 3795 bound_names_are_lexical = | |
| 3796 IsLexicalVariableMode(parsing_result.descriptor.mode); | |
| 3745 init = parsing_result.BuildInitializationBlock( | 3797 init = parsing_result.BuildInitializationBlock( |
| 3746 IsLexicalVariableMode(parsing_result.descriptor.mode) | 3798 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); |
| 3747 ? &lexical_bindings | |
| 3748 : nullptr, | |
| 3749 CHECK_OK); | |
| 3750 } | 3799 } |
| 3751 } else { | 3800 } else { |
| 3752 int lhs_beg_pos = peek_position(); | 3801 int lhs_beg_pos = peek_position(); |
| 3753 ExpressionClassifier classifier(this); | 3802 ExpressionClassifier classifier(this); |
| 3754 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | 3803 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); |
| 3755 int lhs_end_pos = scanner()->location().end_pos; | 3804 int lhs_end_pos = scanner()->location().end_pos; |
| 3756 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3805 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
| 3757 | 3806 |
| 3758 bool is_for_each = CheckInOrOf(&mode, ok); | 3807 bool is_for_each = CheckInOrOf(&mode, ok); |
| 3759 if (!*ok) return nullptr; | 3808 if (!*ok) return nullptr; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3820 // Parsed initializer at this point. | 3869 // Parsed initializer at this point. |
| 3821 Expect(Token::SEMICOLON, CHECK_OK); | 3870 Expect(Token::SEMICOLON, CHECK_OK); |
| 3822 | 3871 |
| 3823 Expression* cond = NULL; | 3872 Expression* cond = NULL; |
| 3824 Statement* next = NULL; | 3873 Statement* next = NULL; |
| 3825 Statement* body = NULL; | 3874 Statement* body = NULL; |
| 3826 | 3875 |
| 3827 // If there are let bindings, then condition and the next statement of the | 3876 // If there are let bindings, then condition and the next statement of the |
| 3828 // for loop must be parsed in a new scope. | 3877 // for loop must be parsed in a new scope. |
| 3829 Scope* inner_scope = scope_; | 3878 Scope* inner_scope = scope_; |
| 3830 if (lexical_bindings.length() > 0) { | 3879 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3831 inner_scope = NewScope(for_scope, BLOCK_SCOPE); | 3880 inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
| 3832 inner_scope->set_start_position(scanner()->location().beg_pos); | 3881 inner_scope->set_start_position(scanner()->location().beg_pos); |
| 3833 } | 3882 } |
| 3834 { | 3883 { |
| 3835 BlockState block_state(&scope_, inner_scope); | 3884 BlockState block_state(&scope_, inner_scope); |
| 3836 | 3885 |
| 3837 if (peek() != Token::SEMICOLON) { | 3886 if (peek() != Token::SEMICOLON) { |
| 3838 cond = ParseExpression(true, CHECK_OK); | 3887 cond = ParseExpression(true, CHECK_OK); |
| 3839 } | 3888 } |
| 3840 Expect(Token::SEMICOLON, CHECK_OK); | 3889 Expect(Token::SEMICOLON, CHECK_OK); |
| 3841 | 3890 |
| 3842 if (peek() != Token::RPAREN) { | 3891 if (peek() != Token::RPAREN) { |
| 3843 Expression* exp = ParseExpression(true, CHECK_OK); | 3892 Expression* exp = ParseExpression(true, CHECK_OK); |
| 3844 next = factory()->NewExpressionStatement(exp, exp->position()); | 3893 next = factory()->NewExpressionStatement(exp, exp->position()); |
| 3845 } | 3894 } |
| 3846 Expect(Token::RPAREN, CHECK_OK); | 3895 Expect(Token::RPAREN, CHECK_OK); |
| 3847 | 3896 |
| 3848 body = ParseScopedStatement(NULL, true, CHECK_OK); | 3897 body = ParseScopedStatement(NULL, true, CHECK_OK); |
| 3849 } | 3898 } |
| 3850 | 3899 |
| 3851 Statement* result = NULL; | 3900 Statement* result = NULL; |
| 3852 if (lexical_bindings.length() > 0) { | 3901 if (bound_names_are_lexical && bound_names.length() > 0) { |
| 3853 BlockState block_state(&scope_, for_scope); | 3902 BlockState block_state(&scope_, for_scope); |
| 3854 result = DesugarLexicalBindingsInForStatement( | 3903 result = DesugarLexicalBindingsInForStatement( |
| 3855 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, | 3904 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, |
| 3856 init, cond, next, body, CHECK_OK); | 3905 cond, next, body, CHECK_OK); |
| 3857 for_scope->set_end_position(scanner()->location().end_pos); | 3906 for_scope->set_end_position(scanner()->location().end_pos); |
| 3858 } else { | 3907 } else { |
| 3859 for_scope->set_end_position(scanner()->location().end_pos); | 3908 for_scope->set_end_position(scanner()->location().end_pos); |
| 3860 for_scope = for_scope->FinalizeBlockScope(); | 3909 for_scope = for_scope->FinalizeBlockScope(); |
| 3861 if (for_scope) { | 3910 if (for_scope) { |
| 3862 // Rewrite a for statement of the form | 3911 // Rewrite a for statement of the form |
| 3863 // for (const x = i; c; n) b | 3912 // for (const x = i; c; n) b |
| 3864 // | 3913 // |
| 3865 // into | 3914 // into |
| 3866 // | 3915 // |
| (...skipping 3151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7018 try_block, target); | 7067 try_block, target); |
| 7019 final_loop = target; | 7068 final_loop = target; |
| 7020 } | 7069 } |
| 7021 | 7070 |
| 7022 return final_loop; | 7071 return final_loop; |
| 7023 } | 7072 } |
| 7024 | 7073 |
| 7025 | 7074 |
| 7026 } // namespace internal | 7075 } // namespace internal |
| 7027 } // namespace v8 | 7076 } // namespace v8 |
| OLD | NEW |