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