// Copyright 2018 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.

#ifndef V8_OBJECTS_INSTANCE_TYPE_H_
#define V8_OBJECTS_INSTANCE_TYPE_H_

#include "src/elements-kind.h"
#include "src/objects-definitions.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

// We use the full 16 bits of the instance_type field to encode heap object
// instance types. All the high-order bits (bit 7-15) are cleared if the object
// is a string, and contain set bits if it is not a string.
const uint32_t kIsNotStringMask = 0xff80;
const uint32_t kStringTag = 0x0;

// Bit 6 indicates that the object is an internalized string (if set) or not.
// Bit 7 has to be clear as well.
const uint32_t kIsNotInternalizedMask = 0x40;
const uint32_t kNotInternalizedTag = 0x40;
const uint32_t kInternalizedTag = 0x0;

// If bit 7 is clear then bit 3 indicates whether the string consists of
// two-byte characters or one-byte characters.
const uint32_t kStringEncodingMask = 0x8;
const uint32_t kTwoByteStringTag = 0x0;
const uint32_t kOneByteStringTag = 0x8;

// If bit 7 is clear, the low-order 3 bits indicate the representation
// of the string.
const uint32_t kStringRepresentationMask = 0x07;
enum StringRepresentationTag {
  kSeqStringTag = 0x0,
  kConsStringTag = 0x1,
  kExternalStringTag = 0x2,
  kSlicedStringTag = 0x3,
  kThinStringTag = 0x5
};
const uint32_t kIsIndirectStringMask = 0x1;
const uint32_t kIsIndirectStringTag = 0x1;
STATIC_ASSERT((kSeqStringTag & kIsIndirectStringMask) == 0);       // NOLINT
STATIC_ASSERT((kExternalStringTag & kIsIndirectStringMask) == 0);  // NOLINT
STATIC_ASSERT((kConsStringTag & kIsIndirectStringMask) ==
              kIsIndirectStringTag);  // NOLINT
STATIC_ASSERT((kSlicedStringTag & kIsIndirectStringMask) ==
              kIsIndirectStringTag);  // NOLINT
STATIC_ASSERT((kThinStringTag & kIsIndirectStringMask) == kIsIndirectStringTag);

// If bit 7 is clear, then bit 4 indicates whether this two-byte
// string actually contains one byte data.
const uint32_t kOneByteDataHintMask = 0x10;
const uint32_t kOneByteDataHintTag = 0x10;

// If bit 7 is clear and string representation indicates an external string,
// then bit 5 indicates whether the data pointer is cached.
const uint32_t kUncachedExternalStringMask = 0x20;
const uint32_t kUncachedExternalStringTag = 0x20;

// A ConsString with an empty string as the right side is a candidate
// for being shortcut by the garbage collector. We don't allocate any
// non-flat internalized strings, so we do not shortcut them thereby
// avoiding turning internalized strings into strings. The bit-masks
// below contain the internalized bit as additional safety.
// See heap.cc, mark-compact.cc and objects-visiting.cc.
const uint32_t kShortcutTypeMask =
    kIsNotStringMask | kIsNotInternalizedMask | kStringRepresentationMask;
const uint32_t kShortcutTypeTag = kConsStringTag | kNotInternalizedTag;

static inline bool IsShortcutCandidate(int type) {
  return ((type & kShortcutTypeMask) == kShortcutTypeTag);
}

enum InstanceType : uint16_t {
  // String types.
  INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag |
                             kInternalizedTag,  // FIRST_PRIMITIVE_TYPE
  ONE_BYTE_INTERNALIZED_STRING_TYPE =
      kOneByteStringTag | kSeqStringTag | kInternalizedTag,
  EXTERNAL_INTERNALIZED_STRING_TYPE =
      kTwoByteStringTag | kExternalStringTag | kInternalizedTag,
  EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
      kOneByteStringTag | kExternalStringTag | kInternalizedTag,
  EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
      EXTERNAL_INTERNALIZED_STRING_TYPE | kOneByteDataHintTag |
      kInternalizedTag,
  UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE =
      EXTERNAL_INTERNALIZED_STRING_TYPE | kUncachedExternalStringTag |
      kInternalizedTag,
  UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE =
      EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kUncachedExternalStringTag |
      kInternalizedTag,
  UNCACHED_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE =
      EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
      kUncachedExternalStringTag | kInternalizedTag,
  STRING_TYPE = INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  ONE_BYTE_STRING_TYPE =
      ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  CONS_STRING_TYPE = kTwoByteStringTag | kConsStringTag | kNotInternalizedTag,
  CONS_ONE_BYTE_STRING_TYPE =
      kOneByteStringTag | kConsStringTag | kNotInternalizedTag,
  SLICED_STRING_TYPE =
      kTwoByteStringTag | kSlicedStringTag | kNotInternalizedTag,
  SLICED_ONE_BYTE_STRING_TYPE =
      kOneByteStringTag | kSlicedStringTag | kNotInternalizedTag,
  EXTERNAL_STRING_TYPE =
      EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  EXTERNAL_ONE_BYTE_STRING_TYPE =
      EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
      EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
      kNotInternalizedTag,
  UNCACHED_EXTERNAL_STRING_TYPE =
      UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE =
      UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE | kNotInternalizedTag,
  UNCACHED_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE =
      UNCACHED_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE |
      kNotInternalizedTag,
  THIN_STRING_TYPE = kTwoByteStringTag | kThinStringTag | kNotInternalizedTag,
  THIN_ONE_BYTE_STRING_TYPE =
      kOneByteStringTag | kThinStringTag | kNotInternalizedTag,

  // Non-string names
  SYMBOL_TYPE =
      1 + (kIsNotInternalizedMask | kUncachedExternalStringMask |
           kOneByteDataHintMask | kStringEncodingMask |
           kStringRepresentationMask),  // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE

  // Other primitives (cannot contain non-map-word pointers to heap objects).
  HEAP_NUMBER_TYPE,
  BIGINT_TYPE,
  ODDBALL_TYPE,  // LAST_PRIMITIVE_TYPE

  // Objects allocated in their own spaces (never in new space).
  MAP_TYPE,
  CODE_TYPE,

  // "Data", objects that cannot contain non-map-word pointers to heap
  // objects.
  MUTABLE_HEAP_NUMBER_TYPE,
  FOREIGN_TYPE,
  BYTE_ARRAY_TYPE,
  BYTECODE_ARRAY_TYPE,
  FREE_SPACE_TYPE,
  FIXED_INT8_ARRAY_TYPE,  // FIRST_FIXED_TYPED_ARRAY_TYPE
  FIXED_UINT8_ARRAY_TYPE,
  FIXED_INT16_ARRAY_TYPE,
  FIXED_UINT16_ARRAY_TYPE,
  FIXED_INT32_ARRAY_TYPE,
  FIXED_UINT32_ARRAY_TYPE,
  FIXED_FLOAT32_ARRAY_TYPE,
  FIXED_FLOAT64_ARRAY_TYPE,
  FIXED_UINT8_CLAMPED_ARRAY_TYPE,
  FIXED_BIGINT64_ARRAY_TYPE,
  FIXED_BIGUINT64_ARRAY_TYPE,  // LAST_FIXED_TYPED_ARRAY_TYPE
  FIXED_DOUBLE_ARRAY_TYPE,
  FEEDBACK_METADATA_TYPE,
  FILLER_TYPE,  // LAST_DATA_TYPE

  // Structs.
  ACCESS_CHECK_INFO_TYPE,
  ACCESSOR_INFO_TYPE,
  ACCESSOR_PAIR_TYPE,
  ALIASED_ARGUMENTS_ENTRY_TYPE,
  ALLOCATION_MEMENTO_TYPE,
  ASM_WASM_DATA_TYPE,
  ASYNC_GENERATOR_REQUEST_TYPE,
  CLASS_POSITIONS_TYPE,
  DEBUG_INFO_TYPE,
  FUNCTION_TEMPLATE_INFO_TYPE,
  FUNCTION_TEMPLATE_RARE_DATA_TYPE,
  INTERCEPTOR_INFO_TYPE,
  INTERPRETER_DATA_TYPE,
  MODULE_INFO_ENTRY_TYPE,
  MODULE_TYPE,
  OBJECT_TEMPLATE_INFO_TYPE,
  PROMISE_CAPABILITY_TYPE,
  PROMISE_REACTION_TYPE,
  PROTOTYPE_INFO_TYPE,
  SCRIPT_TYPE,
  STACK_FRAME_INFO_TYPE,
  STACK_TRACE_FRAME_TYPE,
  TUPLE2_TYPE,
  TUPLE3_TYPE,
  ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
  WASM_DEBUG_INFO_TYPE,
  WASM_EXCEPTION_TAG_TYPE,
  WASM_EXPORTED_FUNCTION_DATA_TYPE,

  CALLABLE_TASK_TYPE,  // FIRST_MICROTASK_TYPE
  CALLBACK_TASK_TYPE,
  PROMISE_FULFILL_REACTION_JOB_TASK_TYPE,
  PROMISE_REJECT_REACTION_JOB_TASK_TYPE,
  PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE,
  FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE,  // LAST_MICROTASK_TYPE

  ALLOCATION_SITE_TYPE,
  EMBEDDER_DATA_ARRAY_TYPE,
  // FixedArrays.
  FIXED_ARRAY_TYPE,  // FIRST_FIXED_ARRAY_TYPE
  OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
  HASH_TABLE_TYPE,        // FIRST_HASH_TABLE_TYPE
  ORDERED_HASH_MAP_TYPE,  // FIRST_DICTIONARY_TYPE
  ORDERED_HASH_SET_TYPE,
  ORDERED_NAME_DICTIONARY_TYPE,
  NAME_DICTIONARY_TYPE,
  GLOBAL_DICTIONARY_TYPE,
  NUMBER_DICTIONARY_TYPE,
  SIMPLE_NUMBER_DICTIONARY_TYPE,  // LAST_DICTIONARY_TYPE
  STRING_TABLE_TYPE,
  EPHEMERON_HASH_TABLE_TYPE,  // LAST_HASH_TABLE_TYPE
  SCOPE_INFO_TYPE,
  SCRIPT_CONTEXT_TABLE_TYPE,  // LAST_FIXED_ARRAY_TYPE,

  // Contexts.
  AWAIT_CONTEXT_TYPE,  // FIRST_CONTEXT_TYPE
  BLOCK_CONTEXT_TYPE,
  CATCH_CONTEXT_TYPE,
  DEBUG_EVALUATE_CONTEXT_TYPE,
  EVAL_CONTEXT_TYPE,
  FUNCTION_CONTEXT_TYPE,
  MODULE_CONTEXT_TYPE,
  NATIVE_CONTEXT_TYPE,
  SCRIPT_CONTEXT_TYPE,
  WITH_CONTEXT_TYPE,  // LAST_CONTEXT_TYPE

  WEAK_FIXED_ARRAY_TYPE,  // FIRST_WEAK_FIXED_ARRAY_TYPE
  TRANSITION_ARRAY_TYPE,  // LAST_WEAK_FIXED_ARRAY_TYPE

  // Misc.
  CALL_HANDLER_INFO_TYPE,
  CELL_TYPE,
  CODE_DATA_CONTAINER_TYPE,
  DESCRIPTOR_ARRAY_TYPE,
  FEEDBACK_CELL_TYPE,
  FEEDBACK_VECTOR_TYPE,
  LOAD_HANDLER_TYPE,
  PREPARSE_DATA_TYPE,
  PROPERTY_ARRAY_TYPE,
  PROPERTY_CELL_TYPE,
  SHARED_FUNCTION_INFO_TYPE,
  SMALL_ORDERED_HASH_MAP_TYPE,
  SMALL_ORDERED_HASH_SET_TYPE,
  SMALL_ORDERED_NAME_DICTIONARY_TYPE,
  STORE_HANDLER_TYPE,
  UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
  UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
  WEAK_ARRAY_LIST_TYPE,
  WEAK_CELL_TYPE,

  // All the following types are subtypes of JSReceiver, which corresponds to
  // objects in the JS sense. The first and the last type in this range are
  // the two forms of function. This organization enables using the same
  // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range.
  // Some of the following instance types are exposed in v8.h, so to not
  // unnecessarily change the ABI when we introduce new instance types in the
  // future, we leave some space between instance types.
  JS_PROXY_TYPE = 0x0400,  // FIRST_JS_RECEIVER_TYPE
  JS_GLOBAL_OBJECT_TYPE,   // FIRST_JS_OBJECT_TYPE
  JS_GLOBAL_PROXY_TYPE,
  JS_MODULE_NAMESPACE_TYPE,
  // Like JS_API_OBJECT_TYPE, but requires access checks and/or has
  // interceptors.
  JS_SPECIAL_API_OBJECT_TYPE = 0x0410,  // LAST_SPECIAL_RECEIVER_TYPE
  JS_VALUE_TYPE,                        // LAST_CUSTOM_ELEMENTS_RECEIVER
  // Like JS_OBJECT_TYPE, but created from API function.
  JS_API_OBJECT_TYPE = 0x0420,
  JS_OBJECT_TYPE,
  JS_ARGUMENTS_TYPE,
  JS_ARRAY_BUFFER_TYPE,
  JS_ARRAY_ITERATOR_TYPE,
  JS_ARRAY_TYPE,
  JS_ASYNC_FROM_SYNC_ITERATOR_TYPE,
  JS_ASYNC_FUNCTION_OBJECT_TYPE,
  JS_ASYNC_GENERATOR_OBJECT_TYPE,
  JS_CONTEXT_EXTENSION_OBJECT_TYPE,
  JS_DATE_TYPE,
  JS_ERROR_TYPE,
  JS_GENERATOR_OBJECT_TYPE,
  JS_MAP_TYPE,
  JS_MAP_KEY_ITERATOR_TYPE,
  JS_MAP_KEY_VALUE_ITERATOR_TYPE,
  JS_MAP_VALUE_ITERATOR_TYPE,
  JS_MESSAGE_OBJECT_TYPE,
  JS_PROMISE_TYPE,
  JS_REGEXP_TYPE,
  JS_REGEXP_STRING_ITERATOR_TYPE,
  JS_SET_TYPE,
  JS_SET_KEY_VALUE_ITERATOR_TYPE,
  JS_SET_VALUE_ITERATOR_TYPE,
  JS_STRING_ITERATOR_TYPE,
  JS_WEAK_REF_TYPE,
  JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE,
  JS_FINALIZATION_GROUP_TYPE,
  JS_WEAK_MAP_TYPE,
  JS_WEAK_SET_TYPE,

  JS_TYPED_ARRAY_TYPE,
  JS_DATA_VIEW_TYPE,

#ifdef V8_INTL_SUPPORT
  JS_INTL_V8_BREAK_ITERATOR_TYPE,
  JS_INTL_COLLATOR_TYPE,
  JS_INTL_DATE_TIME_FORMAT_TYPE,
  JS_INTL_LIST_FORMAT_TYPE,
  JS_INTL_LOCALE_TYPE,
  JS_INTL_NUMBER_FORMAT_TYPE,
  JS_INTL_PLURAL_RULES_TYPE,
  JS_INTL_RELATIVE_TIME_FORMAT_TYPE,
  JS_INTL_SEGMENT_ITERATOR_TYPE,
  JS_INTL_SEGMENTER_TYPE,
#endif  // V8_INTL_SUPPORT

  WASM_EXCEPTION_TYPE,
  WASM_GLOBAL_TYPE,
  WASM_INSTANCE_TYPE,
  WASM_MEMORY_TYPE,
  WASM_MODULE_TYPE,
  WASM_TABLE_TYPE,
  JS_BOUND_FUNCTION_TYPE,
  JS_FUNCTION_TYPE,  // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE

  // Pseudo-types
  FIRST_TYPE = 0x0,
  LAST_TYPE = JS_FUNCTION_TYPE,
  FIRST_STRING_TYPE = FIRST_TYPE,
  FIRST_NAME_TYPE = FIRST_STRING_TYPE,
  LAST_NAME_TYPE = SYMBOL_TYPE,
  FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE,
  LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
  FIRST_NONSTRING_TYPE = SYMBOL_TYPE,
  FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE,
  LAST_PRIMITIVE_TYPE = ODDBALL_TYPE,
  FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE,
  LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE,
  // Boundaries for testing if given HeapObject is a subclass of FixedArray.
  FIRST_FIXED_ARRAY_TYPE = FIXED_ARRAY_TYPE,
  LAST_FIXED_ARRAY_TYPE = SCRIPT_CONTEXT_TABLE_TYPE,
  // Boundaries for testing if given HeapObject is a subclass of HashTable
  FIRST_HASH_TABLE_TYPE = HASH_TABLE_TYPE,
  LAST_HASH_TABLE_TYPE = EPHEMERON_HASH_TABLE_TYPE,
  // Boundaries for testing if given HeapObject is a subclass of Dictionary
  FIRST_DICTIONARY_TYPE = ORDERED_HASH_MAP_TYPE,
  LAST_DICTIONARY_TYPE = SIMPLE_NUMBER_DICTIONARY_TYPE,
  // Boundaries for testing if given HeapObject is a subclass of WeakFixedArray.
  FIRST_WEAK_FIXED_ARRAY_TYPE = WEAK_FIXED_ARRAY_TYPE,
  LAST_WEAK_FIXED_ARRAY_TYPE = TRANSITION_ARRAY_TYPE,
  // Boundaries for testing if given HeapObject is a Context
  FIRST_CONTEXT_TYPE = AWAIT_CONTEXT_TYPE,
  LAST_CONTEXT_TYPE = WITH_CONTEXT_TYPE,
  // Boundaries for testing if given HeapObject is a subclass of Microtask.
  FIRST_MICROTASK_TYPE = CALLABLE_TASK_TYPE,
  LAST_MICROTASK_TYPE = FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE,
  // Boundaries for testing for a fixed typed array.
  FIRST_FIXED_TYPED_ARRAY_TYPE = FIXED_INT8_ARRAY_TYPE,
  LAST_FIXED_TYPED_ARRAY_TYPE = FIXED_BIGUINT64_ARRAY_TYPE,
  // Boundary for promotion to old space.
  LAST_DATA_TYPE = FILLER_TYPE,
  // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
  // Note that there is no range for JSObject or JSProxy, since their subtypes
  // are not continuous in this enum! The enum ranges instead reflect the
  // external class names, where proxies are treated as either ordinary objects,
  // or functions.
  FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE,
  LAST_JS_RECEIVER_TYPE = LAST_TYPE,
  // Boundaries for testing the types represented as JSObject
  FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE,
  LAST_JS_OBJECT_TYPE = LAST_TYPE,
  // Boundary for testing JSReceivers that need special property lookup handling
  LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE,
  // Boundary case for testing JSReceivers that may have elements while having
  // an empty fixed array as elements backing store. This is true for string
  // wrappers.
  LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,

  FIRST_SET_ITERATOR_TYPE = JS_SET_KEY_VALUE_ITERATOR_TYPE,
  LAST_SET_ITERATOR_TYPE = JS_SET_VALUE_ITERATOR_TYPE,

  FIRST_MAP_ITERATOR_TYPE = JS_MAP_KEY_ITERATOR_TYPE,
  LAST_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE,
};

// This constant is defined outside of the InstanceType enum because the
// string instance types are sparce and there's no such a string instance type.
// But it's still useful for range checks to have such a value.
constexpr InstanceType LAST_STRING_TYPE =
    static_cast<InstanceType>(FIRST_NONSTRING_TYPE - 1);

STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag);
STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
STATIC_ASSERT(JS_SPECIAL_API_OBJECT_TYPE == Internals::kJSSpecialApiObjectType);
STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType);

V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           InstanceType instance_type);

// List of object types that have a single unique instance type.
#define INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V)                                \
  V(AllocationSite, ALLOCATION_SITE_TYPE)                                    \
  V(BigInt, BIGINT_TYPE)                                                     \
  V(ObjectBoilerplateDescription, OBJECT_BOILERPLATE_DESCRIPTION_TYPE)       \
  V(BreakPoint, TUPLE2_TYPE)                                                 \
  V(BreakPointInfo, TUPLE2_TYPE)                                             \
  V(ByteArray, BYTE_ARRAY_TYPE)                                              \
  V(BytecodeArray, BYTECODE_ARRAY_TYPE)                                      \
  V(CallHandlerInfo, CALL_HANDLER_INFO_TYPE)                                 \
  V(Cell, CELL_TYPE)                                                         \
  V(Code, CODE_TYPE)                                                         \
  V(CachedTemplateObject, TUPLE3_TYPE)                                       \
  V(CodeDataContainer, CODE_DATA_CONTAINER_TYPE)                             \
  V(CoverageInfo, FIXED_ARRAY_TYPE)                                          \
  V(DescriptorArray, DESCRIPTOR_ARRAY_TYPE)                                  \
  V(EmbedderDataArray, EMBEDDER_DATA_ARRAY_TYPE)                             \
  V(EphemeronHashTable, EPHEMERON_HASH_TABLE_TYPE)                           \
  V(FeedbackCell, FEEDBACK_CELL_TYPE)                                        \
  V(FeedbackMetadata, FEEDBACK_METADATA_TYPE)                                \
  V(FeedbackVector, FEEDBACK_VECTOR_TYPE)                                    \
  V(FixedArrayExact, FIXED_ARRAY_TYPE)                                       \
  V(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)                               \
  V(Foreign, FOREIGN_TYPE)                                                   \
  V(FreeSpace, FREE_SPACE_TYPE)                                              \
  V(GlobalDictionary, GLOBAL_DICTIONARY_TYPE)                                \
  V(HeapNumber, HEAP_NUMBER_TYPE)                                            \
  V(JSArgumentsObject, JS_ARGUMENTS_TYPE)                                    \
  V(JSArgumentsObjectWithLength, JS_ARGUMENTS_TYPE)                          \
  V(JSArray, JS_ARRAY_TYPE)                                                  \
  V(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)                                     \
  V(JSArrayIterator, JS_ARRAY_ITERATOR_TYPE)                                 \
  V(JSAsyncFromSyncIterator, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE)               \
  V(JSAsyncFunctionObject, JS_ASYNC_FUNCTION_OBJECT_TYPE)                    \
  V(JSAsyncGeneratorObject, JS_ASYNC_GENERATOR_OBJECT_TYPE)                  \
  V(JSBoundFunction, JS_BOUND_FUNCTION_TYPE)                                 \
  V(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)              \
  V(JSDataView, JS_DATA_VIEW_TYPE)                                           \
  V(JSDate, JS_DATE_TYPE)                                                    \
  V(JSError, JS_ERROR_TYPE)                                                  \
  V(JSFunction, JS_FUNCTION_TYPE)                                            \
  V(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)                                   \
  V(JSGlobalProxy, JS_GLOBAL_PROXY_TYPE)                                     \
  V(JSMap, JS_MAP_TYPE)                                                      \
  V(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)                                 \
  V(JSModuleNamespace, JS_MODULE_NAMESPACE_TYPE)                             \
  V(JSPromise, JS_PROMISE_TYPE)                                              \
  V(JSProxy, JS_PROXY_TYPE)                                                  \
  V(JSRegExp, JS_REGEXP_TYPE)                                                \
  V(JSRegExpResult, JS_ARRAY_TYPE)                                           \
  V(JSRegExpStringIterator, JS_REGEXP_STRING_ITERATOR_TYPE)                  \
  V(JSSet, JS_SET_TYPE)                                                      \
  V(JSStringIterator, JS_STRING_ITERATOR_TYPE)                               \
  V(JSTypedArray, JS_TYPED_ARRAY_TYPE)                                       \
  V(JSValue, JS_VALUE_TYPE)                                                  \
  V(JSFinalizationGroup, JS_FINALIZATION_GROUP_TYPE)                         \
  V(JSFinalizationGroupCleanupIterator,                                      \
    JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE)                             \
  V(JSWeakMap, JS_WEAK_MAP_TYPE)                                             \
  V(JSWeakRef, JS_WEAK_REF_TYPE)                                             \
  V(JSWeakSet, JS_WEAK_SET_TYPE)                                             \
  V(LoadHandler, LOAD_HANDLER_TYPE)                                          \
  V(Map, MAP_TYPE)                                                           \
  V(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)                             \
  V(NameDictionary, NAME_DICTIONARY_TYPE)                                    \
  V(NativeContext, NATIVE_CONTEXT_TYPE)                                      \
  V(NumberDictionary, NUMBER_DICTIONARY_TYPE)                                \
  V(Oddball, ODDBALL_TYPE)                                                   \
  V(OrderedHashMap, ORDERED_HASH_MAP_TYPE)                                   \
  V(OrderedHashSet, ORDERED_HASH_SET_TYPE)                                   \
  V(OrderedNameDictionary, ORDERED_NAME_DICTIONARY_TYPE)                     \
  V(PreparseData, PREPARSE_DATA_TYPE)                                        \
  V(PropertyArray, PROPERTY_ARRAY_TYPE)                                      \
  V(PropertyCell, PROPERTY_CELL_TYPE)                                        \
  V(PropertyDescriptorObject, FIXED_ARRAY_TYPE)                              \
  V(ScopeInfo, SCOPE_INFO_TYPE)                                              \
  V(ScriptContextTable, SCRIPT_CONTEXT_TABLE_TYPE)                           \
  V(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)                           \
  V(SimpleNumberDictionary, SIMPLE_NUMBER_DICTIONARY_TYPE)                   \
  V(SmallOrderedHashMap, SMALL_ORDERED_HASH_MAP_TYPE)                        \
  V(SmallOrderedHashSet, SMALL_ORDERED_HASH_SET_TYPE)                        \
  V(SmallOrderedNameDictionary, SMALL_ORDERED_NAME_DICTIONARY_TYPE)          \
  V(SourcePositionTableWithFrameCache, TUPLE2_TYPE)                          \
  V(StoreHandler, STORE_HANDLER_TYPE)                                        \
  V(StringTable, STRING_TABLE_TYPE)                                          \
  V(Symbol, SYMBOL_TYPE)                                                     \
  V(TemplateObjectDescription, TUPLE2_TYPE)                                  \
  V(TransitionArray, TRANSITION_ARRAY_TYPE)                                  \
  V(UncompiledDataWithoutPreparseData,                                       \
    UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE)                              \
  V(UncompiledDataWithPreparseData, UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE) \
  V(WasmExceptionObject, WASM_EXCEPTION_TYPE)                                \
  V(WasmGlobalObject, WASM_GLOBAL_TYPE)                                      \
  V(WasmInstanceObject, WASM_INSTANCE_TYPE)                                  \
  V(WasmMemoryObject, WASM_MEMORY_TYPE)                                      \
  V(WasmModuleObject, WASM_MODULE_TYPE)                                      \
  V(WasmTableObject, WASM_TABLE_TYPE)                                        \
  V(WeakArrayList, WEAK_ARRAY_LIST_TYPE)                                     \
  V(WeakCell, WEAK_CELL_TYPE)
#ifdef V8_INTL_SUPPORT

#define INSTANCE_TYPE_CHECKERS_SINGLE(V)                     \
  INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V)                      \
  V(JSV8BreakIterator, JS_INTL_V8_BREAK_ITERATOR_TYPE)       \
  V(JSCollator, JS_INTL_COLLATOR_TYPE)                       \
  V(JSDateTimeFormat, JS_INTL_DATE_TIME_FORMAT_TYPE)         \
  V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE)                  \
  V(JSLocale, JS_INTL_LOCALE_TYPE)                           \
  V(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE)              \
  V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE)                \
  V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \
  V(JSSegmentIterator, JS_INTL_SEGMENT_ITERATOR_TYPE)        \
  V(JSSegmenter, JS_INTL_SEGMENTER_TYPE)

#else

#define INSTANCE_TYPE_CHECKERS_SINGLE(V) INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V)

#endif  // V8_INTL_SUPPORT

#define INSTANCE_TYPE_CHECKERS_RANGE(V)                             \
  V(Context, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)                 \
  V(Dictionary, FIRST_DICTIONARY_TYPE, LAST_DICTIONARY_TYPE)        \
  V(FixedArray, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE)      \
  V(FixedTypedArrayBase, FIRST_FIXED_TYPED_ARRAY_TYPE,              \
    LAST_FIXED_TYPED_ARRAY_TYPE)                                    \
  V(HashTable, FIRST_HASH_TABLE_TYPE, LAST_HASH_TABLE_TYPE)         \
  V(JSMapIterator, FIRST_MAP_ITERATOR_TYPE, LAST_MAP_ITERATOR_TYPE) \
  V(JSSetIterator, FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE) \
  V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE)           \
  V(Name, FIRST_NAME_TYPE, LAST_NAME_TYPE)                          \
  V(String, FIRST_STRING_TYPE, LAST_STRING_TYPE)                    \
  V(WeakFixedArray, FIRST_WEAK_FIXED_ARRAY_TYPE, LAST_WEAK_FIXED_ARRAY_TYPE)

#define INSTANCE_TYPE_CHECKERS_CUSTOM(V) \
  V(FixedArrayBase)                      \
  V(InternalizedString)                  \
  V(JSObject)                            \
  V(JSReceiver)

#define INSTANCE_TYPE_CHECKERS(V)  \
  INSTANCE_TYPE_CHECKERS_SINGLE(V) \
  INSTANCE_TYPE_CHECKERS_RANGE(V)  \
  INSTANCE_TYPE_CHECKERS_CUSTOM(V)

namespace InstanceTypeChecker {
#define IS_TYPE_FUNCTION_DECL(Type, ...) \
  V8_INLINE bool Is##Type(InstanceType instance_type);

INSTANCE_TYPE_CHECKERS(IS_TYPE_FUNCTION_DECL)

#define TYPED_ARRAY_IS_TYPE_FUNCTION_DECL(Type, ...) \
  IS_TYPE_FUNCTION_DECL(Fixed##Type##Array)
TYPED_ARRAYS(TYPED_ARRAY_IS_TYPE_FUNCTION_DECL)
#undef TYPED_ARRAY_IS_TYPE_FUNCTION_DECL

#define STRUCT_IS_TYPE_FUNCTION_DECL(NAME, Name, name) \
  IS_TYPE_FUNCTION_DECL(Name)
STRUCT_LIST(STRUCT_IS_TYPE_FUNCTION_DECL)
#undef STRUCT_IS_TYPE_FUNCTION_DECL

#undef IS_TYPE_FUNCTION_DECL
}  // namespace InstanceTypeChecker

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_INSTANCE_TYPE_H_