Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/parsing/parameter-initializer-rewriter.cc b/src/parsing/parameter-initializer-rewriter.cc
index 3e3587b..6362c63 100644
--- a/src/parsing/parameter-initializer-rewriter.cc
+++ b/src/parsing/parameter-initializer-rewriter.cc
@@ -4,6 +4,10 @@
#include "src/parsing/parameter-initializer-rewriter.h"
+#include <algorithm>
+#include <utility>
+#include <vector>
+
#include "src/ast/ast.h"
#include "src/ast/ast-expression-visitor.h"
#include "src/ast/scopes.h"
@@ -21,6 +25,7 @@
: AstExpressionVisitor(stack_limit, initializer),
old_scope_(old_scope),
new_scope_(new_scope) {}
+ ~Rewriter();
private:
void VisitExpression(Expression* expr) override {}
@@ -29,10 +34,32 @@
void VisitClassLiteral(ClassLiteral* expr) override;
void VisitVariableProxy(VariableProxy* expr) override;
+ void VisitBlock(Block* stmt) override;
+ void VisitTryCatchStatement(TryCatchStatement* stmt) override;
+ void VisitWithStatement(WithStatement* stmt) override;
+
Scope* old_scope_;
Scope* new_scope_;
+ std::vector<std::pair<Variable*, int>> temps_;
};
+struct LessThanSecond {
+ bool operator()(const std::pair<Variable*, int>& left,
+ const std::pair<Variable*, int>& right) {
+ return left.second < right.second;
+ }
+};
+
+Rewriter::~Rewriter() {
+ if (!temps_.empty()) {
+ // 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);
+ }
+ }
+}
void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
function_literal->scope()->ReplaceOuterScope(new_scope_);
@@ -63,9 +90,13 @@
if (proxy->is_resolved()) {
Variable* var = proxy->var();
if (var->mode() != TEMPORARY) return;
- if (old_scope_->RemoveTemporary(var)) {
- var->set_scope(new_scope_);
- new_scope_->AddTemporary(var);
+ // 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);
+ if (index >= 0) {
+ temps_.push_back(std::make_pair(var, index));
}
} else if (old_scope_->RemoveUnresolved(proxy)) {
new_scope_->AddUnresolved(proxy);
@@ -73,6 +104,26 @@
}
+void Rewriter::VisitBlock(Block* stmt) {
+ if (stmt->scope() != nullptr)
+ stmt->scope()->ReplaceOuterScope(new_scope_);
+ else
+ VisitStatements(stmt->statements());
+}
+
+
+void Rewriter::VisitTryCatchStatement(TryCatchStatement* stmt) {
+ Visit(stmt->try_block());
+ stmt->scope()->ReplaceOuterScope(new_scope_);
+}
+
+
+void Rewriter::VisitWithStatement(WithStatement* stmt) {
+ Visit(stmt->expression());
+ stmt->scope()->ReplaceOuterScope(new_scope_);
+}
+
+
} // anonymous namespace