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 3313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3324 assign_each, RelocInfo::kNoPosition), | 3324 assign_each, RelocInfo::kNoPosition), |
3325 zone()); | 3325 zone()); |
3326 block->statements()->Add(body, zone()); | 3326 block->statements()->Add(body, zone()); |
3327 body = block; | 3327 body = block; |
3328 each = factory()->NewVariableProxy(temp); | 3328 each = factory()->NewVariableProxy(temp); |
3329 } | 3329 } |
3330 stmt->Initialize(each, subject, body); | 3330 stmt->Initialize(each, subject, body); |
3331 } | 3331 } |
3332 } | 3332 } |
3333 | 3333 |
3334 | |
3335 Statement* Parser::DesugarLexicalBindingsInForStatement( | 3334 Statement* Parser::DesugarLexicalBindingsInForStatement( |
3336 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, | 3335 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, |
3337 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 3336 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
3338 Statement* body, bool* ok) { | 3337 Statement* body, bool* ok) { |
3339 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 3338 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
3340 // copied into a new environment. Moreover, the "next" statement must be | 3339 // copied into a new environment. Moreover, the "next" statement must be |
3341 // evaluated not in the environment of the just completed iteration but in | 3340 // evaluated not in the environment of the just completed iteration but in |
3342 // that of the upcoming one. We achieve this with the following desugaring. | 3341 // that of the upcoming one. We achieve this with the following desugaring. |
3343 // Extra care is needed to preserve the completion value of the original loop. | 3342 // Extra care is needed to preserve the completion value of the original loop. |
3344 // | 3343 // |
3345 // We are given a for statement of the form | 3344 // We are given a for statement of the form |
3346 // | 3345 // |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3431 Block* inner_block = | 3430 Block* inner_block = |
3432 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 3431 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
3433 { | 3432 { |
3434 BlockState block_state(&scope_, inner_scope); | 3433 BlockState block_state(&scope_, inner_scope); |
3435 | 3434 |
3436 Block* ignore_completion_block = factory()->NewBlock( | 3435 Block* ignore_completion_block = factory()->NewBlock( |
3437 NULL, names->length() + 3, true, RelocInfo::kNoPosition); | 3436 NULL, names->length() + 3, true, RelocInfo::kNoPosition); |
3438 ZoneList<Variable*> inner_vars(names->length(), zone()); | 3437 ZoneList<Variable*> inner_vars(names->length(), zone()); |
3439 // For each let variable x: | 3438 // For each let variable x: |
3440 // make statement: let/const x = temp_x. | 3439 // make statement: let/const x = temp_x. |
3441 VariableMode mode = is_const ? CONST : LET; | |
3442 for (int i = 0; i < names->length(); i++) { | 3440 for (int i = 0; i < names->length(); i++) { |
3443 VariableProxy* proxy = NewUnresolved(names->at(i), mode); | 3441 VariableProxy* proxy = NewUnresolved(names->at(i), mode); |
3444 Declaration* declaration = factory()->NewVariableDeclaration( | 3442 Declaration* declaration = factory()->NewVariableDeclaration( |
3445 proxy, mode, scope_, RelocInfo::kNoPosition); | 3443 proxy, mode, scope_, RelocInfo::kNoPosition); |
3446 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 3444 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
3447 inner_vars.Add(declaration->proxy()->var(), zone()); | 3445 inner_vars.Add(declaration->proxy()->var(), zone()); |
3448 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 3446 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
3449 Assignment* assignment = factory()->NewAssignment( | 3447 Assignment* assignment = factory()->NewAssignment( |
3450 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition); | 3448 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition); |
3451 Statement* assignment_statement = | 3449 Statement* assignment_statement = |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3581 return outer_block; | 3579 return outer_block; |
3582 } | 3580 } |
3583 | 3581 |
3584 | 3582 |
3585 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3583 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
3586 bool* ok) { | 3584 bool* ok) { |
3587 // ForStatement :: | 3585 // ForStatement :: |
3588 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3586 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
3589 | 3587 |
3590 int stmt_pos = peek_position(); | 3588 int stmt_pos = peek_position(); |
3591 bool is_const = false; | |
3592 Statement* init = NULL; | 3589 Statement* init = NULL; |
3593 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3590 ZoneList<const AstRawString*> lexical_bindings(1, zone()); |
3594 | 3591 |
3595 // Create an in-between scope for let-bound iteration variables. | 3592 // Create an in-between scope for let-bound iteration variables. |
3596 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 3593 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); |
3597 | 3594 |
3598 BlockState block_state(&scope_, for_scope); | 3595 BlockState block_state(&scope_, for_scope); |
3599 Expect(Token::FOR, CHECK_OK); | 3596 Expect(Token::FOR, CHECK_OK); |
3600 Expect(Token::LPAREN, CHECK_OK); | 3597 Expect(Token::LPAREN, CHECK_OK); |
3601 for_scope->set_start_position(scanner()->location().beg_pos); | 3598 for_scope->set_start_position(scanner()->location().beg_pos); |
3602 bool is_let_identifier_expression = false; | 3599 bool is_let_identifier_expression = false; |
3603 DeclarationParsingResult parsing_result; | 3600 DeclarationParsingResult parsing_result; |
3604 if (peek() != Token::SEMICOLON) { | 3601 if (peek() != Token::SEMICOLON) { |
3605 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || | 3602 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || |
3606 (peek() == Token::LET && IsNextLetKeyword())) { | 3603 (peek() == Token::LET && IsNextLetKeyword())) { |
3607 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK); | 3604 ParseVariableDeclarations(kForStatement, &parsing_result, CHECK_OK); |
3608 is_const = parsing_result.descriptor.mode == CONST; | |
3609 | 3605 |
3610 int num_decl = parsing_result.declarations.length(); | |
3611 bool accept_IN = num_decl >= 1; | |
3612 ForEachStatement::VisitMode mode; | 3606 ForEachStatement::VisitMode mode; |
3613 int each_beg_pos = scanner()->location().beg_pos; | 3607 int each_beg_pos = scanner()->location().beg_pos; |
3614 int each_end_pos = scanner()->location().end_pos; | 3608 int each_end_pos = scanner()->location().end_pos; |
3615 | 3609 |
3616 if (accept_IN && CheckInOrOf(&mode, ok)) { | 3610 if (CheckInOrOf(&mode, ok)) { |
3617 if (!*ok) return nullptr; | 3611 if (!*ok) return nullptr; |
3618 if (num_decl != 1) { | 3612 if (parsing_result.declarations.length() != 1) { |
3619 const char* loop_type = | |
3620 mode == ForEachStatement::ITERATE ? "for-of" : "for-in"; | |
3621 ParserTraits::ReportMessageAt( | 3613 ParserTraits::ReportMessageAt( |
3622 parsing_result.bindings_loc, | 3614 parsing_result.bindings_loc, |
3623 MessageTemplate::kForInOfLoopMultiBindings, loop_type); | 3615 MessageTemplate::kForInOfLoopMultiBindings, |
| 3616 ForEachStatement::VisitModeString(mode)); |
3624 *ok = false; | 3617 *ok = false; |
3625 return nullptr; | 3618 return nullptr; |
3626 } | 3619 } |
3627 DeclarationParsingResult::Declaration& decl = | 3620 DeclarationParsingResult::Declaration& decl = |
3628 parsing_result.declarations[0]; | 3621 parsing_result.declarations[0]; |
3629 if (parsing_result.first_initializer_loc.IsValid() && | 3622 if (parsing_result.first_initializer_loc.IsValid() && |
3630 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || | 3623 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || |
3631 IsLexicalVariableMode(parsing_result.descriptor.mode) || | 3624 IsLexicalVariableMode(parsing_result.descriptor.mode) || |
3632 !decl.pattern->IsVariableProxy())) { | 3625 !decl.pattern->IsVariableProxy())) { |
3633 if (mode == ForEachStatement::ITERATE) { | 3626 ParserTraits::ReportMessageAt( |
3634 ReportMessageAt(parsing_result.first_initializer_loc, | 3627 parsing_result.first_initializer_loc, |
3635 MessageTemplate::kForOfLoopInitializer); | 3628 MessageTemplate::kForInOfLoopInitializer, |
3636 } else { | 3629 ForEachStatement::VisitModeString(mode)); |
3637 // TODO(caitp): This should be an error in sloppy mode too. | |
3638 ReportMessageAt(parsing_result.first_initializer_loc, | |
3639 MessageTemplate::kForInLoopInitializer); | |
3640 } | |
3641 *ok = false; | 3630 *ok = false; |
3642 return nullptr; | 3631 return nullptr; |
3643 } | 3632 } |
3644 | 3633 |
3645 Block* init_block = nullptr; | 3634 Block* init_block = nullptr; |
3646 | 3635 |
3647 // special case for legacy for (var/const x =.... in) | 3636 // special case for legacy for (var/const x =.... in) |
3648 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && | 3637 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && |
3649 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { | 3638 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { |
3650 ++use_counts_[v8::Isolate::kForInInitializer]; | 3639 ++use_counts_[v8::Isolate::kForInInitializer]; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3888 } | 3877 } |
3889 Expect(Token::RPAREN, CHECK_OK); | 3878 Expect(Token::RPAREN, CHECK_OK); |
3890 | 3879 |
3891 body = ParseSubStatement(NULL, CHECK_OK); | 3880 body = ParseSubStatement(NULL, CHECK_OK); |
3892 } | 3881 } |
3893 | 3882 |
3894 Statement* result = NULL; | 3883 Statement* result = NULL; |
3895 if (lexical_bindings.length() > 0) { | 3884 if (lexical_bindings.length() > 0) { |
3896 BlockState block_state(&scope_, for_scope); | 3885 BlockState block_state(&scope_, for_scope); |
3897 result = DesugarLexicalBindingsInForStatement( | 3886 result = DesugarLexicalBindingsInForStatement( |
3898 inner_scope, is_const, &lexical_bindings, loop, init, cond, | 3887 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, |
3899 next, body, CHECK_OK); | 3888 init, cond, next, body, CHECK_OK); |
3900 for_scope->set_end_position(scanner()->location().end_pos); | 3889 for_scope->set_end_position(scanner()->location().end_pos); |
3901 } else { | 3890 } else { |
3902 for_scope->set_end_position(scanner()->location().end_pos); | 3891 for_scope->set_end_position(scanner()->location().end_pos); |
3903 for_scope = for_scope->FinalizeBlockScope(); | 3892 for_scope = for_scope->FinalizeBlockScope(); |
3904 if (for_scope) { | 3893 if (for_scope) { |
3905 // Rewrite a for statement of the form | 3894 // Rewrite a for statement of the form |
3906 // for (const x = i; c; n) b | 3895 // for (const x = i; c; n) b |
3907 // | 3896 // |
3908 // into | 3897 // into |
3909 // | 3898 // |
(...skipping 1869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5779 function->set_raw_name(name); | 5768 function->set_raw_name(name); |
5780 } else { | 5769 } else { |
5781 DCHECK(value->IsClassLiteral()); | 5770 DCHECK(value->IsClassLiteral()); |
5782 value->AsClassLiteral()->constructor()->set_raw_name(name); | 5771 value->AsClassLiteral()->constructor()->set_raw_name(name); |
5783 } | 5772 } |
5784 } | 5773 } |
5785 | 5774 |
5786 | 5775 |
5787 } // namespace internal | 5776 } // namespace internal |
5788 } // namespace v8 | 5777 } // namespace v8 |
OLD | NEW |