V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
expression-scope-reparenter.cc
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/expression-scope-reparenter.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 class Reparenter final : public AstTraversalVisitor<Reparenter> {
18  public:
19  Reparenter(uintptr_t stack_limit, Expression* initializer, Scope* scope)
20  : AstTraversalVisitor(stack_limit, initializer), scope_(scope) {}
21 
22  private:
23  // This is required so that the overriden Visit* methods can be
24  // called by the base class (template).
25  friend class AstTraversalVisitor<Reparenter>;
26 
27  void VisitFunctionLiteral(FunctionLiteral* expr);
28  void VisitClassLiteral(ClassLiteral* expr);
29  void VisitVariableProxy(VariableProxy* expr);
30  void VisitRewritableExpression(RewritableExpression* expr);
31 
32  void VisitBlock(Block* stmt);
33  void VisitTryCatchStatement(TryCatchStatement* stmt);
34  void VisitWithStatement(WithStatement* stmt);
35 
36  Scope* scope_;
37 };
38 
39 void Reparenter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
40  function_literal->scope()->ReplaceOuterScope(scope_);
41 }
42 
43 void Reparenter::VisitClassLiteral(ClassLiteral* class_literal) {
44  class_literal->scope()->ReplaceOuterScope(scope_);
45  // No need to visit the constructor since it will have the class
46  // scope on its scope chain.
47  DCHECK_EQ(class_literal->constructor()->scope()->outer_scope(),
48  class_literal->scope());
49 
50  if (class_literal->static_fields_initializer() != nullptr) {
51  DCHECK_EQ(
52  class_literal->static_fields_initializer()->scope()->outer_scope(),
53  class_literal->scope());
54  }
55 #if DEBUG
56  // The same goes for the rest of the class, but we do some
57  // sanity checking in debug mode.
58  ZonePtrList<ClassLiteralProperty>* props = class_literal->properties();
59  for (int i = 0; i < props->length(); ++i) {
60  ClassLiteralProperty* prop = props->at(i);
61  // No need to visit the values, since all values are functions with
62  // the class scope on their scope chain.
63  DCHECK(prop->value()->IsFunctionLiteral());
64  DCHECK_EQ(prop->value()->AsFunctionLiteral()->scope()->outer_scope(),
65  class_literal->scope());
66  }
67 #endif
68 }
69 
70 void Reparenter::VisitVariableProxy(VariableProxy* proxy) {
71  if (!proxy->is_resolved()) {
72  if (scope_->outer_scope()->RemoveUnresolved(proxy)) {
73  scope_->AddUnresolved(proxy);
74  }
75  } else {
76  // Ensure that temporaries we find are already in the correct scope.
77  DCHECK(proxy->var()->mode() != VariableMode::kTemporary ||
78  proxy->var()->scope() == scope_->GetClosureScope());
79  }
80 }
81 
82 void Reparenter::VisitRewritableExpression(RewritableExpression* expr) {
83  Visit(expr->expression());
84  expr->set_scope(scope_);
85 }
86 
87 void Reparenter::VisitBlock(Block* stmt) {
88  if (stmt->scope())
89  stmt->scope()->ReplaceOuterScope(scope_);
90  else
91  VisitStatements(stmt->statements());
92 }
93 
94 void Reparenter::VisitTryCatchStatement(TryCatchStatement* stmt) {
95  Visit(stmt->try_block());
96  if (stmt->scope()) {
97  stmt->scope()->ReplaceOuterScope(scope_);
98  } else {
99  Visit(stmt->catch_block());
100  }
101 }
102 
103 void Reparenter::VisitWithStatement(WithStatement* stmt) {
104  Visit(stmt->expression());
105  stmt->scope()->ReplaceOuterScope(scope_);
106 }
107 
108 } // anonymous namespace
109 
110 void ReparentExpressionScope(uintptr_t stack_limit, Expression* expr,
111  Scope* scope) {
112  // The only case that uses this code is block scopes for parameters containing
113  // sloppy eval.
114  DCHECK(scope->is_block_scope());
115  DCHECK(scope->is_declaration_scope());
116  DCHECK(scope->AsDeclarationScope()->calls_sloppy_eval());
117  DCHECK(scope->outer_scope()->is_function_scope());
118 
119  Reparenter r(stack_limit, expr, scope);
120  r.Run();
121 }
122 
123 } // namespace internal
124 } // namespace v8
Definition: libplatform.h:13