| Index: src/parsing/pattern-rewriter.cc
|
| diff --git a/src/parsing/pattern-rewriter.cc b/src/parsing/pattern-rewriter.cc
|
| index 808c0c096458cf7aa0f0c8a0809b5abe7e4e3423..3dcff983c4ff0d93f85e454090269d79a8939bcd 100644
|
| --- a/src/parsing/pattern-rewriter.cc
|
| +++ b/src/parsing/pattern-rewriter.cc
|
| @@ -381,6 +381,37 @@ void Parser::PatternRewriter::VisitRewritableExpression(
|
| return set_context(old_context);
|
| }
|
|
|
| +// Two cases for scope rewriting the scope of default parameters:
|
| +// - Eagerly parsed arrow functions are initially parsed as having
|
| +// expressions in the enclosing scope, but when the arrow is encountered,
|
| +// need to be in the scope of the function.
|
| +// - When an extra declaration scope needs to be inserted to account for
|
| +// a sloppy eval in a default parameter or function body, the expressions
|
| +// needs to be in that new inner scope which was added after initial
|
| +// parsing.
|
| +// Each of these cases can be handled by rewriting the contents of the
|
| +// expression to the current scope. The source scope is typically the outer
|
| +// scope when one case occurs; when both cases occur, both scopes need to
|
| +// be included as the outer scope. (Both rewritings still need to be done
|
| +// to account for lazily parsed arrow functions which hit the second case.)
|
| +// TODO(littledan): Remove the outer_scope parameter of
|
| +// RewriteParameterInitializerScope
|
| +void Parser::PatternRewriter::RewriteParameterScopes(Expression* expr) {
|
| + if (!IsBindingContext()) return;
|
| + if (descriptor_->declaration_kind != DeclarationDescriptor::PARAMETER) return;
|
| + if (!scope()->is_arrow_scope() && !scope()->is_block_scope()) return;
|
| +
|
| + // Either this scope is an arrow scope or a declaration block scope.
|
| + DCHECK(scope()->is_declaration_scope());
|
| +
|
| + if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) {
|
| + RewriteParameterInitializerScope(parser_->stack_limit(), expr,
|
| + scope()->outer_scope()->outer_scope(),
|
| + scope());
|
| + }
|
| + RewriteParameterInitializerScope(parser_->stack_limit(), expr,
|
| + scope()->outer_scope(), scope());
|
| +}
|
|
|
| void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
|
| Variable** temp_var) {
|
| @@ -390,6 +421,11 @@ void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
|
|
|
| for (ObjectLiteralProperty* property : *pattern->properties()) {
|
| PatternContext context = SetInitializerContextIfNeeded(property->value());
|
| +
|
| + // Computed property names contain expressions which might require
|
| + // scope rewriting.
|
| + if (!property->key()->IsLiteral()) RewriteParameterScopes(property->key());
|
| +
|
| RecurseIntoSubpattern(
|
| property->value(),
|
| factory()->NewProperty(factory()->NewVariableProxy(temp),
|
| @@ -677,32 +713,8 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
|
| RelocInfo::kNoPosition);
|
| }
|
|
|
| - // Two cases for scope rewriting the scope of default parameters:
|
| - // - Eagerly parsed arrow functions are initially parsed as having
|
| - // initializers in the enclosing scope, but when the arrow is encountered,
|
| - // need to be in the scope of the function.
|
| - // - When an extra declaration scope needs to be inserted to account for
|
| - // a sloppy eval in a default parameter or function body, the initializer
|
| - // needs to be in that new inner scope which was added after initial
|
| - // parsing.
|
| - // Each of these cases can be handled by rewriting the contents of the
|
| - // initializer to the current scope. The source scope is typically the outer
|
| - // scope when one case occurs; when both cases occur, both scopes need to
|
| - // be included as the outer scope. (Both rewritings still need to be done
|
| - // to account for lazily parsed arrow functions which hit the second case.)
|
| - // TODO(littledan): Remove the outer_scope parameter of
|
| - // RewriteParameterInitializerScope
|
| - if (IsBindingContext() &&
|
| - descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
|
| - (scope()->is_arrow_scope() || scope()->is_block_scope())) {
|
| - if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) {
|
| - RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
|
| - scope()->outer_scope()->outer_scope(),
|
| - scope());
|
| - }
|
| - RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
|
| - scope()->outer_scope(), scope());
|
| - }
|
| + // Initializer may have been parsed in the wrong scope.
|
| + RewriteParameterScopes(initializer);
|
|
|
| PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
|
| RecurseIntoSubpattern(node->target(), value);
|
|
|