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