OLD | NEW |
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> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 old_scope_(old_scope), | 26 old_scope_(old_scope), |
27 new_scope_(new_scope), | 27 new_scope_(new_scope), |
28 old_scope_closure_(old_scope->ClosureScope()), | 28 old_scope_closure_(old_scope->ClosureScope()), |
29 new_scope_closure_(new_scope->ClosureScope()) {} | 29 new_scope_closure_(new_scope->ClosureScope()) {} |
30 ~Rewriter(); | 30 ~Rewriter(); |
31 | 31 |
32 private: | 32 private: |
33 void VisitExpression(Expression* expr) override {} | 33 void VisitExpression(Expression* expr) override {} |
34 | 34 |
35 void VisitFunctionLiteral(FunctionLiteral* expr) override; | 35 void VisitFunctionLiteral(FunctionLiteral* expr) override; |
36 void VisitClassLiteral(ClassLiteral* expr) override; | |
37 void VisitVariableProxy(VariableProxy* expr) override; | 36 void VisitVariableProxy(VariableProxy* expr) override; |
38 | 37 |
39 void VisitBlock(Block* stmt) override; | 38 void VisitBlock(Block* stmt) override; |
40 void VisitTryCatchStatement(TryCatchStatement* stmt) override; | 39 void VisitTryCatchStatement(TryCatchStatement* stmt) override; |
41 void VisitWithStatement(WithStatement* stmt) override; | 40 void VisitWithStatement(WithStatement* stmt) override; |
42 | 41 |
43 Scope* old_scope_; | 42 Scope* old_scope_; |
44 Scope* new_scope_; | 43 Scope* new_scope_; |
45 Scope* old_scope_closure_; | 44 Scope* old_scope_closure_; |
46 Scope* new_scope_closure_; | 45 Scope* new_scope_closure_; |
(...skipping 12 matching lines...) Expand all Loading... |
59 // Ensure that we add temporaries in the order they appeared in old_scope_. | 58 // Ensure that we add temporaries in the order they appeared in old_scope_. |
60 std::sort(temps_.begin(), temps_.end(), LessThanSecond()); | 59 std::sort(temps_.begin(), temps_.end(), LessThanSecond()); |
61 for (auto var_and_index : temps_) { | 60 for (auto var_and_index : temps_) { |
62 var_and_index.first->set_scope(new_scope_closure_); | 61 var_and_index.first->set_scope(new_scope_closure_); |
63 new_scope_closure_->AddTemporary(var_and_index.first); | 62 new_scope_closure_->AddTemporary(var_and_index.first); |
64 } | 63 } |
65 } | 64 } |
66 } | 65 } |
67 | 66 |
68 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) { | 67 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) { |
69 function_literal->scope()->ReplaceOuterScope(new_scope_); | 68 if (function_literal->scope()->outer_scope() == old_scope_) { |
70 } | 69 function_literal->scope()->ReplaceOuterScope(new_scope_); |
71 | |
72 | |
73 void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) { | |
74 class_literal->scope()->ReplaceOuterScope(new_scope_); | |
75 if (class_literal->extends() != nullptr) { | |
76 Visit(class_literal->extends()); | |
77 } | |
78 // No need to visit the constructor since it will have the class | |
79 // scope on its scope chain. | |
80 ZoneList<ObjectLiteralProperty*>* props = class_literal->properties(); | |
81 for (int i = 0; i < props->length(); ++i) { | |
82 ObjectLiteralProperty* prop = props->at(i); | |
83 if (!prop->key()->IsLiteral()) { | |
84 Visit(prop->key()); | |
85 } | |
86 // No need to visit the values, since all values are functions with | |
87 // the class scope on their scope chain. | |
88 DCHECK(prop->value()->IsFunctionLiteral()); | |
89 } | 70 } |
90 } | 71 } |
91 | 72 |
92 | 73 |
93 void Rewriter::VisitVariableProxy(VariableProxy* proxy) { | 74 void Rewriter::VisitVariableProxy(VariableProxy* proxy) { |
94 if (proxy->is_resolved()) { | 75 if (proxy->is_resolved()) { |
95 Variable* var = proxy->var(); | 76 Variable* var = proxy->var(); |
96 if (var->mode() != TEMPORARY) return; | 77 if (var->mode() != TEMPORARY) return; |
97 // Temporaries are only placed in ClosureScopes. | 78 // Temporaries are only placed in ClosureScopes. |
98 DCHECK_EQ(var->scope(), var->scope()->ClosureScope()); | 79 DCHECK_EQ(var->scope(), var->scope()->ClosureScope()); |
99 // If the temporary is already where it should be, return quickly. | 80 // If the temporary is already where it should be, return quickly. |
100 if (var->scope() == new_scope_closure_) return; | 81 if (var->scope() == new_scope_closure_) return; |
101 int index = old_scope_closure_->RemoveTemporary(var); | 82 int index = old_scope_closure_->RemoveTemporary(var); |
102 if (index >= 0) { | 83 if (index >= 0) { |
103 temps_.push_back(std::make_pair(var, index)); | 84 temps_.push_back(std::make_pair(var, index)); |
104 } | 85 } |
105 } else if (old_scope_->RemoveUnresolved(proxy)) { | 86 } else if (old_scope_->RemoveUnresolved(proxy)) { |
106 new_scope_->AddUnresolved(proxy); | 87 new_scope_->AddUnresolved(proxy); |
107 } | 88 } |
108 } | 89 } |
109 | 90 |
110 | 91 |
111 void Rewriter::VisitBlock(Block* stmt) { | 92 void Rewriter::VisitBlock(Block* stmt) { |
112 if (stmt->scope() != nullptr) | 93 if (stmt->scope() != nullptr && stmt->scope()->outer_scope() == old_scope_) { |
113 stmt->scope()->ReplaceOuterScope(new_scope_); | 94 stmt->scope()->ReplaceOuterScope(new_scope_); |
114 else | 95 } |
115 VisitStatements(stmt->statements()); | 96 VisitStatements(stmt->statements()); |
116 } | 97 } |
117 | 98 |
118 | 99 |
119 void Rewriter::VisitTryCatchStatement(TryCatchStatement* stmt) { | 100 void Rewriter::VisitTryCatchStatement(TryCatchStatement* stmt) { |
120 Visit(stmt->try_block()); | 101 Visit(stmt->try_block()); |
121 stmt->scope()->ReplaceOuterScope(new_scope_); | 102 if (stmt->scope()->outer_scope() == old_scope_) { |
| 103 stmt->scope()->ReplaceOuterScope(new_scope_); |
| 104 } |
122 } | 105 } |
123 | 106 |
124 | 107 |
125 void Rewriter::VisitWithStatement(WithStatement* stmt) { | 108 void Rewriter::VisitWithStatement(WithStatement* stmt) { |
126 Visit(stmt->expression()); | 109 Visit(stmt->expression()); |
127 stmt->scope()->ReplaceOuterScope(new_scope_); | 110 if (stmt->scope()->outer_scope() == old_scope_) { |
| 111 stmt->scope()->ReplaceOuterScope(new_scope_); |
| 112 } |
128 } | 113 } |
129 | 114 |
130 | 115 |
131 } // anonymous namespace | 116 } // anonymous namespace |
132 | 117 |
133 | 118 |
134 void RewriteParameterInitializerScope(uintptr_t stack_limit, | 119 void RewriteParameterInitializerScope(uintptr_t stack_limit, |
135 Expression* initializer, Scope* old_scope, | 120 Expression* initializer, Scope* old_scope, |
136 Scope* new_scope) { | 121 Scope* new_scope) { |
137 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope); | 122 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope); |
138 rewriter.Run(); | 123 rewriter.Run(); |
139 } | 124 } |
140 | 125 |
141 | 126 |
142 } // namespace internal | 127 } // namespace internal |
143 } // namespace v8 | 128 } // namespace v8 |
OLD | NEW |