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