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

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: Don't reuse VariableProxy ast node 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 ForOfStatement* for_of = stmt->AsForOfStatement(); 3332 ForOfStatement* for_of = stmt->AsForOfStatement();
3333 3333
3334 if (for_of != NULL) { 3334 if (for_of != NULL) {
3335 Variable* iterator = scope_->NewTemporary( 3335 Variable* iterator = scope_->NewTemporary(
3336 ast_value_factory()->dot_iterator_string()); 3336 ast_value_factory()->dot_iterator_string());
3337 Variable* result = scope_->NewTemporary( 3337 Variable* result = scope_->NewTemporary(
3338 ast_value_factory()->dot_result_string()); 3338 ast_value_factory()->dot_result_string());
3339 3339
3340 Expression* assign_iterator; 3340 Expression* assign_iterator;
3341 Expression* next_result; 3341 Expression* next_result;
(...skipping 30 matching lines...) Expand all
3372 3372
3373 // each = result.value 3373 // each = result.value
3374 { 3374 {
3375 Expression* value_literal = factory()->NewStringLiteral( 3375 Expression* value_literal = factory()->NewStringLiteral(
3376 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 3376 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3377 Expression* result_proxy = factory()->NewVariableProxy(result); 3377 Expression* result_proxy = factory()->NewVariableProxy(result);
3378 Expression* result_value = factory()->NewProperty( 3378 Expression* result_value = factory()->NewProperty(
3379 result_proxy, value_literal, RelocInfo::kNoPosition); 3379 result_proxy, value_literal, RelocInfo::kNoPosition);
3380 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3380 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3381 RelocInfo::kNoPosition); 3381 RelocInfo::kNoPosition);
3382 if (is_destructuring) {
3383 DCHECK(allow_harmony_destructuring_assignment());
3384 bool ok = true;
3385 auto rewrite =
3386 factory()->NewRewritableAssignmentExpression(assign_each);
adamk 2015/12/10 17:28:03 Making the callers here and below construct a Rewr
caitp (gmail) 2015/12/10 18:19:35 Done
3387 PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_,
3388 &ok);
3389 DCHECK(ok);
adamk 2015/12/10 17:28:03 It looks like all callers of RewriteDestructuringA
caitp (gmail) 2015/12/10 18:19:36 Done.
3390 assign_each = rewrite->expression();
3391 }
3382 } 3392 }
3383 3393
3384 for_of->Initialize(each, subject, body, 3394 for_of->Initialize(each, subject, body,
3385 assign_iterator, 3395 assign_iterator,
3386 next_result, 3396 next_result,
3387 result_done, 3397 result_done,
3388 assign_each); 3398 assign_each);
3389 } else { 3399 } else {
3400 if (is_destructuring) {
3401 Variable* temp =
3402 scope_->NewTemporary(ast_value_factory()->dot_result_string());
adamk 2015/12/10 17:28:03 dot_result_string has a special usage (for complet
caitp (gmail) 2015/12/10 18:19:36 I think this is the completion-correct model, and
adamk 2015/12/10 19:23:33 If there's a reason for it to be .result, I'd expe
3403 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3404 bool ok = true;
3405 auto rewrite =
3406 factory()->NewRewritableAssignmentExpression(factory()->NewAssignment(
3407 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition));
3408 PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_,
3409 &ok);
3410 DCHECK(ok);
3411 auto block =
3412 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition);
3413 block->statements()->Add(
3414 factory()->NewExpressionStatement(rewrite->expression(),
3415 RelocInfo::kNoPosition),
3416 zone());
3417 block->statements()->Add(body, zone());
3418 body = block;
3419 each = factory()->NewVariableProxy(temp);
3420 }
3390 stmt->Initialize(each, subject, body); 3421 stmt->Initialize(each, subject, body);
3391 } 3422 }
3392 } 3423 }
3393 3424
3394 3425
3395 Statement* Parser::DesugarLexicalBindingsInForStatement( 3426 Statement* Parser::DesugarLexicalBindingsInForStatement(
3396 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3427 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3397 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3428 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3398 Statement* body, bool* ok) { 3429 Statement* body, bool* ok) {
3399 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 3430 // 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, 3795 each_initialization_block, &descriptor, &decl,
3765 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3796 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
3766 : nullptr, 3797 : nullptr,
3767 CHECK_OK); 3798 CHECK_OK);
3768 } 3799 }
3769 3800
3770 body_block->statements()->Add(each_initialization_block, zone()); 3801 body_block->statements()->Add(each_initialization_block, zone());
3771 body_block->statements()->Add(body, zone()); 3802 body_block->statements()->Add(body, zone());
3772 VariableProxy* temp_proxy = 3803 VariableProxy* temp_proxy =
3773 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3804 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3774 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); 3805 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
3806 false);
3775 scope_ = for_scope; 3807 scope_ = for_scope;
3776 body_scope->set_end_position(scanner()->location().end_pos); 3808 body_scope->set_end_position(scanner()->location().end_pos);
3777 body_scope = body_scope->FinalizeBlockScope(); 3809 body_scope = body_scope->FinalizeBlockScope();
3778 if (body_scope != nullptr) { 3810 if (body_scope != nullptr) {
3779 body_block->set_scope(body_scope); 3811 body_block->set_scope(body_scope);
3780 } 3812 }
3781 3813
3782 // Create a TDZ for any lexically-bound names. 3814 // Create a TDZ for any lexically-bound names.
3783 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3815 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
3784 DCHECK_NULL(init_block); 3816 DCHECK_NULL(init_block);
(...skipping 30 matching lines...) Expand all
3815 } 3847 }
3816 } else { 3848 } else {
3817 init = parsing_result.BuildInitializationBlock( 3849 init = parsing_result.BuildInitializationBlock(
3818 IsLexicalVariableMode(parsing_result.descriptor.mode) 3850 IsLexicalVariableMode(parsing_result.descriptor.mode)
3819 ? &lexical_bindings 3851 ? &lexical_bindings
3820 : nullptr, 3852 : nullptr,
3821 CHECK_OK); 3853 CHECK_OK);
3822 } 3854 }
3823 } else { 3855 } else {
3824 int lhs_beg_pos = peek_position(); 3856 int lhs_beg_pos = peek_position();
3825 Expression* expression = ParseExpression(false, CHECK_OK); 3857 ExpressionClassifier classifier;
3858 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3826 int lhs_end_pos = scanner()->location().end_pos; 3859 int lhs_end_pos = scanner()->location().end_pos;
3827 ForEachStatement::VisitMode mode; 3860 ForEachStatement::VisitMode mode;
3828 is_let_identifier_expression = 3861 is_let_identifier_expression =
3829 expression->IsVariableProxy() && 3862 expression->IsVariableProxy() &&
3830 expression->AsVariableProxy()->raw_name() == 3863 expression->AsVariableProxy()->raw_name() ==
3831 ast_value_factory()->let_string(); 3864 ast_value_factory()->let_string();
3832 3865
3833 if (CheckInOrOf(&mode, ok)) { 3866 if (CheckInOrOf(&mode, ok)) {
3834 if (!*ok) return nullptr; 3867 if (!*ok) return nullptr;
3835 expression = this->CheckAndRewriteReferenceExpression( 3868 bool is_destructuring =
3836 expression, lhs_beg_pos, lhs_end_pos, 3869 allow_harmony_destructuring_assignment() &&
3837 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); 3870 (expression->IsArrayLiteral() || expression->IsObjectLiteral());
3871 if (is_destructuring) {
3872 ValidateAssignmentPattern(&classifier, CHECK_OK);
3873 } else {
3874 ValidateExpression(&classifier, CHECK_OK);
3875 expression = this->CheckAndRewriteReferenceExpression(
3876 expression, lhs_beg_pos, lhs_end_pos,
3877 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
3878 }
3838 3879
3839 ForEachStatement* loop = 3880 ForEachStatement* loop =
3840 factory()->NewForEachStatement(mode, labels, stmt_pos); 3881 factory()->NewForEachStatement(mode, labels, stmt_pos);
3841 Target target(&this->target_stack_, loop); 3882 Target target(&this->target_stack_, loop);
3842 3883
3843 Expression* enumerable = ParseExpression(true, CHECK_OK); 3884 Expression* enumerable = ParseExpression(true, CHECK_OK);
3844 Expect(Token::RPAREN, CHECK_OK); 3885 Expect(Token::RPAREN, CHECK_OK);
3845 3886
3846 // Make a block around the statement in case a lexical binding 3887 // Make a block around the statement in case a lexical binding
3847 // is introduced, e.g. by a FunctionDeclaration. 3888 // is introduced, e.g. by a FunctionDeclaration.
3848 // This block must not use for_scope as its scope because if a 3889 // 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, 3890 // lexical binding is introduced which overlaps with the for-in/of,
3850 // expressions in head of the loop should actually have variables 3891 // expressions in head of the loop should actually have variables
3851 // resolved in the outer scope. 3892 // resolved in the outer scope.
3852 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); 3893 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE);
3853 scope_ = body_scope; 3894 scope_ = body_scope;
3854 Block* block = 3895 Block* block =
3855 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3896 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3856 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3897 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3857 block->statements()->Add(body, zone()); 3898 block->statements()->Add(body, zone());
3858 InitializeForEachStatement(loop, expression, enumerable, block); 3899 InitializeForEachStatement(loop, expression, enumerable, block,
3900 is_destructuring);
3859 scope_ = saved_scope; 3901 scope_ = saved_scope;
3860 body_scope->set_end_position(scanner()->location().end_pos); 3902 body_scope->set_end_position(scanner()->location().end_pos);
3861 body_scope = body_scope->FinalizeBlockScope(); 3903 body_scope = body_scope->FinalizeBlockScope();
3862 if (body_scope != nullptr) { 3904 if (body_scope != nullptr) {
3863 block->set_scope(body_scope); 3905 block->set_scope(body_scope);
3864 } 3906 }
3865 for_scope->set_end_position(scanner()->location().end_pos); 3907 for_scope->set_end_position(scanner()->location().end_pos);
3866 for_scope = for_scope->FinalizeBlockScope(); 3908 for_scope = for_scope->FinalizeBlockScope();
3867 DCHECK(for_scope == nullptr); 3909 DCHECK(for_scope == nullptr);
3868 // Parsed for-in loop. 3910 // Parsed for-in loop.
(...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after
6541 6583
6542 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 6584 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
6543 DCHECK(expr->IsRewritableAssignmentExpression()); 6585 DCHECK(expr->IsRewritableAssignmentExpression());
6544 parser_->function_state_->AddDestructuringAssignment( 6586 parser_->function_state_->AddDestructuringAssignment(
6545 Parser::DestructuringAssignment(expr, parser_->scope_)); 6587 Parser::DestructuringAssignment(expr, parser_->scope_));
6546 } 6588 }
6547 6589
6548 6590
6549 } // namespace internal 6591 } // namespace internal
6550 } // namespace v8 6592 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/preparser.cc » ('j') | src/parsing/preparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698