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 ForOfStatement* for_of = stmt->AsForOfStatement(); | 3332 ForOfStatement* for_of = stmt->AsForOfStatement(); |
3333 | 3333 |
3334 if (for_of != NULL) { | 3334 if (for_of != NULL) { |
3335 Variable* iterator = scope_->NewTemporary( | 3335 Variable* iterator = scope_->NewTemporary( |
3336 ast_value_factory()->dot_iterator_string()); | 3336 ast_value_factory()->dot_iterator_string()); |
3337 Variable* result = scope_->NewTemporary( | 3337 Variable* result = scope_->NewTemporary( |
3338 ast_value_factory()->dot_result_string()); | 3338 ast_value_factory()->dot_result_string()); |
3339 | 3339 |
3340 Expression* assign_iterator; | 3340 Expression* assign_iterator; |
3341 Expression* next_result; | 3341 Expression* next_result; |
(...skipping 30 matching lines...) Expand all Loading... | |
3372 | 3372 |
3373 // each = result.value | 3373 // each = result.value |
3374 { | 3374 { |
3375 Expression* value_literal = factory()->NewStringLiteral( | 3375 Expression* value_literal = factory()->NewStringLiteral( |
3376 ast_value_factory()->value_string(), RelocInfo::kNoPosition); | 3376 ast_value_factory()->value_string(), RelocInfo::kNoPosition); |
3377 Expression* result_proxy = factory()->NewVariableProxy(result); | 3377 Expression* result_proxy = factory()->NewVariableProxy(result); |
3378 Expression* result_value = factory()->NewProperty( | 3378 Expression* result_value = factory()->NewProperty( |
3379 result_proxy, value_literal, RelocInfo::kNoPosition); | 3379 result_proxy, value_literal, RelocInfo::kNoPosition); |
3380 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, | 3380 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, |
3381 RelocInfo::kNoPosition); | 3381 RelocInfo::kNoPosition); |
3382 if (is_destructuring) { | |
3383 DCHECK(allow_harmony_destructuring_assignment()); | |
3384 bool ok = true; | |
3385 auto rewrite = | |
3386 factory()->NewRewritableAssignmentExpression(assign_each); | |
adamk
2015/12/10 17:28:03
Making the callers here and below construct a Rewr
caitp (gmail)
2015/12/10 18:19:35
Done
| |
3387 PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_, | |
3388 &ok); | |
3389 DCHECK(ok); | |
adamk
2015/12/10 17:28:03
It looks like all callers of RewriteDestructuringA
caitp (gmail)
2015/12/10 18:19:36
Done.
| |
3390 assign_each = rewrite->expression(); | |
3391 } | |
3382 } | 3392 } |
3383 | 3393 |
3384 for_of->Initialize(each, subject, body, | 3394 for_of->Initialize(each, subject, body, |
3385 assign_iterator, | 3395 assign_iterator, |
3386 next_result, | 3396 next_result, |
3387 result_done, | 3397 result_done, |
3388 assign_each); | 3398 assign_each); |
3389 } else { | 3399 } else { |
3400 if (is_destructuring) { | |
3401 Variable* temp = | |
3402 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | |
adamk
2015/12/10 17:28:03
dot_result_string has a special usage (for complet
caitp (gmail)
2015/12/10 18:19:36
I think this is the completion-correct model, and
adamk
2015/12/10 19:23:33
If there's a reason for it to be .result, I'd expe
| |
3403 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | |
3404 bool ok = true; | |
3405 auto rewrite = | |
3406 factory()->NewRewritableAssignmentExpression(factory()->NewAssignment( | |
3407 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition)); | |
3408 PatternRewriter::RewriteDestructuringAssignment(this, rewrite, scope_, | |
3409 &ok); | |
3410 DCHECK(ok); | |
3411 auto block = | |
3412 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition); | |
3413 block->statements()->Add( | |
3414 factory()->NewExpressionStatement(rewrite->expression(), | |
3415 RelocInfo::kNoPosition), | |
3416 zone()); | |
3417 block->statements()->Add(body, zone()); | |
3418 body = block; | |
3419 each = factory()->NewVariableProxy(temp); | |
3420 } | |
3390 stmt->Initialize(each, subject, body); | 3421 stmt->Initialize(each, subject, body); |
3391 } | 3422 } |
3392 } | 3423 } |
3393 | 3424 |
3394 | 3425 |
3395 Statement* Parser::DesugarLexicalBindingsInForStatement( | 3426 Statement* Parser::DesugarLexicalBindingsInForStatement( |
3396 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, | 3427 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, |
3397 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 3428 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
3398 Statement* body, bool* ok) { | 3429 Statement* body, bool* ok) { |
3399 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 3430 // 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, | 3795 each_initialization_block, &descriptor, &decl, |
3765 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings | 3796 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings |
3766 : nullptr, | 3797 : nullptr, |
3767 CHECK_OK); | 3798 CHECK_OK); |
3768 } | 3799 } |
3769 | 3800 |
3770 body_block->statements()->Add(each_initialization_block, zone()); | 3801 body_block->statements()->Add(each_initialization_block, zone()); |
3771 body_block->statements()->Add(body, zone()); | 3802 body_block->statements()->Add(body, zone()); |
3772 VariableProxy* temp_proxy = | 3803 VariableProxy* temp_proxy = |
3773 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | 3804 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
3774 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 3805 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, |
3806 false); | |
3775 scope_ = for_scope; | 3807 scope_ = for_scope; |
3776 body_scope->set_end_position(scanner()->location().end_pos); | 3808 body_scope->set_end_position(scanner()->location().end_pos); |
3777 body_scope = body_scope->FinalizeBlockScope(); | 3809 body_scope = body_scope->FinalizeBlockScope(); |
3778 if (body_scope != nullptr) { | 3810 if (body_scope != nullptr) { |
3779 body_block->set_scope(body_scope); | 3811 body_block->set_scope(body_scope); |
3780 } | 3812 } |
3781 | 3813 |
3782 // Create a TDZ for any lexically-bound names. | 3814 // Create a TDZ for any lexically-bound names. |
3783 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { | 3815 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { |
3784 DCHECK_NULL(init_block); | 3816 DCHECK_NULL(init_block); |
(...skipping 30 matching lines...) Expand all Loading... | |
3815 } | 3847 } |
3816 } else { | 3848 } else { |
3817 init = parsing_result.BuildInitializationBlock( | 3849 init = parsing_result.BuildInitializationBlock( |
3818 IsLexicalVariableMode(parsing_result.descriptor.mode) | 3850 IsLexicalVariableMode(parsing_result.descriptor.mode) |
3819 ? &lexical_bindings | 3851 ? &lexical_bindings |
3820 : nullptr, | 3852 : nullptr, |
3821 CHECK_OK); | 3853 CHECK_OK); |
3822 } | 3854 } |
3823 } else { | 3855 } else { |
3824 int lhs_beg_pos = peek_position(); | 3856 int lhs_beg_pos = peek_position(); |
3825 Expression* expression = ParseExpression(false, CHECK_OK); | 3857 ExpressionClassifier classifier; |
3858 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | |
3826 int lhs_end_pos = scanner()->location().end_pos; | 3859 int lhs_end_pos = scanner()->location().end_pos; |
3827 ForEachStatement::VisitMode mode; | 3860 ForEachStatement::VisitMode mode; |
3828 is_let_identifier_expression = | 3861 is_let_identifier_expression = |
3829 expression->IsVariableProxy() && | 3862 expression->IsVariableProxy() && |
3830 expression->AsVariableProxy()->raw_name() == | 3863 expression->AsVariableProxy()->raw_name() == |
3831 ast_value_factory()->let_string(); | 3864 ast_value_factory()->let_string(); |
3832 | 3865 |
3833 if (CheckInOrOf(&mode, ok)) { | 3866 if (CheckInOrOf(&mode, ok)) { |
3834 if (!*ok) return nullptr; | 3867 if (!*ok) return nullptr; |
3835 expression = this->CheckAndRewriteReferenceExpression( | 3868 bool is_destructuring = |
3836 expression, lhs_beg_pos, lhs_end_pos, | 3869 allow_harmony_destructuring_assignment() && |
3837 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); | 3870 (expression->IsArrayLiteral() || expression->IsObjectLiteral()); |
3871 if (is_destructuring) { | |
3872 ValidateAssignmentPattern(&classifier, CHECK_OK); | |
3873 } else { | |
3874 ValidateExpression(&classifier, CHECK_OK); | |
3875 expression = this->CheckAndRewriteReferenceExpression( | |
3876 expression, lhs_beg_pos, lhs_end_pos, | |
3877 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); | |
3878 } | |
3838 | 3879 |
3839 ForEachStatement* loop = | 3880 ForEachStatement* loop = |
3840 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3881 factory()->NewForEachStatement(mode, labels, stmt_pos); |
3841 Target target(&this->target_stack_, loop); | 3882 Target target(&this->target_stack_, loop); |
3842 | 3883 |
3843 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3884 Expression* enumerable = ParseExpression(true, CHECK_OK); |
3844 Expect(Token::RPAREN, CHECK_OK); | 3885 Expect(Token::RPAREN, CHECK_OK); |
3845 | 3886 |
3846 // Make a block around the statement in case a lexical binding | 3887 // Make a block around the statement in case a lexical binding |
3847 // is introduced, e.g. by a FunctionDeclaration. | 3888 // is introduced, e.g. by a FunctionDeclaration. |
3848 // This block must not use for_scope as its scope because if a | 3889 // 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, | 3890 // lexical binding is introduced which overlaps with the for-in/of, |
3850 // expressions in head of the loop should actually have variables | 3891 // expressions in head of the loop should actually have variables |
3851 // resolved in the outer scope. | 3892 // resolved in the outer scope. |
3852 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); | 3893 Scope* body_scope = NewScope(for_scope, BLOCK_SCOPE); |
3853 scope_ = body_scope; | 3894 scope_ = body_scope; |
3854 Block* block = | 3895 Block* block = |
3855 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 3896 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
3856 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3897 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
3857 block->statements()->Add(body, zone()); | 3898 block->statements()->Add(body, zone()); |
3858 InitializeForEachStatement(loop, expression, enumerable, block); | 3899 InitializeForEachStatement(loop, expression, enumerable, block, |
3900 is_destructuring); | |
3859 scope_ = saved_scope; | 3901 scope_ = saved_scope; |
3860 body_scope->set_end_position(scanner()->location().end_pos); | 3902 body_scope->set_end_position(scanner()->location().end_pos); |
3861 body_scope = body_scope->FinalizeBlockScope(); | 3903 body_scope = body_scope->FinalizeBlockScope(); |
3862 if (body_scope != nullptr) { | 3904 if (body_scope != nullptr) { |
3863 block->set_scope(body_scope); | 3905 block->set_scope(body_scope); |
3864 } | 3906 } |
3865 for_scope->set_end_position(scanner()->location().end_pos); | 3907 for_scope->set_end_position(scanner()->location().end_pos); |
3866 for_scope = for_scope->FinalizeBlockScope(); | 3908 for_scope = for_scope->FinalizeBlockScope(); |
3867 DCHECK(for_scope == nullptr); | 3909 DCHECK(for_scope == nullptr); |
3868 // Parsed for-in loop. | 3910 // Parsed for-in loop. |
(...skipping 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6541 | 6583 |
6542 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 6584 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
6543 DCHECK(expr->IsRewritableAssignmentExpression()); | 6585 DCHECK(expr->IsRewritableAssignmentExpression()); |
6544 parser_->function_state_->AddDestructuringAssignment( | 6586 parser_->function_state_->AddDestructuringAssignment( |
6545 Parser::DestructuringAssignment(expr, parser_->scope_)); | 6587 Parser::DestructuringAssignment(expr, parser_->scope_)); |
6546 } | 6588 } |
6547 | 6589 |
6548 | 6590 |
6549 } // namespace internal | 6591 } // namespace internal |
6550 } // namespace v8 | 6592 } // namespace v8 |
OLD | NEW |