| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/ast/ast.h" | 5 #include "src/ast/ast.h" |
| 6 #include "src/messages.h" | 6 #include "src/messages.h" |
| 7 #include "src/parsing/parameter-initializer-rewriter.h" | 7 #include "src/parsing/parameter-initializer-rewriter.h" |
| 8 #include "src/parsing/parser.h" | 8 #include "src/parsing/parser.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 Expression* expr = factory()->NewDoExpression(block_, temp, pos); | 374 Expression* expr = factory()->NewDoExpression(block_, temp, pos); |
| 375 node->Rewrite(expr); | 375 node->Rewrite(expr); |
| 376 block_ = old_block; | 376 block_ = old_block; |
| 377 if (block_) { | 377 if (block_) { |
| 378 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos), | 378 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos), |
| 379 zone()); | 379 zone()); |
| 380 } | 380 } |
| 381 return set_context(old_context); | 381 return set_context(old_context); |
| 382 } | 382 } |
| 383 | 383 |
| 384 // Two cases for scope rewriting the scope of default parameters: |
| 385 // - Eagerly parsed arrow functions are initially parsed as having |
| 386 // expressions in the enclosing scope, but when the arrow is encountered, |
| 387 // need to be in the scope of the function. |
| 388 // - When an extra declaration scope needs to be inserted to account for |
| 389 // a sloppy eval in a default parameter or function body, the expressions |
| 390 // needs to be in that new inner scope which was added after initial |
| 391 // parsing. |
| 392 // Each of these cases can be handled by rewriting the contents of the |
| 393 // expression to the current scope. The source scope is typically the outer |
| 394 // scope when one case occurs; when both cases occur, both scopes need to |
| 395 // be included as the outer scope. (Both rewritings still need to be done |
| 396 // to account for lazily parsed arrow functions which hit the second case.) |
| 397 // TODO(littledan): Remove the outer_scope parameter of |
| 398 // RewriteParameterInitializerScope |
| 399 void Parser::PatternRewriter::RewriteParameterScopes(Expression* expr) { |
| 400 if (!IsBindingContext()) return; |
| 401 if (descriptor_->declaration_kind != DeclarationDescriptor::PARAMETER) return; |
| 402 if (!scope()->is_arrow_scope() && !scope()->is_block_scope()) return; |
| 403 |
| 404 // Either this scope is an arrow scope or a declaration block scope. |
| 405 DCHECK(scope()->is_declaration_scope()); |
| 406 |
| 407 if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) { |
| 408 RewriteParameterInitializerScope(parser_->stack_limit(), expr, |
| 409 scope()->outer_scope()->outer_scope(), |
| 410 scope()); |
| 411 } |
| 412 RewriteParameterInitializerScope(parser_->stack_limit(), expr, |
| 413 scope()->outer_scope(), scope()); |
| 414 } |
| 384 | 415 |
| 385 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern, | 416 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern, |
| 386 Variable** temp_var) { | 417 Variable** temp_var) { |
| 387 auto temp = *temp_var = CreateTempVar(current_value_); | 418 auto temp = *temp_var = CreateTempVar(current_value_); |
| 388 | 419 |
| 389 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); | 420 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone()); |
| 390 | 421 |
| 391 for (ObjectLiteralProperty* property : *pattern->properties()) { | 422 for (ObjectLiteralProperty* property : *pattern->properties()) { |
| 392 PatternContext context = SetInitializerContextIfNeeded(property->value()); | 423 PatternContext context = SetInitializerContextIfNeeded(property->value()); |
| 424 |
| 425 // Computed property names contain expressions which might require |
| 426 // scope rewriting. |
| 427 if (!property->key()->IsLiteral()) RewriteParameterScopes(property->key()); |
| 428 |
| 393 RecurseIntoSubpattern( | 429 RecurseIntoSubpattern( |
| 394 property->value(), | 430 property->value(), |
| 395 factory()->NewProperty(factory()->NewVariableProxy(temp), | 431 factory()->NewProperty(factory()->NewVariableProxy(temp), |
| 396 property->key(), RelocInfo::kNoPosition)); | 432 property->key(), RelocInfo::kNoPosition)); |
| 397 set_context(context); | 433 set_context(context); |
| 398 } | 434 } |
| 399 } | 435 } |
| 400 | 436 |
| 401 | 437 |
| 402 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { | 438 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 if (IsInitializerContext()) { | 706 if (IsInitializerContext()) { |
| 671 Expression* is_undefined = factory()->NewCompareOperation( | 707 Expression* is_undefined = factory()->NewCompareOperation( |
| 672 Token::EQ_STRICT, factory()->NewVariableProxy(temp), | 708 Token::EQ_STRICT, factory()->NewVariableProxy(temp), |
| 673 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 709 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
| 674 RelocInfo::kNoPosition); | 710 RelocInfo::kNoPosition); |
| 675 value = factory()->NewConditional(is_undefined, initializer, | 711 value = factory()->NewConditional(is_undefined, initializer, |
| 676 factory()->NewVariableProxy(temp), | 712 factory()->NewVariableProxy(temp), |
| 677 RelocInfo::kNoPosition); | 713 RelocInfo::kNoPosition); |
| 678 } | 714 } |
| 679 | 715 |
| 680 // Two cases for scope rewriting the scope of default parameters: | 716 // Initializer may have been parsed in the wrong scope. |
| 681 // - Eagerly parsed arrow functions are initially parsed as having | 717 RewriteParameterScopes(initializer); |
| 682 // initializers in the enclosing scope, but when the arrow is encountered, | |
| 683 // need to be in the scope of the function. | |
| 684 // - When an extra declaration scope needs to be inserted to account for | |
| 685 // a sloppy eval in a default parameter or function body, the initializer | |
| 686 // needs to be in that new inner scope which was added after initial | |
| 687 // parsing. | |
| 688 // Each of these cases can be handled by rewriting the contents of the | |
| 689 // initializer to the current scope. The source scope is typically the outer | |
| 690 // scope when one case occurs; when both cases occur, both scopes need to | |
| 691 // be included as the outer scope. (Both rewritings still need to be done | |
| 692 // to account for lazily parsed arrow functions which hit the second case.) | |
| 693 // TODO(littledan): Remove the outer_scope parameter of | |
| 694 // RewriteParameterInitializerScope | |
| 695 if (IsBindingContext() && | |
| 696 descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER && | |
| 697 (scope()->is_arrow_scope() || scope()->is_block_scope())) { | |
| 698 if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) { | |
| 699 RewriteParameterInitializerScope(parser_->stack_limit(), initializer, | |
| 700 scope()->outer_scope()->outer_scope(), | |
| 701 scope()); | |
| 702 } | |
| 703 RewriteParameterInitializerScope(parser_->stack_limit(), initializer, | |
| 704 scope()->outer_scope(), scope()); | |
| 705 } | |
| 706 | 718 |
| 707 PatternContext old_context = SetAssignmentContextIfNeeded(initializer); | 719 PatternContext old_context = SetAssignmentContextIfNeeded(initializer); |
| 708 RecurseIntoSubpattern(node->target(), value); | 720 RecurseIntoSubpattern(node->target(), value); |
| 709 set_context(old_context); | 721 set_context(old_context); |
| 710 } | 722 } |
| 711 | 723 |
| 712 | 724 |
| 713 // =============== AssignmentPattern only ================== | 725 // =============== AssignmentPattern only ================== |
| 714 | 726 |
| 715 void Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) { | 727 void Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 NOT_A_PATTERN(TryFinallyStatement) | 787 NOT_A_PATTERN(TryFinallyStatement) |
| 776 NOT_A_PATTERN(UnaryOperation) | 788 NOT_A_PATTERN(UnaryOperation) |
| 777 NOT_A_PATTERN(VariableDeclaration) | 789 NOT_A_PATTERN(VariableDeclaration) |
| 778 NOT_A_PATTERN(WhileStatement) | 790 NOT_A_PATTERN(WhileStatement) |
| 779 NOT_A_PATTERN(WithStatement) | 791 NOT_A_PATTERN(WithStatement) |
| 780 NOT_A_PATTERN(Yield) | 792 NOT_A_PATTERN(Yield) |
| 781 | 793 |
| 782 #undef NOT_A_PATTERN | 794 #undef NOT_A_PATTERN |
| 783 } // namespace internal | 795 } // namespace internal |
| 784 } // namespace v8 | 796 } // namespace v8 |
| OLD | NEW |