Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Version 5.3.332.7 (cherry-pick)
Browse files Browse the repository at this point in the history
Merged 61c137c

Fix bug with re-scoping arrow function parameter initializers

BUG=chromium:622663
LOG=N
R=hablich@chromium.org
NOTRY=true
NOPRESUBMIT=true

Review-Url: https://codereview.chromium.org/2121083003
Cr-Commit-Position: refs/branch-heads/5.3@{#9}
Cr-Branched-From: 820a23a-refs/heads/5.3.332@{#2}
Cr-Branched-From: 37538cb-refs/heads/master@{#37308}
  • Loading branch information
nickie authored and Commit bot committed Jul 5, 2016
1 parent 476af19 commit bf485d3
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 10 deletions.
2 changes: 1 addition & 1 deletion include/v8-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 3
#define V8_BUILD_NUMBER 332
#define V8_PATCH_LEVEL 6
#define V8_PATCH_LEVEL 7

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
5 changes: 5 additions & 0 deletions src/ast/scopes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,11 @@ Variable* Scope::NewTemporary(const AstRawString* name) {

int Scope::RemoveTemporary(Variable* var) {
DCHECK_NOT_NULL(var);
// Temporaries are only placed in ClosureScopes.
DCHECK_EQ(ClosureScope(), this);
DCHECK_EQ(var->scope()->ClosureScope(), var->scope());
// If the temporary is not here, return quickly.
if (var->scope() != this) return -1;
// Most likely (always?) any temporary variable we want to remove
// was just added before, so we search backwards.
for (int i = temps_.length(); i-- > 0;) {
Expand Down
6 changes: 5 additions & 1 deletion src/ast/scopes.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,11 @@ class Scope: public ZoneObject {
// Adds a temporary variable in this scope's TemporaryScope. This is for
// adjusting the scope of temporaries used when desugaring parameter
// initializers.
void AddTemporary(Variable* var) { temps_.Add(var, zone()); }
void AddTemporary(Variable* var) {
// Temporaries are only placed in ClosureScopes.
DCHECK_EQ(ClosureScope(), this);
temps_.Add(var, zone());
}

// Adds the specific declaration node to the list of declarations in
// this scope. The declarations are processed as part of entering
Expand Down
20 changes: 12 additions & 8 deletions src/parsing/parameter-initializer-rewriter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class Rewriter final : public AstExpressionVisitor {
Scope* new_scope)
: AstExpressionVisitor(stack_limit, initializer),
old_scope_(old_scope),
new_scope_(new_scope) {}
new_scope_(new_scope),
old_scope_closure_(old_scope->ClosureScope()),
new_scope_closure_(new_scope->ClosureScope()) {}
~Rewriter();

private:
Expand All @@ -40,6 +42,8 @@ class Rewriter final : public AstExpressionVisitor {

Scope* old_scope_;
Scope* new_scope_;
Scope* old_scope_closure_;
Scope* new_scope_closure_;
std::vector<std::pair<Variable*, int>> temps_;
};

Expand All @@ -55,8 +59,8 @@ Rewriter::~Rewriter() {
// Ensure that we add temporaries in the order they appeared in old_scope_.
std::sort(temps_.begin(), temps_.end(), LessThanSecond());
for (auto var_and_index : temps_) {
var_and_index.first->set_scope(new_scope_);
new_scope_->AddTemporary(var_and_index.first);
var_and_index.first->set_scope(new_scope_closure_);
new_scope_closure_->AddTemporary(var_and_index.first);
}
}
}
Expand Down Expand Up @@ -90,11 +94,11 @@ void Rewriter::VisitVariableProxy(VariableProxy* proxy) {
if (proxy->is_resolved()) {
Variable* var = proxy->var();
if (var->mode() != TEMPORARY) return;
// For rewriting inside the same ClosureScope (e.g., putting default
// parameter values in their own inner scope in certain cases), refrain
// from invalidly moving temporaries to a block scope.
if (var->scope()->ClosureScope() == new_scope_->ClosureScope()) return;
int index = old_scope_->RemoveTemporary(var);
// Temporaries are only placed in ClosureScopes.
DCHECK_EQ(var->scope(), var->scope()->ClosureScope());
// If the temporary is already where it should be, return quickly.
if (var->scope() == new_scope_closure_) return;
int index = old_scope_closure_->RemoveTemporary(var);
if (index >= 0) {
temps_.push_back(std::make_pair(var, index));
}
Expand Down
14 changes: 14 additions & 0 deletions test/mjsunit/regress/regress-622663.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-lazy

(function() {
try { (y = [...[]]) => {} } catch(_) {} // will core dump, if not fixed
})();

(function() {
try { ((y = [...[]]) => {})(); } catch(_) {} // will core dump, if not fixed,
// even without --no-lazy
})();

0 comments on commit bf485d3

Please sign in to comment.