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 |