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 3 // found in the LICENSE file. 4 5 #include "src/parsing/parameter-initializer-rewriter.h" 6 7 #include "src/ast/ast.h" 8 #include "src/ast/ast-expression-visitor.h" 9 #include "src/ast/scopes.h" 10 11 namespace v8 { 12 namespace internal { 13 14 namespace { 15 16 17 class Rewriter final : public AstExpressionVisitor { 18 public: 19 Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope, 20 Scope* new_scope) 21 : AstExpressionVisitor(stack_limit, initializer), 22 old_scope_(old_scope), 23 new_scope_(new_scope) {} 24 25 private: 26 void VisitExpression(Expression* expr) override {} 27 28 void VisitFunctionLiteral(FunctionLiteral* expr) override; 29 void VisitClassLiteral(ClassLiteral* expr) override; 30 void VisitVariableProxy(VariableProxy* expr) override; 31 32 Scope* old_scope_; 33 Scope* new_scope_; 34 }; 35 36 37 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) { 38 function_literal->scope()->ReplaceOuterScope(new_scope_); 39 } 40 41 42 void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) { 43 class_literal->scope()->ReplaceOuterScope(new_scope_); 44 if (class_literal->extends() != nullptr) { 45 Visit(class_literal->extends()); 46 } 47 // No need to visit the constructor since it will have the class 48 // scope on its scope chain. 49 ZoneList<ObjectLiteralProperty*>* props = class_literal->properties(); 50 for (int i = 0; i < props->length(); ++i) { 51 ObjectLiteralProperty* prop = props->at(i); 52 if (!prop->key()->IsLiteral()) { 53 Visit(prop->key()); 54 } 55 // No need to visit the values, since all values are functions with 56 // the class scope on their scope chain. 57 DCHECK(prop->value()->IsFunctionLiteral()); 58 } 59 } 60 61 62 void Rewriter::VisitVariableProxy(VariableProxy* proxy) { 63 if (proxy->is_resolved()) { 64 Variable* var = proxy->var(); 65 DCHECK_EQ(var->mode(), TEMPORARY); 66 if (old_scope_->RemoveTemporary(var)) { 67 var->set_scope(new_scope_); 68 new_scope_->AddTemporary(var); 69 } 70 } else if (old_scope_->RemoveUnresolved(proxy)) { 71 new_scope_->AddUnresolved(proxy); 72 } 73 } 74 75 76 } // anonymous namespace 77 78 79 void RewriteParameterInitializerScope(uintptr_t stack_limit, 80 Expression* initializer, Scope* old_scope, 81 Scope* new_scope) { 82 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope); 83 rewriter.Run(); 84 } 85 86 87 } // namespace internal 88 } // namespace v8 89