Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Side by Side Diff: src/parsing/parameter-initializer-rewriter.cc

Issue 1784893003: ParameterInitializerRewriter must maintain temporary variable order (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parameter-initializer-rewriter.h" 5 #include "src/parsing/parameter-initializer-rewriter.h"
6 6
7 #include <algorithm>
8 #include <utility>
9 #include <vector>
10
7 #include "src/ast/ast.h" 11 #include "src/ast/ast.h"
8 #include "src/ast/ast-expression-visitor.h" 12 #include "src/ast/ast-expression-visitor.h"
9 #include "src/ast/scopes.h" 13 #include "src/ast/scopes.h"
10 14
11 namespace v8 { 15 namespace v8 {
12 namespace internal { 16 namespace internal {
13 17
14 namespace { 18 namespace {
15 19
16 20
17 class Rewriter final : public AstExpressionVisitor { 21 class Rewriter final : public AstExpressionVisitor {
18 public: 22 public:
19 Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope, 23 Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope,
20 Scope* new_scope) 24 Scope* new_scope)
21 : AstExpressionVisitor(stack_limit, initializer), 25 : AstExpressionVisitor(stack_limit, initializer),
22 old_scope_(old_scope), 26 old_scope_(old_scope),
23 new_scope_(new_scope) {} 27 new_scope_(new_scope) {}
28 ~Rewriter();
24 29
25 private: 30 private:
26 void VisitExpression(Expression* expr) override {} 31 void VisitExpression(Expression* expr) override {}
27 32
28 void VisitFunctionLiteral(FunctionLiteral* expr) override; 33 void VisitFunctionLiteral(FunctionLiteral* expr) override;
29 void VisitClassLiteral(ClassLiteral* expr) override; 34 void VisitClassLiteral(ClassLiteral* expr) override;
30 void VisitVariableProxy(VariableProxy* expr) override; 35 void VisitVariableProxy(VariableProxy* expr) override;
31 36
32 Scope* old_scope_; 37 Scope* old_scope_;
33 Scope* new_scope_; 38 Scope* new_scope_;
39 std::vector<std::pair<Variable*, int>> temps_;
34 }; 40 };
35 41
42 struct LessThanSecond {
43 bool operator()(const std::pair<Variable*, int>& left,
44 const std::pair<Variable*, int>& right) {
45 return left.second < right.second;
46 }
47 };
48
49 Rewriter::~Rewriter() {
50 if (!temps_.empty()) {
51 // Ensure that we add temporaries in the order they appeared in old_scope_.
52 std::sort(temps_.begin(), temps_.end(), LessThanSecond());
nickie 2016/03/11 10:48:44 You wouldn't need LessThanSecond if the elements o
53 for (auto var_and_index : temps_) {
54 var_and_index.first->set_scope(new_scope_);
55 new_scope_->AddTemporary(var_and_index.first);
56 }
57 }
58 }
36 59
37 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) { 60 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
38 function_literal->scope()->ReplaceOuterScope(new_scope_); 61 function_literal->scope()->ReplaceOuterScope(new_scope_);
39 } 62 }
40 63
41 64
42 void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) { 65 void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) {
43 class_literal->scope()->ReplaceOuterScope(new_scope_); 66 class_literal->scope()->ReplaceOuterScope(new_scope_);
44 if (class_literal->extends() != nullptr) { 67 if (class_literal->extends() != nullptr) {
45 Visit(class_literal->extends()); 68 Visit(class_literal->extends());
(...skipping 10 matching lines...) Expand all
56 // the class scope on their scope chain. 79 // the class scope on their scope chain.
57 DCHECK(prop->value()->IsFunctionLiteral()); 80 DCHECK(prop->value()->IsFunctionLiteral());
58 } 81 }
59 } 82 }
60 83
61 84
62 void Rewriter::VisitVariableProxy(VariableProxy* proxy) { 85 void Rewriter::VisitVariableProxy(VariableProxy* proxy) {
63 if (proxy->is_resolved()) { 86 if (proxy->is_resolved()) {
64 Variable* var = proxy->var(); 87 Variable* var = proxy->var();
65 if (var->mode() != TEMPORARY) return; 88 if (var->mode() != TEMPORARY) return;
66 if (old_scope_->RemoveTemporary(var)) { 89 int index = old_scope_->RemoveTemporary(var);
67 var->set_scope(new_scope_); 90 if (index >= 0) {
68 new_scope_->AddTemporary(var); 91 temps_.push_back(std::make_pair(var, index));
69 } 92 }
70 } else if (old_scope_->RemoveUnresolved(proxy)) { 93 } else if (old_scope_->RemoveUnresolved(proxy)) {
71 new_scope_->AddUnresolved(proxy); 94 new_scope_->AddUnresolved(proxy);
72 } 95 }
73 } 96 }
74 97
75 98
76 } // anonymous namespace 99 } // anonymous namespace
77 100
78 101
79 void RewriteParameterInitializerScope(uintptr_t stack_limit, 102 void RewriteParameterInitializerScope(uintptr_t stack_limit,
80 Expression* initializer, Scope* old_scope, 103 Expression* initializer, Scope* old_scope,
81 Scope* new_scope) { 104 Scope* new_scope) {
82 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope); 105 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope);
83 rewriter.Run(); 106 rewriter.Run();
84 } 107 }
85 108
86 109
87 } // namespace internal 110 } // namespace internal
88 } // namespace v8 111 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698