1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_JS_HCLASS_H
17#define ECMASCRIPT_JS_HCLASS_H
18
19#include "ecmascript/ecma_macros.h"
20#include "ecmascript/elements.h"
21#include "ecmascript/js_tagged_value.h"
22#include "ecmascript/mem/tagged_object.h"
23#include "ecmascript/mem/barriers.h"
24#include "ecmascript/mem/slots.h"
25#include "ecmascript/mem/visitor.h"
26#include "ecmascript/property_attributes.h"
27
28#include "libpandabase/utils/bit_field.h"
29
30/*
31 *                         JS Object and JS HClass Layout
32 *
33 *      Properties                         JS Object                    JS HClass
34 *      +------------+                     +------------+               +------------------+
35 *      |arrayHClass + <---------|         |JS HClass   +-------------->|   meta hclass    |
36 *      +------------+           |         +------------+               +------------------+
37 *      | property 0 |           |         |Hash        |               |   hclass level   |
38 *      +------------+           |         +------------+               +------------------+
39 *      | property 1 |           |-------  |Properties  |               |   supers[]       |
40 *      +------------+                     +------------+               +------------------+
41 *      |...         |           |-------  |Elements    |               |   vtable[]       |
42 *      +------------+           |         +------------+               +------------------+
43 *                               |         |inl-prop-0  |               |   prototype      |
44 *      Elements                 |         +------------+               +------------------+
45 *      +------------+           |         |inl-prop-1  |               |   layout         |
46 *      |arrayHClass + <---------|         +------------+               +------------------+
47 *      +------------+                     |...         |               |   transitions    |
48 *      | value 0    |                     +------------+               +------------------+
49 *      +------------+                                                  |    parent        |
50 *      | value 1    |                                                  +------------------+
51 *      +------------+                                                  |ProtoChangeMarker |
52 *      |...         |                                                  +------------------+
53 *      +------------+                                                  |    EnumCache     |
54 *                                                                      +------------------+
55 *
56 *                          Proto: [[Prototype]] in Ecma spec
57 *                          Layout: record key and attr
58 *                          ProtoChangeMarker, ProtoChangeDetails: monitor [[prototype]] chain
59 *                          EnumCache: use for for-in syntax
60 *
61 */
62namespace panda::ecmascript {
63class ProtoChangeDetails;
64class PropertyLookupResult;
65class SharedHeap;
66class JSSharedArray;
67class LayoutInfo;
68class NameDictionary;
69namespace pgo {
70    class HClassLayoutDesc;
71    class PGOHClassTreeDesc;
72    class PGOHandler;
73} // namespace pgo
74using HClassLayoutDesc = pgo::HClassLayoutDesc;
75using PGOHClassTreeDesc = pgo::PGOHClassTreeDesc;
76using PGOHandler = pgo::PGOHandler;
77
78struct Reference;
79
80// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
81#define JSTYPE_DECL       /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
82    INVALID = 0,          /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
83        JS_OBJECT,        /* JS_OBJECT_FIRST ////////////////////////////////////////////////////////////////////// */ \
84        JS_SHARED_OBJECT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
85        JS_REALM,         /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
86        JS_FUNCTION_BASE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
87        JS_FUNCTION,      /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
88        JS_SHARED_FUNCTION,            /* /////////////////////////////////////////////////////////////////-PADDING */ \
89        JS_PROXY_REVOC_FUNCTION,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
90        JS_PROMISE_REACTIONS_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \
91        JS_PROMISE_EXECUTOR_FUNCTION,  /* /////////////////////////////////////////////////////////////////-PADDING */ \
92        JS_ASYNC_MODULE_FULFILLED_FUNCTION, /* ////////////////////////////////////////////////////////////-PADDING */ \
93        JS_ASYNC_MODULE_REJECTED_FUNCTION, /* /////////////////////////////////////////////////////////////-PADDING */ \
94        JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
95        JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
96        JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN, /* ///////////////////////////////////////-PADDING */ \
97        JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION,  /* ///////////////////////////////////////////////////////-PADDING */ \
98        JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
99        JS_PROMISE_FINALLY_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
100        JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION,  /* ///////////////////////////////////////////////////-PADDING */ \
101        JS_GENERATOR_FUNCTION, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
102        JS_ASYNC_GENERATOR_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
103        JS_ASYNC_FUNCTION, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
104        JS_SHARED_ASYNC_FUNCTION, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
105        JS_INTL_BOUND_FUNCTION, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
106        JS_ASYNC_AWAIT_STATUS_FUNCTION, /* ////////////////////////////////////////////////////////////////-PADDING */ \
107        JS_BOUND_FUNCTION, /*  //////////////////////////////////////////////////////////////////////////////////// */ \
108                                                                                                                       \
109        JS_ERROR,           /* JS_ERROR_FIRST /////////////////////////////////////////////////////////////-PADDING */ \
110        JS_EVAL_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
111        JS_RANGE_ERROR,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
112        JS_REFERENCE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
113        JS_TYPE_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
114        JS_AGGREGATE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
115        JS_URI_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
116        JS_SYNTAX_ERROR,    /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
117        JS_OOM_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
118        JS_TERMINATION_ERROR, /* JS_ERROR_LAST //////////////////////////////////////////////////////////////////// */ \
119                                                                                                                       \
120        JS_REG_EXP,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
121        JS_SET,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
122        JS_SHARED_SET, /*  ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
123        JS_MAP,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
124        JS_SHARED_MAP, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
125        JS_WEAK_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
126        JS_WEAK_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
127        JS_WEAK_REF, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
128        JS_FINALIZATION_REGISTRY, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
129        JS_DATE,     /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
130        JS_ITERATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
131        JS_ASYNCITERATOR, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
132        JS_ASYNC_FROM_SYNC_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
133        JS_FORIN_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
134        JS_MAP_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
135        JS_SHARED_MAP_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
136        JS_SET_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
137        JS_SHARED_SET_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
138        JS_REG_EXP_ITERATOR,        /* ////////////////////////////////////////////////////////////////////-PADDING */ \
139        JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
140        JS_API_DEQUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
141        JS_API_HASHMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
142        JS_API_HASHSET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
143        JS_API_LIGHT_WEIGHT_MAP_ITERATOR, /* //////////////////////////////////////////////////////////////-PADDING */ \
144        JS_API_LIGHT_WEIGHT_SET_ITERATOR,  /* /////////////////////////////////////////////////////////////-PADDING */ \
145        JS_API_PLAIN_ARRAY_ITERATOR,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
146        JS_API_QUEUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
147        JS_API_STACK_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
148        JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
149        JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
150        JS_API_VECTOR_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
151        JS_API_BITVECTOR_ITERATOR,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
152        JS_API_LINKED_LIST_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
153        JS_API_LIST_ITERATOR,    /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
154        JS_ARRAY_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
155        JS_SHARED_ARRAY_ITERATOR, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
156        JS_SEGMENT_ITERATOR,       /* /////////////////////////////////////////////////////////////////////-PADDING */ \
157        JS_STRING_ITERATOR,      /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
158        JS_INTL, /* ///////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
159        JS_LOCALE, /* /////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
160        JS_DATE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
161        JS_RELATIVE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
162        JS_NUMBER_FORMAT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
163        JS_COLLATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
164        JS_PLURAL_RULES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
165        JS_DISPLAYNAMES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
166        JS_LIST_FORMAT,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
167        JS_SEGMENTER, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
168        JS_SEGMENTS, /* /////////////////////////////////////////////////////////////////////////// ///////-PADDING */ \
169                                                                                                                       \
170        JS_ARRAY_BUFFER, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
171        JS_SHARED_ARRAY_BUFFER, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
172        JS_SENDABLE_ARRAY_BUFFER, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
173        JS_PROMISE,      /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
174        JS_DATA_VIEW,    /* /////////////////////////////////////////////////////////////////////////////////////// */ \
175        JS_ARGUMENTS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
176        JS_GENERATOR_OBJECT,  /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
177        JS_ASYNC_GENERATOR_OBJECT,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
178        JS_ASYNC_FUNC_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
179                                                                                                                       \
180        /* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \
181        JS_ARRAY,       /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
182        JS_SHARED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
183        JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
184        JS_API_LIGHT_WEIGHT_MAP,      /* //////////////////////////////////////////////////////////////////-PADDING */ \
185        JS_API_LIGHT_WEIGHT_SET, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
186        JS_API_VECTOR,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
187        JS_API_BITVECTOR,     /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
188        JS_API_LINKED_LIST, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
189        JS_API_LIST,       /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
190        JS_API_HASH_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
191        JS_API_HASH_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
192        JS_API_TREE_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
193        JS_API_TREE_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
194        JS_API_DEQUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
195        JS_API_STACK,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
196        JS_API_PLAIN_ARRAY, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
197        JS_API_QUEUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
198        JS_TYPED_ARRAY, /* JS_TYPED_ARRAY_FIRST /////////////////////////////////////////////////////////////////// */ \
199        JS_INT8_ARRAY,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
200        JS_UINT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
201        JS_UINT8_CLAMPED_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
202        JS_INT16_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
203        JS_UINT16_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
204        JS_INT32_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
205        JS_UINT32_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
206        JS_FLOAT32_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
207        JS_FLOAT64_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
208        JS_BIGINT64_ARRAY,      /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
209        JS_BIGUINT64_ARRAY,     /* JS_TYPED_ARRAY_LAST //////////////////////////////////////////////////////////// */ \
210        JS_SHARED_TYPED_ARRAY,  /* JS_SHARED_TYPED_ARRAY_FIRST //////////////////////////////////////////////////// */ \
211        JS_SHARED_INT8_ARRAY,  /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
212        JS_SHARED_UINT8_ARRAY, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
213        JS_SHARED_UINT8_CLAMPED_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \
214        JS_SHARED_INT16_ARRAY,         /* /////////////////////////////////////////////////////////////////-PADDING */ \
215        JS_SHARED_UINT16_ARRAY,        /* /////////////////////////////////////////////////////////////////-PADDING */ \
216        JS_SHARED_INT32_ARRAY,         /* /////////////////////////////////////////////////////////////////-PADDING */ \
217        JS_SHARED_UINT32_ARRAY,        /* /////////////////////////////////////////////////////////////////-PADDING */ \
218        JS_SHARED_FLOAT32_ARRAY,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
219        JS_SHARED_FLOAT64_ARRAY,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
220        JS_SHARED_BIGINT64_ARRAY,      /* /////////////////////////////////////////////////////////////////-PADDING */ \
221        JS_SHARED_BIGUINT64_ARRAY,     /* JS_SHARED_TYPED_ARRAY_LAST ////////////////////////////////////////////// */ \
222        JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \
223        JS_MODULE_NAMESPACE, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
224        JS_CJS_MODULE, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
225        JS_CJS_EXPORTS, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
226        JS_CJS_REQUIRE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
227        NATIVE_MODULE_FAILURE_INFO, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
228        JS_GLOBAL_OBJECT, /* JS_OBJECT_LAST////////////////////////////////////////////////////////////////-PADDING */ \
229        JS_PROXY, /* ECMA_OBJECT_LAST ///////////////////////////////////////////////////////////////////////////// */ \
230                                                                                                                       \
231        HCLASS,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
232        LINE_STRING,   /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
233        CONSTANT_STRING,  /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
234        SLICED_STRING,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
235        TREE_STRING,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
236        BIGINT,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
237        TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
238        MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
239        BYTE_ARRAY,   /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
240        LEXICAL_ENV,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
241        SENDABLE_ENV,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */\
242        TAGGED_DICTIONARY, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
243        CONSTANT_POOL, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
244        PROFILE_TYPE_INFO, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
245        COW_MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
246        COW_TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
247        LINKED_NODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
248        RB_TREENODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
249        FREE_OBJECT_WITH_ONE_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
250        FREE_OBJECT_WITH_NONE_FIELD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
251        FREE_OBJECT_WITH_TWO_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
252        JS_NATIVE_POINTER, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
253        GLOBAL_ENV,        /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
254        ACCESSOR_DATA,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
255        INTERNAL_ACCESSOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
256        SYMBOL, /* ////////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
257        JS_GENERATOR_CONTEXT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
258        PROTOTYPE_HANDLER,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
259        TRANSITION_HANDLER,   /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
260        TRANS_WITH_PROTO_HANDLER,    /* ///////////////////////////////////////////////////////////////////-PADDING */ \
261        STORE_TS_HANDLER,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
262        PROPERTY_BOX, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
263        PROTO_CHANGE_MARKER, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
264        MARKER_CELL, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
265        TRACK_INFO,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
266        PROTOTYPE_INFO,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
267        TEMPLATE_MAP,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
268        PROGRAM,       /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
269        METHOD,     /* ////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
270        CLASS_LITERAL,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
271                                                                                                                       \
272        PROMISE_CAPABILITY, /* JS_RECORD_FIRST //////////////////////////////////////////////////////////////////// */ \
273        PROMISE_RECORD,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
274        RESOLVING_FUNCTIONS_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
275        PROMISE_REACTIONS,          /* ////////////////////////////////////////////////////////////////////-PADDING */ \
276        ASYNC_GENERATOR_REQUEST, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
277        ASYNC_ITERATOR_RECORD,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
278        PROMISE_ITERATOR_RECORD,    /* ////////////////////////////////////////////////////////////////////-PADDING */ \
279        MICRO_JOB_QUEUE, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
280        PENDING_JOB,     /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
281        MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
282        SOURCE_TEXT_MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
283        IMPORTENTRY_RECORD, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
284        LOCAL_EXPORTENTRY_RECORD, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
285        INDIRECT_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
286        STAR_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
287        RESOLVEDBINDING_RECORD, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
288        RESOLVEDINDEXBINDING_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
289        RESOLVEDRECORDINDEXBINDING_RECORD, /* /////////////////////////////////////////////////////////////-PADDING */ \
290        RESOLVEDRECORDBINDING_RECORD, /* //////////////////////////////////////////////////////////////////-PADDING */ \
291        CELL_RECORD,          /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
292        COMPLETION_RECORD, /* JS_RECORD_LAST ////////////////////////////////////////////////////////////////////// */ \
293        MACHINE_CODE_OBJECT,                                                                                           \
294        CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
295                                                                                                                       \
296        PROFILE_TYPE_INFO_CELL_0,  /* PROFILE_TYPE_INFO_CELL_FIRST ////////////////////////////////////////-PADDING */ \
297        PROFILE_TYPE_INFO_CELL_1,  /* /////////////////////////////////////////////////////////////////////-PADDING */ \
298        PROFILE_TYPE_INFO_CELL_N,  /* PROFILE_TYPE_INFO_CELL_LAST /////////////////////////////////////////-PADDING */ \
299                                                                                                                       \
300        EXTRA_PROFILE_TYPE_INFO,      /* //////////////////////////////////////////////////////////////////-PADDING */ \
301        FUNCTION_TEMPLATE,            /* //////////////////////////////////////////////////////////////////-PADDING */ \
302                                                                                                                       \
303        VTABLE,                       /* //////////////////////////////////////////////////////////////////-PADDING */ \
304        AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
305        TYPE_LAST = AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \
306                                                                                                                       \
307        JS_FUNCTION_FIRST = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \
308        JS_FUNCTION_LAST = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* /////////////////////////////////////////////-PADDING */ \
309                                                                                                                       \
310        JS_OBJECT_FIRST = JS_OBJECT, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
311        JS_OBJECT_LAST = JS_GLOBAL_OBJECT, /* /////////////////////////////////////////////////////////////-PADDING */ \
312                                                                                                                       \
313        ECMA_OBJECT_FIRST = JS_OBJECT, /* /////////////////////////////////////////////////////////////////-PADDING */ \
314        ECMA_OBJECT_LAST = JS_PROXY,    /* ////////////////////////////////////////////////////////////////-PADDING */ \
315                                                                                                                       \
316        JS_ERROR_FIRST = JS_ERROR,      /* ////////////////////////////////////////////////////////////////-PADDING */ \
317        JS_ERROR_LAST = JS_TERMINATION_ERROR,    /* ///////////////////////////////////////////////////////-PADDING */ \
318                                                                                                                       \
319        JS_ITERATOR_FIRST = JS_ITERATOR,      /* //////////////////////////////////////////////////////////-PADDING */ \
320        JS_ITERATOR_LAST = JS_STRING_ITERATOR, /* /////////////////////////////////////////////////////////-PADDING */ \
321                                                                                                                       \
322        JS_RECORD_FIRST = PROMISE_CAPABILITY, /* //////////////////////////////////////////////////////////-PADDING */ \
323        JS_RECORD_LAST = COMPLETION_RECORD,    /* /////////////////////////////////////////////////////////-PADDING */ \
324                                                                                                                       \
325        JS_TYPED_ARRAY_FIRST = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
326        JS_TYPED_ARRAY_LAST = JS_BIGUINT64_ARRAY, /* //////////////////////////////////////////////////////-PADDING */ \
327                                                                                                                       \
328        JS_SHARED_TYPED_ARRAY_FIRST = JS_SHARED_TYPED_ARRAY, /* ///////////////////////////////////////////-PADDING */ \
329        JS_SHARED_TYPED_ARRAY_LAST = JS_SHARED_BIGUINT64_ARRAY, /* ////////////////////////////////////////-PADDING */ \
330                                                                                                                       \
331        MODULE_RECORD_FIRST = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \
332        MODULE_RECORD_LAST = SOURCE_TEXT_MODULE_RECORD, /* ////////////////////////////////////////////////-PADDING */ \
333                                                                                                                       \
334        STRING_FIRST = LINE_STRING, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
335        STRING_LAST = TREE_STRING,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
336                                                                                                                       \
337        PROFILE_TYPE_INFO_CELL_FIRST = PROFILE_TYPE_INFO_CELL_0,  /* //////////////////////////////////////-PADDING */ \
338        PROFILE_TYPE_INFO_CELL_LAST = PROFILE_TYPE_INFO_CELL_N    /* //////////////////////////////////////-PADDING */
339
340enum class JSType : uint8_t {
341    JSTYPE_DECL,
342};
343
344// EnumCache:
345// +-----------------+----------------------+
346// |      value      |     status           |
347// +-----------------+----------------------+
348// |      null       |    uninitialized     |
349// ------------------------------------------
350// |    undefined    | a fast path to check |
351// |                 | simple enum cache    |
352// ------------------------------------------
353// |   empty array   |  enum keys is empty  |
354// ------------------------------------------
355// | non-empty array |  non-empty enum keys |
356// +----------------------------------------+
357// structure of non-empty array of EnumCache:
358// 0: an int value indicating enum cache kind
359// 1-n: enum keys
360namespace EnumCache {
361static constexpr uint32_t ENUM_CACHE_HEADER_SIZE = 1;
362static constexpr uint32_t ENUM_CACHE_KIND_OFFSET = 0;
363enum class EnumCacheKind : uint8_t {
364    NONE = 0,
365    SIMPLE,        // simple enum cache(used in for-in)
366                   // make sure EnumCache is empty array only for SIMPLE
367    PROTOCHAIN,    // enum cache with prototype chain info(used in for-in)
368    ONLY_OWN_KEYS  // enum cache with only own enum keys(used in Json.stringify and Object.keys)
369};
370
371}  // namespace EnumCache
372
373struct TransitionResult {
374    bool isTagged;
375    bool isTransition;
376    JSTaggedValue value;
377};
378
379class JSHClass : public TaggedObject {
380public:
381    static constexpr int TYPE_BITFIELD_NUM = 8;
382    static constexpr int LEVEL_BTTFIELD_NUM = 5;
383    static constexpr int ELEMENTS_KIND_BITFIELD_NUM = 5;
384    static constexpr unsigned BITS_PER_BYTE = 8;
385    using ObjectTypeBits = BitField<JSType, 0, TYPE_BITFIELD_NUM>;                                // 8
386    using CallableBit = ObjectTypeBits::NextFlag;                                                 // 9
387    using ConstructorBit = CallableBit::NextFlag;                                                 // 10
388    using ExtensibleBit = ConstructorBit::NextFlag;                                               // 11
389    using IsPrototypeBit = ExtensibleBit::NextFlag;                                               // 12
390    using ElementsKindBits = IsPrototypeBit::NextField<ElementsKind, ELEMENTS_KIND_BITFIELD_NUM>; // 13-17
391    using DictionaryElementBits = ElementsKindBits::NextFlag;                                     // 18
392    using IsDictionaryBit = DictionaryElementBits::NextFlag;                                      // 19
393    using IsStableElementsBit = IsDictionaryBit::NextFlag;                                        // 20
394    using HasConstructorBits = IsStableElementsBit::NextFlag;                                     // 21
395    using IsClassConstructorOrPrototypeBit = HasConstructorBits::NextFlag;                        // 22
396    using IsNativeBindingObjectBit = IsClassConstructorOrPrototypeBit::NextFlag;                  // 23
397    using IsTSBit = IsNativeBindingObjectBit::NextFlag;                                           // 24
398    using LevelBit = IsTSBit::NextField<uint32_t, LEVEL_BTTFIELD_NUM>;                            // 25-29
399    using IsJSFunctionBit = LevelBit::NextFlag;                                                   // 30
400    using IsOnHeap = IsJSFunctionBit::NextFlag;                                                   // 31
401    using IsJSSharedBit = IsOnHeap::NextFlag;                                                     // 32
402    using BitFieldLastBit = IsJSSharedBit;
403    static_assert(BitFieldLastBit::START_BIT + BitFieldLastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
404
405    static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4;
406    static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5;
407    static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS =
408        PropertyAttributes::OFFSET_BITFIELD_NUM + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED;
409    static constexpr int MAX_OBJECT_SIZE_IN_WORDS = (1U << OFFSET_MAX_OBJECT_SIZE_IN_WORDS) - 1;
410
411    using NumberOfPropsBits = BitField<uint32_t, 0, PropertyAttributes::OFFSET_BITFIELD_NUM>;                  // 10
412    using InlinedPropsStartBits = NumberOfPropsBits::NextField<uint32_t,
413        OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED>;                                                      // 15
414    using ObjectSizeInWordsBits = InlinedPropsStartBits::NextField<uint32_t, OFFSET_MAX_OBJECT_SIZE_IN_WORDS>; // 30
415    using HasDeletePropertyBit = ObjectSizeInWordsBits::NextFlag;                                              //
416    using IsAllTaggedPropBit = HasDeletePropertyBit::NextFlag;                                                 // 32
417    using BitField1LastBit = IsAllTaggedPropBit;
418    static_assert(BitField1LastBit::START_BIT + BitField1LastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
419
420    static JSHClass *Cast(const TaggedObject *object)
421    {
422        ASSERT(JSTaggedValue(object).IsJSHClass());
423        return static_cast<JSHClass *>(const_cast<TaggedObject *>(object));
424    }
425
426    inline size_t SizeFromJSHClass(TaggedObject *header);
427    inline bool HasReferenceField();
428
429    // size need to add inlined property numbers
430    void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps);
431    // for sharedHeap
432    void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps,
433        const JSHandle<JSTaggedValue> &layout);
434    static JSHandle<JSHClass> Clone(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
435                                    bool withoutInlinedProperties = false, uint32_t incInlinedProperties = 0);
436    static JSHandle<JSHClass> CloneWithoutInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
437    static JSHandle<JSHClass> CloneWithElementsKind(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
438                                                    const ElementsKind kind, bool isPrototype);
439
440    static void TransitionElementsToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
441    static void OptimizeAsFastElements(const JSThread *thread, JSHandle<JSObject> obj);
442    static void OptimizeAsFastProperties(const JSThread *thread, const JSHandle<JSObject> &obj,
443                                         const std::vector<int> &indexArray = {}, bool isDictionary = false);
444    template<bool checkDuplicateKeys = false>
445    static JSHandle<JSHClass> SetPropertyOfObjHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass,
446                                                     const JSHandle<JSTaggedValue> &key,
447                                                     const PropertyAttributes &attr,
448                                                     const Representation &rep);
449    static void PUBLIC_API AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj,
450                                       const JSHandle<JSTaggedValue> &key, const PropertyAttributes &attr,
451                                       const Representation &rep = Representation::NONE);
452
453    inline static void RestoreElementsKindToGeneric(JSHClass *newJsHClass);
454
455    static JSHandle<JSHClass> TransitionExtension(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
456    static void ReBuildFunctionInheritanceRelationship(const JSThread *thread,
457                                                       const JSHandle<JSTaggedValue> &proto,
458                                                       const JSHandle<JSTaggedValue> &baseIhc,
459                                                       const JSHandle<JSTaggedValue> &transIhc,
460                                                       const JSHandle<JSTaggedValue> &transPhc);
461    static JSHandle<JSHClass> TransitionProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
462                                              const JSHandle<JSTaggedValue> &proto, bool isChangeProto = false);
463    static JSHClass *FindTransitionProtoForAOT(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
464                                               const JSHandle<JSTaggedValue> &proto);
465    static JSHandle<JSHClass> TransProtoWithoutLayout(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
466                                                      const JSHandle<JSTaggedValue> &proto);
467    static JSHandle<JSHClass> CloneWithAddProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
468                                                const JSHandle<JSTaggedValue> &key,
469                                                const JSHandle<JSTaggedValue> &proto);
470    static void TransitionToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
471    static void TransitionForRepChange(const JSThread *thread, const JSHandle<JSObject> &receiver,
472                                       const JSHandle<JSTaggedValue> &key, PropertyAttributes attr);
473    static void TransitionForElementsKindChange(const JSThread *thread, const JSHandle<JSObject> &receiver,
474                                         const ElementsKind newKind);
475    static bool IsInitialArrayHClassWithElementsKind(const JSThread *thread, const JSHClass *targetHClass,
476                                                     const ElementsKind targetKind);
477    static bool PUBLIC_API TransitToElementsKindUncheck(const JSThread *thread, const JSHandle<JSObject> &obj,
478                                                        ElementsKind newKind);
479    static void PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSArray> &array,
480                                                 ElementsKind newKind = ElementsKind::NONE);
481    static bool PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSObject> &object,
482                                                 const JSHandle<JSTaggedValue> &value,
483                                                 ElementsKind kind = ElementsKind::NONE);
484    static TransitionResult PUBLIC_API ConvertOrTransitionWithRep(const JSThread *thread,
485        const JSHandle<JSObject> &receiver, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value,
486        PropertyAttributes &attr);
487
488    static void UpdateFieldType(JSHClass *hclass, const PropertyAttributes &attr);
489    static JSHClass *FindFieldOwnHClass(JSHClass *hclass, const PropertyAttributes &attr);
490    static void VisitAndUpdateLayout(JSHClass *ownHClass, const PropertyAttributes &attr);
491
492    static JSHandle<JSTaggedValue> EnableProtoChangeMarker(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
493    static JSHandle<JSTaggedValue> EnablePHCProtoChangeMarker(
494        const JSThread *thread, const JSHandle<JSHClass> &protoClass);
495
496    static void NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> oldHclass, JSHandle<JSHClass> newHclass,
497                                    JSTaggedValue addedKey = JSTaggedValue::Undefined());
498
499    static void NotifyAccessorChanged(const JSThread *thread, JSHandle<JSHClass> hclass);
500
501    static void RegisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
502
503    static bool UnregisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
504
505    static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread,
506                                                              const JSHandle<JSHClass> &jshclass);
507
508    static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, const JSHandle<JSObject> &obj);
509
510    inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key,
511                                      const PropertyAttributes &metaData);
512
513    static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
514
515    static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
516                                   JSTaggedValue addedKey = JSTaggedValue::Undefined());
517
518    static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass,
519                             const JSHandle<JSHClass> &newHclass);
520
521    static bool IsNeedNotifyHclassChangedForAotTransition(const JSThread *thread, const JSHandle<JSHClass> &hclass,
522                                                          JSTaggedValue key);
523
524    static JSHandle<JSTaggedValue> ParseKeyFromPGOCString(ObjectFactory* factory,
525                                                          const CString& key,
526                                                          const PGOHandler& handler);
527
528    inline void ClearBitField()
529    {
530        SetProfileType(0ULL);
531        SetBitField(0UL);
532        SetBitField1(0UL);
533    }
534
535    inline JSType GetObjectType() const
536    {
537        uint32_t bits = GetBitField();
538        return ObjectTypeBits::Decode(bits);
539    }
540
541    inline void SetObjectType(JSType type)
542    {
543        uint32_t bits = GetBitField();
544        uint32_t newVal = ObjectTypeBits::Update(bits, type);
545        SetBitField(newVal);
546    }
547
548    inline void SetCallable(bool flag)
549    {
550        CallableBit::Set<uint32_t>(flag, GetBitFieldAddr());
551    }
552
553    inline void SetConstructor(bool flag) const
554    {
555        ConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
556    }
557
558    inline void SetExtensible(bool flag) const
559    {
560        ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr());
561    }
562
563    inline void SetIsPrototype(bool flag) const
564    {
565        IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
566    }
567
568    inline void SetClassConstructor(bool flag) const
569    {
570        IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
571        SetConstructor(flag);
572    }
573
574    inline void SetClassPrototype(bool flag) const
575    {
576        IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
577        SetIsPrototype(flag);
578    }
579
580    inline void SetIsNativeBindingObject(bool flag) const
581    {
582        IsNativeBindingObjectBit::Set<uint32_t>(flag, GetBitFieldAddr());
583    }
584
585    inline void SetIsDictionaryMode(bool flag) const
586    {
587        IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
588    }
589
590    inline void SetTS(bool flag) const
591    {
592        IsTSBit::Set<uint32_t>(flag, GetBitFieldAddr());
593    }
594
595    inline void SetIsJSFunction(bool flag) const
596    {
597        IsJSFunctionBit::Set<uint32_t>(flag, GetBitFieldAddr());
598    }
599
600    inline void SetIsOnHeap(bool flag) const
601    {
602        IsOnHeap::Set<uint32_t>(flag, GetBitFieldAddr());
603    }
604
605    inline bool IsJSObject() const
606    {
607        return IsJSTypeObject(GetObjectType());
608    }
609
610    inline bool IsOnlyJSObject() const
611    {
612        return GetObjectType() == JSType::JS_OBJECT;
613    }
614
615    inline bool IsECMAObject() const
616    {
617        JSType jsType = GetObjectType();
618        return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST);
619    }
620
621    inline bool ShouldSetDefaultSupers() const
622    {
623        return IsECMAObject() || IsStringOrSymbol();
624    }
625
626    inline bool IsRealm() const
627    {
628        return GetObjectType() == JSType::JS_REALM;
629    }
630
631    inline bool IsHClass() const
632    {
633        return GetObjectType() == JSType::HCLASS;
634    }
635
636    inline bool IsString() const
637    {
638        JSType jsType = GetObjectType();
639        return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST);
640    }
641
642    inline bool IsLineString() const
643    {
644        return GetObjectType() == JSType::LINE_STRING;
645    }
646
647    inline bool IsConstantString() const
648    {
649        return GetObjectType() == JSType::CONSTANT_STRING;
650    }
651
652    inline bool IsSlicedString() const
653    {
654        return GetObjectType() == JSType::SLICED_STRING;
655    }
656
657    inline bool IsTreeString() const
658    {
659        return GetObjectType() == JSType::TREE_STRING;
660    }
661
662    inline bool IsBigInt() const
663    {
664        return GetObjectType() == JSType::BIGINT;
665    }
666
667    inline bool IsSymbol() const
668    {
669        return GetObjectType() == JSType::SYMBOL;
670    }
671
672    inline bool IsStringOrSymbol() const
673    {
674        JSType jsType = GetObjectType();
675        return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST) || (jsType == JSType::SYMBOL);
676    }
677
678    inline bool IsTaggedArray() const
679    {
680        JSType jsType = GetObjectType();
681        switch (jsType) {
682            case JSType::TAGGED_ARRAY:
683            case JSType::TAGGED_DICTIONARY:
684            case JSType::LEXICAL_ENV:
685            case JSType::SENDABLE_ENV:
686            case JSType::CONSTANT_POOL:
687            case JSType::PROFILE_TYPE_INFO:
688            case JSType::AOT_LITERAL_INFO:
689            case JSType::VTABLE:
690            case JSType::COW_TAGGED_ARRAY:
691            case JSType::MUTANT_TAGGED_ARRAY:
692            case JSType::COW_MUTANT_TAGGED_ARRAY:
693                return true;
694            default:
695                return false;
696        }
697    }
698
699    inline bool IsLexicalEnv() const
700    {
701        return GetObjectType() == JSType::LEXICAL_ENV;
702    }
703    inline bool IsByteArray() const
704    {
705        return GetObjectType() == JSType::BYTE_ARRAY;
706    }
707
708    inline bool IsConstantPool() const
709    {
710        return GetObjectType() == JSType::CONSTANT_POOL;
711    }
712
713    inline bool IsDictionary() const
714    {
715        return GetObjectType() == JSType::TAGGED_DICTIONARY;
716    }
717
718    inline bool IsCOWArray() const
719    {
720        // Copy On Write ARRAY.
721        return GetObjectType() == JSType::COW_TAGGED_ARRAY ||
722               GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY;
723    }
724
725    inline bool IsMutantTaggedArray() const
726    {
727        return GetObjectType() == JSType::MUTANT_TAGGED_ARRAY ||
728               GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY;
729    }
730
731    inline bool IsJSNativePointer() const
732    {
733        return GetObjectType() == JSType::JS_NATIVE_POINTER;
734    }
735
736    inline bool IsJSSymbol() const
737    {
738        return GetObjectType() == JSType::SYMBOL;
739    }
740
741    inline bool IsJSArray() const
742    {
743        return GetObjectType() == JSType::JS_ARRAY;
744    }
745
746    inline bool IsTypedArray() const
747    {
748        JSType jsType = GetObjectType();
749        return (JSType::JS_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_TYPED_ARRAY_LAST);
750    }
751
752    inline bool IsSharedTypedArray() const
753    {
754        JSType jsType = GetObjectType();
755        return (JSType::JS_SHARED_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_SHARED_TYPED_ARRAY_LAST);
756    }
757
758    inline bool HasOrdinaryGet() const
759    {
760        return (IsSpecialContainer() || IsModuleNamespace() || IsBigInt64Array());
761    }
762
763    inline bool IsJSTypedArray() const
764    {
765        return GetObjectType() == JSType::JS_TYPED_ARRAY;
766    }
767
768    inline bool IsJSInt8Array() const
769    {
770        return GetObjectType() == JSType::JS_INT8_ARRAY;
771    }
772
773    inline bool IsJSUint8Array() const
774    {
775        return GetObjectType() == JSType::JS_UINT8_ARRAY;
776    }
777
778    inline bool IsJSUint8ClampedArray() const
779    {
780        return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY;
781    }
782
783    inline bool IsJSInt16Array() const
784    {
785        return GetObjectType() == JSType::JS_INT16_ARRAY;
786    }
787
788    inline bool IsJSUint16Array() const
789    {
790        return GetObjectType() == JSType::JS_UINT16_ARRAY;
791    }
792
793    inline bool IsJSInt32Array() const
794    {
795        return GetObjectType() == JSType::JS_INT32_ARRAY;
796    }
797
798    inline bool IsJSUint32Array() const
799    {
800        return GetObjectType() == JSType::JS_UINT32_ARRAY;
801    }
802
803    inline bool IsJSFloat32Array() const
804    {
805        return GetObjectType() == JSType::JS_FLOAT32_ARRAY;
806    }
807
808    inline bool IsJSFloat64Array() const
809    {
810        return GetObjectType() == JSType::JS_FLOAT64_ARRAY;
811    }
812
813    inline bool IsJSBigInt64Array() const
814    {
815        return GetObjectType() == JSType::JS_BIGINT64_ARRAY;
816    }
817
818    inline bool IsJSBigUint64Array() const
819    {
820        return GetObjectType() == JSType::JS_BIGUINT64_ARRAY;
821    }
822
823    inline bool IsJSSharedTypedArray() const
824    {
825        return GetObjectType() == JSType::JS_SHARED_TYPED_ARRAY;
826    }
827
828    inline bool IsJSSharedInt8Array() const
829    {
830        return GetObjectType() == JSType::JS_SHARED_INT8_ARRAY;
831    }
832
833    inline bool IsJSSharedUint8Array() const
834    {
835        return GetObjectType() == JSType::JS_SHARED_UINT8_ARRAY;
836    }
837
838    inline bool IsJSSharedUint8ClampedArray() const
839    {
840        return GetObjectType() == JSType::JS_SHARED_UINT8_CLAMPED_ARRAY;
841    }
842
843    inline bool IsJSSharedInt16Array() const
844    {
845        return GetObjectType() == JSType::JS_SHARED_INT16_ARRAY;
846    }
847
848    inline bool IsJSSharedUint16Array() const
849    {
850        return GetObjectType() == JSType::JS_SHARED_UINT16_ARRAY;
851    }
852
853    inline bool IsJSSharedInt32Array() const
854    {
855        return GetObjectType() == JSType::JS_SHARED_INT32_ARRAY;
856    }
857
858    inline bool IsJSSharedUint32Array() const
859    {
860        return GetObjectType() == JSType::JS_SHARED_UINT32_ARRAY;
861    }
862
863    inline bool IsJSSharedFloat32Array() const
864    {
865        return GetObjectType() == JSType::JS_SHARED_FLOAT32_ARRAY;
866    }
867
868    inline bool IsJSSharedFloat64Array() const
869    {
870        return GetObjectType() == JSType::JS_SHARED_FLOAT64_ARRAY;
871    }
872
873    inline bool IsJSSharedBigInt64Array() const
874    {
875        return GetObjectType() == JSType::JS_SHARED_BIGINT64_ARRAY;
876    }
877
878    inline bool IsJSSharedBigUint64Array() const
879    {
880        return GetObjectType() == JSType::JS_SHARED_BIGUINT64_ARRAY;
881    }
882
883    inline bool IsBigInt64Array() const
884    {
885        JSType jsType = GetObjectType();
886        return jsType == JSType::JS_SHARED_BIGUINT64_ARRAY || jsType == JSType::JS_SHARED_BIGINT64_ARRAY ||
887               jsType == JSType::JS_BIGUINT64_ARRAY || jsType == JSType::JS_BIGINT64_ARRAY;
888    }
889
890    inline bool IsJsGlobalEnv() const
891    {
892        return GetObjectType() == JSType::GLOBAL_ENV;
893    }
894
895    inline bool IsJSFunctionBase() const
896    {
897        JSType jsType = GetObjectType();
898        return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION;
899    }
900
901    inline bool IsJsBoundFunction() const
902    {
903        return GetObjectType() == JSType::JS_BOUND_FUNCTION;
904    }
905
906    inline bool IsJSIntlBoundFunction() const
907    {
908        return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION;
909    }
910
911    inline bool IsJSProxyRevocFunction() const
912    {
913        return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION;
914    }
915
916    inline bool IsJSAsyncFunction() const
917    {
918        return GetObjectType() == JSType::JS_ASYNC_FUNCTION || GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
919    }
920
921    inline bool IsJSSharedAsyncFunction() const
922    {
923        return GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
924    }
925
926    inline bool IsJSAsyncAwaitStatusFunction() const
927    {
928        return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION;
929    }
930
931    inline bool IsJSPromiseReactionFunction() const
932    {
933        return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION;
934    }
935
936    inline bool IsJSPromiseExecutorFunction() const
937    {
938        return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION;
939    }
940
941    inline bool IsJSAsyncModuleFulfilledFunction() const
942    {
943        return GetObjectType() == JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION;
944    }
945
946    inline bool IsJSAsyncModuleRejectedFunction() const
947    {
948        return GetObjectType() == JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION;
949    }
950
951    inline bool IsJSAsyncFromSyncIterUnwarpFunction() const
952    {
953        return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION;
954    }
955
956    inline bool IsJSPromiseAllResolveElementFunction() const
957    {
958        return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION;
959    }
960
961    inline bool IsJSAsyncGeneratorResNextRetProRstFtn() const
962    {
963        return GetObjectType() == JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN;
964    }
965
966    inline bool IsJSPromiseAnyRejectElementFunction() const
967    {
968        return GetObjectType() == JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION;
969    }
970
971    inline bool IsJSPromiseAllSettledElementFunction() const
972    {
973        return GetObjectType() == JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION;
974    }
975
976    inline bool IsJSPromiseFinallyFunction() const
977    {
978        return GetObjectType() == JSType::JS_PROMISE_FINALLY_FUNCTION;
979    }
980
981    inline bool IsJSPromiseValueThunkOrThrowerFunction() const
982    {
983        return GetObjectType() == JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION;
984    }
985
986    inline bool IsMicroJobQueue() const
987    {
988        return GetObjectType() == JSType::MICRO_JOB_QUEUE;
989    }
990
991    inline bool IsPendingJob() const
992    {
993        return GetObjectType() == JSType::PENDING_JOB;
994    }
995
996    inline bool IsJsPrimitiveRef() const
997    {
998        return GetObjectType() == JSType::JS_PRIMITIVE_REF;
999    }
1000
1001    bool IsJSSet() const
1002    {
1003        return GetObjectType() == JSType::JS_SET;
1004    }
1005
1006    bool IsJSSharedSet() const
1007    {
1008        return GetObjectType() == JSType::JS_SHARED_SET;
1009    }
1010
1011    bool IsJSMap() const
1012    {
1013        return GetObjectType() == JSType::JS_MAP;
1014    }
1015
1016    bool IsJSSharedMap() const
1017    {
1018        return GetObjectType() == JSType::JS_SHARED_MAP;
1019    }
1020
1021    bool IsJSWeakMap() const
1022    {
1023        return GetObjectType() == JSType::JS_WEAK_MAP;
1024    }
1025
1026    bool IsJSWeakSet() const
1027    {
1028        return GetObjectType() == JSType::JS_WEAK_SET;
1029    }
1030
1031    bool IsJSWeakRef() const
1032    {
1033        return GetObjectType() == JSType::JS_WEAK_REF;
1034    }
1035
1036    bool IsJSFinalizationRegistry() const
1037    {
1038        return GetObjectType() == JSType::JS_FINALIZATION_REGISTRY;
1039    }
1040
1041    bool IsJSFunction() const
1042    {
1043        return GetObjectType() >= JSType::JS_FUNCTION_FIRST && GetObjectType() <= JSType::JS_FUNCTION_LAST;
1044    }
1045
1046    bool IsJSSharedFunction() const
1047    {
1048        return GetObjectType() == JSType::JS_SHARED_FUNCTION;
1049    }
1050
1051    bool IsJSShared() const
1052    {
1053        uint32_t bits = GetBitField();
1054        return IsJSSharedBit::Decode(bits);
1055    }
1056
1057    inline void SetIsJSShared(bool flag) const
1058    {
1059        IsJSSharedBit::Set<uint32_t>(flag, GetBitFieldAddr());
1060    }
1061
1062    inline bool IsJSError() const
1063    {
1064        JSType jsType = GetObjectType();
1065        return jsType >= JSType::JS_ERROR_FIRST && jsType <= JSType::JS_ERROR_LAST;
1066    }
1067
1068    inline bool IsArguments() const
1069    {
1070        return GetObjectType() == JSType::JS_ARGUMENTS;
1071    }
1072
1073    inline bool IsDate() const
1074    {
1075        return GetObjectType() == JSType::JS_DATE;
1076    }
1077
1078    inline bool IsJSRegExp() const
1079    {
1080        return GetObjectType() == JSType::JS_REG_EXP;
1081    }
1082
1083    inline bool IsJSProxy() const
1084    {
1085        return GetObjectType() == JSType::JS_PROXY;
1086    }
1087
1088    inline bool IsJSLocale() const
1089    {
1090        return GetObjectType() == JSType::JS_LOCALE;
1091    }
1092
1093    inline bool IsJSIntl() const
1094    {
1095        return GetObjectType() == JSType::JS_INTL;
1096    }
1097
1098    inline bool IsJSDateTimeFormat() const
1099    {
1100        return GetObjectType() == JSType::JS_DATE_TIME_FORMAT;
1101    }
1102
1103    inline bool IsJSRelativeTimeFormat() const
1104    {
1105        return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT;
1106    }
1107
1108    inline bool IsJSNumberFormat() const
1109    {
1110        return GetObjectType() == JSType::JS_NUMBER_FORMAT;
1111    }
1112
1113    inline bool IsJSCollator() const
1114    {
1115        return GetObjectType() == JSType::JS_COLLATOR;
1116    }
1117
1118    inline bool IsJSPluralRules() const
1119    {
1120        return GetObjectType() == JSType::JS_PLURAL_RULES;
1121    }
1122
1123    inline bool IsJSDisplayNames() const
1124    {
1125        return GetObjectType() == JSType::JS_DISPLAYNAMES;
1126    }
1127
1128    inline bool IsJSSegmenter() const
1129    {
1130        return GetObjectType() == JSType::JS_SEGMENTER;
1131    }
1132
1133    inline bool IsJSSegments() const
1134    {
1135        return GetObjectType() == JSType::JS_SEGMENTS;
1136    }
1137
1138    inline bool IsJSSegmentIterator() const
1139    {
1140        return GetObjectType() == JSType::JS_SEGMENT_ITERATOR;
1141    }
1142
1143    inline bool IsJSListFormat() const
1144    {
1145        return GetObjectType() == JSType::JS_LIST_FORMAT;
1146    }
1147
1148    inline bool IsMethod() const
1149    {
1150        return GetObjectType() == JSType::METHOD;
1151    }
1152
1153    inline bool IsClassLiteral() const
1154    {
1155        return GetObjectType() == JSType::CLASS_LITERAL;
1156    }
1157
1158    // non ECMA standard jsapi containers.
1159    inline bool IsSpecialContainer() const
1160    {
1161        return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_API_QUEUE;
1162    }
1163
1164    inline bool IsRegularObject() const
1165    {
1166        return GetObjectType() < JSType::JS_API_ARRAY_LIST;
1167    }
1168
1169    inline bool IsJSAPIArrayList() const
1170    {
1171        return GetObjectType() == JSType::JS_API_ARRAY_LIST;
1172    }
1173
1174    inline bool IsJSAPIArrayListIterator() const
1175    {
1176        return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
1177    }
1178    inline bool IsJSAPILightWeightMap() const
1179    {
1180        return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP;
1181    }
1182    inline bool IsJSAPILightWeightMapIterator() const
1183    {
1184        return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR;
1185    }
1186    inline bool IsJSAPILightWeightSet() const
1187    {
1188        return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET;
1189    }
1190    inline bool IsJSAPILightWeightSetIterator() const
1191    {
1192        return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR;
1193    }
1194    inline bool IsJSAPIStack() const
1195    {
1196        return GetObjectType() == JSType::JS_API_STACK;
1197    }
1198    inline bool IsJSAPIDeque() const
1199    {
1200        return GetObjectType() == JSType::JS_API_DEQUE;
1201    }
1202    inline bool IsLinkedNode() const
1203    {
1204        return GetObjectType() == JSType::LINKED_NODE;
1205    }
1206
1207    inline bool IsRBTreeNode() const
1208    {
1209        return GetObjectType() == JSType::RB_TREENODE;
1210    }
1211
1212    inline bool IsJSAPIHashMap() const
1213    {
1214        return GetObjectType() == JSType::JS_API_HASH_MAP;
1215    }
1216
1217    inline bool IsJSAPIHashSet() const
1218    {
1219        return GetObjectType() == JSType::JS_API_HASH_SET;
1220    }
1221
1222    inline bool IsJSAPIHashMapIterator() const
1223    {
1224        return GetObjectType() == JSType::JS_API_HASHMAP_ITERATOR;
1225    }
1226
1227    inline bool IsJSAPIHashSetIterator() const
1228    {
1229        return GetObjectType() == JSType::JS_API_HASHSET_ITERATOR;
1230    }
1231    inline bool IsJSAPIQueue() const
1232    {
1233        return GetObjectType() == JSType::JS_API_QUEUE;
1234    }
1235
1236    inline bool IsJSAPIPlainArray() const
1237    {
1238        return GetObjectType() == JSType::JS_API_PLAIN_ARRAY;
1239    }
1240
1241    inline bool IsJSAPIQueueIterator() const
1242    {
1243        return GetObjectType() == JSType::JS_API_QUEUE_ITERATOR;
1244    }
1245    inline bool IsJSAPIList() const
1246    {
1247        return GetObjectType() == JSType::JS_API_LIST;
1248    }
1249    inline bool IsJSAPILinkedList() const
1250    {
1251        return GetObjectType() == JSType::JS_API_LINKED_LIST;
1252    }
1253    inline bool IsJSAPITreeMap() const
1254    {
1255        return GetObjectType() == JSType::JS_API_TREE_MAP;
1256    }
1257
1258    inline bool IsJSAPITreeSet() const
1259    {
1260        return GetObjectType() == JSType::JS_API_TREE_SET;
1261    }
1262
1263    inline bool IsJSAPITreeMapIterator() const
1264    {
1265        return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR;
1266    }
1267
1268    inline bool IsJSAPITreeSetIterator() const
1269    {
1270        return GetObjectType() == JSType::JS_API_TREESET_ITERATOR;
1271    }
1272    inline bool IsJSAPIVector() const
1273    {
1274        return GetObjectType() == JSType::JS_API_VECTOR;
1275    }
1276    inline bool IsJSAPIVectorIterator() const
1277    {
1278        return GetObjectType() == JSType::JS_API_VECTOR_ITERATOR;
1279    }
1280    inline bool IsJSAPIBitVector() const
1281    {
1282        return GetObjectType() == JSType::JS_API_BITVECTOR;
1283    }
1284    inline bool IsJSAPIBitVectorIterator() const
1285    {
1286        return GetObjectType() == JSType::JS_API_BITVECTOR_ITERATOR;
1287    }
1288
1289    inline bool IsAccessorData() const
1290    {
1291        return GetObjectType() == JSType::ACCESSOR_DATA;
1292    }
1293
1294    inline bool IsInternalAccessor() const
1295    {
1296        return GetObjectType() == JSType::INTERNAL_ACCESSOR;
1297    }
1298
1299    inline bool IsIterator() const
1300    {
1301        JSType jsType = GetObjectType();
1302        return jsType >= JSType::JS_ITERATOR_FIRST && jsType <= JSType::JS_ITERATOR_LAST;
1303    }
1304
1305    inline bool IsAsyncIterator() const
1306    {
1307        return GetObjectType() == JSType::JS_ASYNCITERATOR;
1308    }
1309
1310    inline bool IsAsyncFromSyncIterator() const
1311    {
1312        return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITERATOR;
1313    }
1314
1315    inline bool IsForinIterator() const
1316    {
1317        return GetObjectType() == JSType::JS_FORIN_ITERATOR;
1318    }
1319
1320    inline bool IsStringIterator() const
1321    {
1322        return GetObjectType() == JSType::JS_STRING_ITERATOR;
1323    }
1324
1325    inline bool IsArrayBuffer() const
1326    {
1327        return GetObjectType() == JSType::JS_ARRAY_BUFFER;
1328    }
1329
1330    inline bool IsSharedArrayBuffer() const
1331    {
1332        return GetObjectType() == JSType::JS_SHARED_ARRAY_BUFFER;
1333    }
1334
1335    inline bool IsSendableArrayBuffer() const
1336    {
1337        return GetObjectType() == JSType::JS_SENDABLE_ARRAY_BUFFER;
1338    }
1339
1340    inline bool IsDataView() const
1341    {
1342        return GetObjectType() == JSType::JS_DATA_VIEW;
1343    }
1344
1345    inline bool IsJSSetIterator() const
1346    {
1347        return GetObjectType() == JSType::JS_SET_ITERATOR;
1348    }
1349
1350    // iterator of shared set
1351    inline bool IsJSSharedSetIterator() const
1352    {
1353        return GetObjectType() == JSType::JS_SHARED_SET_ITERATOR;
1354    }
1355
1356    inline bool IsJSRegExpIterator() const
1357    {
1358        return GetObjectType() == JSType::JS_REG_EXP_ITERATOR;
1359    }
1360
1361    inline bool IsJSMapIterator() const
1362    {
1363        return GetObjectType() == JSType::JS_MAP_ITERATOR;
1364    }
1365
1366    // iterator of shared map
1367    inline bool IsJSSharedMapIterator() const
1368    {
1369        return GetObjectType() == JSType::JS_SHARED_MAP_ITERATOR;
1370    }
1371
1372    inline bool IsJSArrayIterator() const
1373    {
1374        return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
1375    }
1376
1377    inline bool IsJSSharedArrayIterator() const
1378    {
1379        return GetObjectType() == JSType::JS_SHARED_ARRAY_ITERATOR;
1380    }
1381
1382    inline bool IsJSAPIPlainArrayIterator() const
1383    {
1384        return GetObjectType() == JSType::JS_API_PLAIN_ARRAY_ITERATOR;
1385    }
1386
1387    inline bool IsJSAPIDequeIterator() const
1388    {
1389        return GetObjectType() == JSType::JS_API_DEQUE_ITERATOR;
1390    }
1391
1392    inline bool IsJSAPIStackIterator() const
1393    {
1394        return GetObjectType() == JSType::JS_API_STACK_ITERATOR;
1395    }
1396
1397    inline bool IsJSAPILinkedListIterator() const
1398    {
1399        return GetObjectType() == JSType::JS_API_LINKED_LIST_ITERATOR;
1400    }
1401
1402    inline bool IsJSAPIListIterator() const
1403    {
1404        return GetObjectType() == JSType::JS_API_LIST_ITERATOR;
1405    }
1406
1407    inline bool IsPrototypeHandler() const
1408    {
1409        return GetObjectType() == JSType::PROTOTYPE_HANDLER;
1410    }
1411
1412    inline bool IsTransitionHandler() const
1413    {
1414        return GetObjectType() == JSType::TRANSITION_HANDLER;
1415    }
1416
1417    inline bool IsTransWithProtoHandler() const
1418    {
1419        return GetObjectType() == JSType::TRANS_WITH_PROTO_HANDLER;
1420    }
1421
1422    inline bool IsStoreTSHandler() const
1423    {
1424        return GetObjectType() == JSType::STORE_TS_HANDLER;
1425    }
1426
1427    inline bool IsPropertyBox() const
1428    {
1429        return GetObjectType() == JSType::PROPERTY_BOX;
1430    }
1431    inline bool IsProtoChangeMarker() const
1432    {
1433        return GetObjectType() == JSType::PROTO_CHANGE_MARKER;
1434    }
1435
1436    inline bool IsMarkerCell() const
1437    {
1438        return GetObjectType() == JSType::MARKER_CELL;
1439    }
1440
1441    inline bool IsTrackInfoObject() const
1442    {
1443        return GetObjectType() == JSType::TRACK_INFO;
1444    }
1445
1446    inline bool IsProtoChangeDetails() const
1447    {
1448        return GetObjectType() == JSType::PROTOTYPE_INFO;
1449    }
1450
1451    inline bool IsProgram() const
1452    {
1453        return GetObjectType() == JSType::PROGRAM;
1454    }
1455
1456    inline bool IsClassInfoExtractor() const
1457    {
1458        return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR;
1459    }
1460
1461    inline bool IsCallable() const
1462    {
1463        uint32_t bits = GetBitField();
1464        return CallableBit::Decode(bits);
1465    }
1466
1467    inline bool IsConstructor() const
1468    {
1469        uint32_t bits = GetBitField();
1470        return ConstructorBit::Decode(bits);
1471    }
1472
1473    inline bool IsExtensible() const
1474    {
1475        uint32_t bits = GetBitField();
1476        return ExtensibleBit::Decode(bits);
1477    }
1478
1479    inline bool IsPrototype() const
1480    {
1481        uint32_t bits = GetBitField();
1482        return IsPrototypeBit::Decode(bits);
1483    }
1484
1485    inline bool IsClassConstructor() const
1486    {
1487        uint32_t bits = GetBitField();
1488        return IsClassConstructorOrPrototypeBit::Decode(bits) && IsConstructor();
1489    }
1490
1491    inline bool IsJSGlobalObject() const
1492    {
1493        return GetObjectType() == JSType::JS_GLOBAL_OBJECT;
1494    }
1495
1496    inline bool IsClassPrototype() const
1497    {
1498        uint32_t bits = GetBitField();
1499        return IsClassConstructorOrPrototypeBit::Decode(bits) && IsPrototype();
1500    }
1501
1502    inline bool IsNativeBindingObject() const
1503    {
1504        uint32_t bits = GetBitField();
1505        return IsNativeBindingObjectBit::Decode(bits);
1506    }
1507
1508    inline bool IsDictionaryMode() const
1509    {
1510        uint32_t bits = GetBitField();
1511        return IsDictionaryBit::Decode(bits);
1512    }
1513
1514    // created from TypeScript Types
1515    inline bool IsTS() const
1516    {
1517        uint32_t bits = GetBitField();
1518        return IsTSBit::Decode(bits);
1519    }
1520
1521    inline bool IsJSFunctionFromBitField() const
1522    {
1523        uint32_t bits = GetBitField();
1524        return IsJSFunctionBit::Decode(bits);
1525    }
1526
1527    inline bool IsOnHeapFromBitField() const
1528    {
1529        uint32_t bits = GetBitField();
1530        return IsOnHeap::Decode(bits);
1531    }
1532
1533    inline bool IsGeneratorFunction() const
1534    {
1535        return GetObjectType() == JSType::JS_GENERATOR_FUNCTION;
1536    }
1537
1538    inline bool IsAsyncGeneratorFunction() const
1539    {
1540        return GetObjectType() == JSType::JS_ASYNC_GENERATOR_FUNCTION;
1541    }
1542
1543    inline bool IsGeneratorObject() const
1544    {
1545        JSType jsType = GetObjectType();
1546        return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT;
1547    }
1548
1549    inline bool IsAsyncGeneratorObject() const
1550    {
1551        JSType jsType = GetObjectType();
1552        return jsType == JSType::JS_ASYNC_GENERATOR_OBJECT;
1553    }
1554
1555    inline bool IsGeneratorContext() const
1556    {
1557        return GetObjectType() == JSType::JS_GENERATOR_CONTEXT;
1558    }
1559
1560    inline bool IsAsyncGeneratorRequest() const
1561    {
1562        JSType jsType = GetObjectType();
1563        return jsType == JSType::ASYNC_GENERATOR_REQUEST;
1564    }
1565
1566    inline bool IsAsyncIteratorRecord() const
1567    {
1568        JSType jsType = GetObjectType();
1569        return jsType == JSType::ASYNC_ITERATOR_RECORD;
1570    }
1571
1572    inline bool IsAsyncFuncObject() const
1573    {
1574        return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT;
1575    }
1576
1577    inline bool IsJSPromise() const
1578    {
1579        return GetObjectType() == JSType::JS_PROMISE;
1580    }
1581
1582    inline bool IsResolvingFunctionsRecord() const
1583    {
1584        return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD;
1585    }
1586
1587    inline bool IsPromiseRecord() const
1588    {
1589        return GetObjectType() == JSType::PROMISE_RECORD;
1590    }
1591
1592    inline bool IsPromiseIteratorRecord() const
1593    {
1594        return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD;
1595    }
1596
1597    inline bool IsPromiseCapability() const
1598    {
1599        return GetObjectType() == JSType::PROMISE_CAPABILITY;
1600    }
1601
1602    inline bool IsPromiseReaction() const
1603    {
1604        return GetObjectType() == JSType::PROMISE_REACTIONS;
1605    }
1606
1607    inline bool IsCellRecord() const
1608    {
1609        return GetObjectType() == JSType::CELL_RECORD;
1610    }
1611
1612    inline bool IsCompletionRecord() const
1613    {
1614        return GetObjectType() == JSType::COMPLETION_RECORD;
1615    }
1616
1617    inline bool IsRecord() const
1618    {
1619        JSType jsType = GetObjectType();
1620        return jsType >= JSType::JS_RECORD_FIRST && jsType <= JSType::JS_RECORD_LAST;
1621    }
1622
1623    inline bool IsTemplateMap() const
1624    {
1625        return GetObjectType() == JSType::TEMPLATE_MAP;
1626    }
1627
1628    inline bool IsFreeObject() const
1629    {
1630        JSType t = GetObjectType();
1631        return (t >= JSType::FREE_OBJECT_WITH_ONE_FIELD) && (t <= JSType::FREE_OBJECT_WITH_TWO_FIELD);
1632    }
1633
1634    inline bool IsFreeObjectWithShortField() const
1635    {
1636        switch (GetObjectType()) {
1637            case JSType::FREE_OBJECT_WITH_ONE_FIELD:
1638            case JSType::FREE_OBJECT_WITH_NONE_FIELD:
1639                return true;
1640            default:
1641                return false;
1642        }
1643    }
1644
1645    inline bool IsFreeObjectWithOneField() const
1646    {
1647        return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD;
1648    }
1649
1650    inline bool IsFreeObjectWithNoneField() const
1651    {
1652        return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD;
1653    }
1654
1655    inline bool IsFreeObjectWithTwoField() const
1656    {
1657        return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD;
1658    }
1659
1660    inline bool IsMachineCodeObject() const
1661    {
1662        return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
1663    }
1664
1665    inline bool IsAOTLiteralInfo() const
1666    {
1667        return GetObjectType() == JSType::AOT_LITERAL_INFO;
1668    }
1669
1670    inline bool IsExtraProfileTypeInfo() const
1671    {
1672        return GetObjectType() == JSType::EXTRA_PROFILE_TYPE_INFO;
1673    }
1674
1675    inline bool IsProfileTypeInfoCell() const
1676    {
1677        JSType jsType = GetObjectType();
1678        return jsType >= JSType::PROFILE_TYPE_INFO_CELL_FIRST && jsType <= JSType::PROFILE_TYPE_INFO_CELL_LAST;
1679    }
1680
1681    inline bool IsProfileTypeInfoCell0() const
1682    {
1683        JSType jsType = GetObjectType();
1684        return jsType == JSType::PROFILE_TYPE_INFO_CELL_0;
1685    }
1686
1687    inline bool IsFunctionTemplate() const
1688    {
1689        JSType jsType = GetObjectType();
1690        return jsType == JSType::FUNCTION_TEMPLATE;
1691    }
1692
1693    inline bool IsVTable() const
1694    {
1695        return GetObjectType() == JSType::VTABLE;
1696    }
1697
1698    inline bool IsModuleRecord() const
1699    {
1700        JSType jsType = GetObjectType();
1701        return jsType >= JSType::MODULE_RECORD_FIRST && jsType <= JSType::MODULE_RECORD_LAST;
1702    }
1703
1704    inline bool IsSourceTextModule() const
1705    {
1706        return GetObjectType() == JSType::SOURCE_TEXT_MODULE_RECORD;
1707    }
1708
1709    inline bool IsCjsExports() const
1710    {
1711        return GetObjectType() == JSType::JS_CJS_EXPORTS;
1712    }
1713
1714    inline bool IsCjsModule() const
1715    {
1716        return GetObjectType() == JSType::JS_CJS_MODULE;
1717    }
1718
1719    inline bool IsCjsRequire() const
1720    {
1721        return GetObjectType() == JSType::JS_CJS_REQUIRE;
1722    }
1723
1724    inline bool IsImportEntry() const
1725    {
1726        return GetObjectType() == JSType::IMPORTENTRY_RECORD;
1727    }
1728
1729    inline bool IsLocalExportEntry() const
1730    {
1731        return GetObjectType() == JSType::LOCAL_EXPORTENTRY_RECORD;
1732    }
1733
1734    inline bool IsIndirectExportEntry() const
1735    {
1736        return GetObjectType() == JSType::INDIRECT_EXPORTENTRY_RECORD;
1737    }
1738
1739    inline bool IsStarExportEntry() const
1740    {
1741        return GetObjectType() == JSType::STAR_EXPORTENTRY_RECORD;
1742    }
1743
1744    inline bool IsResolvedBinding() const
1745    {
1746        return GetObjectType() == JSType::RESOLVEDBINDING_RECORD;
1747    }
1748
1749    inline bool IsResolvedIndexBinding() const
1750    {
1751        return GetObjectType() == JSType::RESOLVEDINDEXBINDING_RECORD;
1752    }
1753
1754    inline bool IsResolvedRecordIndexBinding() const
1755    {
1756        return GetObjectType() == JSType::RESOLVEDRECORDINDEXBINDING_RECORD;
1757    }
1758
1759    inline bool IsResolvedRecordBinding() const
1760    {
1761        return GetObjectType() == JSType::RESOLVEDRECORDBINDING_RECORD;
1762    }
1763
1764    inline bool IsModuleNamespace() const
1765    {
1766        return GetObjectType() == JSType::JS_MODULE_NAMESPACE;
1767    }
1768
1769    inline bool IsNativeModuleFailureInfo() const
1770    {
1771        return GetObjectType() == JSType::NATIVE_MODULE_FAILURE_INFO;
1772    }
1773
1774    inline bool IsJSSharedObject() const
1775    {
1776        return GetObjectType() == JSType::JS_SHARED_OBJECT;
1777    }
1778
1779    inline bool IsJSSharedArray() const
1780    {
1781        return GetObjectType() == JSType::JS_SHARED_ARRAY;
1782    }
1783
1784    inline void SetElementsKind(ElementsKind kind)
1785    {
1786        uint32_t bits = GetBitField();
1787        uint32_t newVal = ElementsKindBits::Update(bits, kind);
1788        SetBitField(newVal);
1789    }
1790
1791    inline ElementsKind GetElementsKind() const
1792    {
1793        uint32_t bits = GetBitField();
1794        return ElementsKindBits::Decode(bits);
1795    }
1796
1797    inline void SetLevel(uint8_t level)
1798    {
1799        uint32_t bits = GetBitField();
1800        uint32_t newVal = LevelBit::Update(bits, level);
1801        SetBitField(newVal);
1802    }
1803
1804    inline uint8_t GetLevel() const
1805    {
1806        uint32_t bits = GetBitField();
1807        return LevelBit::Decode(bits);
1808    }
1809
1810    inline void SetIsDictionaryElement(bool value)
1811    {
1812        uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
1813        SetBitField(newVal);
1814    }
1815    inline bool IsDictionaryElement() const
1816    {
1817        return DictionaryElementBits::Decode(GetBitField());
1818    }
1819    inline void SetIsStableElements(bool value)
1820    {
1821        uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value);
1822        SetBitField(newVal);
1823    }
1824    inline bool IsStableElements() const
1825    {
1826        return IsStableElementsBit::Decode(GetBitField());
1827    }
1828    inline bool IsStableJSArguments() const
1829    {
1830        uint32_t bits = GetBitField();
1831        auto type = ObjectTypeBits::Decode(bits);
1832        return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS);
1833    }
1834    inline bool IsStableJSArray() const
1835    {
1836        uint32_t bits = GetBitField();
1837        auto type = ObjectTypeBits::Decode(bits);
1838        return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY);
1839    }
1840    inline void SetHasConstructor(bool value)
1841    {
1842        JSTaggedType newVal = HasConstructorBits::Update(GetBitField(), value);
1843        SetBitField(newVal);
1844    }
1845    inline bool HasConstructor() const
1846    {
1847        return HasConstructorBits::Decode(GetBitField());
1848    }
1849
1850    inline void SetNumberOfProps(uint32_t num)
1851    {
1852        uint32_t bits = GetBitField1();
1853        uint32_t newVal = NumberOfPropsBits::Update(bits, num);
1854        SetBitField1(newVal);
1855    }
1856
1857    inline void IncNumberOfProps()
1858    {
1859        ASSERT(NumberOfProps() < PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
1860        SetNumberOfProps(NumberOfProps() + 1);
1861    }
1862
1863    inline uint32_t NumberOfProps() const
1864    {
1865        uint32_t bits = GetBitField1();
1866        return NumberOfPropsBits::Decode(bits);
1867    }
1868
1869    inline bool HasProps() const
1870    {
1871        return NumberOfProps() > 0;
1872    }
1873
1874    inline bool PropsIsEmpty() const
1875    {
1876        return NumberOfProps() == 0;
1877    }
1878
1879    inline uint32_t LastPropIndex() const
1880    {
1881        ASSERT(NumberOfProps() > 0);
1882        return NumberOfProps() - 1;
1883    }
1884
1885    inline int32_t GetNextInlinedPropsIndex() const
1886    {
1887        uint32_t inlinedProperties = GetInlinedProperties();
1888        uint32_t numberOfProps = NumberOfProps();
1889        if (numberOfProps < inlinedProperties) {
1890            return numberOfProps;
1891        }
1892        return -1;
1893    }
1894
1895    inline int32_t GetNextNonInlinedPropsIndex() const
1896    {
1897        uint32_t inlinedProperties = GetInlinedProperties();
1898        uint32_t numberOfProps = NumberOfProps();
1899        if (numberOfProps >= inlinedProperties) {
1900            return numberOfProps - inlinedProperties;
1901        }
1902        return -1;
1903    }
1904
1905    inline uint32_t GetObjectSize() const
1906    {
1907        uint32_t bits = GetBitField1();
1908        return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1909    }
1910
1911    inline uint32_t GetObjectSizeExcludeInlinedProps() const
1912    {
1913        return GetObjectSize() - GetInlinedProperties() * JSTaggedValue::TaggedTypeSize();
1914    }
1915
1916    inline void SetObjectSize(uint32_t num)
1917    {
1918        ASSERT((num / JSTaggedValue::TaggedTypeSize()) <= MAX_OBJECT_SIZE_IN_WORDS);
1919        uint32_t bits = GetBitField1();
1920        uint32_t newVal = ObjectSizeInWordsBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1921        SetBitField1(newVal);
1922    }
1923
1924    inline uint32_t GetInlinedPropertiesOffset(uint32_t index) const
1925    {
1926        ASSERT(index < GetInlinedProperties());
1927        return GetInlinedPropertiesIndex(index) * JSTaggedValue::TaggedTypeSize();
1928    }
1929
1930    inline uint32_t GetInlinedPropertiesIndex(uint32_t index) const
1931    {
1932        ASSERT(index < GetInlinedProperties());
1933        uint32_t bits = GetBitField1();
1934        return InlinedPropsStartBits::Decode(bits) + index;
1935    }
1936
1937    inline void SetInlinedPropsStart(uint32_t num)
1938    {
1939        uint32_t bits = GetBitField1();
1940        uint32_t newVal = InlinedPropsStartBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1941        SetBitField1(newVal);
1942    }
1943
1944    inline uint32_t GetInlinedPropsStartSize() const
1945    {
1946        uint32_t bits = GetBitField1();
1947        return InlinedPropsStartBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1948    }
1949
1950    inline uint32_t GetInlinedProperties() const
1951    {
1952        if (IsJSObject()) {
1953            uint32_t bits = GetBitField1();
1954            return static_cast<uint32_t>(ObjectSizeInWordsBits::Decode(bits) - InlinedPropsStartBits::Decode(bits));
1955        } else {
1956            return 0;
1957        }
1958    }
1959
1960    inline void SetHasDeleteProperty(bool flag) const
1961    {
1962        HasDeletePropertyBit::Set<uint32_t>(flag, GetBitField1Addr());
1963    }
1964
1965    inline bool HasDeleteProperty() const
1966    {
1967        uint32_t bits = GetBitField1();
1968        return HasDeletePropertyBit::Decode(bits);
1969    }
1970
1971    inline void SetIsAllTaggedProp(bool flag) const
1972    {
1973        IsAllTaggedPropBit::Set<uint32_t>(flag, GetBitField1Addr());
1974    }
1975
1976    inline bool IsAllTaggedProp() const
1977    {
1978        uint32_t bits = GetBitField1();
1979        return IsAllTaggedPropBit::Decode(bits);
1980    }
1981
1982    inline static JSHClass *FindRootHClass(JSHClass *hclass);
1983    inline static JSTaggedValue FindProtoHClass(JSHClass *hclass);
1984    inline static JSTaggedValue FindProtoRootHClass(JSHClass *hclass);
1985    inline static void UpdateRootHClass(const JSThread *thread, const JSHandle<JSHClass> &parent,
1986                                        const JSHandle<JSHClass> &child);
1987
1988    inline static int FindPropertyEntry(const JSThread *thread, JSHClass *hclass, JSTaggedValue key);
1989
1990    static PUBLIC_API PropertyLookupResult LookupPropertyInAotHClass(const JSThread *thread, JSHClass *hclass,
1991        JSTaggedValue key);
1992    static PUBLIC_API PropertyLookupResult LookupPropertyInPGOHClass(const JSThread *thread, JSHClass *hclass,
1993        JSTaggedValue key);
1994    static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinPrototypeHClass(const JSThread *thread,
1995                                                                                  JSHClass *hclass, JSTaggedValue key);
1996    static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinHClass(const JSThread *thread, JSHClass *hclass,
1997                                                                         JSTaggedValue key);
1998
1999    static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize();
2000    ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET);
2001    ACCESSORS_SYNCHRONIZED(Layout, LAYOUT_OFFSET, TRANSTIONS_OFFSET);
2002    ACCESSORS(Transitions, TRANSTIONS_OFFSET, PARENT_OFFSET);
2003    ACCESSORS(Parent, PARENT_OFFSET, PROTO_CHANGE_MARKER_OFFSET);
2004    ACCESSORS(ProtoChangeMarker, PROTO_CHANGE_MARKER_OFFSET, PROTO_CHANGE_DETAILS_OFFSET);
2005    ACCESSORS(ProtoChangeDetails, PROTO_CHANGE_DETAILS_OFFSET, ENUM_CACHE_OFFSET);
2006    ACCESSORS(EnumCache, ENUM_CACHE_OFFSET, PROFILE_TYPE);
2007    ACCESSORS_PRIMITIVE_FIELD(ProfileType, uint64_t, PROFILE_TYPE, BIT_FIELD_OFFSET);
2008    ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD1_OFFSET);
2009    ACCESSORS_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, LAST_OFFSET);
2010    DEFINE_ALIGN_SIZE(LAST_OFFSET);
2011
2012    static JSHandle<JSHClass> SetPrototypeWithNotification(const JSThread *thread,
2013                                                           const JSHandle<JSHClass> &hclass,
2014                                                           const JSHandle<JSTaggedValue> &proto,
2015                                                           bool isChangeProto = false);
2016    static void SetPrototypeTransition(JSThread *thread, const JSHandle<JSObject> &object,
2017                                       const JSHandle<JSTaggedValue> &proto,
2018                                       bool isChangeProto = false);
2019    void SetPrototype(const JSThread *thread, JSTaggedValue proto, bool isChangeProto = false);
2020    void PUBLIC_API SetPrototype(const JSThread *thread,
2021                                 const JSHandle<JSTaggedValue> &proto,
2022                                 bool isChangeProto = false);
2023    static void OptimizePrototypeForIC(const JSThread *thread,
2024                                       const JSHandle<JSTaggedValue> &proto,
2025                                       bool isChangeProto = false);
2026    inline JSTaggedValue GetPrototype() const
2027    {
2028        return GetProto();
2029    }
2030
2031    inline JSHClass *FindTransitions(const JSTaggedValue &key,
2032                                     const JSTaggedValue &metaData,
2033                                     const Representation &rep);
2034    inline JSHClass *CheckHClassForRep(JSHClass *hclass, const Representation &rep);
2035
2036    DECL_DUMP()
2037
2038    static CString DumpJSType(JSType type);
2039
2040    static JSHandle<JSHClass> CreateRootHClassFromPGO(const JSThread* thread,
2041                                                      const HClassLayoutDesc* desc,
2042                                                      uint32_t maxNum,
2043                                                      bool isCache);
2044    static JSHandle<JSHClass> CreateRootHClassWithCached(const JSThread* thread,
2045                                                         const HClassLayoutDesc* desc,
2046                                                         uint32_t maxNum);
2047    static JSHandle<JSHClass> CreateChildHClassFromPGO(const JSThread* thread,
2048                                                       const JSHandle<JSHClass>& parent,
2049                                                       const HClassLayoutDesc* desc);
2050    static bool DumpRootHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc);
2051    static bool DumpChildHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc);
2052    static bool UpdateRootLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* rootDesc);
2053    static bool UpdateChildLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* childDesc);
2054    static CString DumpToString(JSTaggedType hclassVal);
2055
2056    DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, PROFILE_TYPE);
2057    inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto);
2058    inline bool HasTransitions() const
2059    {
2060        return !GetTransitions().IsUndefined();
2061    }
2062
2063    static JSHandle<JSHClass> CreateSHClass(JSThread *thread,
2064                                            const std::vector<PropertyDescriptor> &descs,
2065                                            const JSHClass *parentHClass = nullptr,
2066                                            bool isFunction = false);
2067    static JSHandle<JSHClass> CreateSConstructorHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
2068    static JSHandle<JSHClass> CreateSPrototypeHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs);
2069
2070private:
2071
2072    static inline bool ProtoIsFastJSArray(const JSThread *thread, const JSHandle<JSTaggedValue> proto,
2073                                          const JSHandle<JSHClass> hclass);
2074
2075    static void CreateSInlinedLayout(JSThread *thread,
2076                                     const std::vector<PropertyDescriptor> &descs,
2077                                     const JSHandle<JSHClass> &hclass,
2078                                     const JSHClass *parentHClass = nullptr);
2079    static void CreateSDictLayout(JSThread *thread,
2080                                  const std::vector<PropertyDescriptor> &descs,
2081                                  const JSHandle<JSHClass> &hclass,
2082                                  const JSHClass *parentHClass = nullptr);
2083    static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2084                                      const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
2085                                      PropertyAttributes attr);
2086    static inline void AddExtensionTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2087                                               const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key);
2088    static inline void AddProtoTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
2089                                           const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
2090                                           const JSHandle<JSTaggedValue> &proto);
2091    template<bool checkDuplicateKeys = false>
2092    static inline void AddPropertyToNewHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass,
2093                                              JSHandle<JSHClass> &newJsHClass, const JSHandle<JSTaggedValue> &key,
2094                                              const PropertyAttributes &attr);
2095
2096    void InitializeWithDefaultValue(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps);
2097
2098    static bool IsJSTypeObject(JSType type)
2099    {
2100        return JSType::JS_OBJECT_FIRST <= type && type <= JSType::JS_OBJECT_LAST;
2101    }
2102
2103    static bool IsJSTypeShared(JSType type);
2104
2105    inline void Copy(const JSThread *thread, const JSHClass *jshclass);
2106
2107    uint32_t *GetBitFieldAddr() const
2108    {
2109        return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET);
2110    }
2111
2112    uint32_t *GetBitField1Addr() const
2113    {
2114        return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD1_OFFSET);
2115    }
2116    friend class RuntimeStubs;
2117};
2118static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
2119
2120// record property look up info in local and vtable
2121class PropertyLookupResult {
2122public:
2123    static constexpr uint32_t OFFSET_BITFIELD_NUM = 14;
2124    using IsFoundBit = BitField<bool, 0, 1>;
2125    using IsLocalBit = IsFoundBit::NextFlag;
2126    using IsNotHoleBit = IsLocalBit::NextFlag;
2127    using IsAccessorBit = IsNotHoleBit::NextFlag;
2128    using OffsetBits = IsAccessorBit::NextField<uint32_t, OFFSET_BITFIELD_NUM>;
2129    using WritableField = OffsetBits::NextFlag;
2130    using RepresentationBits = WritableField::NextField<Representation, PropertyAttributes::REPRESENTATION_NUM>;
2131    using IsInlinedPropsBits = RepresentationBits::NextFlag;
2132
2133    explicit PropertyLookupResult(uint32_t data = 0) : data_(data) {}
2134    ~PropertyLookupResult() = default;
2135    DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyLookupResult);
2136    DEFAULT_COPY_SEMANTIC(PropertyLookupResult);
2137
2138    inline bool IsFound() const
2139    {
2140        return IsFoundBit::Get(data_);
2141    }
2142
2143    inline void SetIsFound(bool flag)
2144    {
2145        IsFoundBit::Set(flag, &data_);
2146    }
2147
2148    inline bool IsWritable() const
2149    {
2150        return WritableField::Get(data_);
2151    }
2152
2153    inline void SetIsWritable(bool flag)
2154    {
2155        WritableField::Set(flag, &data_);
2156    }
2157
2158    inline bool IsLocal() const
2159    {
2160        return IsLocalBit::Get(data_);
2161    }
2162
2163    inline void SetIsLocal(bool flag)
2164    {
2165        IsLocalBit::Set(flag, &data_);
2166    }
2167
2168    inline bool IsNotHole() const
2169    {
2170        return IsNotHoleBit::Get(data_);
2171    }
2172
2173    inline void SetIsNotHole(bool flag)
2174    {
2175        IsNotHoleBit::Set(flag, &data_);
2176    }
2177
2178    inline bool IsVtable() const
2179    {
2180        return IsFound() && !IsLocal();
2181    }
2182
2183    inline void SetIsVtable()
2184    {
2185        SetIsFound(true);
2186        SetIsLocal(false);
2187    }
2188
2189    inline bool IsAccessor() const
2190    {
2191        return IsAccessorBit::Get(data_);
2192    }
2193
2194    inline void SetIsAccessor(bool flag)
2195    {
2196        IsAccessorBit::Set(flag, &data_);
2197    }
2198
2199    inline bool IsFunction() const
2200    {
2201        return IsVtable() && !IsAccessor();
2202    }
2203
2204    inline uint32_t GetOffset() const
2205    {
2206        return OffsetBits::Get(data_);
2207    }
2208
2209    inline void SetOffset(uint32_t offset)
2210    {
2211        OffsetBits::Set<uint32_t>(offset, &data_);
2212    }
2213
2214    inline void SetRepresentation(Representation rep)
2215    {
2216        RepresentationBits::Set(rep, &data_);
2217    }
2218
2219    inline Representation GetRepresentation()
2220    {
2221        return RepresentationBits::Get(data_);
2222    }
2223
2224    inline void SetIsInlinedProps(bool flag)
2225    {
2226        IsInlinedPropsBits::Set(flag, &data_);
2227    }
2228
2229    inline bool IsInlinedProps()
2230    {
2231        return IsInlinedPropsBits::Get(data_);
2232    }
2233
2234    inline uint32_t GetData() const
2235    {
2236        return data_;
2237    }
2238
2239private:
2240    uint32_t data_ {0};
2241};
2242static_assert(PropertyLookupResult::OffsetBits::MaxValue() >
2243              (PropertyAttributes::MAX_FAST_PROPS_CAPACITY * JSTaggedValue::TaggedTypeSize()));
2244}  // namespace panda::ecmascript
2245
2246#endif  // ECMASCRIPT_JS_HCLASS_H
2247