• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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