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 |