1 // Copyright 2019 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_OBJECTS_FUNCTION_KIND_H_
6 #define V8_OBJECTS_FUNCTION_KIND_H_
7
8 #include "src/base/bounds.h"
9 #include "src/base/macros.h"
10
11 namespace v8 {
12 namespace internal {
13
14 enum class FunctionKind : uint8_t {
15 // BEGIN constructable functions
16 kNormalFunction,
17 kModule,
18 kAsyncModule,
19 // BEGIN class constructors
20 // BEGIN base constructors
21 kBaseConstructor,
22 // BEGIN default constructors
23 kDefaultBaseConstructor,
24 // END base constructors
25 // BEGIN derived constructors
26 kDefaultDerivedConstructor,
27 // END default constructors
28 kDerivedConstructor,
29 // END derived constructors
30 // END class constructors
31 // END constructable functions.
32 // BEGIN accessors
33 kGetterFunction,
34 kStaticGetterFunction,
35 kSetterFunction,
36 kStaticSetterFunction,
37 // END accessors
38 // BEGIN arrow functions
39 kArrowFunction,
40 // BEGIN async functions
41 kAsyncArrowFunction,
42 // END arrow functions
43 kAsyncFunction,
44 // BEGIN concise methods 1
45 kAsyncConciseMethod,
46 kStaticAsyncConciseMethod,
47 // BEGIN generators
48 kAsyncConciseGeneratorMethod,
49 kStaticAsyncConciseGeneratorMethod,
50 // END concise methods 1
51 kAsyncGeneratorFunction,
52 // END async functions
53 kGeneratorFunction,
54 // BEGIN concise methods 2
55 kConciseGeneratorMethod,
56 kStaticConciseGeneratorMethod,
57 // END generators
58 kConciseMethod,
59 kStaticConciseMethod,
60 kClassMembersInitializerFunction,
61 kClassStaticInitializerFunction,
62 // END concise methods 2
63 kInvalid,
64
65 kLastFunctionKind = kClassStaticInitializerFunction,
66 };
67
68 constexpr int kFunctionKindBitSize = 5;
69 STATIC_ASSERT(static_cast<int>(FunctionKind::kLastFunctionKind) <
70 (1 << kFunctionKindBitSize));
71
IsArrowFunction(FunctionKind kind)72 inline bool IsArrowFunction(FunctionKind kind) {
73 return base::IsInRange(kind, FunctionKind::kArrowFunction,
74 FunctionKind::kAsyncArrowFunction);
75 }
76
IsModule(FunctionKind kind)77 inline bool IsModule(FunctionKind kind) {
78 return base::IsInRange(kind, FunctionKind::kModule,
79 FunctionKind::kAsyncModule);
80 }
81
IsAsyncModule(FunctionKind kind)82 inline bool IsAsyncModule(FunctionKind kind) {
83 return kind == FunctionKind::kAsyncModule;
84 }
85
IsAsyncGeneratorFunction(FunctionKind kind)86 inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
87 return base::IsInRange(kind, FunctionKind::kAsyncConciseGeneratorMethod,
88 FunctionKind::kAsyncGeneratorFunction);
89 }
90
IsGeneratorFunction(FunctionKind kind)91 inline bool IsGeneratorFunction(FunctionKind kind) {
92 return base::IsInRange(kind, FunctionKind::kAsyncConciseGeneratorMethod,
93 FunctionKind::kStaticConciseGeneratorMethod);
94 }
95
IsAsyncFunction(FunctionKind kind)96 inline bool IsAsyncFunction(FunctionKind kind) {
97 return base::IsInRange(kind, FunctionKind::kAsyncArrowFunction,
98 FunctionKind::kAsyncGeneratorFunction);
99 }
100
IsResumableFunction(FunctionKind kind)101 inline bool IsResumableFunction(FunctionKind kind) {
102 return IsGeneratorFunction(kind) || IsAsyncFunction(kind) || IsModule(kind);
103 }
104
IsConciseMethod(FunctionKind kind)105 inline bool IsConciseMethod(FunctionKind kind) {
106 return base::IsInRange(kind, FunctionKind::kAsyncConciseMethod,
107 FunctionKind::kStaticAsyncConciseGeneratorMethod) ||
108 base::IsInRange(kind, FunctionKind::kConciseGeneratorMethod,
109 FunctionKind::kClassStaticInitializerFunction);
110 }
111
IsStrictFunctionWithoutPrototype(FunctionKind kind)112 inline bool IsStrictFunctionWithoutPrototype(FunctionKind kind) {
113 return base::IsInRange(kind, FunctionKind::kGetterFunction,
114 FunctionKind::kAsyncArrowFunction) ||
115 base::IsInRange(kind, FunctionKind::kAsyncConciseMethod,
116 FunctionKind::kStaticAsyncConciseGeneratorMethod) ||
117 base::IsInRange(kind, FunctionKind::kConciseGeneratorMethod,
118 FunctionKind::kClassStaticInitializerFunction);
119 }
120
IsGetterFunction(FunctionKind kind)121 inline bool IsGetterFunction(FunctionKind kind) {
122 return base::IsInRange(kind, FunctionKind::kGetterFunction,
123 FunctionKind::kStaticGetterFunction);
124 }
125
IsSetterFunction(FunctionKind kind)126 inline bool IsSetterFunction(FunctionKind kind) {
127 return base::IsInRange(kind, FunctionKind::kSetterFunction,
128 FunctionKind::kStaticSetterFunction);
129 }
130
IsAccessorFunction(FunctionKind kind)131 inline bool IsAccessorFunction(FunctionKind kind) {
132 return base::IsInRange(kind, FunctionKind::kGetterFunction,
133 FunctionKind::kStaticSetterFunction);
134 }
135
IsDefaultConstructor(FunctionKind kind)136 inline bool IsDefaultConstructor(FunctionKind kind) {
137 return base::IsInRange(kind, FunctionKind::kDefaultBaseConstructor,
138 FunctionKind::kDefaultDerivedConstructor);
139 }
140
IsBaseConstructor(FunctionKind kind)141 inline bool IsBaseConstructor(FunctionKind kind) {
142 return base::IsInRange(kind, FunctionKind::kBaseConstructor,
143 FunctionKind::kDefaultBaseConstructor);
144 }
145
IsDerivedConstructor(FunctionKind kind)146 inline bool IsDerivedConstructor(FunctionKind kind) {
147 return base::IsInRange(kind, FunctionKind::kDefaultDerivedConstructor,
148 FunctionKind::kDerivedConstructor);
149 }
150
IsClassConstructor(FunctionKind kind)151 inline bool IsClassConstructor(FunctionKind kind) {
152 return base::IsInRange(kind, FunctionKind::kBaseConstructor,
153 FunctionKind::kDerivedConstructor);
154 }
155
IsClassMembersInitializerFunction(FunctionKind kind)156 inline bool IsClassMembersInitializerFunction(FunctionKind kind) {
157 return base::IsInRange(kind, FunctionKind::kClassMembersInitializerFunction,
158 FunctionKind::kClassStaticInitializerFunction);
159 }
160
IsConstructable(FunctionKind kind)161 inline bool IsConstructable(FunctionKind kind) {
162 return base::IsInRange(kind, FunctionKind::kNormalFunction,
163 FunctionKind::kDerivedConstructor);
164 }
165
IsStatic(FunctionKind kind)166 inline bool IsStatic(FunctionKind kind) {
167 switch (kind) {
168 case FunctionKind::kStaticGetterFunction:
169 case FunctionKind::kStaticSetterFunction:
170 case FunctionKind::kStaticConciseMethod:
171 case FunctionKind::kStaticConciseGeneratorMethod:
172 case FunctionKind::kStaticAsyncConciseMethod:
173 case FunctionKind::kStaticAsyncConciseGeneratorMethod:
174 case FunctionKind::kClassStaticInitializerFunction:
175 return true;
176 default:
177 return false;
178 }
179 }
180
BindsSuper(FunctionKind kind)181 inline bool BindsSuper(FunctionKind kind) {
182 return IsConciseMethod(kind) || IsAccessorFunction(kind) ||
183 IsClassConstructor(kind);
184 }
185
IsAwaitAsIdentifierDisallowed(FunctionKind kind)186 inline bool IsAwaitAsIdentifierDisallowed(FunctionKind kind) {
187 // 'await' is always disallowed as an identifier in module contexts. Callers
188 // should short-circuit the module case instead of calling this.
189 DCHECK(!IsModule(kind));
190 return IsAsyncFunction(kind) ||
191 kind == FunctionKind::kClassStaticInitializerFunction;
192 }
193
FunctionKind2String(FunctionKind kind)194 inline const char* FunctionKind2String(FunctionKind kind) {
195 switch (kind) {
196 case FunctionKind::kNormalFunction:
197 return "NormalFunction";
198 case FunctionKind::kArrowFunction:
199 return "ArrowFunction";
200 case FunctionKind::kGeneratorFunction:
201 return "GeneratorFunction";
202 case FunctionKind::kConciseMethod:
203 return "ConciseMethod";
204 case FunctionKind::kStaticConciseMethod:
205 return "StaticConciseMethod";
206 case FunctionKind::kDerivedConstructor:
207 return "DerivedConstructor";
208 case FunctionKind::kBaseConstructor:
209 return "BaseConstructor";
210 case FunctionKind::kGetterFunction:
211 return "GetterFunction";
212 case FunctionKind::kStaticGetterFunction:
213 return "StaticGetterFunction";
214 case FunctionKind::kSetterFunction:
215 return "SetterFunction";
216 case FunctionKind::kStaticSetterFunction:
217 return "StaticSetterFunction";
218 case FunctionKind::kAsyncFunction:
219 return "AsyncFunction";
220 case FunctionKind::kModule:
221 return "Module";
222 case FunctionKind::kAsyncModule:
223 return "AsyncModule";
224 case FunctionKind::kClassMembersInitializerFunction:
225 return "ClassMembersInitializerFunction";
226 case FunctionKind::kClassStaticInitializerFunction:
227 return "ClassStaticInitializerFunction";
228 case FunctionKind::kDefaultBaseConstructor:
229 return "DefaultBaseConstructor";
230 case FunctionKind::kDefaultDerivedConstructor:
231 return "DefaultDerivedConstructor";
232 case FunctionKind::kAsyncArrowFunction:
233 return "AsyncArrowFunction";
234 case FunctionKind::kAsyncConciseMethod:
235 return "AsyncConciseMethod";
236 case FunctionKind::kStaticAsyncConciseMethod:
237 return "StaticAsyncConciseMethod";
238 case FunctionKind::kConciseGeneratorMethod:
239 return "ConciseGeneratorMethod";
240 case FunctionKind::kStaticConciseGeneratorMethod:
241 return "StaticConciseGeneratorMethod";
242 case FunctionKind::kAsyncConciseGeneratorMethod:
243 return "AsyncConciseGeneratorMethod";
244 case FunctionKind::kStaticAsyncConciseGeneratorMethod:
245 return "StaticAsyncConciseGeneratorMethod";
246 case FunctionKind::kAsyncGeneratorFunction:
247 return "AsyncGeneratorFunction";
248 case FunctionKind::kInvalid:
249 return "Invalid";
250 }
251 UNREACHABLE();
252 }
253
254 inline std::ostream& operator<<(std::ostream& os, FunctionKind kind) {
255 return os << FunctionKind2String(kind);
256 }
257
258 } // namespace internal
259 } // namespace v8
260
261 #endif // V8_OBJECTS_FUNCTION_KIND_H_
262