Skip to content

Commit e60cafd

Browse files
committed
deps: backport f795a79 from upstream V8
Original commit message: Rewrite scopes in computed properties in destructured parameters While we properly handled scopes of initializers in destructured parameters, we never did the right thing for computed properties. This patch fixes that by factoring out PatternRewriter's scope rewriting logic and calls it for the computed property case. BUG=chromium:620119 Review-Url: https://codereview.chromium.org/2084103002 Cr-Commit-Position: refs/heads/master@{#37228} Fixes: #10347 PR-URL: #10386 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 272a971 commit e60cafd

File tree

3 files changed

+48
-26
lines changed

3 files changed

+48
-26
lines changed

deps/v8/src/parsing/parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,8 @@ class Parser : public ParserBase<ParserTraits> {
880880
PatternContext SetAssignmentContextIfNeeded(Expression* node);
881881
PatternContext SetInitializerContextIfNeeded(Expression* node);
882882

883+
void RewriteParameterScopes(Expression* expr);
884+
883885
Variable* CreateTempVar(Expression* value = nullptr);
884886

885887
AstNodeFactory* factory() const { return parser_->factory(); }

deps/v8/src/parsing/pattern-rewriter.cc

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,37 @@ void Parser::PatternRewriter::VisitRewritableExpression(
387387
return set_context(old_context);
388388
}
389389

390+
// Two cases for scope rewriting the scope of default parameters:
391+
// - Eagerly parsed arrow functions are initially parsed as having
392+
// expressions in the enclosing scope, but when the arrow is encountered,
393+
// need to be in the scope of the function.
394+
// - When an extra declaration scope needs to be inserted to account for
395+
// a sloppy eval in a default parameter or function body, the expressions
396+
// needs to be in that new inner scope which was added after initial
397+
// parsing.
398+
// Each of these cases can be handled by rewriting the contents of the
399+
// expression to the current scope. The source scope is typically the outer
400+
// scope when one case occurs; when both cases occur, both scopes need to
401+
// be included as the outer scope. (Both rewritings still need to be done
402+
// to account for lazily parsed arrow functions which hit the second case.)
403+
// TODO(littledan): Remove the outer_scope parameter of
404+
// RewriteParameterInitializerScope
405+
void Parser::PatternRewriter::RewriteParameterScopes(Expression* expr) {
406+
if (!IsBindingContext()) return;
407+
if (descriptor_->declaration_kind != DeclarationDescriptor::PARAMETER) return;
408+
if (!scope()->is_arrow_scope() && !scope()->is_block_scope()) return;
409+
410+
// Either this scope is an arrow scope or a declaration block scope.
411+
DCHECK(scope()->is_declaration_scope());
412+
413+
if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) {
414+
RewriteParameterInitializerScope(parser_->stack_limit(), expr,
415+
scope()->outer_scope()->outer_scope(),
416+
scope());
417+
}
418+
RewriteParameterInitializerScope(parser_->stack_limit(), expr,
419+
scope()->outer_scope(), scope());
420+
}
390421

391422
void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
392423
Variable** temp_var) {
@@ -396,6 +427,11 @@ void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
396427

397428
for (ObjectLiteralProperty* property : *pattern->properties()) {
398429
PatternContext context = SetInitializerContextIfNeeded(property->value());
430+
431+
// Computed property names contain expressions which might require
432+
// scope rewriting.
433+
if (!property->key()->IsLiteral()) RewriteParameterScopes(property->key());
434+
399435
RecurseIntoSubpattern(
400436
property->value(),
401437
factory()->NewProperty(factory()->NewVariableProxy(temp),
@@ -668,32 +704,8 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
668704
RelocInfo::kNoPosition);
669705
}
670706

671-
// Two cases for scope rewriting the scope of default parameters:
672-
// - Eagerly parsed arrow functions are initially parsed as having
673-
// initializers in the enclosing scope, but when the arrow is encountered,
674-
// need to be in the scope of the function.
675-
// - When an extra declaration scope needs to be inserted to account for
676-
// a sloppy eval in a default parameter or function body, the initializer
677-
// needs to be in that new inner scope which was added after initial
678-
// parsing.
679-
// Each of these cases can be handled by rewriting the contents of the
680-
// initializer to the current scope. The source scope is typically the outer
681-
// scope when one case occurs; when both cases occur, both scopes need to
682-
// be included as the outer scope. (Both rewritings still need to be done
683-
// to account for lazily parsed arrow functions which hit the second case.)
684-
// TODO(littledan): Remove the outer_scope parameter of
685-
// RewriteParameterInitializerScope
686-
if (IsBindingContext() &&
687-
descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
688-
(scope()->is_arrow_scope() || scope()->is_block_scope())) {
689-
if (scope()->outer_scope()->is_arrow_scope() && scope()->is_block_scope()) {
690-
RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
691-
scope()->outer_scope()->outer_scope(),
692-
scope());
693-
}
694-
RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
695-
scope()->outer_scope(), scope());
696-
}
707+
// Initializer may have been parsed in the wrong scope.
708+
RewriteParameterScopes(initializer);
697709

698710
PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
699711
RecurseIntoSubpattern(node->target(), value);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright 2016 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --no-lazy
6+
7+
assertEquals(0, ((x, {[(x = function() { y = 0 }, "foo")]: y = eval(1)}) => { x(); return y })(42, {}));
8+
assertEquals(0, (function (x, {[(x = function() { y = 0 }, "foo")]: y = eval(1)}) { x(); return y })(42, {}));

0 commit comments

Comments
 (0)