| 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 3308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |