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  */
62 namespace panda::ecmascript {
63 class ProtoChangeDetails;
64 class PropertyLookupResult;
65 class SharedHeap;
66 class JSSharedArray;
67 class LayoutInfo;
68 class NameDictionary;
69 namespace pgo {
70     class HClassLayoutDesc;
71     class PGOHClassTreeDesc;
72     class PGOHandler;
73 } // namespace pgo
74 using HClassLayoutDesc = pgo::HClassLayoutDesc;
75 using PGOHClassTreeDesc = pgo::PGOHClassTreeDesc;
76 using PGOHandler = pgo::PGOHandler;
77 
78 struct 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 
340 enum 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
360 namespace EnumCache {
361 static constexpr uint32_t ENUM_CACHE_HEADER_SIZE = 1;
362 static constexpr uint32_t ENUM_CACHE_KIND_OFFSET = 0;
363 enum 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 
373 struct TransitionResult {
374     bool isTagged;
375     bool isTransition;
376     JSTaggedValue value;
377 };
378 
379 class JSHClass : public TaggedObject {
380 public:
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 
Cast(const TaggedObject *object)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 
ClearBitField()528     inline void ClearBitField()
529     {
530         SetProfileType(0ULL);
531         SetBitField(0UL);
532         SetBitField1(0UL);
533     }
534 
GetObjectType() const535     inline JSType GetObjectType() const
536     {
537         uint32_t bits = GetBitField();
538         return ObjectTypeBits::Decode(bits);
539     }
540 
SetObjectType(JSType type)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 
SetCallable(bool flag)548     inline void SetCallable(bool flag)
549     {
550         CallableBit::Set<uint32_t>(flag, GetBitFieldAddr());
551     }
552 
SetConstructor(bool flag) const553     inline void SetConstructor(bool flag) const
554     {
555         ConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
556     }
557 
SetExtensible(bool flag) const558     inline void SetExtensible(bool flag) const
559     {
560         ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr());
561     }
562 
SetIsPrototype(bool flag) const563     inline void SetIsPrototype(bool flag) const
564     {
565         IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
566     }
567 
SetClassConstructor(bool flag) const568     inline void SetClassConstructor(bool flag) const
569     {
570         IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
571         SetConstructor(flag);
572     }
573 
SetClassPrototype(bool flag) const574     inline void SetClassPrototype(bool flag) const
575     {
576         IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
577         SetIsPrototype(flag);
578     }
579 
SetIsNativeBindingObject(bool flag) const580     inline void SetIsNativeBindingObject(bool flag) const
581     {
582         IsNativeBindingObjectBit::Set<uint32_t>(flag, GetBitFieldAddr());
583     }
584 
SetIsDictionaryMode(bool flag) const585     inline void SetIsDictionaryMode(bool flag) const
586     {
587         IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
588     }
589 
SetTS(bool flag) const590     inline void SetTS(bool flag) const
591     {
592         IsTSBit::Set<uint32_t>(flag, GetBitFieldAddr());
593     }
594 
SetIsJSFunction(bool flag) const595     inline void SetIsJSFunction(bool flag) const
596     {
597         IsJSFunctionBit::Set<uint32_t>(flag, GetBitFieldAddr());
598     }
599 
SetIsOnHeap(bool flag) const600     inline void SetIsOnHeap(bool flag) const
601     {
602         IsOnHeap::Set<uint32_t>(flag, GetBitFieldAddr());
603     }
604 
IsJSObject() const605     inline bool IsJSObject() const
606     {
607         return IsJSTypeObject(GetObjectType());
608     }
609 
IsOnlyJSObject() const610     inline bool IsOnlyJSObject() const
611     {
612         return GetObjectType() == JSType::JS_OBJECT;
613     }
614 
IsECMAObject() const615     inline bool IsECMAObject() const
616     {
617         JSType jsType = GetObjectType();
618         return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST);
619     }
620 
ShouldSetDefaultSupers() const621     inline bool ShouldSetDefaultSupers() const
622     {
623         return IsECMAObject() || IsStringOrSymbol();
624     }
625 
IsRealm() const626     inline bool IsRealm() const
627     {
628         return GetObjectType() == JSType::JS_REALM;
629     }
630 
IsHClass() const631     inline bool IsHClass() const
632     {
633         return GetObjectType() == JSType::HCLASS;
634     }
635 
IsString() const636     inline bool IsString() const
637     {
638         JSType jsType = GetObjectType();
639         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST);
640     }
641 
IsLineString() const642     inline bool IsLineString() const
643     {
644         return GetObjectType() == JSType::LINE_STRING;
645     }
646 
IsConstantString() const647     inline bool IsConstantString() const
648     {
649         return GetObjectType() == JSType::CONSTANT_STRING;
650     }
651 
IsSlicedString() const652     inline bool IsSlicedString() const
653     {
654         return GetObjectType() == JSType::SLICED_STRING;
655     }
656 
IsTreeString() const657     inline bool IsTreeString() const
658     {
659         return GetObjectType() == JSType::TREE_STRING;
660     }
661 
IsBigInt() const662     inline bool IsBigInt() const
663     {
664         return GetObjectType() == JSType::BIGINT;
665     }
666 
IsSymbol() const667     inline bool IsSymbol() const
668     {
669         return GetObjectType() == JSType::SYMBOL;
670     }
671 
IsStringOrSymbol() const672     inline bool IsStringOrSymbol() const
673     {
674         JSType jsType = GetObjectType();
675         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST) || (jsType == JSType::SYMBOL);
676     }
677 
IsTaggedArray() const678     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 
IsLexicalEnv() const699     inline bool IsLexicalEnv() const
700     {
701         return GetObjectType() == JSType::LEXICAL_ENV;
702     }
IsByteArray() const703     inline bool IsByteArray() const
704     {
705         return GetObjectType() == JSType::BYTE_ARRAY;
706     }
707 
IsConstantPool() const708     inline bool IsConstantPool() const
709     {
710         return GetObjectType() == JSType::CONSTANT_POOL;
711     }
712 
IsDictionary() const713     inline bool IsDictionary() const
714     {
715         return GetObjectType() == JSType::TAGGED_DICTIONARY;
716     }
717 
IsCOWArray() const718     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 
IsMutantTaggedArray() const725     inline bool IsMutantTaggedArray() const
726     {
727         return GetObjectType() == JSType::MUTANT_TAGGED_ARRAY ||
728                GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY;
729     }
730 
IsJSNativePointer() const731     inline bool IsJSNativePointer() const
732     {
733         return GetObjectType() == JSType::JS_NATIVE_POINTER;
734     }
735 
IsJSSymbol() const736     inline bool IsJSSymbol() const
737     {
738         return GetObjectType() == JSType::SYMBOL;
739     }
740 
IsJSArray() const741     inline bool IsJSArray() const
742     {
743         return GetObjectType() == JSType::JS_ARRAY;
744     }
745 
IsTypedArray() const746     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 
IsSharedTypedArray() const752     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 
HasOrdinaryGet() const758     inline bool HasOrdinaryGet() const
759     {
760         return (IsSpecialContainer() || IsModuleNamespace() || IsBigInt64Array());
761     }
762 
IsJSTypedArray() const763     inline bool IsJSTypedArray() const
764     {
765         return GetObjectType() == JSType::JS_TYPED_ARRAY;
766     }
767 
IsJSInt8Array() const768     inline bool IsJSInt8Array() const
769     {
770         return GetObjectType() == JSType::JS_INT8_ARRAY;
771     }
772 
IsJSUint8Array() const773     inline bool IsJSUint8Array() const
774     {
775         return GetObjectType() == JSType::JS_UINT8_ARRAY;
776     }
777 
IsJSUint8ClampedArray() const778     inline bool IsJSUint8ClampedArray() const
779     {
780         return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY;
781     }
782 
IsJSInt16Array() const783     inline bool IsJSInt16Array() const
784     {
785         return GetObjectType() == JSType::JS_INT16_ARRAY;
786     }
787 
IsJSUint16Array() const788     inline bool IsJSUint16Array() const
789     {
790         return GetObjectType() == JSType::JS_UINT16_ARRAY;
791     }
792 
IsJSInt32Array() const793     inline bool IsJSInt32Array() const
794     {
795         return GetObjectType() == JSType::JS_INT32_ARRAY;
796     }
797 
IsJSUint32Array() const798     inline bool IsJSUint32Array() const
799     {
800         return GetObjectType() == JSType::JS_UINT32_ARRAY;
801     }
802 
IsJSFloat32Array() const803     inline bool IsJSFloat32Array() const
804     {
805         return GetObjectType() == JSType::JS_FLOAT32_ARRAY;
806     }
807 
IsJSFloat64Array() const808     inline bool IsJSFloat64Array() const
809     {
810         return GetObjectType() == JSType::JS_FLOAT64_ARRAY;
811     }
812 
IsJSBigInt64Array() const813     inline bool IsJSBigInt64Array() const
814     {
815         return GetObjectType() == JSType::JS_BIGINT64_ARRAY;
816     }
817 
IsJSBigUint64Array() const818     inline bool IsJSBigUint64Array() const
819     {
820         return GetObjectType() == JSType::JS_BIGUINT64_ARRAY;
821     }
822 
IsJSSharedTypedArray() const823     inline bool IsJSSharedTypedArray() const
824     {
825         return GetObjectType() == JSType::JS_SHARED_TYPED_ARRAY;
826     }
827 
IsJSSharedInt8Array() const828     inline bool IsJSSharedInt8Array() const
829     {
830         return GetObjectType() == JSType::JS_SHARED_INT8_ARRAY;
831     }
832 
IsJSSharedUint8Array() const833     inline bool IsJSSharedUint8Array() const
834     {
835         return GetObjectType() == JSType::JS_SHARED_UINT8_ARRAY;
836     }
837 
IsJSSharedUint8ClampedArray() const838     inline bool IsJSSharedUint8ClampedArray() const
839     {
840         return GetObjectType() == JSType::JS_SHARED_UINT8_CLAMPED_ARRAY;
841     }
842 
IsJSSharedInt16Array() const843     inline bool IsJSSharedInt16Array() const
844     {
845         return GetObjectType() == JSType::JS_SHARED_INT16_ARRAY;
846     }
847 
IsJSSharedUint16Array() const848     inline bool IsJSSharedUint16Array() const
849     {
850         return GetObjectType() == JSType::JS_SHARED_UINT16_ARRAY;
851     }
852 
IsJSSharedInt32Array() const853     inline bool IsJSSharedInt32Array() const
854     {
855         return GetObjectType() == JSType::JS_SHARED_INT32_ARRAY;
856     }
857 
IsJSSharedUint32Array() const858     inline bool IsJSSharedUint32Array() const
859     {
860         return GetObjectType() == JSType::JS_SHARED_UINT32_ARRAY;
861     }
862 
IsJSSharedFloat32Array() const863     inline bool IsJSSharedFloat32Array() const
864     {
865         return GetObjectType() == JSType::JS_SHARED_FLOAT32_ARRAY;
866     }
867 
IsJSSharedFloat64Array() const868     inline bool IsJSSharedFloat64Array() const
869     {
870         return GetObjectType() == JSType::JS_SHARED_FLOAT64_ARRAY;
871     }
872 
IsJSSharedBigInt64Array() const873     inline bool IsJSSharedBigInt64Array() const
874     {
875         return GetObjectType() == JSType::JS_SHARED_BIGINT64_ARRAY;
876     }
877 
IsJSSharedBigUint64Array() const878     inline bool IsJSSharedBigUint64Array() const
879     {
880         return GetObjectType() == JSType::JS_SHARED_BIGUINT64_ARRAY;
881     }
882 
IsBigInt64Array() const883     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 
IsJsGlobalEnv() const890     inline bool IsJsGlobalEnv() const
891     {
892         return GetObjectType() == JSType::GLOBAL_ENV;
893     }
894 
IsJSFunctionBase() const895     inline bool IsJSFunctionBase() const
896     {
897         JSType jsType = GetObjectType();
898         return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION;
899     }
900 
IsJsBoundFunction() const901     inline bool IsJsBoundFunction() const
902     {
903         return GetObjectType() == JSType::JS_BOUND_FUNCTION;
904     }
905 
IsJSIntlBoundFunction() const906     inline bool IsJSIntlBoundFunction() const
907     {
908         return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION;
909     }
910 
IsJSProxyRevocFunction() const911     inline bool IsJSProxyRevocFunction() const
912     {
913         return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION;
914     }
915 
IsJSAsyncFunction() const916     inline bool IsJSAsyncFunction() const
917     {
918         return GetObjectType() == JSType::JS_ASYNC_FUNCTION || GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
919     }
920 
IsJSSharedAsyncFunction() const921     inline bool IsJSSharedAsyncFunction() const
922     {
923         return GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION;
924     }
925 
IsJSAsyncAwaitStatusFunction() const926     inline bool IsJSAsyncAwaitStatusFunction() const
927     {
928         return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION;
929     }
930 
IsJSPromiseReactionFunction() const931     inline bool IsJSPromiseReactionFunction() const
932     {
933         return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION;
934     }
935 
IsJSPromiseExecutorFunction() const936     inline bool IsJSPromiseExecutorFunction() const
937     {
938         return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION;
939     }
940 
IsJSAsyncModuleFulfilledFunction() const941     inline bool IsJSAsyncModuleFulfilledFunction() const
942     {
943         return GetObjectType() == JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION;
944     }
945 
IsJSAsyncModuleRejectedFunction() const946     inline bool IsJSAsyncModuleRejectedFunction() const
947     {
948         return GetObjectType() == JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION;
949     }
950 
IsJSAsyncFromSyncIterUnwarpFunction() const951     inline bool IsJSAsyncFromSyncIterUnwarpFunction() const
952     {
953         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION;
954     }
955 
IsJSPromiseAllResolveElementFunction() const956     inline bool IsJSPromiseAllResolveElementFunction() const
957     {
958         return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION;
959     }
960 
IsJSAsyncGeneratorResNextRetProRstFtn() const961     inline bool IsJSAsyncGeneratorResNextRetProRstFtn() const
962     {
963         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN;
964     }
965 
IsJSPromiseAnyRejectElementFunction() const966     inline bool IsJSPromiseAnyRejectElementFunction() const
967     {
968         return GetObjectType() == JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION;
969     }
970 
IsJSPromiseAllSettledElementFunction() const971     inline bool IsJSPromiseAllSettledElementFunction() const
972     {
973         return GetObjectType() == JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION;
974     }
975 
IsJSPromiseFinallyFunction() const976     inline bool IsJSPromiseFinallyFunction() const
977     {
978         return GetObjectType() == JSType::JS_PROMISE_FINALLY_FUNCTION;
979     }
980 
IsJSPromiseValueThunkOrThrowerFunction() const981     inline bool IsJSPromiseValueThunkOrThrowerFunction() const
982     {
983         return GetObjectType() == JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION;
984     }
985 
IsMicroJobQueue() const986     inline bool IsMicroJobQueue() const
987     {
988         return GetObjectType() == JSType::MICRO_JOB_QUEUE;
989     }
990 
IsPendingJob() const991     inline bool IsPendingJob() const
992     {
993         return GetObjectType() == JSType::PENDING_JOB;
994     }
995 
IsJsPrimitiveRef() const996     inline bool IsJsPrimitiveRef() const
997     {
998         return GetObjectType() == JSType::JS_PRIMITIVE_REF;
999     }
1000 
IsJSSet() const1001     bool IsJSSet() const
1002     {
1003         return GetObjectType() == JSType::JS_SET;
1004     }
1005 
IsJSSharedSet() const1006     bool IsJSSharedSet() const
1007     {
1008         return GetObjectType() == JSType::JS_SHARED_SET;
1009     }
1010 
IsJSMap() const1011     bool IsJSMap() const
1012     {
1013         return GetObjectType() == JSType::JS_MAP;
1014     }
1015 
IsJSSharedMap() const1016     bool IsJSSharedMap() const
1017     {
1018         return GetObjectType() == JSType::JS_SHARED_MAP;
1019     }
1020 
IsJSWeakMap() const1021     bool IsJSWeakMap() const
1022     {
1023         return GetObjectType() == JSType::JS_WEAK_MAP;
1024     }
1025 
IsJSWeakSet() const1026     bool IsJSWeakSet() const
1027     {
1028         return GetObjectType() == JSType::JS_WEAK_SET;
1029     }
1030 
IsJSWeakRef() const1031     bool IsJSWeakRef() const
1032     {
1033         return GetObjectType() == JSType::JS_WEAK_REF;
1034     }
1035 
IsJSFinalizationRegistry() const1036     bool IsJSFinalizationRegistry() const
1037     {
1038         return GetObjectType() == JSType::JS_FINALIZATION_REGISTRY;
1039     }
1040 
IsJSFunction() const1041     bool IsJSFunction() const
1042     {
1043         return GetObjectType() >= JSType::JS_FUNCTION_FIRST && GetObjectType() <= JSType::JS_FUNCTION_LAST;
1044     }
1045 
IsJSSharedFunction() const1046     bool IsJSSharedFunction() const
1047     {
1048         return GetObjectType() == JSType::JS_SHARED_FUNCTION;
1049     }
1050 
IsJSShared() const1051     bool IsJSShared() const
1052     {
1053         uint32_t bits = GetBitField();
1054         return IsJSSharedBit::Decode(bits);
1055     }
1056 
SetIsJSShared(bool flag) const1057     inline void SetIsJSShared(bool flag) const
1058     {
1059         IsJSSharedBit::Set<uint32_t>(flag, GetBitFieldAddr());
1060     }
1061 
IsJSError() const1062     inline bool IsJSError() const
1063     {
1064         JSType jsType = GetObjectType();
1065         return jsType >= JSType::JS_ERROR_FIRST && jsType <= JSType::JS_ERROR_LAST;
1066     }
1067 
IsArguments() const1068     inline bool IsArguments() const
1069     {
1070         return GetObjectType() == JSType::JS_ARGUMENTS;
1071     }
1072 
IsDate() const1073     inline bool IsDate() const
1074     {
1075         return GetObjectType() == JSType::JS_DATE;
1076     }
1077 
IsJSRegExp() const1078     inline bool IsJSRegExp() const
1079     {
1080         return GetObjectType() == JSType::JS_REG_EXP;
1081     }
1082 
IsJSProxy() const1083     inline bool IsJSProxy() const
1084     {
1085         return GetObjectType() == JSType::JS_PROXY;
1086     }
1087 
IsJSLocale() const1088     inline bool IsJSLocale() const
1089     {
1090         return GetObjectType() == JSType::JS_LOCALE;
1091     }
1092 
IsJSIntl() const1093     inline bool IsJSIntl() const
1094     {
1095         return GetObjectType() == JSType::JS_INTL;
1096     }
1097 
IsJSDateTimeFormat() const1098     inline bool IsJSDateTimeFormat() const
1099     {
1100         return GetObjectType() == JSType::JS_DATE_TIME_FORMAT;
1101     }
1102 
IsJSRelativeTimeFormat() const1103     inline bool IsJSRelativeTimeFormat() const
1104     {
1105         return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT;
1106     }
1107 
IsJSNumberFormat() const1108     inline bool IsJSNumberFormat() const
1109     {
1110         return GetObjectType() == JSType::JS_NUMBER_FORMAT;
1111     }
1112 
IsJSCollator() const1113     inline bool IsJSCollator() const
1114     {
1115         return GetObjectType() == JSType::JS_COLLATOR;
1116     }
1117 
IsJSPluralRules() const1118     inline bool IsJSPluralRules() const
1119     {
1120         return GetObjectType() == JSType::JS_PLURAL_RULES;
1121     }
1122 
IsJSDisplayNames() const1123     inline bool IsJSDisplayNames() const
1124     {
1125         return GetObjectType() == JSType::JS_DISPLAYNAMES;
1126     }
1127 
IsJSSegmenter() const1128     inline bool IsJSSegmenter() const
1129     {
1130         return GetObjectType() == JSType::JS_SEGMENTER;
1131     }
1132 
IsJSSegments() const1133     inline bool IsJSSegments() const
1134     {
1135         return GetObjectType() == JSType::JS_SEGMENTS;
1136     }
1137 
IsJSSegmentIterator() const1138     inline bool IsJSSegmentIterator() const
1139     {
1140         return GetObjectType() == JSType::JS_SEGMENT_ITERATOR;
1141     }
1142 
IsJSListFormat() const1143     inline bool IsJSListFormat() const
1144     {
1145         return GetObjectType() == JSType::JS_LIST_FORMAT;
1146     }
1147 
IsMethod() const1148     inline bool IsMethod() const
1149     {
1150         return GetObjectType() == JSType::METHOD;
1151     }
1152 
IsClassLiteral() const1153     inline bool IsClassLiteral() const
1154     {
1155         return GetObjectType() == JSType::CLASS_LITERAL;
1156     }
1157 
1158     // non ECMA standard jsapi containers.
IsSpecialContainer() const1159     inline bool IsSpecialContainer() const
1160     {
1161         return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_API_QUEUE;
1162     }
1163 
IsRegularObject() const1164     inline bool IsRegularObject() const
1165     {
1166         return GetObjectType() < JSType::JS_API_ARRAY_LIST;
1167     }
1168 
IsJSAPIArrayList() const1169     inline bool IsJSAPIArrayList() const
1170     {
1171         return GetObjectType() == JSType::JS_API_ARRAY_LIST;
1172     }
1173 
IsJSAPIArrayListIterator() const1174     inline bool IsJSAPIArrayListIterator() const
1175     {
1176         return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
1177     }
IsJSAPILightWeightMap() const1178     inline bool IsJSAPILightWeightMap() const
1179     {
1180         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP;
1181     }
IsJSAPILightWeightMapIterator() const1182     inline bool IsJSAPILightWeightMapIterator() const
1183     {
1184         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR;
1185     }
IsJSAPILightWeightSet() const1186     inline bool IsJSAPILightWeightSet() const
1187     {
1188         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET;
1189     }
IsJSAPILightWeightSetIterator() const1190     inline bool IsJSAPILightWeightSetIterator() const
1191     {
1192         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR;
1193     }
IsJSAPIStack() const1194     inline bool IsJSAPIStack() const
1195     {
1196         return GetObjectType() == JSType::JS_API_STACK;
1197     }
IsJSAPIDeque() const1198     inline bool IsJSAPIDeque() const
1199     {
1200         return GetObjectType() == JSType::JS_API_DEQUE;
1201     }
IsLinkedNode() const1202     inline bool IsLinkedNode() const
1203     {
1204         return GetObjectType() == JSType::LINKED_NODE;
1205     }
1206 
IsRBTreeNode() const1207     inline bool IsRBTreeNode() const
1208     {
1209         return GetObjectType() == JSType::RB_TREENODE;
1210     }
1211 
IsJSAPIHashMap() const1212     inline bool IsJSAPIHashMap() const
1213     {
1214         return GetObjectType() == JSType::JS_API_HASH_MAP;
1215     }
1216 
IsJSAPIHashSet() const1217     inline bool IsJSAPIHashSet() const
1218     {
1219         return GetObjectType() == JSType::JS_API_HASH_SET;
1220     }
1221 
IsJSAPIHashMapIterator() const1222     inline bool IsJSAPIHashMapIterator() const
1223     {
1224         return GetObjectType() == JSType::JS_API_HASHMAP_ITERATOR;
1225     }
1226 
IsJSAPIHashSetIterator() const1227     inline bool IsJSAPIHashSetIterator() const
1228     {
1229         return GetObjectType() == JSType::JS_API_HASHSET_ITERATOR;
1230     }
IsJSAPIQueue() const1231     inline bool IsJSAPIQueue() const
1232     {
1233         return GetObjectType() == JSType::JS_API_QUEUE;
1234     }
1235 
IsJSAPIPlainArray() const1236     inline bool IsJSAPIPlainArray() const
1237     {
1238         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY;
1239     }
1240 
IsJSAPIQueueIterator() const1241     inline bool IsJSAPIQueueIterator() const
1242     {
1243         return GetObjectType() == JSType::JS_API_QUEUE_ITERATOR;
1244     }
IsJSAPIList() const1245     inline bool IsJSAPIList() const
1246     {
1247         return GetObjectType() == JSType::JS_API_LIST;
1248     }
IsJSAPILinkedList() const1249     inline bool IsJSAPILinkedList() const
1250     {
1251         return GetObjectType() == JSType::JS_API_LINKED_LIST;
1252     }
IsJSAPITreeMap() const1253     inline bool IsJSAPITreeMap() const
1254     {
1255         return GetObjectType() == JSType::JS_API_TREE_MAP;
1256     }
1257 
IsJSAPITreeSet() const1258     inline bool IsJSAPITreeSet() const
1259     {
1260         return GetObjectType() == JSType::JS_API_TREE_SET;
1261     }
1262 
IsJSAPITreeMapIterator() const1263     inline bool IsJSAPITreeMapIterator() const
1264     {
1265         return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR;
1266     }
1267 
IsJSAPITreeSetIterator() const1268     inline bool IsJSAPITreeSetIterator() const
1269     {
1270         return GetObjectType() == JSType::JS_API_TREESET_ITERATOR;
1271     }
IsJSAPIVector() const1272     inline bool IsJSAPIVector() const
1273     {
1274         return GetObjectType() == JSType::JS_API_VECTOR;
1275     }
IsJSAPIVectorIterator() const1276     inline bool IsJSAPIVectorIterator() const
1277     {
1278         return GetObjectType() == JSType::JS_API_VECTOR_ITERATOR;
1279     }
IsJSAPIBitVector() const1280     inline bool IsJSAPIBitVector() const
1281     {
1282         return GetObjectType() == JSType::JS_API_BITVECTOR;
1283     }
IsJSAPIBitVectorIterator() const1284     inline bool IsJSAPIBitVectorIterator() const
1285     {
1286         return GetObjectType() == JSType::JS_API_BITVECTOR_ITERATOR;
1287     }
1288 
IsAccessorData() const1289     inline bool IsAccessorData() const
1290     {
1291         return GetObjectType() == JSType::ACCESSOR_DATA;
1292     }
1293 
IsInternalAccessor() const1294     inline bool IsInternalAccessor() const
1295     {
1296         return GetObjectType() == JSType::INTERNAL_ACCESSOR;
1297     }
1298 
IsIterator() const1299     inline bool IsIterator() const
1300     {
1301         JSType jsType = GetObjectType();
1302         return jsType >= JSType::JS_ITERATOR_FIRST && jsType <= JSType::JS_ITERATOR_LAST;
1303     }
1304 
IsAsyncIterator() const1305     inline bool IsAsyncIterator() const
1306     {
1307         return GetObjectType() == JSType::JS_ASYNCITERATOR;
1308     }
1309 
IsAsyncFromSyncIterator() const1310     inline bool IsAsyncFromSyncIterator() const
1311     {
1312         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITERATOR;
1313     }
1314 
IsForinIterator() const1315     inline bool IsForinIterator() const
1316     {
1317         return GetObjectType() == JSType::JS_FORIN_ITERATOR;
1318     }
1319 
IsStringIterator() const1320     inline bool IsStringIterator() const
1321     {
1322         return GetObjectType() == JSType::JS_STRING_ITERATOR;
1323     }
1324 
IsArrayBuffer() const1325     inline bool IsArrayBuffer() const
1326     {
1327         return GetObjectType() == JSType::JS_ARRAY_BUFFER;
1328     }
1329 
IsSharedArrayBuffer() const1330     inline bool IsSharedArrayBuffer() const
1331     {
1332         return GetObjectType() == JSType::JS_SHARED_ARRAY_BUFFER;
1333     }
1334 
IsSendableArrayBuffer() const1335     inline bool IsSendableArrayBuffer() const
1336     {
1337         return GetObjectType() == JSType::JS_SENDABLE_ARRAY_BUFFER;
1338     }
1339 
IsDataView() const1340     inline bool IsDataView() const
1341     {
1342         return GetObjectType() == JSType::JS_DATA_VIEW;
1343     }
1344 
IsJSSetIterator() const1345     inline bool IsJSSetIterator() const
1346     {
1347         return GetObjectType() == JSType::JS_SET_ITERATOR;
1348     }
1349 
1350     // iterator of shared set
IsJSSharedSetIterator() const1351     inline bool IsJSSharedSetIterator() const
1352     {
1353         return GetObjectType() == JSType::JS_SHARED_SET_ITERATOR;
1354     }
1355 
IsJSRegExpIterator() const1356     inline bool IsJSRegExpIterator() const
1357     {
1358         return GetObjectType() == JSType::JS_REG_EXP_ITERATOR;
1359     }
1360 
IsJSMapIterator() const1361     inline bool IsJSMapIterator() const
1362     {
1363         return GetObjectType() == JSType::JS_MAP_ITERATOR;
1364     }
1365 
1366     // iterator of shared map
IsJSSharedMapIterator() const1367     inline bool IsJSSharedMapIterator() const
1368     {
1369         return GetObjectType() == JSType::JS_SHARED_MAP_ITERATOR;
1370     }
1371 
IsJSArrayIterator() const1372     inline bool IsJSArrayIterator() const
1373     {
1374         return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
1375     }
1376 
IsJSSharedArrayIterator() const1377     inline bool IsJSSharedArrayIterator() const
1378     {
1379         return GetObjectType() == JSType::JS_SHARED_ARRAY_ITERATOR;
1380     }
1381 
IsJSAPIPlainArrayIterator() const1382     inline bool IsJSAPIPlainArrayIterator() const
1383     {
1384         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY_ITERATOR;
1385     }
1386 
IsJSAPIDequeIterator() const1387     inline bool IsJSAPIDequeIterator() const
1388     {
1389         return GetObjectType() == JSType::JS_API_DEQUE_ITERATOR;
1390     }
1391 
IsJSAPIStackIterator() const1392     inline bool IsJSAPIStackIterator() const
1393     {
1394         return GetObjectType() == JSType::JS_API_STACK_ITERATOR;
1395     }
1396 
IsJSAPILinkedListIterator() const1397     inline bool IsJSAPILinkedListIterator() const
1398     {
1399         return GetObjectType() == JSType::JS_API_LINKED_LIST_ITERATOR;
1400     }
1401 
IsJSAPIListIterator() const1402     inline bool IsJSAPIListIterator() const
1403     {
1404         return GetObjectType() == JSType::JS_API_LIST_ITERATOR;
1405     }
1406 
IsPrototypeHandler() const1407     inline bool IsPrototypeHandler() const
1408     {
1409         return GetObjectType() == JSType::PROTOTYPE_HANDLER;
1410     }
1411 
IsTransitionHandler() const1412     inline bool IsTransitionHandler() const
1413     {
1414         return GetObjectType() == JSType::TRANSITION_HANDLER;
1415     }
1416 
IsTransWithProtoHandler() const1417     inline bool IsTransWithProtoHandler() const
1418     {
1419         return GetObjectType() == JSType::TRANS_WITH_PROTO_HANDLER;
1420     }
1421 
IsStoreTSHandler() const1422     inline bool IsStoreTSHandler() const
1423     {
1424         return GetObjectType() == JSType::STORE_TS_HANDLER;
1425     }
1426 
IsPropertyBox() const1427     inline bool IsPropertyBox() const
1428     {
1429         return GetObjectType() == JSType::PROPERTY_BOX;
1430     }
IsProtoChangeMarker() const1431     inline bool IsProtoChangeMarker() const
1432     {
1433         return GetObjectType() == JSType::PROTO_CHANGE_MARKER;
1434     }
1435 
IsMarkerCell() const1436     inline bool IsMarkerCell() const
1437     {
1438         return GetObjectType() == JSType::MARKER_CELL;
1439     }
1440 
IsTrackInfoObject() const1441     inline bool IsTrackInfoObject() const
1442     {
1443         return GetObjectType() == JSType::TRACK_INFO;
1444     }
1445 
IsProtoChangeDetails() const1446     inline bool IsProtoChangeDetails() const
1447     {
1448         return GetObjectType() == JSType::PROTOTYPE_INFO;
1449     }
1450 
IsProgram() const1451     inline bool IsProgram() const
1452     {
1453         return GetObjectType() == JSType::PROGRAM;
1454     }
1455 
IsClassInfoExtractor() const1456     inline bool IsClassInfoExtractor() const
1457     {
1458         return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR;
1459     }
1460 
IsCallable() const1461     inline bool IsCallable() const
1462     {
1463         uint32_t bits = GetBitField();
1464         return CallableBit::Decode(bits);
1465     }
1466 
IsConstructor() const1467     inline bool IsConstructor() const
1468     {
1469         uint32_t bits = GetBitField();
1470         return ConstructorBit::Decode(bits);
1471     }
1472 
IsExtensible() const1473     inline bool IsExtensible() const
1474     {
1475         uint32_t bits = GetBitField();
1476         return ExtensibleBit::Decode(bits);
1477     }
1478 
IsPrototype() const1479     inline bool IsPrototype() const
1480     {
1481         uint32_t bits = GetBitField();
1482         return IsPrototypeBit::Decode(bits);
1483     }
1484 
IsClassConstructor() const1485     inline bool IsClassConstructor() const
1486     {
1487         uint32_t bits = GetBitField();
1488         return IsClassConstructorOrPrototypeBit::Decode(bits) && IsConstructor();
1489     }
1490 
IsJSGlobalObject() const1491     inline bool IsJSGlobalObject() const
1492     {
1493         return GetObjectType() == JSType::JS_GLOBAL_OBJECT;
1494     }
1495 
IsClassPrototype() const1496     inline bool IsClassPrototype() const
1497     {
1498         uint32_t bits = GetBitField();
1499         return IsClassConstructorOrPrototypeBit::Decode(bits) && IsPrototype();
1500     }
1501 
IsNativeBindingObject() const1502     inline bool IsNativeBindingObject() const
1503     {
1504         uint32_t bits = GetBitField();
1505         return IsNativeBindingObjectBit::Decode(bits);
1506     }
1507 
IsDictionaryMode() const1508     inline bool IsDictionaryMode() const
1509     {
1510         uint32_t bits = GetBitField();
1511         return IsDictionaryBit::Decode(bits);
1512     }
1513 
1514     // created from TypeScript Types
IsTS() const1515     inline bool IsTS() const
1516     {
1517         uint32_t bits = GetBitField();
1518         return IsTSBit::Decode(bits);
1519     }
1520 
IsJSFunctionFromBitField() const1521     inline bool IsJSFunctionFromBitField() const
1522     {
1523         uint32_t bits = GetBitField();
1524         return IsJSFunctionBit::Decode(bits);
1525     }
1526 
IsOnHeapFromBitField() const1527     inline bool IsOnHeapFromBitField() const
1528     {
1529         uint32_t bits = GetBitField();
1530         return IsOnHeap::Decode(bits);
1531     }
1532 
IsGeneratorFunction() const1533     inline bool IsGeneratorFunction() const
1534     {
1535         return GetObjectType() == JSType::JS_GENERATOR_FUNCTION;
1536     }
1537 
IsAsyncGeneratorFunction() const1538     inline bool IsAsyncGeneratorFunction() const
1539     {
1540         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_FUNCTION;
1541     }
1542 
IsGeneratorObject() const1543     inline bool IsGeneratorObject() const
1544     {
1545         JSType jsType = GetObjectType();
1546         return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT;
1547     }
1548 
IsAsyncGeneratorObject() const1549     inline bool IsAsyncGeneratorObject() const
1550     {
1551         JSType jsType = GetObjectType();
1552         return jsType == JSType::JS_ASYNC_GENERATOR_OBJECT;
1553     }
1554 
IsGeneratorContext() const1555     inline bool IsGeneratorContext() const
1556     {
1557         return GetObjectType() == JSType::JS_GENERATOR_CONTEXT;
1558     }
1559 
IsAsyncGeneratorRequest() const1560     inline bool IsAsyncGeneratorRequest() const
1561     {
1562         JSType jsType = GetObjectType();
1563         return jsType == JSType::ASYNC_GENERATOR_REQUEST;
1564     }
1565 
IsAsyncIteratorRecord() const1566     inline bool IsAsyncIteratorRecord() const
1567     {
1568         JSType jsType = GetObjectType();
1569         return jsType == JSType::ASYNC_ITERATOR_RECORD;
1570     }
1571 
IsAsyncFuncObject() const1572     inline bool IsAsyncFuncObject() const
1573     {
1574         return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT;
1575     }
1576 
IsJSPromise() const1577     inline bool IsJSPromise() const
1578     {
1579         return GetObjectType() == JSType::JS_PROMISE;
1580     }
1581 
IsResolvingFunctionsRecord() const1582     inline bool IsResolvingFunctionsRecord() const
1583     {
1584         return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD;
1585     }
1586 
IsPromiseRecord() const1587     inline bool IsPromiseRecord() const
1588     {
1589         return GetObjectType() == JSType::PROMISE_RECORD;
1590     }
1591 
IsPromiseIteratorRecord() const1592     inline bool IsPromiseIteratorRecord() const
1593     {
1594         return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD;
1595     }
1596 
IsPromiseCapability() const1597     inline bool IsPromiseCapability() const
1598     {
1599         return GetObjectType() == JSType::PROMISE_CAPABILITY;
1600     }
1601 
IsPromiseReaction() const1602     inline bool IsPromiseReaction() const
1603     {
1604         return GetObjectType() == JSType::PROMISE_REACTIONS;
1605     }
1606 
IsCellRecord() const1607     inline bool IsCellRecord() const
1608     {
1609         return GetObjectType() == JSType::CELL_RECORD;
1610     }
1611 
IsCompletionRecord() const1612     inline bool IsCompletionRecord() const
1613     {
1614         return GetObjectType() == JSType::COMPLETION_RECORD;
1615     }
1616 
IsRecord() const1617     inline bool IsRecord() const
1618     {
1619         JSType jsType = GetObjectType();
1620         return jsType >= JSType::JS_RECORD_FIRST && jsType <= JSType::JS_RECORD_LAST;
1621     }
1622 
IsTemplateMap() const1623     inline bool IsTemplateMap() const
1624     {
1625         return GetObjectType() == JSType::TEMPLATE_MAP;
1626     }
1627 
IsFreeObject() const1628     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 
IsFreeObjectWithShortField() const1634     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 
IsFreeObjectWithOneField() const1645     inline bool IsFreeObjectWithOneField() const
1646     {
1647         return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD;
1648     }
1649 
IsFreeObjectWithNoneField() const1650     inline bool IsFreeObjectWithNoneField() const
1651     {
1652         return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD;
1653     }
1654 
IsFreeObjectWithTwoField() const1655     inline bool IsFreeObjectWithTwoField() const
1656     {
1657         return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD;
1658     }
1659 
IsMachineCodeObject() const1660     inline bool IsMachineCodeObject() const
1661     {
1662         return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
1663     }
1664 
IsAOTLiteralInfo() const1665     inline bool IsAOTLiteralInfo() const
1666     {
1667         return GetObjectType() == JSType::AOT_LITERAL_INFO;
1668     }
1669 
IsExtraProfileTypeInfo() const1670     inline bool IsExtraProfileTypeInfo() const
1671     {
1672         return GetObjectType() == JSType::EXTRA_PROFILE_TYPE_INFO;
1673     }
1674 
IsProfileTypeInfoCell() const1675     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 
IsProfileTypeInfoCell0() const1681     inline bool IsProfileTypeInfoCell0() const
1682     {
1683         JSType jsType = GetObjectType();
1684         return jsType == JSType::PROFILE_TYPE_INFO_CELL_0;
1685     }
1686 
IsFunctionTemplate() const1687     inline bool IsFunctionTemplate() const
1688     {
1689         JSType jsType = GetObjectType();
1690         return jsType == JSType::FUNCTION_TEMPLATE;
1691     }
1692 
IsVTable() const1693     inline bool IsVTable() const
1694     {
1695         return GetObjectType() == JSType::VTABLE;
1696     }
1697 
IsModuleRecord() const1698     inline bool IsModuleRecord() const
1699     {
1700         JSType jsType = GetObjectType();
1701         return jsType >= JSType::MODULE_RECORD_FIRST && jsType <= JSType::MODULE_RECORD_LAST;
1702     }
1703 
IsSourceTextModule() const1704     inline bool IsSourceTextModule() const
1705     {
1706         return GetObjectType() == JSType::SOURCE_TEXT_MODULE_RECORD;
1707     }
1708 
IsCjsExports() const1709     inline bool IsCjsExports() const
1710     {
1711         return GetObjectType() == JSType::JS_CJS_EXPORTS;
1712     }
1713 
IsCjsModule() const1714     inline bool IsCjsModule() const
1715     {
1716         return GetObjectType() == JSType::JS_CJS_MODULE;
1717     }
1718 
IsCjsRequire() const1719     inline bool IsCjsRequire() const
1720     {
1721         return GetObjectType() == JSType::JS_CJS_REQUIRE;
1722     }
1723 
IsImportEntry() const1724     inline bool IsImportEntry() const
1725     {
1726         return GetObjectType() == JSType::IMPORTENTRY_RECORD;
1727     }
1728 
IsLocalExportEntry() const1729     inline bool IsLocalExportEntry() const
1730     {
1731         return GetObjectType() == JSType::LOCAL_EXPORTENTRY_RECORD;
1732     }
1733 
IsIndirectExportEntry() const1734     inline bool IsIndirectExportEntry() const
1735     {
1736         return GetObjectType() == JSType::INDIRECT_EXPORTENTRY_RECORD;
1737     }
1738 
IsStarExportEntry() const1739     inline bool IsStarExportEntry() const
1740     {
1741         return GetObjectType() == JSType::STAR_EXPORTENTRY_RECORD;
1742     }
1743 
IsResolvedBinding() const1744     inline bool IsResolvedBinding() const
1745     {
1746         return GetObjectType() == JSType::RESOLVEDBINDING_RECORD;
1747     }
1748 
IsResolvedIndexBinding() const1749     inline bool IsResolvedIndexBinding() const
1750     {
1751         return GetObjectType() == JSType::RESOLVEDINDEXBINDING_RECORD;
1752     }
1753 
IsResolvedRecordIndexBinding() const1754     inline bool IsResolvedRecordIndexBinding() const
1755     {
1756         return GetObjectType() == JSType::RESOLVEDRECORDINDEXBINDING_RECORD;
1757     }
1758 
IsResolvedRecordBinding() const1759     inline bool IsResolvedRecordBinding() const
1760     {
1761         return GetObjectType() == JSType::RESOLVEDRECORDBINDING_RECORD;
1762     }
1763 
IsModuleNamespace() const1764     inline bool IsModuleNamespace() const
1765     {
1766         return GetObjectType() == JSType::JS_MODULE_NAMESPACE;
1767     }
1768 
IsNativeModuleFailureInfo() const1769     inline bool IsNativeModuleFailureInfo() const
1770     {
1771         return GetObjectType() == JSType::NATIVE_MODULE_FAILURE_INFO;
1772     }
1773 
IsJSSharedObject() const1774     inline bool IsJSSharedObject() const
1775     {
1776         return GetObjectType() == JSType::JS_SHARED_OBJECT;
1777     }
1778 
IsJSSharedArray() const1779     inline bool IsJSSharedArray() const
1780     {
1781         return GetObjectType() == JSType::JS_SHARED_ARRAY;
1782     }
1783 
SetElementsKind(ElementsKind kind)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 
GetElementsKind() const1791     inline ElementsKind GetElementsKind() const
1792     {
1793         uint32_t bits = GetBitField();
1794         return ElementsKindBits::Decode(bits);
1795     }
1796 
SetLevel(uint8_t level)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 
GetLevel() const1804     inline uint8_t GetLevel() const
1805     {
1806         uint32_t bits = GetBitField();
1807         return LevelBit::Decode(bits);
1808     }
1809 
SetIsDictionaryElement(bool value)1810     inline void SetIsDictionaryElement(bool value)
1811     {
1812         uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
1813         SetBitField(newVal);
1814     }
IsDictionaryElement() const1815     inline bool IsDictionaryElement() const
1816     {
1817         return DictionaryElementBits::Decode(GetBitField());
1818     }
SetIsStableElements(bool value)1819     inline void SetIsStableElements(bool value)
1820     {
1821         uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value);
1822         SetBitField(newVal);
1823     }
IsStableElements() const1824     inline bool IsStableElements() const
1825     {
1826         return IsStableElementsBit::Decode(GetBitField());
1827     }
IsStableJSArguments() const1828     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     }
IsStableJSArray() const1834     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     }
SetHasConstructor(bool value)1840     inline void SetHasConstructor(bool value)
1841     {
1842         JSTaggedType newVal = HasConstructorBits::Update(GetBitField(), value);
1843         SetBitField(newVal);
1844     }
HasConstructor() const1845     inline bool HasConstructor() const
1846     {
1847         return HasConstructorBits::Decode(GetBitField());
1848     }
1849 
SetNumberOfProps(uint32_t num)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 
IncNumberOfProps()1857     inline void IncNumberOfProps()
1858     {
1859         ASSERT(NumberOfProps() < PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
1860         SetNumberOfProps(NumberOfProps() + 1);
1861     }
1862 
NumberOfProps() const1863     inline uint32_t NumberOfProps() const
1864     {
1865         uint32_t bits = GetBitField1();
1866         return NumberOfPropsBits::Decode(bits);
1867     }
1868 
HasProps() const1869     inline bool HasProps() const
1870     {
1871         return NumberOfProps() > 0;
1872     }
1873 
PropsIsEmpty() const1874     inline bool PropsIsEmpty() const
1875     {
1876         return NumberOfProps() == 0;
1877     }
1878 
LastPropIndex() const1879     inline uint32_t LastPropIndex() const
1880     {
1881         ASSERT(NumberOfProps() > 0);
1882         return NumberOfProps() - 1;
1883     }
1884 
GetNextInlinedPropsIndex() const1885     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 
GetNextNonInlinedPropsIndex() const1895     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 
GetObjectSize() const1905     inline uint32_t GetObjectSize() const
1906     {
1907         uint32_t bits = GetBitField1();
1908         return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1909     }
1910 
GetObjectSizeExcludeInlinedProps() const1911     inline uint32_t GetObjectSizeExcludeInlinedProps() const
1912     {
1913         return GetObjectSize() - GetInlinedProperties() * JSTaggedValue::TaggedTypeSize();
1914     }
1915 
SetObjectSize(uint32_t num)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 
GetInlinedPropertiesOffset(uint32_t index) const1924     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 
2070 private:
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 };
2118 static_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
2121 class PropertyLookupResult {
2122 public:
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 
2239 private:
2240     uint32_t data_ {0};
2241 };
2242 static_assert(PropertyLookupResult::OffsetBits::MaxValue() >
2243               (PropertyAttributes::MAX_FAST_PROPS_CAPACITY * JSTaggedValue::TaggedTypeSize()));
2244 }  // namespace panda::ecmascript
2245 
2246 #endif  // ECMASCRIPT_JS_HCLASS_H
2247