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

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

Issue 1508933004: [es6] support AssignmentPattern as LHS in for-in/of loops (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Further fixups Created 5 years 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
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-visitor.h" 9 #include "src/ast/ast-expression-visitor.h"
10 #include "src/ast/ast-literal-reindexer.h" 10 #include "src/ast/ast-literal-reindexer.h"
(...skipping 3308 matching lines...) Expand 10 before | Expand all | Expand 10 after
3319 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 3319 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3320 3320
3321 return factory()->NewBinaryOperation( 3321 return factory()->NewBinaryOperation(
3322 Token::AND, 3322 Token::AND,
3323 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 3323 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3324 throw_call, pos); 3324 throw_call, pos);
3325 } 3325 }
3326 3326
3327 3327
3328 void Parser::InitializeForEachStatement(ForEachStatement* stmt, 3328 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3329 Expression* each, 3329 Expression* each, Expression* subject,
3330 Expression* subject, 3330 Statement* body,
3331 Statement* body) { 3331 bool is_destructuring) {
3332 DCHECK(!is_destructuring || allow_harmony_destructuring_assignment());
3332 ForOfStatement* for_of = stmt->AsForOfStatement(); 3333 ForOfStatement* for_of = stmt->AsForOfStatement();
3333 3334
3334 if (for_of != NULL) { 3335 if (for_of != NULL) {
3335 Variable* iterator = scope_->NewTemporary( 3336 Variable* iterator = scope_->NewTemporary(
3336 ast_value_factory()->dot_iterator_string()); 3337 ast_value_factory()->dot_iterator_string());
3337 Variable* result = scope_->NewTemporary( 3338 Variable* result = scope_->NewTemporary(
3338 ast_value_factory()->dot_result_string()); 3339 ast_value_factory()->dot_result_string());
3339 3340
3340 Expression* assign_iterator; 3341 Expression* assign_iterator;
3341 Expression* next_result; 3342 Expression* next_result;
(...skipping 30 matching lines...) Expand all
3372 3373
3373 // each = result.value 3374 // each = result.value
3374 { 3375 {
3375 Expression* value_literal = factory()->NewStringLiteral( 3376 Expression* value_literal = factory()->NewStringLiteral(
3376 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 3377 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3377 Expression* result_proxy = factory()->NewVariableProxy(result); 3378 Expression* result_proxy = factory()->NewVariableProxy(result);
3378 Expression* result_value = factory()->NewProperty( 3379 Expression* result_value = factory()->NewProperty(
3379 result_proxy, value_literal, RelocInfo::kNoPosition); 3380 result_proxy, value_literal, RelocInfo::kNoPosition);
3380 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3381 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3381 RelocInfo::kNoPosition); 3382 RelocInfo::kNoPosition);
3383 if (is_destructuring) {
3384 assign_each = PatternRewriter::RewriteDestructuringAssignment(
3385 this, assign_each->AsAssignment(), scope_);
3386 }
3382 } 3387 }
3383 3388
3384 for_of->Initialize(each, subject, body, 3389 for_of->Initialize(each, subject, body,
3385 assign_iterator, 3390 assign_iterator,
3386 next_result, 3391 next_result,
3387 result_done, 3392 result_done,
3388 assign_each); 3393 assign_each);
3389 } else { 3394 } else {
3395 if (is_destructuring) {
3396 Variable* temp =
3397 scope_->NewTemporary(ast_value_factory()->empty_string());
3398 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3399 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
3400 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
3401 RelocInfo::kNoPosition),
3402 scope_);
3403 auto block =
3404 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
3405 block->statements()->Add(factory()->NewExpressionStatement(
3406 assign_each, RelocInfo::kNoPosition),
3407 zone());
3408 block->statements()->Add(body, zone());
3409 body = block;
3410 each = factory()->NewVariableProxy(temp);
3411 }
3390 stmt->Initialize(each, subject, body); 3412 stmt->Initialize(each, subject, body);
3391 } 3413 }
3392 } 3414 }
3393 3415
3394 3416
3395 Statement* Parser::DesugarLexicalBindingsInForStatement( 3417 Statement* Parser::DesugarLexicalBindingsInForStatement(
3396 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3418 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3397 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3419 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3398 Statement* body, bool* ok) { 3420 Statement* body, bool* ok) {
3399 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 3421 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
3764 each_initialization_block, &descriptor, &decl, 3786 each_initialization_block, &descriptor, &decl,
3765 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3787 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3766 : nullptr, 3788 : nullptr,
3767 CHECK_OK); 3789 CHECK_OK);
3768 } 3790 }
3769 3791
3770 body_block->statements()->Add(each_initialization_block, zone()); 3792 body_block->statements()->Add(each_initialization_block, zone());
3771 body_block->statements()->Add(body, zone()); 3793 body_block->statements()->Add(body, zone());
3772 VariableProxy* temp_proxy = 3794 VariableProxy* temp_proxy =
3773 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3795 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3774 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3796 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3797 false);
3775 scope_ = for_scope; 3798 scope_ = for_scope;
3776 body_scope->set_end_position(scanner()->location().end_pos); 3799 body_scope->set_end_position(scanner()->location().end_pos);
3777 body_scope = body_scope->FinalizeBlockScope(); 3800 body_scope = body_scope->FinalizeBlockScope();
3778 if (body_scope != nullptr) { 3801 if (body_scope != nullptr) {
3779 body_block->set_scope(body_scope); 3802 body_block->set_scope(body_scope);
3780 } 3803 }
3781 3804
3782 // Create a TDZ for any lexically-bound names. 3805 // Create a TDZ for any lexically-bound names.
3783 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3806 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3784 DCHECK_NULL(init_block); 3807 DCHECK_NULL(init_block);
(...skipping 30 matching lines...) Expand all
3815 } 3838 }
3816 } else { 3839 } else {
3817 init = parsing_result.BuildInitializationBlock( 3840 init = parsing_result.BuildInitializationBlock(
3818 IsLexicalVariableMode(parsing_result.descriptor.mode) 3841 IsLexicalVariableMode(parsing_result.descriptor.mode)
3819 ? &lexical_bindings 3842 ? &lexical_bindings
3820 : nullptr, 3843 : nullptr,
3821 CHECK_OK); 3844 CHECK_OK);
3822 } 3845 }
3823 } else { 3846 } else {
3824 int lhs_beg_pos = peek_position(); 3847 int lhs_beg_pos = peek_position();
3825 Expression* expression = ParseExpression(false, CHECK_OK); 3848 ExpressionClassifier classifier;
3849 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3826 int lhs_end_pos = scanner()->location().end_pos; 3850 int lhs_end_pos = scanner()->location().end_pos;
3827 ForEachStatement::VisitMode mode; 3851 ForEachStatement::VisitMode mode;
3828 is_let_identifier_expression = 3852 is_let_identifier_expression =
3829 expression->IsVariableProxy() && 3853 expression->IsVariableProxy() &&
3830 expression->AsVariableProxy()->raw_name() == 3854 expression->AsVariableProxy()->raw_name() ==
3831 ast_value_factory()->let_string(); 3855 ast_value_factory()->let_string();
3832 3856
3833 if (CheckInOrOf(&mode, ok)) { 3857 if (CheckInOrOf(&mode, ok)) {
3834 if (!*ok) return nullptr; 3858 if (!*ok) return nullptr;
3835 expression = this->CheckAndRewriteReferenceExpression( 3859 bool is_destructuring =
3836 expression, lhs_beg_pos, lhs_end_pos, 3860 allow_harmony_destructuring_assignment() &&
3837 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); 3861 (expression->IsArrayLiteral() || expression->IsObjectLiteral());
3862 if (is_destructuring) {
3863 ValidateAssignmentPattern(&classifier, CHECK_OK);
3864 } else {
3865 ValidateExpression(&classifier, CHECK_OK);
3866 expression = this->CheckAndRewriteReferenceExpression(
3867 expression, lhs_beg_pos, lhs_end_pos,
3868 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3869 }
3838 3870
3839 ForEachStatement* loop = 3871 ForEachStatement* loop =
3840 factory()->NewForEachStatement(mode, labels, stmt_pos); 3872 factory()->NewForEachStatement(mode, labels, stmt_pos);
3841 Target target(&this->target_stack_, loop); 3873 Target target(&this->target_stack_, loop);
3842 3874
3843 Expression* enumerable = ParseExpression(true, CHECK_OK); 3875 Expression* enumerable = ParseExpression(true, CHECK_OK);
3844 Expect(Token::RPAREN, CHECK_OK); 3876 Expect(Token::RPAREN, CHECK_OK);
3845 3877
3846 // Make a block around the statement in case a lexical binding 3878 // Make a block around the statement in case a lexical binding
3847 // is introduced, e.g. by a FunctionDeclaration. 3879 // is introduced, e.g. by a FunctionDeclaration.
3848 // This block must not use for_scope as its scope because if a 3880 // This block must not use for_scope as its scope because if a
3849 // lexical binding is introduced which overlaps with the for-in/of, 3881 // lexical binding is introduced which overlaps with the for-in/of,
3850 // expressions in head of the loop should actually have variables 3882 // expressions in head of the loop should actually have variables
3851 // resolved in the outer scope. 3883 // resolved in the outer scope.
3852 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); 3884 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3853 scope_ = body_scope; 3885 scope_ = body_scope;
3854 Block* block = 3886 Block* block =
3855 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3887 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3856 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3888 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3857 block->statements()->Add(body, zone()); 3889 block->statements()->Add(body, zone());
3858 InitializeForEachStatement(loop, expression, enumerable, block); 3890 InitializeForEachStatement(loop, expression, enumerable, block,
3891 is_destructuring);
3859 scope_ = saved_scope; 3892 scope_ = saved_scope;
3860 body_scope->set_end_position(scanner()->location().end_pos); 3893 body_scope->set_end_position(scanner()->location().end_pos);
3861 body_scope = body_scope->FinalizeBlockScope(); 3894 body_scope = body_scope->FinalizeBlockScope();
3862 if (body_scope != nullptr) { 3895 if (body_scope != nullptr) {
3863 block->set_scope(body_scope); 3896 block->set_scope(body_scope);
3864 } 3897 }
3865 for_scope->set_end_position(scanner()->location().end_pos); 3898 for_scope->set_end_position(scanner()->location().end_pos);
3866 for_scope = for_scope->FinalizeBlockScope(); 3899 for_scope = for_scope->FinalizeBlockScope();
3867 DCHECK(for_scope == nullptr); 3900 DCHECK(for_scope == nullptr);
3868 // Parsed for-in loop. 3901 // Parsed for-in loop.
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
4548 : AstExpressionVisitor(stack_limit, root), 4581 : AstExpressionVisitor(stack_limit, root),
4549 parser_(parser), 4582 parser_(parser),
4550 scope_(scope) {} 4583 scope_(scope) {}
4551 4584
4552 private: 4585 private:
4553 void VisitExpression(Expression* expr) { 4586 void VisitExpression(Expression* expr) {
4554 RewritableAssignmentExpression* to_rewrite = 4587 RewritableAssignmentExpression* to_rewrite =
4555 expr->AsRewritableAssignmentExpression(); 4588 expr->AsRewritableAssignmentExpression();
4556 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return; 4589 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
4557 4590
4558 bool ok = true;
4559 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, 4591 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
4560 scope_, &ok); 4592 scope_);
4561 DCHECK(ok);
4562 } 4593 }
4563 4594
4564 private: 4595 private:
4565 Parser* parser_; 4596 Parser* parser_;
4566 Scope* scope_; 4597 Scope* scope_;
4567 }; 4598 };
4568 4599
4569 4600
4570 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { 4601 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
4571 InitializerRewriter rewriter(stack_limit_, expr, this, scope); 4602 InitializerRewriter rewriter(stack_limit_, expr, this, scope);
(...skipping 1951 matching lines...) Expand 10 before | Expand all | Expand 10 after
6523 func->destructuring_assignments_to_rewrite(); 6554 func->destructuring_assignments_to_rewrite();
6524 for (int i = assignments.length() - 1; i >= 0; --i) { 6555 for (int i = assignments.length() - 1; i >= 0; --i) {
6525 // Rewrite list in reverse, so that nested assignment patterns are rewritten 6556 // Rewrite list in reverse, so that nested assignment patterns are rewritten
6526 // correctly. 6557 // correctly.
6527 DestructuringAssignment pair = assignments.at(i); 6558 DestructuringAssignment pair = assignments.at(i);
6528 RewritableAssignmentExpression* to_rewrite = 6559 RewritableAssignmentExpression* to_rewrite =
6529 pair.assignment->AsRewritableAssignmentExpression(); 6560 pair.assignment->AsRewritableAssignmentExpression();
6530 Scope* scope = pair.scope; 6561 Scope* scope = pair.scope;
6531 DCHECK_NOT_NULL(to_rewrite); 6562 DCHECK_NOT_NULL(to_rewrite);
6532 if (!to_rewrite->is_rewritten()) { 6563 if (!to_rewrite->is_rewritten()) {
6533 bool ok = true; 6564 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
6534 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope,
6535 &ok);
6536 DCHECK(ok);
6537 } 6565 }
6538 } 6566 }
6539 } 6567 }
6540 6568
6541 6569
6542 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 6570 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
6543 DCHECK(expr->IsRewritableAssignmentExpression()); 6571 DCHECK(expr->IsRewritableAssignmentExpression());
6544 parser_->function_state_->AddDestructuringAssignment( 6572 parser_->function_state_->AddDestructuringAssignment(
6545 Parser::DestructuringAssignment(expr, parser_->scope_)); 6573 Parser::DestructuringAssignment(expr, parser_->scope_));
6546 } 6574 }
6547 6575
6548 6576
6549 } // namespace internal 6577 } // namespace internal
6550 } // namespace v8 6578 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698