Chromium Code Reviews| 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 } |
|
adamk
2016/07/14 22:00:47
Why does this else go away?
bakkot
2016/07/14 22:46:01
It prevents recursing into statements in DoExpress
| |
| 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 |