• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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/ast/ast-function-literal-id-reindexer.h"
6 #include "src/objects/objects-inl.h"
7 
8 #include "src/ast/ast.h"
9 
10 namespace v8 {
11 namespace internal {
12 
AstFunctionLiteralIdReindexer(size_t stack_limit,int delta)13 AstFunctionLiteralIdReindexer::AstFunctionLiteralIdReindexer(size_t stack_limit,
14                                                              int delta)
15     : AstTraversalVisitor(stack_limit), delta_(delta) {}
16 
17 AstFunctionLiteralIdReindexer::~AstFunctionLiteralIdReindexer() = default;
18 
Reindex(Expression * pattern)19 void AstFunctionLiteralIdReindexer::Reindex(Expression* pattern) {
20 #ifdef DEBUG
21   visited_.clear();
22 #endif
23   Visit(pattern);
24   CheckVisited(pattern);
25 }
26 
VisitFunctionLiteral(FunctionLiteral * lit)27 void AstFunctionLiteralIdReindexer::VisitFunctionLiteral(FunctionLiteral* lit) {
28   // Make sure we're not already in the visited set.
29   DCHECK(visited_.insert(lit).second);
30 
31   AstTraversalVisitor::VisitFunctionLiteral(lit);
32   lit->set_function_literal_id(lit->function_literal_id() + delta_);
33 }
34 
VisitClassLiteral(ClassLiteral * expr)35 void AstFunctionLiteralIdReindexer::VisitClassLiteral(ClassLiteral* expr) {
36   // Manually visit the class literal so that we can change the property walk.
37   // This should be kept in-sync with AstTraversalVisitor::VisitClassLiteral.
38 
39   if (expr->extends() != nullptr) {
40     Visit(expr->extends());
41   }
42   Visit(expr->constructor());
43   if (expr->static_initializer() != nullptr) {
44     Visit(expr->static_initializer());
45   }
46   if (expr->instance_members_initializer_function() != nullptr) {
47     Visit(expr->instance_members_initializer_function());
48   }
49   ZonePtrList<ClassLiteral::Property>* private_members =
50       expr->private_members();
51   for (int i = 0; i < private_members->length(); ++i) {
52     ClassLiteralProperty* prop = private_members->at(i);
53 
54     // Private fields have their key and value present in
55     // instance_members_initializer_function, so they will
56     // already have been visited.
57     if (prop->kind() == ClassLiteralProperty::Kind::FIELD) {
58       CheckVisited(prop->value());
59     } else {
60       Visit(prop->value());
61     }
62   }
63   ZonePtrList<ClassLiteral::Property>* props = expr->public_members();
64   for (int i = 0; i < props->length(); ++i) {
65     ClassLiteralProperty* prop = props->at(i);
66 
67     // Public fields with computed names have their key
68     // and value present in instance_members_initializer_function, so they will
69     // already have been visited.
70     if (prop->is_computed_name() &&
71         prop->kind() == ClassLiteralProperty::Kind::FIELD) {
72       if (!prop->key()->IsLiteral()) {
73         CheckVisited(prop->key());
74       }
75       CheckVisited(prop->value());
76     } else {
77       if (!prop->key()->IsLiteral()) {
78         Visit(prop->key());
79       }
80       Visit(prop->value());
81     }
82   }
83 }
84 
85 #ifdef DEBUG
86 namespace {
87 
88 class AstFunctionLiteralIdReindexChecker final
89     : public AstTraversalVisitor<AstFunctionLiteralIdReindexChecker> {
90  public:
AstFunctionLiteralIdReindexChecker(size_t stack_limit,const std::set<FunctionLiteral * > * visited)91   AstFunctionLiteralIdReindexChecker(size_t stack_limit,
92                                      const std::set<FunctionLiteral*>* visited)
93       : AstTraversalVisitor(stack_limit), visited_(visited) {}
94 
VisitFunctionLiteral(FunctionLiteral * lit)95   void VisitFunctionLiteral(FunctionLiteral* lit) {
96     // TODO(leszeks): It would be nice to print the unvisited function literal
97     // here, but that requires more advanced DCHECK support with formatting.
98     DCHECK(visited_->find(lit) != visited_->end());
99   }
100 
101  private:
102   const std::set<FunctionLiteral*>* visited_;
103 };
104 
105 }  // namespace
106 
CheckVisited(Expression * expr)107 void AstFunctionLiteralIdReindexer::CheckVisited(Expression* expr) {
108   AstFunctionLiteralIdReindexChecker(stack_limit(), &visited_).Visit(expr);
109 }
110 #endif
111 
112 }  // namespace internal
113 }  // namespace v8
114