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); |