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