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 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3056 Expect(Token::LBRACE, CHECK_OK); | 3056 Expect(Token::LBRACE, CHECK_OK); |
3057 while (peek() != Token::RBRACE) { | 3057 while (peek() != Token::RBRACE) { |
3058 Statement* stat = ParseStatementListItem(CHECK_OK); | 3058 Statement* stat = ParseStatementListItem(CHECK_OK); |
3059 if (stat && !stat->IsEmpty()) { | 3059 if (stat && !stat->IsEmpty()) { |
3060 catch_block->statements()->Add(stat, zone()); | 3060 catch_block->statements()->Add(stat, zone()); |
3061 } | 3061 } |
3062 } | 3062 } |
3063 Consume(Token::RBRACE); | 3063 Consume(Token::RBRACE); |
3064 } | 3064 } |
3065 block_scope->set_end_position(scanner()->location().end_pos); | 3065 block_scope->set_end_position(scanner()->location().end_pos); |
3066 if (is_simple) { | |
3067 // Check for `catch(e) { let e; }` and similar errors. | |
3068 // The BindingPattern case is handled elsewhere, because | |
3069 // the names created by destructuring being lexical. | |
3070 Variable* var = block_scope->LookupLocal(name); | |
3071 if (var != nullptr && IsLexicalVariableMode(var->mode())) { | |
3072 auto position = pattern->position(); | |
3073 Scanner::Location location = | |
3074 position == RelocInfo::kNoPosition | |
3075 ? Scanner::Location::invalid() | |
3076 : Scanner::Location(position, position + 1); | |
3077 ParserTraits::ReportMessageAt( | |
3078 location, MessageTemplate::kVarRedeclaration, name); | |
3079 *ok = false; | |
3080 return NULL; | |
3081 } | |
3082 } | |
3066 block_scope = block_scope->FinalizeBlockScope(); | 3083 block_scope = block_scope->FinalizeBlockScope(); |
3067 catch_block->set_scope(block_scope); | 3084 catch_block->set_scope(block_scope); |
3068 } | 3085 } |
3069 | 3086 |
3070 catch_scope->set_end_position(scanner()->location().end_pos); | 3087 catch_scope->set_end_position(scanner()->location().end_pos); |
3071 tok = peek(); | 3088 tok = peek(); |
3072 } | 3089 } |
3073 | 3090 |
3074 Block* finally_block = NULL; | 3091 Block* finally_block = NULL; |
3075 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 3092 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3561 body_scope = body_scope->FinalizeBlockScope(); | 3578 body_scope = body_scope->FinalizeBlockScope(); |
3562 block->set_scope(body_scope); | 3579 block->set_scope(body_scope); |
3563 return block; | 3580 return block; |
3564 } | 3581 } |
3565 } | 3582 } |
3566 | 3583 |
3567 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3584 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
3568 bool* ok) { | 3585 bool* ok) { |
3569 int stmt_pos = peek_position(); | 3586 int stmt_pos = peek_position(); |
3570 Statement* init = NULL; | 3587 Statement* init = NULL; |
3571 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3588 ZoneList<const AstRawString*> bound_names(1, zone()); |
3589 bool bound_names_are_lexical = false; | |
3572 | 3590 |
3573 // Create an in-between scope for let-bound iteration variables. | 3591 // Create an in-between scope for let-bound iteration variables. |
3574 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3592 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3575 | 3593 |
3576 BlockState block_state(&scope_, for_scope); | 3594 BlockState block_state(&scope_, for_scope); |
3577 Expect(Token::FOR, CHECK_OK); | 3595 Expect(Token::FOR, CHECK_OK); |
3578 Expect(Token::LPAREN, CHECK_OK); | 3596 Expect(Token::LPAREN, CHECK_OK); |
3579 for_scope->set_start_position(scanner()->location().beg_pos); | 3597 for_scope->set_start_position(scanner()->location().beg_pos); |
3580 for_scope->set_is_hidden(); | 3598 for_scope->set_is_hidden(); |
3581 DeclarationParsingResult parsing_result; | 3599 DeclarationParsingResult parsing_result; |
(...skipping 30 matching lines...) Expand all Loading... | |
3612 } | 3630 } |
3613 ParserTraits::ReportMessageAt( | 3631 ParserTraits::ReportMessageAt( |
3614 parsing_result.first_initializer_loc, | 3632 parsing_result.first_initializer_loc, |
3615 MessageTemplate::kForInOfLoopInitializer, | 3633 MessageTemplate::kForInOfLoopInitializer, |
3616 ForEachStatement::VisitModeString(mode)); | 3634 ForEachStatement::VisitModeString(mode)); |
3617 *ok = false; | 3635 *ok = false; |
3618 return nullptr; | 3636 return nullptr; |
3619 } | 3637 } |
3620 | 3638 |
3621 Block* init_block = nullptr; | 3639 Block* init_block = nullptr; |
3640 bound_names_are_lexical = | |
3641 IsLexicalVariableMode(parsing_result.descriptor.mode); | |
3622 | 3642 |
3623 // special case for legacy for (var/const x =.... in) | 3643 // special case for legacy for (var/const x =.... in) |
Dan Ehrenberg
2016/06/29 20:24:32
It's only var at this point, right? Could you chan
bakkot
2016/06/29 21:10:13
Done, and in a few other places.
| |
3624 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && | 3644 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && |
3625 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { | 3645 decl.initializer != nullptr) { |
3626 DCHECK(!allow_harmony_for_in()); | 3646 DCHECK(!allow_harmony_for_in()); |
3627 ++use_counts_[v8::Isolate::kForInInitializer]; | 3647 ++use_counts_[v8::Isolate::kForInInitializer]; |
3628 const AstRawString* name = | 3648 const AstRawString* name = |
3629 decl.pattern->AsVariableProxy()->raw_name(); | 3649 decl.pattern->AsVariableProxy()->raw_name(); |
3630 VariableProxy* single_var = scope_->NewUnresolved( | 3650 VariableProxy* single_var = scope_->NewUnresolved( |
3631 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); | 3651 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); |
3632 init_block = factory()->NewBlock( | 3652 init_block = factory()->NewBlock( |
3633 nullptr, 2, true, parsing_result.descriptor.declaration_pos); | 3653 nullptr, 2, true, parsing_result.descriptor.declaration_pos); |
3634 init_block->statements()->Add( | 3654 init_block->statements()->Add( |
3635 factory()->NewExpressionStatement( | 3655 factory()->NewExpressionStatement( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3691 auto each_initialization_block = | 3711 auto each_initialization_block = |
3692 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); | 3712 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); |
3693 { | 3713 { |
3694 auto descriptor = parsing_result.descriptor; | 3714 auto descriptor = parsing_result.descriptor; |
3695 descriptor.declaration_pos = RelocInfo::kNoPosition; | 3715 descriptor.declaration_pos = RelocInfo::kNoPosition; |
3696 descriptor.initialization_pos = RelocInfo::kNoPosition; | 3716 descriptor.initialization_pos = RelocInfo::kNoPosition; |
3697 decl.initializer = factory()->NewVariableProxy(temp); | 3717 decl.initializer = factory()->NewVariableProxy(temp); |
3698 | 3718 |
3699 PatternRewriter::DeclareAndInitializeVariables( | 3719 PatternRewriter::DeclareAndInitializeVariables( |
3700 each_initialization_block, &descriptor, &decl, | 3720 each_initialization_block, &descriptor, &decl, |
3701 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3721 bound_names_are_lexical || |
3702 : nullptr, | 3722 (mode == ForEachStatement::ITERATE && |
3723 parsing_result.descriptor.mode == VariableMode::VAR) | |
Dan Ehrenberg
2016/06/29 20:24:32
Minor cleanup suggestion: since it occurs multiple
bakkot
2016/06/29 21:10:13
Done.
| |
3724 ? &bound_names | |
3725 : nullptr, | |
3703 CHECK_OK); | 3726 CHECK_OK); |
3727 | |
3728 // Annex B.3.5 prohibits the form | |
3729 // `try {} catch(e) { for (var e of {}); }` | |
3730 // So if we are parsing a statement like `for (var ... of ...)` | |
3731 // we need to walk up the scope chain and look for catch scopes | |
3732 // which have a simple binding, then compare their binding against | |
3733 // all of the names declared in the init of the for-of we're | |
3734 // parsing. | |
3735 if (mode == ForEachStatement::ITERATE && | |
3736 parsing_result.descriptor.mode == VariableMode::VAR) { | |
3737 Scope* catch_scope = scope_; | |
3738 while (catch_scope != nullptr && | |
3739 !catch_scope->is_declaration_scope()) { | |
3740 if (catch_scope->is_catch_scope()) { | |
3741 auto name = catch_scope->catch_variable_name(); | |
3742 if (name != | |
3743 ast_value_factory() | |
3744 ->dot_catch_string()) { // i.e. is a simple binding | |
3745 if (bound_names.Contains(name)) { | |
3746 ParserTraits::ReportMessageAt( | |
3747 parsing_result.bindings_loc, | |
3748 MessageTemplate::kVarRedeclaration, name); | |
3749 *ok = false; | |
3750 return nullptr; | |
3751 } | |
3752 } | |
3753 } | |
3754 catch_scope = catch_scope->outer_scope(); | |
3755 } | |
3756 } | |
3704 } | 3757 } |
3705 | 3758 |
3706 body_block->statements()->Add(each_initialization_block, zone()); | 3759 body_block->statements()->Add(each_initialization_block, zone()); |
3707 body_block->statements()->Add(body, zone()); | 3760 body_block->statements()->Add(body, zone()); |
3708 VariableProxy* temp_proxy = | 3761 VariableProxy* temp_proxy = |
3709 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3762 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
3710 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, | 3763 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, |
3711 each_keyword_position); | 3764 each_keyword_position); |
3712 } | 3765 } |
3713 body_scope->set_end_position(scanner()->location().end_pos); | 3766 body_scope->set_end_position(scanner()->location().end_pos); |
3714 body_scope = body_scope->FinalizeBlockScope(); | 3767 body_scope = body_scope->FinalizeBlockScope(); |
3715 body_block->set_scope(body_scope); | 3768 body_block->set_scope(body_scope); |
3716 | 3769 |
3717 // Create a TDZ for any lexically-bound names. | 3770 // Create a TDZ for any lexically-bound names. |
3718 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3771 if (bound_names_are_lexical) { |
3719 DCHECK_NULL(init_block); | 3772 DCHECK_NULL(init_block); |
3720 | 3773 |
3721 init_block = | 3774 init_block = |
3722 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); | 3775 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); |
3723 | 3776 |
3724 for (int i = 0; i < lexical_bindings.length(); ++i) { | 3777 for (int i = 0; i < bound_names.length(); ++i) { |
3725 // TODO(adamk): This needs to be some sort of special | 3778 // TODO(adamk): This needs to be some sort of special |
3726 // INTERNAL variable that's invisible to the debugger | 3779 // INTERNAL variable that's invisible to the debugger |
3727 // but visible to everything else. | 3780 // but visible to everything else. |
3728 VariableProxy* tdz_proxy = | 3781 VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET); |
3729 NewUnresolved(lexical_bindings[i], LET); | |
3730 Declaration* tdz_decl = factory()->NewVariableDeclaration( | 3782 Declaration* tdz_decl = factory()->NewVariableDeclaration( |
3731 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); | 3783 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); |
3732 Variable* tdz_var = Declare( | 3784 Variable* tdz_var = Declare( |
3733 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3785 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
3734 tdz_var->set_initializer_position(position()); | 3786 tdz_var->set_initializer_position(position()); |
3735 } | 3787 } |
3736 } | 3788 } |
3737 | 3789 |
3738 Statement* final_loop = loop->IsForOfStatement() | 3790 Statement* final_loop = loop->IsForOfStatement() |
3739 ? FinalizeForOfStatement( | 3791 ? FinalizeForOfStatement( |
3740 loop->AsForOfStatement(), RelocInfo::kNoPosition) | 3792 loop->AsForOfStatement(), RelocInfo::kNoPosition) |
3741 : loop; | 3793 : loop; |
3742 | 3794 |
3743 for_scope->set_end_position(scanner()->location().end_pos); | 3795 for_scope->set_end_position(scanner()->location().end_pos); |
3744 for_scope = for_scope->FinalizeBlockScope(); | 3796 for_scope = for_scope->FinalizeBlockScope(); |
3745 // Parsed for-in loop w/ variable declarations. | 3797 // Parsed for-in loop w/ variable declarations. |
3746 if (init_block != nullptr) { | 3798 if (init_block != nullptr) { |
3747 init_block->statements()->Add(final_loop, zone()); | 3799 init_block->statements()->Add(final_loop, zone()); |
3748 init_block->set_scope(for_scope); | 3800 init_block->set_scope(for_scope); |
3749 return init_block; | 3801 return init_block; |
3750 } else { | 3802 } else { |
3751 DCHECK_NULL(for_scope); | 3803 DCHECK_NULL(for_scope); |
3752 return final_loop; | 3804 return final_loop; |
3753 } | 3805 } |
3754 } else { | 3806 } else { |
3807 bound_names_are_lexical = | |
3808 IsLexicalVariableMode(parsing_result.descriptor.mode); | |
3755 init = parsing_result.BuildInitializationBlock( | 3809 init = parsing_result.BuildInitializationBlock( |
3756 IsLexicalVariableMode(parsing_result.descriptor.mode) | 3810 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); |
3757 ? &lexical_bindings | |
3758 : nullptr, | |
3759 CHECK_OK); | |
3760 } | 3811 } |
3761 } else { | 3812 } else { |
3762 int lhs_beg_pos = peek_position(); | 3813 int lhs_beg_pos = peek_position(); |
3763 ExpressionClassifier classifier(this); | 3814 ExpressionClassifier classifier(this); |
3764 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | 3815 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); |
3765 int lhs_end_pos = scanner()->location().end_pos; | 3816 int lhs_end_pos = scanner()->location().end_pos; |
3766 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3817 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
3767 | 3818 |
3768 bool is_for_each = CheckInOrOf(&mode, ok); | 3819 bool is_for_each = CheckInOrOf(&mode, ok); |
3769 if (!*ok) return nullptr; | 3820 if (!*ok) return nullptr; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3829 // Parsed initializer at this point. | 3880 // Parsed initializer at this point. |
3830 Expect(Token::SEMICOLON, CHECK_OK); | 3881 Expect(Token::SEMICOLON, CHECK_OK); |
3831 | 3882 |
3832 Expression* cond = NULL; | 3883 Expression* cond = NULL; |
3833 Statement* next = NULL; | 3884 Statement* next = NULL; |
3834 Statement* body = NULL; | 3885 Statement* body = NULL; |
3835 | 3886 |
3836 // If there are let bindings, then condition and the next statement of the | 3887 // If there are let bindings, then condition and the next statement of the |
3837 // for loop must be parsed in a new scope. | 3888 // for loop must be parsed in a new scope. |
3838 Scope* inner_scope = scope_; | 3889 Scope* inner_scope = scope_; |
3839 if (lexical_bindings.length() > 0) { | 3890 if (bound_names_are_lexical && bound_names.length() > 0) { |
3840 inner_scope = NewScope(for_scope, BLOCK_SCOPE); | 3891 inner_scope = NewScope(for_scope, BLOCK_SCOPE); |
3841 inner_scope->set_start_position(scanner()->location().beg_pos); | 3892 inner_scope->set_start_position(scanner()->location().beg_pos); |
3842 } | 3893 } |
3843 { | 3894 { |
3844 BlockState block_state(&scope_, inner_scope); | 3895 BlockState block_state(&scope_, inner_scope); |
3845 | 3896 |
3846 if (peek() != Token::SEMICOLON) { | 3897 if (peek() != Token::SEMICOLON) { |
3847 cond = ParseExpression(true, CHECK_OK); | 3898 cond = ParseExpression(true, CHECK_OK); |
3848 } | 3899 } |
3849 Expect(Token::SEMICOLON, CHECK_OK); | 3900 Expect(Token::SEMICOLON, CHECK_OK); |
3850 | 3901 |
3851 if (peek() != Token::RPAREN) { | 3902 if (peek() != Token::RPAREN) { |
3852 Expression* exp = ParseExpression(true, CHECK_OK); | 3903 Expression* exp = ParseExpression(true, CHECK_OK); |
3853 next = factory()->NewExpressionStatement(exp, exp->position()); | 3904 next = factory()->NewExpressionStatement(exp, exp->position()); |
3854 } | 3905 } |
3855 Expect(Token::RPAREN, CHECK_OK); | 3906 Expect(Token::RPAREN, CHECK_OK); |
3856 | 3907 |
3857 body = ParseScopedStatement(NULL, true, CHECK_OK); | 3908 body = ParseScopedStatement(NULL, true, CHECK_OK); |
3858 } | 3909 } |
3859 | 3910 |
3860 Statement* result = NULL; | 3911 Statement* result = NULL; |
3861 if (lexical_bindings.length() > 0) { | 3912 if (bound_names_are_lexical && bound_names.length() > 0) { |
3862 BlockState block_state(&scope_, for_scope); | 3913 BlockState block_state(&scope_, for_scope); |
3863 result = DesugarLexicalBindingsInForStatement( | 3914 result = DesugarLexicalBindingsInForStatement( |
3864 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, | 3915 inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init, |
3865 init, cond, next, body, CHECK_OK); | 3916 cond, next, body, CHECK_OK); |
3866 for_scope->set_end_position(scanner()->location().end_pos); | 3917 for_scope->set_end_position(scanner()->location().end_pos); |
3867 } else { | 3918 } else { |
3868 for_scope->set_end_position(scanner()->location().end_pos); | 3919 for_scope->set_end_position(scanner()->location().end_pos); |
3869 for_scope = for_scope->FinalizeBlockScope(); | 3920 for_scope = for_scope->FinalizeBlockScope(); |
3870 if (for_scope) { | 3921 if (for_scope) { |
3871 // Rewrite a for statement of the form | 3922 // Rewrite a for statement of the form |
3872 // for (const x = i; c; n) b | 3923 // for (const x = i; c; n) b |
3873 // | 3924 // |
3874 // into | 3925 // into |
3875 // | 3926 // |
(...skipping 3113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6989 try_block, target); | 7040 try_block, target); |
6990 final_loop = target; | 7041 final_loop = target; |
6991 } | 7042 } |
6992 | 7043 |
6993 return final_loop; | 7044 return final_loop; |
6994 } | 7045 } |
6995 | 7046 |
6996 | 7047 |
6997 } // namespace internal | 7048 } // namespace internal |
6998 } // namespace v8 | 7049 } // namespace v8 |
OLD | NEW |