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

Side by Side Diff: src/parsing/parser.cc

Issue 1757543003: Restrict FunctionDeclarations in Statement position (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: git cl format Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.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 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 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); 767 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
768 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); 768 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
769 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind); 769 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind);
770 set_allow_harmony_destructuring_assignment( 770 set_allow_harmony_destructuring_assignment(
771 FLAG_harmony_destructuring_assignment); 771 FLAG_harmony_destructuring_assignment);
772 set_allow_strong_mode(FLAG_strong_mode); 772 set_allow_strong_mode(FLAG_strong_mode);
773 set_allow_legacy_const(FLAG_legacy_const); 773 set_allow_legacy_const(FLAG_legacy_const);
774 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 774 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
775 set_allow_harmony_function_name(FLAG_harmony_function_name); 775 set_allow_harmony_function_name(FLAG_harmony_function_name);
776 set_allow_harmony_function_sent(FLAG_harmony_function_sent); 776 set_allow_harmony_function_sent(FLAG_harmony_function_sent);
777 set_allow_harmony_restrictive_declarations(
778 FLAG_harmony_restrictive_declarations);
777 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 779 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
778 ++feature) { 780 ++feature) {
779 use_counts_[feature] = 0; 781 use_counts_[feature] = 0;
780 } 782 }
781 if (info->ast_value_factory() == NULL) { 783 if (info->ast_value_factory() == NULL) {
782 // info takes ownership of AstValueFactory. 784 // info takes ownership of AstValueFactory.
783 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 785 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
784 info->set_ast_value_factory_owned(); 786 info->set_ast_value_factory_owned();
785 ast_value_factory_ = info->ast_value_factory(); 787 ast_value_factory_ = info->ast_value_factory();
786 } 788 }
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 return result; 1834 return result;
1833 } 1835 }
1834 } 1836 }
1835 1837
1836 case Token::WITH: 1838 case Token::WITH:
1837 return ParseWithStatement(labels, ok); 1839 return ParseWithStatement(labels, ok);
1838 1840
1839 case Token::SWITCH: 1841 case Token::SWITCH:
1840 return ParseSwitchStatement(labels, ok); 1842 return ParseSwitchStatement(labels, ok);
1841 1843
1842 case Token::FUNCTION: { 1844 case Token::FUNCTION:
1843 // FunctionDeclaration is only allowed in the context of SourceElements 1845 // FunctionDeclaration only allowed as a StatementListItem, not in
1844 // (Ecma 262 5th Edition, clause 14): 1846 // an arbitrary Statement position. Exceptions such as
1845 // SourceElement: 1847 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1846 // Statement 1848 // are handled by calling ParseScopedStatement rather than
1847 // FunctionDeclaration 1849 // ParseSubStatement directly.
1848 // Common language extension is to allow function declaration in place 1850 ReportMessageAt(scanner()->peek_location(),
1849 // of any statement. This language extension is disabled in strict mode. 1851 is_strict(language_mode())
1850 // 1852 ? MessageTemplate::kStrictFunction
1851 // In Harmony mode, this case also handles the extension: 1853 : MessageTemplate::kSloppyFunction);
1852 // Statement: 1854 *ok = false;
1853 // GeneratorDeclaration 1855 return nullptr;
1854 if (is_strict(language_mode())) {
1855 ReportMessageAt(scanner()->peek_location(),
1856 MessageTemplate::kStrictFunction);
1857 *ok = false;
1858 return NULL;
1859 }
1860 return ParseFunctionDeclaration(NULL, ok);
1861 }
1862 1856
1863 case Token::DEBUGGER: 1857 case Token::DEBUGGER:
1864 return ParseDebuggerStatement(ok); 1858 return ParseDebuggerStatement(ok);
1865 1859
1866 case Token::VAR: 1860 case Token::VAR:
1867 return ParseVariableStatement(kStatement, NULL, ok); 1861 return ParseVariableStatement(kStatement, NULL, ok);
1868 1862
1869 case Token::CONST: 1863 case Token::CONST:
1870 // In ES6 CONST is not allowed as a Statement, only as a 1864 // In ES6 CONST is not allowed as a Statement, only as a
1871 // LexicalDeclaration, however we continue to allow it in sloppy mode for 1865 // LexicalDeclaration, however we continue to allow it in sloppy mode for
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
2574 } 2568 }
2575 if (labels == NULL) { 2569 if (labels == NULL) {
2576 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); 2570 labels = new(zone()) ZoneList<const AstRawString*>(4, zone());
2577 } 2571 }
2578 labels->Add(label, zone()); 2572 labels->Add(label, zone());
2579 // Remove the "ghost" variable that turned out to be a label 2573 // Remove the "ghost" variable that turned out to be a label
2580 // from the top scope. This way, we don't try to resolve it 2574 // from the top scope. This way, we don't try to resolve it
2581 // during the scope processing. 2575 // during the scope processing.
2582 scope_->RemoveUnresolved(var); 2576 scope_->RemoveUnresolved(var);
2583 Expect(Token::COLON, CHECK_OK); 2577 Expect(Token::COLON, CHECK_OK);
2578 // ES#sec-labelled-function-declarations Labelled Function Declarations
2579 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
2580 return ParseFunctionDeclaration(labels, ok);
2581 }
2584 return ParseStatement(labels, ok); 2582 return ParseStatement(labels, ok);
2585 } 2583 }
2586 2584
2587 // If we have an extension, we allow a native function declaration. 2585 // If we have an extension, we allow a native function declaration.
2588 // A native function declaration starts with "native function" with 2586 // A native function declaration starts with "native function" with
2589 // no line-terminator between the two words. 2587 // no line-terminator between the two words.
2590 if (extension_ != NULL && peek() == Token::FUNCTION && 2588 if (extension_ != NULL && peek() == Token::FUNCTION &&
2591 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2589 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2592 expr->AsVariableProxy() != NULL && 2590 expr->AsVariableProxy() != NULL &&
2593 expr->AsVariableProxy()->raw_name() == 2591 expr->AsVariableProxy()->raw_name() ==
(...skipping 20 matching lines...) Expand all
2614 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 2612 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2615 bool* ok) { 2613 bool* ok) {
2616 // IfStatement :: 2614 // IfStatement ::
2617 // 'if' '(' Expression ')' Statement ('else' Statement)? 2615 // 'if' '(' Expression ')' Statement ('else' Statement)?
2618 2616
2619 int pos = peek_position(); 2617 int pos = peek_position();
2620 Expect(Token::IF, CHECK_OK); 2618 Expect(Token::IF, CHECK_OK);
2621 Expect(Token::LPAREN, CHECK_OK); 2619 Expect(Token::LPAREN, CHECK_OK);
2622 Expression* condition = ParseExpression(true, CHECK_OK); 2620 Expression* condition = ParseExpression(true, CHECK_OK);
2623 Expect(Token::RPAREN, CHECK_OK); 2621 Expect(Token::RPAREN, CHECK_OK);
2624 Statement* then_statement = ParseSubStatement(labels, CHECK_OK); 2622 Statement* then_statement = ParseScopedStatement(labels, false, CHECK_OK);
2625 Statement* else_statement = NULL; 2623 Statement* else_statement = NULL;
2626 if (peek() == Token::ELSE) { 2624 if (peek() == Token::ELSE) {
2627 Next(); 2625 Next();
2628 else_statement = ParseSubStatement(labels, CHECK_OK); 2626 else_statement = ParseScopedStatement(labels, false, CHECK_OK);
2629 } else { 2627 } else {
2630 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 2628 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2631 } 2629 }
2632 return factory()->NewIfStatement( 2630 return factory()->NewIfStatement(
2633 condition, then_statement, else_statement, pos); 2631 condition, then_statement, else_statement, pos);
2634 } 2632 }
2635 2633
2636 2634
2637 Statement* Parser::ParseContinueStatement(bool* ok) { 2635 Statement* Parser::ParseContinueStatement(bool* ok) {
2638 // ContinueStatement :: 2636 // ContinueStatement ::
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 *ok = false; 2815 *ok = false;
2818 return NULL; 2816 return NULL;
2819 } 2817 }
2820 2818
2821 Expect(Token::LPAREN, CHECK_OK); 2819 Expect(Token::LPAREN, CHECK_OK);
2822 Expression* expr = ParseExpression(true, CHECK_OK); 2820 Expression* expr = ParseExpression(true, CHECK_OK);
2823 Expect(Token::RPAREN, CHECK_OK); 2821 Expect(Token::RPAREN, CHECK_OK);
2824 2822
2825 scope_->DeclarationScope()->RecordWithStatement(); 2823 scope_->DeclarationScope()->RecordWithStatement();
2826 Scope* with_scope = NewScope(scope_, WITH_SCOPE); 2824 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2827 Block* body; 2825 Statement* body;
2828 { BlockState block_state(&scope_, with_scope); 2826 { BlockState block_state(&scope_, with_scope);
2829 with_scope->set_start_position(scanner()->peek_location().beg_pos); 2827 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2830 2828 body = ParseScopedStatement(labels, true, CHECK_OK);
2831 // The body of the with statement must be enclosed in an additional
2832 // lexical scope in case the body is a FunctionDeclaration.
2833 body = factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
2834 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2835 block_scope->set_start_position(scanner()->location().beg_pos);
2836 {
2837 BlockState block_state(&scope_, block_scope);
2838 Target target(&this->target_stack_, body);
2839 Statement* stmt = ParseSubStatement(labels, CHECK_OK);
2840 body->statements()->Add(stmt, zone());
2841 block_scope->set_end_position(scanner()->location().end_pos);
2842 block_scope = block_scope->FinalizeBlockScope();
2843 body->set_scope(block_scope);
2844 }
2845
2846 with_scope->set_end_position(scanner()->location().end_pos); 2829 with_scope->set_end_position(scanner()->location().end_pos);
2847 } 2830 }
2848 return factory()->NewWithStatement(with_scope, expr, body, pos); 2831 return factory()->NewWithStatement(with_scope, expr, body, pos);
2849 } 2832 }
2850 2833
2851 2834
2852 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 2835 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2853 // CaseClause :: 2836 // CaseClause ::
2854 // 'case' Expression ':' StatementList 2837 // 'case' Expression ':' StatementList
2855 // 'default' ':' StatementList 2838 // 'default' ':' StatementList
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 DoWhileStatement* Parser::ParseDoWhileStatement( 3159 DoWhileStatement* Parser::ParseDoWhileStatement(
3177 ZoneList<const AstRawString*>* labels, bool* ok) { 3160 ZoneList<const AstRawString*>* labels, bool* ok) {
3178 // DoStatement :: 3161 // DoStatement ::
3179 // 'do' Statement 'while' '(' Expression ')' ';' 3162 // 'do' Statement 'while' '(' Expression ')' ';'
3180 3163
3181 DoWhileStatement* loop = 3164 DoWhileStatement* loop =
3182 factory()->NewDoWhileStatement(labels, peek_position()); 3165 factory()->NewDoWhileStatement(labels, peek_position());
3183 Target target(&this->target_stack_, loop); 3166 Target target(&this->target_stack_, loop);
3184 3167
3185 Expect(Token::DO, CHECK_OK); 3168 Expect(Token::DO, CHECK_OK);
3186 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3169 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3187 Expect(Token::WHILE, CHECK_OK); 3170 Expect(Token::WHILE, CHECK_OK);
3188 Expect(Token::LPAREN, CHECK_OK); 3171 Expect(Token::LPAREN, CHECK_OK);
3189 3172
3190 Expression* cond = ParseExpression(true, CHECK_OK); 3173 Expression* cond = ParseExpression(true, CHECK_OK);
3191 Expect(Token::RPAREN, CHECK_OK); 3174 Expect(Token::RPAREN, CHECK_OK);
3192 3175
3193 // Allow do-statements to be terminated with and without 3176 // Allow do-statements to be terminated with and without
3194 // semi-colons. This allows code such as 'do;while(0)return' to 3177 // semi-colons. This allows code such as 'do;while(0)return' to
3195 // parse, which would not be the case if we had used the 3178 // parse, which would not be the case if we had used the
3196 // ExpectSemicolon() functionality here. 3179 // ExpectSemicolon() functionality here.
3197 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 3180 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
3198 3181
3199 if (loop != NULL) loop->Initialize(cond, body); 3182 if (loop != NULL) loop->Initialize(cond, body);
3200 return loop; 3183 return loop;
3201 } 3184 }
3202 3185
3203 3186
3204 WhileStatement* Parser::ParseWhileStatement( 3187 WhileStatement* Parser::ParseWhileStatement(
3205 ZoneList<const AstRawString*>* labels, bool* ok) { 3188 ZoneList<const AstRawString*>* labels, bool* ok) {
3206 // WhileStatement :: 3189 // WhileStatement ::
3207 // 'while' '(' Expression ')' Statement 3190 // 'while' '(' Expression ')' Statement
3208 3191
3209 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); 3192 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position());
3210 Target target(&this->target_stack_, loop); 3193 Target target(&this->target_stack_, loop);
3211 3194
3212 Expect(Token::WHILE, CHECK_OK); 3195 Expect(Token::WHILE, CHECK_OK);
3213 Expect(Token::LPAREN, CHECK_OK); 3196 Expect(Token::LPAREN, CHECK_OK);
3214 Expression* cond = ParseExpression(true, CHECK_OK); 3197 Expression* cond = ParseExpression(true, CHECK_OK);
3215 Expect(Token::RPAREN, CHECK_OK); 3198 Expect(Token::RPAREN, CHECK_OK);
3216 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3199 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3217 3200
3218 if (loop != NULL) loop->Initialize(cond, body); 3201 if (loop != NULL) loop->Initialize(cond, body);
3219 return loop; 3202 return loop;
3220 } 3203 }
3221 3204
3222 3205
3223 // !%_IsJSReceiver(result = iterator.next()) && 3206 // !%_IsJSReceiver(result = iterator.next()) &&
3224 // %ThrowIteratorResultNotAnObject(result) 3207 // %ThrowIteratorResultNotAnObject(result)
3225 Expression* Parser::BuildIteratorNextResult(Expression* iterator, 3208 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
3226 Variable* result, int pos) { 3209 Variable* result, int pos) {
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
3588 } 3571 }
3589 3572
3590 inner_scope->set_end_position(scanner()->location().end_pos); 3573 inner_scope->set_end_position(scanner()->location().end_pos);
3591 inner_block->set_scope(inner_scope); 3574 inner_block->set_scope(inner_scope);
3592 } 3575 }
3593 3576
3594 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3577 outer_loop->Initialize(NULL, NULL, NULL, inner_block);
3595 return outer_block; 3578 return outer_block;
3596 } 3579 }
3597 3580
3581 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels,
3582 bool legacy, bool* ok) {
3583 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
3584 (legacy && allow_harmony_restrictive_declarations())) {
3585 return ParseSubStatement(labels, ok);
3586 } else {
3587 if (legacy) {
3588 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration];
3589 }
3590 // Make a block around the statement for a lexical binding
3591 // is introduced by a FunctionDeclaration.
3592 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3593 BlockState block_state(&scope_, body_scope);
3594 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3595 Statement* body = ParseFunctionDeclaration(NULL, CHECK_OK);
3596 block->statements()->Add(body, zone());
3597 body_scope->set_end_position(scanner()->location().end_pos);
3598 body_scope = body_scope->FinalizeBlockScope();
3599 block->set_scope(body_scope);
3600 return block;
3601 }
3602 }
3598 3603
3599 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3604 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
3600 bool* ok) { 3605 bool* ok) {
3601 int stmt_pos = peek_position(); 3606 int stmt_pos = peek_position();
3602 Statement* init = NULL; 3607 Statement* init = NULL;
3603 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3608 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3604 3609
3605 // Create an in-between scope for let-bound iteration variables. 3610 // Create an in-between scope for let-bound iteration variables.
3606 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3611 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3607 3612
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 3706
3702 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3707 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3703 body_scope->set_start_position(scanner()->location().beg_pos); 3708 body_scope->set_start_position(scanner()->location().beg_pos);
3704 3709
3705 Block* body_block = 3710 Block* body_block =
3706 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3711 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3707 3712
3708 { 3713 {
3709 BlockState block_state(&scope_, body_scope); 3714 BlockState block_state(&scope_, body_scope);
3710 3715
3711 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3716 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3712 3717
3713 auto each_initialization_block = 3718 auto each_initialization_block =
3714 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 3719 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition);
3715 { 3720 {
3716 auto descriptor = parsing_result.descriptor; 3721 auto descriptor = parsing_result.descriptor;
3717 descriptor.declaration_pos = RelocInfo::kNoPosition; 3722 descriptor.declaration_pos = RelocInfo::kNoPosition;
3718 descriptor.initialization_pos = RelocInfo::kNoPosition; 3723 descriptor.initialization_pos = RelocInfo::kNoPosition;
3719 decl.initializer = factory()->NewVariableProxy(temp); 3724 decl.initializer = factory()->NewVariableProxy(temp);
3720 3725
3721 PatternRewriter::DeclareAndInitializeVariables( 3726 PatternRewriter::DeclareAndInitializeVariables(
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3818 if (mode == ForEachStatement::ITERATE) { 3823 if (mode == ForEachStatement::ITERATE) {
3819 ExpressionClassifier classifier(this); 3824 ExpressionClassifier classifier(this);
3820 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK); 3825 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK);
3821 RewriteNonPattern(&classifier, CHECK_OK); 3826 RewriteNonPattern(&classifier, CHECK_OK);
3822 } else { 3827 } else {
3823 enumerable = ParseExpression(true, CHECK_OK); 3828 enumerable = ParseExpression(true, CHECK_OK);
3824 } 3829 }
3825 3830
3826 Expect(Token::RPAREN, CHECK_OK); 3831 Expect(Token::RPAREN, CHECK_OK);
3827 3832
3828 // Make a block around the statement in case a lexical binding 3833 // For legacy compat reasons, give for loops similar treatment to
3829 // is introduced, e.g. by a FunctionDeclaration. 3834 // if statements in allowing a function declaration for a body
3830 // This block must not use for_scope as its scope because if a 3835 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
3831 // lexical binding is introduced which overlaps with the for-in/of, 3836 InitializeForEachStatement(loop, expression, enumerable, body,
3832 // expressions in head of the loop should actually have variables 3837 is_destructuring);
3833 // resolved in the outer scope.
3834 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3835 {
3836 BlockState block_state(&scope_, body_scope);
3837 Block* block =
3838 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3839 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3840 block->statements()->Add(body, zone());
3841 InitializeForEachStatement(loop, expression, enumerable, block,
3842 is_destructuring);
3843 body_scope->set_end_position(scanner()->location().end_pos);
3844 body_scope = body_scope->FinalizeBlockScope();
3845 block->set_scope(body_scope);
3846 }
3847 3838
3848 Statement* final_loop = loop->IsForOfStatement() 3839 Statement* final_loop = loop->IsForOfStatement()
3849 ? FinalizeForOfStatement( 3840 ? FinalizeForOfStatement(
3850 loop->AsForOfStatement(), RelocInfo::kNoPosition) 3841 loop->AsForOfStatement(), RelocInfo::kNoPosition)
3851 : loop; 3842 : loop;
3852 3843
3853 for_scope->set_end_position(scanner()->location().end_pos); 3844 for_scope->set_end_position(scanner()->location().end_pos);
3854 for_scope = for_scope->FinalizeBlockScope(); 3845 for_scope = for_scope->FinalizeBlockScope();
3855 DCHECK(for_scope == nullptr); 3846 DCHECK(for_scope == nullptr);
3856 return final_loop; 3847 return final_loop;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3893 cond = ParseExpression(true, CHECK_OK); 3884 cond = ParseExpression(true, CHECK_OK);
3894 } 3885 }
3895 Expect(Token::SEMICOLON, CHECK_OK); 3886 Expect(Token::SEMICOLON, CHECK_OK);
3896 3887
3897 if (peek() != Token::RPAREN) { 3888 if (peek() != Token::RPAREN) {
3898 Expression* exp = ParseExpression(true, CHECK_OK); 3889 Expression* exp = ParseExpression(true, CHECK_OK);
3899 next = factory()->NewExpressionStatement(exp, exp->position()); 3890 next = factory()->NewExpressionStatement(exp, exp->position());
3900 } 3891 }
3901 Expect(Token::RPAREN, CHECK_OK); 3892 Expect(Token::RPAREN, CHECK_OK);
3902 3893
3903 body = ParseSubStatement(NULL, CHECK_OK); 3894 body = ParseScopedStatement(NULL, true, CHECK_OK);
3904 } 3895 }
3905 3896
3906 Statement* result = NULL; 3897 Statement* result = NULL;
3907 if (lexical_bindings.length() > 0) { 3898 if (lexical_bindings.length() > 0) {
3908 BlockState block_state(&scope_, for_scope); 3899 BlockState block_state(&scope_, for_scope);
3909 result = DesugarLexicalBindingsInForStatement( 3900 result = DesugarLexicalBindingsInForStatement(
3910 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, 3901 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop,
3911 init, cond, next, body, CHECK_OK); 3902 init, cond, next, body, CHECK_OK);
3912 for_scope->set_end_position(scanner()->location().end_pos); 3903 for_scope->set_end_position(scanner()->location().end_pos);
3913 } else { 3904 } else {
(...skipping 3026 matching lines...) Expand 10 before | Expand all | Expand 10 after
6940 Expression* do_each = 6931 Expression* do_each =
6941 factory->NewDoExpression(new_assign_each, var_each, nopos); 6932 factory->NewDoExpression(new_assign_each, var_each, nopos);
6942 loop->set_assign_each(do_each); 6933 loop->set_assign_each(do_each);
6943 6934
6944 return final_loop; 6935 return final_loop;
6945 } 6936 }
6946 6937
6947 6938
6948 } // namespace internal 6939 } // namespace internal
6949 } // namespace v8 6940 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698