• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-traversal-visitor.h"
8  #include "src/ast/ast.h"
9  #include "src/ast/scopes.h"
10  #include "src/objects-inl.h"
11  
12  namespace v8 {
13  namespace internal {
14  
15  namespace {
16  
17  
18  class Rewriter final : public AstTraversalVisitor<Rewriter> {
19   public:
Rewriter(uintptr_t stack_limit,Expression * initializer,Scope * param_scope)20    Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* param_scope)
21        : AstTraversalVisitor(stack_limit, initializer),
22          param_scope_(param_scope) {}
23  
24   private:
25    // This is required so that the overriden Visit* methods can be
26    // called by the base class (template).
27    friend class AstTraversalVisitor<Rewriter>;
28  
29    void VisitFunctionLiteral(FunctionLiteral* expr);
30    void VisitClassLiteral(ClassLiteral* expr);
31    void VisitVariableProxy(VariableProxy* expr);
32  
33    void VisitBlock(Block* stmt);
34    void VisitTryCatchStatement(TryCatchStatement* stmt);
35    void VisitWithStatement(WithStatement* stmt);
36  
37    Scope* param_scope_;
38  };
39  
VisitFunctionLiteral(FunctionLiteral * function_literal)40  void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
41    function_literal->scope()->ReplaceOuterScope(param_scope_);
42  }
43  
44  
VisitClassLiteral(ClassLiteral * class_literal)45  void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) {
46    if (class_literal->extends() != nullptr) {
47      Visit(class_literal->extends());
48    }
49    // No need to visit the constructor since it will have the class
50    // scope on its scope chain.
51    ZoneList<ClassLiteralProperty*>* props = class_literal->properties();
52    for (int i = 0; i < props->length(); ++i) {
53      ClassLiteralProperty* prop = props->at(i);
54      if (!prop->key()->IsLiteral()) {
55        Visit(prop->key());
56      }
57      // No need to visit the values, since all values are functions with
58      // the class scope on their scope chain.
59      DCHECK(prop->value()->IsFunctionLiteral());
60    }
61  }
62  
63  
VisitVariableProxy(VariableProxy * proxy)64  void Rewriter::VisitVariableProxy(VariableProxy* proxy) {
65    if (!proxy->is_resolved()) {
66      if (param_scope_->outer_scope()->RemoveUnresolved(proxy)) {
67        param_scope_->AddUnresolved(proxy);
68      }
69    } else {
70      // Ensure that temporaries we find are already in the correct scope.
71      DCHECK(proxy->var()->mode() != TEMPORARY ||
72             proxy->var()->scope() == param_scope_->GetClosureScope());
73    }
74  }
75  
76  
VisitBlock(Block * stmt)77  void Rewriter::VisitBlock(Block* stmt) {
78    if (stmt->scope() != nullptr)
79      stmt->scope()->ReplaceOuterScope(param_scope_);
80    else
81      VisitStatements(stmt->statements());
82  }
83  
84  
VisitTryCatchStatement(TryCatchStatement * stmt)85  void Rewriter::VisitTryCatchStatement(TryCatchStatement* stmt) {
86    Visit(stmt->try_block());
87    stmt->scope()->ReplaceOuterScope(param_scope_);
88  }
89  
90  
VisitWithStatement(WithStatement * stmt)91  void Rewriter::VisitWithStatement(WithStatement* stmt) {
92    Visit(stmt->expression());
93    stmt->scope()->ReplaceOuterScope(param_scope_);
94  }
95  
96  
97  }  // anonymous namespace
98  
ReparentParameterExpressionScope(uintptr_t stack_limit,Expression * expr,Scope * param_scope)99  void ReparentParameterExpressionScope(uintptr_t stack_limit, Expression* expr,
100                                        Scope* param_scope) {
101    // The only case that uses this code is block scopes for parameters containing
102    // sloppy eval.
103    DCHECK(param_scope->is_block_scope());
104    DCHECK(param_scope->is_declaration_scope());
105    DCHECK(param_scope->calls_sloppy_eval());
106    DCHECK(param_scope->outer_scope()->is_function_scope());
107  
108    Rewriter rewriter(stack_limit, expr, param_scope);
109    rewriter.Run();
110  }
111  
112  
113  }  // namespace internal
114  }  // namespace v8
115