#ifndef V8_OBJECTS_FUNCTION_KIND_H_
#define V8_OBJECTS_FUNCTION_KIND_H_
#include "src/base/bounds.h"
#include "src/base/macros.h"
namespace v8 {
namespace internal {
enum class FunctionKind : uint8_t {
kNormalFunction,
kModule,
kModuleWithTopLevelAwait,
kBaseConstructor,
kDefaultBaseConstructor,
kDefaultDerivedConstructor,
kDerivedConstructor,
kGetterFunction,
kStaticGetterFunction,
kSetterFunction,
kStaticSetterFunction,
kArrowFunction,
kAsyncArrowFunction,
kAsyncFunction,
kAsyncConciseMethod,
kStaticAsyncConciseMethod,
kAsyncConciseGeneratorMethod,
kStaticAsyncConciseGeneratorMethod,
kAsyncGeneratorFunction,
kGeneratorFunction,
kConciseGeneratorMethod,
kStaticConciseGeneratorMethod,
kConciseMethod,
kStaticConciseMethod,
kClassMembersInitializerFunction,
kClassMembersInitializerFunctionPrecededByStatic,
kClassStaticInitializerFunction,
kClassStaticInitializerFunctionPrecededByMember,
kInvalid,
kLastFunctionKind = kClassStaticInitializerFunctionPrecededByMember,
};
constexpr int kFunctionKindBitSize = 5;
static_assert(static_cast<int>(FunctionKind::kLastFunctionKind) <
(1 << kFunctionKindBitSize));
inline bool IsArrowFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kArrowFunction,
FunctionKind::kAsyncArrowFunction);
}
inline bool IsModule(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kModule,
FunctionKind::kModuleWithTopLevelAwait);
}
inline bool IsModuleWithTopLevelAwait(FunctionKind kind) {
return kind == FunctionKind::kModuleWithTopLevelAwait;
}
inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kAsyncConciseGeneratorMethod,
FunctionKind::kAsyncGeneratorFunction);
}
inline bool IsGeneratorFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kAsyncConciseGeneratorMethod,
FunctionKind::kStaticConciseGeneratorMethod);
}
inline bool IsAsyncFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kAsyncArrowFunction,
FunctionKind::kAsyncGeneratorFunction);
}
inline bool IsResumableFunction(FunctionKind kind) {
return IsGeneratorFunction(kind) || IsAsyncFunction(kind) || IsModule(kind);
}
inline bool IsConciseMethod(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kAsyncConciseMethod,
FunctionKind::kStaticAsyncConciseGeneratorMethod) ||
base::IsInRange(
kind, FunctionKind::kConciseGeneratorMethod,
FunctionKind::kClassStaticInitializerFunctionPrecededByMember);
}
inline bool IsStrictFunctionWithoutPrototype(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kGetterFunction,
FunctionKind::kAsyncArrowFunction) ||
base::IsInRange(kind, FunctionKind::kAsyncConciseMethod,
FunctionKind::kStaticAsyncConciseGeneratorMethod) ||
base::IsInRange(
kind, FunctionKind::kConciseGeneratorMethod,
FunctionKind::kClassStaticInitializerFunctionPrecededByMember);
}
inline bool IsGetterFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kGetterFunction,
FunctionKind::kStaticGetterFunction);
}
inline bool IsSetterFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kSetterFunction,
FunctionKind::kStaticSetterFunction);
}
inline bool IsAccessorFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kGetterFunction,
FunctionKind::kStaticSetterFunction);
}
inline bool IsDefaultConstructor(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kDefaultBaseConstructor,
FunctionKind::kDefaultDerivedConstructor);
}
inline bool IsBaseConstructor(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kBaseConstructor,
FunctionKind::kDefaultBaseConstructor);
}
inline bool IsDerivedConstructor(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kDefaultDerivedConstructor,
FunctionKind::kDerivedConstructor);
}
inline bool IsClassConstructor(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kBaseConstructor,
FunctionKind::kDerivedConstructor);
}
inline bool IsClassInitializerFunction(FunctionKind kind) {
return base::IsInRange(
kind, FunctionKind::kClassMembersInitializerFunction,
FunctionKind::kClassStaticInitializerFunctionPrecededByMember);
}
inline bool IsClassInstanceInitializerFunction(FunctionKind kind) {
return base::IsInRange(
kind, FunctionKind::kClassMembersInitializerFunction,
FunctionKind::kClassMembersInitializerFunctionPrecededByStatic);
}
inline bool IsClassStaticInitializerFunction(FunctionKind kind) {
return base::IsInRange(
kind, FunctionKind::kClassStaticInitializerFunction,
FunctionKind::kClassStaticInitializerFunctionPrecededByMember);
}
inline bool IsConstructable(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kNormalFunction,
FunctionKind::kDerivedConstructor);
}
inline bool IsStatic(FunctionKind kind) {
switch (kind) {
case FunctionKind::kStaticGetterFunction:
case FunctionKind::kStaticSetterFunction:
case FunctionKind::kStaticConciseMethod:
case FunctionKind::kStaticConciseGeneratorMethod:
case FunctionKind::kStaticAsyncConciseMethod:
case FunctionKind::kStaticAsyncConciseGeneratorMethod:
case FunctionKind::kClassStaticInitializerFunction:
case FunctionKind::kClassStaticInitializerFunctionPrecededByMember:
return true;
default:
return false;
}
}
inline bool BindsSuper(FunctionKind kind) {
return IsConciseMethod(kind) || IsAccessorFunction(kind) ||
IsClassConstructor(kind);
}
inline const char* FunctionKind2String(FunctionKind kind) {
switch (kind) {
case FunctionKind::kNormalFunction:
return "NormalFunction";
case FunctionKind::kArrowFunction:
return "ArrowFunction";
case FunctionKind::kGeneratorFunction:
return "GeneratorFunction";
case FunctionKind::kConciseMethod:
return "ConciseMethod";
case FunctionKind::kStaticConciseMethod:
return "StaticConciseMethod";
case FunctionKind::kDerivedConstructor:
return "DerivedConstructor";
case FunctionKind::kBaseConstructor:
return "BaseConstructor";
case FunctionKind::kGetterFunction:
return "GetterFunction";
case FunctionKind::kStaticGetterFunction:
return "StaticGetterFunction";
case FunctionKind::kSetterFunction:
return "SetterFunction";
case FunctionKind::kStaticSetterFunction:
return "StaticSetterFunction";
case FunctionKind::kAsyncFunction:
return "AsyncFunction";
case FunctionKind::kModule:
return "Module";
case FunctionKind::kModuleWithTopLevelAwait:
return "AsyncModule";
case FunctionKind::kClassMembersInitializerFunction:
return "ClassMembersInitializerFunction";
case FunctionKind::kClassStaticInitializerFunction:
return "ClassStaticInitializerFunction";
case FunctionKind::kClassMembersInitializerFunctionPrecededByStatic:
return "ClassMembersInitializerFunctionPrecededByStatic";
case FunctionKind::kClassStaticInitializerFunctionPrecededByMember:
return "ClassStaticInitializerFunctionPrecededByMember";
case FunctionKind::kDefaultBaseConstructor:
return "DefaultBaseConstructor";
case FunctionKind::kDefaultDerivedConstructor:
return "DefaultDerivedConstructor";
case FunctionKind::kAsyncArrowFunction:
return "AsyncArrowFunction";
case FunctionKind::kAsyncConciseMethod:
return "AsyncConciseMethod";
case FunctionKind::kStaticAsyncConciseMethod:
return "StaticAsyncConciseMethod";
case FunctionKind::kConciseGeneratorMethod:
return "ConciseGeneratorMethod";
case FunctionKind::kStaticConciseGeneratorMethod:
return "StaticConciseGeneratorMethod";
case FunctionKind::kAsyncConciseGeneratorMethod:
return "AsyncConciseGeneratorMethod";
case FunctionKind::kStaticAsyncConciseGeneratorMethod:
return "StaticAsyncConciseGeneratorMethod";
case FunctionKind::kAsyncGeneratorFunction:
return "AsyncGeneratorFunction";
case FunctionKind::kInvalid:
return "Invalid";
}
UNREACHABLE();
}
inline std::ostream& operator<<(std::ostream& os, FunctionKind kind) {
return os << FunctionKind2String(kind);
}
}
}
#endif