| 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 |