v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
func-name-inferrer.h
Go to the documentation of this file.
1// Copyright 2006-2009 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#ifndef V8_PARSING_FUNC_NAME_INFERRER_H_
6#define V8_PARSING_FUNC_NAME_INFERRER_H_
7
8#include <vector>
9
10#include "src/base/macros.h"
13
14namespace v8 {
15
16namespace internal {
17class AstRawString;
18}
19
20namespace base {
21template <>
23 static constexpr int kAvailableBits = 2;
24};
25} // namespace base
26
27namespace internal {
28
29class AstConsString;
30class AstValueFactory;
31class FunctionLiteral;
32
33enum class InferName { kYes, kNo };
34
35// FuncNameInferrer is a stateful class that is used to perform name
36// inference for anonymous functions during static analysis of source code.
37// Inference is performed in cases when an anonymous function is assigned
38// to a variable or a property (see test-func-name-inference.cc for examples.)
39//
40// The basic idea is that during parsing of LHSs of certain expressions
41// (assignments, declarations, object literals) we collect name strings,
42// and during parsing of the RHS, a function literal can be collected. After
43// parsing the RHS we can infer a name for function literals that do not have
44// a name.
46 public:
47 explicit FuncNameInferrer(AstValueFactory* ast_value_factory);
48
51
52 // To enter function name inference state, put a FuncNameInferrer::State
53 // on the stack.
54 class State {
55 public:
56 explicit State(FuncNameInferrer* fni)
57 : fni_(fni), top_(fni->names_stack_.size()) {
59 }
61 DCHECK(fni_->IsOpen());
62 fni_->names_stack_.resize(top_);
64 }
65 State(const State&) = delete;
66 State& operator=(const State&) = delete;
67
68 private:
70 size_t top_;
71 };
72
73 // Returns whether we have entered name collection state.
74 bool IsOpen() const { return scope_depth_ > 0; }
75
76 // Pushes an enclosing the name of enclosing function onto names stack.
77 void PushEnclosingName(const AstRawString* name);
78
79 // Pushes an encountered name onto names stack when in collection state.
80 void PushLiteralName(const AstRawString* name);
81
82 void PushVariableName(const AstRawString* name);
83
84 // Adds a function to infer name for.
85 void AddFunction(FunctionLiteral* func_to_infer) {
86 if (IsOpen()) {
87 funcs_to_infer_.push_back(func_to_infer);
88 }
89 }
90
92 if (IsOpen() && !funcs_to_infer_.empty()) funcs_to_infer_.pop_back();
93 }
94
96
97 // Infers a function name and leaves names collection state.
98 void Infer() {
99 DCHECK(IsOpen());
100 if (!funcs_to_infer_.empty()) InferFunctionsNames();
101 }
102
103 private:
109 struct Name {
110 // Needed for names_stack_.resize()
112 Name(const AstRawString* name, NameType type)
113 : name_and_type_(name, type) {}
114
116 inline const AstRawString* name() const {
117 return name_and_type_.GetPointer();
118 }
119 inline NameType type() const { return name_and_type_.GetPayload(); }
120 };
121
122 // Constructs a full name in dotted notation from gathered names.
124
125 // Performs name inferring for added functions.
126 void InferFunctionsNames();
127
130 std::vector<FunctionLiteral*> funcs_to_infer_;
131 size_t scope_depth_ = 0;
132};
133
134
135} // namespace internal
136} // namespace v8
137
138#endif // V8_PARSING_FUNC_NAME_INFERRER_H_
State & operator=(const State &)=delete
void PushVariableName(const AstRawString *name)
FuncNameInferrer(const FuncNameInferrer &)=delete
base::SmallVector< Name, 8 > names_stack_
void AddFunction(FunctionLiteral *func_to_infer)
void PushEnclosingName(const AstRawString *name)
void PushLiteralName(const AstRawString *name)
FuncNameInferrer & operator=(const FuncNameInferrer &)=delete
std::vector< FunctionLiteral * > funcs_to_infer_
FuncNameInferrer(AstValueFactory *ast_value_factory)
#define DCHECK(condition)
Definition logging.h:482
const AstRawString * name() const
Name(const AstRawString *name, NameType type)
base::PointerWithPayload< const AstRawString, NameType, 2 > name_and_type_