• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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/pgo_profiler/pgo_profiler_layout.h"
27 #include "ecmascript/property_attributes.h"
28 
29 #include "libpandabase/utils/bit_field.h"
30 
31 /*
32  *                         JS Object and JS HClass Layout
33  *
34  *      Properties                         JS Object                    JS HClass
35  *      +------------+                     +------------+               +------------------+
36  *      |arrayHClass + <---------|         |JS HClass   +-------------->|   meta hclass    |
37  *      +------------+           |         +------------+               +------------------+
38  *      | property 0 |           |         |Hash        |               |   hclass level   |
39  *      +------------+           |         +------------+               +------------------+
40  *      | property 1 |           |-------  |Properties  |               |   supers[]       |
41  *      +------------+                     +------------+               +------------------+
42  *      |...         |           |-------  |Elements    |               |   vtable[]       |
43  *      +------------+           |         +------------+               +------------------+
44  *                               |         |inl-prop-0  |               |   prototype      |
45  *      Elements                 |         +------------+               +------------------+
46  *      +------------+           |         |inl-prop-1  |               |   layout         |
47  *      |arrayHClass + <---------|         +------------+               +------------------+
48  *      +------------+                     |...         |               |   transitions    |
49  *      | value 0    |                     +------------+               +------------------+
50  *      +------------+                                                  |    parent        |
51  *      | value 1    |                                                  +------------------+
52  *      +------------+                                                  |ProtoChangeMarker |
53  *      |...         |                                                  +------------------+
54  *      +------------+                                                  |    EnumCache     |
55  *                                                                      +------------------+
56  *
57  *                          Proto: [[Prototype]] in Ecma spec
58  *                          Layout: record key and attr
59  *                          ProtoChangeMarker, ProtoChangeDetails: monitor [[prototype]] chain
60  *                          EnumCache: use for for-in syntax
61  *
62  */
63 namespace panda::ecmascript {
64 class ProtoChangeDetails;
65 class PropertyLookupResult;
66 
67 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
68 #define JSTYPE_DECL       /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
69     INVALID = 0,          /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
70         JS_OBJECT,        /* JS_OBJECT_FIRST ////////////////////////////////////////////////////////////////////// */ \
71         JS_REALM,         /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
72         JS_FUNCTION_BASE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
73         JS_FUNCTION,      /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
74         JS_PROXY_REVOC_FUNCTION,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
75         JS_PROMISE_REACTIONS_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \
76         JS_PROMISE_EXECUTOR_FUNCTION,  /* /////////////////////////////////////////////////////////////////-PADDING */ \
77         JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
78         JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
79         JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN, /* ///////////////////////////////////////-PADDING */ \
80         JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION,  /* ///////////////////////////////////////////////////////-PADDING */ \
81         JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
82         JS_PROMISE_FINALLY_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
83         JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION,  /* ///////////////////////////////////////////////////-PADDING */ \
84         JS_GENERATOR_FUNCTION, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
85         JS_ASYNC_GENERATOR_FUNCTION,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
86         JS_ASYNC_FUNCTION, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
87         JS_INTL_BOUND_FUNCTION, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
88         JS_ASYNC_AWAIT_STATUS_FUNCTION, /* ////////////////////////////////////////////////////////////////-PADDING */ \
89         JS_BOUND_FUNCTION, /*  //////////////////////////////////////////////////////////////////////////////////// */ \
90                                                                                                                        \
91         JS_ERROR,           /* JS_ERROR_FIRST /////////////////////////////////////////////////////////////-PADDING */ \
92         JS_EVAL_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
93         JS_RANGE_ERROR,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
94         JS_REFERENCE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
95         JS_TYPE_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
96         JS_AGGREGATE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
97         JS_URI_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
98         JS_SYNTAX_ERROR,    /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
99         JS_OOM_ERROR,       /* JS_ERROR_LAST /////////////////////////////////////////////////////////////////////// */\
100                                                                                                                        \
101         JS_REG_EXP,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
102         JS_SET,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
103         JS_MAP,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
104         JS_WEAK_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
105         JS_WEAK_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
106         JS_WEAK_REF, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
107         JS_FINALIZATION_REGISTRY, /* //////////////////////////////////////////////////////////////////////-PADDING */ \
108         JS_DATE,     /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
109         JS_ITERATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
110         JS_ASYNCITERATOR, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
111         JS_ASYNC_FROM_SYNC_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
112         JS_FORIN_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
113         JS_MAP_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
114         JS_SET_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
115         JS_REG_EXP_ITERATOR,        /* ////////////////////////////////////////////////////////////////////-PADDING */ \
116         JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
117         JS_API_DEQUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
118         JS_API_HASHMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
119         JS_API_HASHSET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
120         JS_API_LIGHT_WEIGHT_MAP_ITERATOR, /* //////////////////////////////////////////////////////////////-PADDING */ \
121         JS_API_LIGHT_WEIGHT_SET_ITERATOR,  /* /////////////////////////////////////////////////////////////-PADDING */ \
122         JS_API_PLAIN_ARRAY_ITERATOR,  /* //////////////////////////////////////////////////////////////////-PADDING */ \
123         JS_API_QUEUE_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
124         JS_API_STACK_ITERATOR,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
125         JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
126         JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
127         JS_API_VECTOR_ITERATOR,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
128         JS_API_LINKED_LIST_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
129         JS_API_LIST_ITERATOR,    /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
130         JS_ARRAY_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
131         JS_STRING_ITERATOR,      /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
132         JS_INTL, /* ///////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
133         JS_LOCALE, /* /////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
134         JS_DATE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
135         JS_RELATIVE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
136         JS_NUMBER_FORMAT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
137         JS_COLLATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
138         JS_PLURAL_RULES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
139         JS_DISPLAYNAMES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
140         JS_LIST_FORMAT,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
141                                                                                                                        \
142         JS_ARRAY_BUFFER, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
143         JS_SHARED_ARRAY_BUFFER, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
144         JS_PROMISE,      /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
145         JS_DATA_VIEW,    /* /////////////////////////////////////////////////////////////////////////////////////// */ \
146         JS_ARGUMENTS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
147         JS_GENERATOR_OBJECT,  /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
148         JS_ASYNC_GENERATOR_OBJECT,  /* ////////////////////////////////////////////////////////////////////-PADDING */ \
149         JS_ASYNC_FUNC_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
150                                                                                                                        \
151         /* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \
152         JS_ARRAY,       /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
153         JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
154         JS_API_LIGHT_WEIGHT_MAP,      /* //////////////////////////////////////////////////////////////////-PADDING */ \
155         JS_API_LIGHT_WEIGHT_SET, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
156         JS_API_VECTOR,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
157         JS_API_LINKED_LIST, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
158         JS_API_LIST,       /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
159         JS_API_HASH_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
160         JS_API_HASH_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
161         JS_API_TREE_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
162         JS_API_TREE_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
163         JS_API_DEQUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
164         JS_API_STACK,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
165         JS_API_PLAIN_ARRAY, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
166         JS_API_QUEUE,      /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
167         JS_TYPED_ARRAY, /* JS_TYPED_ARRAY_FIRST /////////////////////////////////////////////////////////////////// */ \
168         JS_INT8_ARRAY,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
169         JS_UINT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
170         JS_UINT8_CLAMPED_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
171         JS_INT16_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
172         JS_UINT16_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
173         JS_INT32_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
174         JS_UINT32_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
175         JS_FLOAT32_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
176         JS_FLOAT64_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
177         JS_BIGINT64_ARRAY,      /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
178         JS_BIGUINT64_ARRAY,     /* JS_TYPED_ARRAY_LAST ///////////////////////////////////////////////////////////// */\
179         JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \
180         JS_MODULE_NAMESPACE, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
181         JS_CJS_MODULE, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
182         JS_CJS_EXPORTS, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
183         JS_CJS_REQUIRE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
184         JS_GLOBAL_OBJECT, /* JS_OBJECT_LAST/////////////////////////////////////////////////////////////////-PADDING */\
185         JS_PROXY, /* ECMA_OBJECT_LAST ////////////////////////////////////////////////////////////////////////////// */\
186                                                                                                                        \
187         HCLASS,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
188         LINE_STRING,   /* //////////////////////////////////////////////////////////////////////////////////-PADDING */\
189         CONSTANT_STRING,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */\
190         TREE_STRING,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
191         BIGINT,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
192         TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
193         BYTE_ARRAY,   /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
194         LEXICAL_ENV,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
195         TAGGED_DICTIONARY, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
196         CONSTANT_POOL, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
197         COW_TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
198         LINKED_NODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
199         RB_TREENODE,  /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
200         FREE_OBJECT_WITH_ONE_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
201         FREE_OBJECT_WITH_NONE_FIELD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
202         FREE_OBJECT_WITH_TWO_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
203         JS_NATIVE_POINTER, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
204         GLOBAL_ENV,        /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
205         ACCESSOR_DATA,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
206         INTERNAL_ACCESSOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
207         SYMBOL, /* ////////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
208         JS_GENERATOR_CONTEXT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
209         PROTOTYPE_HANDLER,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
210         TRANSITION_HANDLER,   /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
211         TRANS_WITH_PROTO_HANDLER,    /* ///////////////////////////////////////////////////////////////////-PADDING */ \
212         STORE_TS_HANDLER,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
213         PROPERTY_BOX, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */  \
214         PROTO_CHANGE_MARKER, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
215         PROTOTYPE_INFO,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
216         TEMPLATE_MAP,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
217         PROGRAM,       /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \
218         METHOD,     /* ////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
219         CLASS_LITERAL,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
220                                                                                                                        \
221         PROMISE_CAPABILITY, /* JS_RECORD_FIRST //////////////////////////////////////////////////////////////////// */ \
222         PROMISE_RECORD,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
223         RESOLVING_FUNCTIONS_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
224         PROMISE_REACTIONS,          /* ////////////////////////////////////////////////////////////////////-PADDING */ \
225         ASYNC_GENERATOR_REQUEST, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
226         ASYNC_ITERATOR_RECORD,   /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
227         PROMISE_ITERATOR_RECORD,    /* ////////////////////////////////////////////////////////////////////-PADDING */ \
228         MICRO_JOB_QUEUE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */   \
229         PENDING_JOB,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */   \
230         MODULE_RECORD, /* //////////////////////////////////////////////////////////////////////////////-PADDING */    \
231         SOURCE_TEXT_MODULE_RECORD, /* //////////////////////////////////////////////////////////////////-PADDING */    \
232         IMPORTENTRY_RECORD, /* /////////////////////////////////////////////////////////////////////////-PADDING */    \
233         LOCAL_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */    \
234         INDIRECT_EXPORTENTRY_RECORD, /* ////////////////////////////////////////////////////////////////-PADDING */    \
235         STAR_EXPORTENTRY_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */    \
236         RESOLVEDBINDING_RECORD, /* /////////////////////////////////////////////////////////////////////-PADDING */    \
237         RESOLVEDINDEXBINDING_RECORD, /* ////////////////////////////////////////////////////////////////-PADDING */    \
238         CELL_RECORD,          /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
239         COMPLETION_RECORD, /* JS_RECORD_LAST /////////////////////////////////////////////////////////////////////// */\
240         MACHINE_CODE_OBJECT,                                                                                           \
241         CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
242         TS_ARRAY_TYPE,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
243         TS_UNION_TYPE,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
244         TS_FUNCTION_TYPE,  /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
245         TS_OBJECT_TYPE,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
246         TS_CLASS_TYPE,    /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
247         TS_CLASS_INSTANCE_TYPE,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
248         TS_INTERFACE_TYPE,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
249         TS_ITERATOR_INSTANCE_TYPE,    /* //////////////////////////////////////////////////////////////////-PADDING */ \
250         TS_NAMESPACE_TYPE,  /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
251                                                                                                                        \
252         VTABLE,                       /* //////////////////////////////////////////////////////////////////-PADDING */ \
253         AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
254         TYPE_LAST = AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \
255                                                                                                                        \
256         JS_FUNCTION_FIRST = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \
257         JS_FUNCTION_LAST = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* //////////////////////////////////////////////-PADDING */\
258                                                                                                                        \
259         JS_OBJECT_FIRST = JS_OBJECT, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
260         JS_OBJECT_LAST = JS_GLOBAL_OBJECT, /* //////////////////////////////////////////////////////////////-PADDING */\
261                                                                                                                        \
262         ECMA_OBJECT_FIRST = JS_OBJECT, /* /////////////////////////////////////////////////////////////////-PADDING */ \
263         ECMA_OBJECT_LAST = JS_PROXY,    /* /////////////////////////////////////////////////////////////////-PADDING */\
264                                                                                                                        \
265         JS_ERROR_FIRST = JS_ERROR,      /* ////////////////////////////////////////////////////////////////-PADDING */ \
266         JS_ERROR_LAST = JS_OOM_ERROR,    /* ////////////////////////////////////////////////////////////////-PADDING */\
267                                                                                                                        \
268         JS_ITERATOR_FIRST = JS_ITERATOR,      /* //////////////////////////////////////////////////////////-PADDING */ \
269         JS_ITERATOR_LAST = JS_STRING_ITERATOR, /* //////////////////////////////////////////////////////////-PADDING */\
270                                                                                                                        \
271         JS_RECORD_FIRST = PROMISE_CAPABILITY, /* //////////////////////////////////////////////////////////-PADDING */ \
272         JS_RECORD_LAST = COMPLETION_RECORD,    /* ///////////////////////////////////////////////////////-PADDING */   \
273                                                                                                                        \
274         JS_TYPED_ARRAY_FIRST = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
275         JS_TYPED_ARRAY_LAST = JS_BIGUINT64_ARRAY, /* ///////////////////////////////////////////////////////-PADDING */\
276                                                                                                                        \
277         MODULE_RECORD_FIRST = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \
278         MODULE_RECORD_LAST = SOURCE_TEXT_MODULE_RECORD, /* ////////////////////////////////////////////////-PADDING */ \
279                                                                                                                        \
280         TS_TYPE_FIRST = TS_ARRAY_TYPE, /* /////////////////////////////////////////////////////////////////-PADDING */ \
281         TS_TYPE_LAST = TS_NAMESPACE_TYPE, /* ///////////////////////////////////////////////////////////////-PADDING */\
282                                                                                                                        \
283         STRING_FIRST = LINE_STRING, /* /////////////////////////////////////////////////////////////////////-PADDING */\
284         STRING_LAST = TREE_STRING  /* /////////////////////////////////////////////////////////////////////-PADDING */
285 
286 enum class JSType : uint8_t {
287     JSTYPE_DECL,
288 };
289 
290 class JSHClass : public TaggedObject {
291 public:
292     static constexpr int TYPE_BITFIELD_NUM = 8;
293     static constexpr int LEVEL_BTTFIELD_NUM = 3;
294     using ObjectTypeBits = BitField<JSType, 0, TYPE_BITFIELD_NUM>;  // 8
295     using CallableBit = ObjectTypeBits::NextFlag;
296     using ConstructorBit = CallableBit::NextFlag;      // 10
297     using ExtensibleBit = ConstructorBit::NextFlag;
298     using IsPrototypeBit = ExtensibleBit::NextFlag;
299     using ElementsKindBits = IsPrototypeBit::NextField<ElementsKind, 5>;        // 5 means next 5 bit
300     using DictionaryElementBits = ElementsKindBits::NextFlag;                     // 16
301     using IsDictionaryBit = DictionaryElementBits::NextFlag;                               // 17
302     using IsStableElementsBit = IsDictionaryBit::NextFlag;                                 // 18
303     using HasConstructorBits = IsStableElementsBit::NextFlag;                              // 19
304     using IsLiteralBit = HasConstructorBits::NextFlag;                                     // 20
305     using ClassConstructorBit = IsLiteralBit::NextFlag;                                    // 21
306     using ClassPrototypeBit = ClassConstructorBit::NextFlag;                               // 22
307     using GlobalConstOrBuiltinsObjectBit = ClassPrototypeBit::NextFlag;                    // 23
308     using IsTSBit = GlobalConstOrBuiltinsObjectBit::NextFlag;                              // 24
309     using LevelBit = IsTSBit::NextField<uint32_t, LEVEL_BTTFIELD_NUM>;                     // 29
310     using IsJSFunctionBit = LevelBit::NextFlag;                                            // 30
311     using IsOptimizedBit = IsJSFunctionBit::NextFlag;                                      // 31
312     using CanFastCallBit = IsOptimizedBit::NextFlag;                                       // 32
313 
314     static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4;
315     static constexpr int MAX_CAPACITY_OF_OUT_OBJECTS =
316         PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES - DEFAULT_CAPACITY_OF_IN_OBJECTS;
317     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5;
318     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS =
319         PropertyAttributes::OFFSET_BITFIELD_NUM + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED;
320     static constexpr int MAX_OBJECT_SIZE_IN_WORDS = (1U << OFFSET_MAX_OBJECT_SIZE_IN_WORDS) - 1;
321     static constexpr uint64_t OPTIMIZED_BIT = 1LU << IsOptimizedBit::START_BIT;
322     static constexpr uint64_t FASTCALL_BIT = 1LU << CanFastCallBit::START_BIT;
323     static constexpr uint64_t OPTIMIZED_FASTCALL_BITS = OPTIMIZED_BIT | FASTCALL_BIT;
324 
325     using NumberOfPropsBits = BitField<uint32_t, 0, PropertyAttributes::OFFSET_BITFIELD_NUM>; // 10
326     using InlinedPropsStartBits = NumberOfPropsBits::NextField<uint32_t,
327             OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED>; // 15
328     using ObjectSizeInWordsBits = InlinedPropsStartBits::NextField<uint32_t, OFFSET_MAX_OBJECT_SIZE_IN_WORDS>; // 30
329     using HasDeletePropertyBit = ObjectSizeInWordsBits::NextFlag;
330     using IsAllTaggedPropBit = HasDeletePropertyBit::NextFlag;  //32
331 
332     static JSHClass *Cast(const TaggedObject *object);
333 
334     inline size_t SizeFromJSHClass(TaggedObject *header);
335     inline bool HasReferenceField();
336 
337     // size need to add inlined property numbers
338     void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps,
339                     bool isOptimized = false, bool canFastCall = false);
340 
341     static JSHandle<JSHClass> Clone(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
342                                     bool withoutInlinedProperties = false);
343     static JSHandle<JSHClass> CloneWithoutInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
344 
345     static void TransitionElementsToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
346     static JSHandle<JSHClass> SetPropertyOfObjHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass,
347                                                      const JSHandle<JSTaggedValue> &key,
348                                                      const PropertyAttributes &attr);
349     static void AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
350                             const PropertyAttributes &attr);
351 
352     static JSHandle<JSHClass> TransitionExtension(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
353     static JSHandle<JSHClass> TransitionProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
354                                               const JSHandle<JSTaggedValue> &proto);
355     static JSHandle<JSHClass> TransProtoWithoutLayout(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
356                                                       const JSHandle<JSTaggedValue> &proto);
357     static void TransitionToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
358     static void TransitionForRepChange(const JSThread *thread, const JSHandle<JSObject> &receiver,
359                                        const JSHandle<JSTaggedValue> &key, PropertyAttributes attr);
360     static void TransitToElementsKind(const JSThread *thread, const JSHandle<JSArray> &array);
361     static void TransitToElementsKind(const JSThread *thread, const JSHandle<JSObject> &object,
362         const JSHandle<JSTaggedValue> &value, ElementsKind kind = ElementsKind::NONE);
363 
364     static JSHandle<JSTaggedValue> EnableProtoChangeMarker(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
365 
366     static void NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> oldHclass, JSHandle<JSHClass> newHclass,
367                                     JSTaggedValue addedKey = JSTaggedValue::Undefined());
368 
369     static void RegisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
370 
371     static bool UnregisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
372 
373     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread,
374                                                               const JSHandle<JSHClass> &jshclass);
375 
376     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, const JSHandle<JSObject> &obj);
377 
378     inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key,
379                                       const PropertyAttributes &metaData);
380 
381     static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
382                                  JSTaggedValue addedKey = JSTaggedValue::Undefined());
383 
384     static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
385                                    JSTaggedValue addedKey = JSTaggedValue::Undefined());
386 
387     static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass,
388                              const JSHandle<JSHClass> &newHclass);
389 
390     void InitTSInheritInfo(const JSThread *thread);
391 
392     bool HasTSSubtyping() const;
393 
394     bool IsTSIHCWithInheritInfo() const;
395 
396     static void CopyTSInheritInfo(const JSThread *thread, const JSHandle<JSHClass> &oldHClass,
397                                   JSHandle<JSHClass> &newHClass);
398 
ClearBitField()399     inline void ClearBitField()
400     {
401         SetBitField(0UL);
402         SetBitField1(0UL);
403     }
404 
GetObjectType()405     inline JSType GetObjectType() const
406     {
407         uint32_t bits = GetBitField();
408         return ObjectTypeBits::Decode(bits);
409     }
410 
SetObjectType(JSType type)411     inline void SetObjectType(JSType type)
412     {
413         uint32_t bits = GetBitField();
414         uint32_t newVal = ObjectTypeBits::Update(bits, type);
415         SetBitField(newVal);
416     }
417 
SetCallable(bool flag)418     inline void SetCallable(bool flag)
419     {
420         CallableBit::Set<uint32_t>(flag, GetBitFieldAddr());
421     }
422 
SetConstructor(bool flag)423     inline void SetConstructor(bool flag) const
424     {
425         ConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
426     }
427 
SetExtensible(bool flag)428     inline void SetExtensible(bool flag) const
429     {
430         ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr());
431     }
432 
SetIsPrototype(bool flag)433     inline void SetIsPrototype(bool flag) const
434     {
435         IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
436     }
437 
SetIsLiteral(bool flag)438     inline void SetIsLiteral(bool flag) const
439     {
440         IsLiteralBit::Set<uint32_t>(flag, GetBitFieldAddr());
441     }
442 
SetClassConstructor(bool flag)443     inline void SetClassConstructor(bool flag) const
444     {
445         ClassConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
446     }
447 
SetClassPrototype(bool flag)448     inline void SetClassPrototype(bool flag) const
449     {
450         ClassPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
451     }
452 
SetGlobalConstOrBuiltinsObject(bool flag)453     inline void SetGlobalConstOrBuiltinsObject(bool flag) const
454     {
455         GlobalConstOrBuiltinsObjectBit::Set<uint32_t>(flag, GetBitFieldAddr());
456     }
457 
SetIsDictionaryMode(bool flag)458     inline void SetIsDictionaryMode(bool flag) const
459     {
460         IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
461     }
462 
SetTS(bool flag)463     inline void SetTS(bool flag) const
464     {
465         IsTSBit::Set<uint32_t>(flag, GetBitFieldAddr());
466     }
467 
SetIsJSFunction(bool flag)468     inline void SetIsJSFunction(bool flag) const
469     {
470         IsJSFunctionBit::Set<uint32_t>(flag, GetBitFieldAddr());
471     }
472 
ClearOptimizedFlags()473     inline void ClearOptimizedFlags() const
474     {
475         SetIsOptimized(false);
476         SetCanFastCall(false);
477     }
478 
SetIsOptimized(bool flag)479     inline void SetIsOptimized(bool flag) const
480     {
481         IsOptimizedBit::Set<uint32_t>(flag, GetBitFieldAddr());
482     }
483 
SetCanFastCall(bool flag)484     inline void SetCanFastCall(bool flag) const
485     {
486         CanFastCallBit::Set<uint32_t>(flag, GetBitFieldAddr());
487     }
488 
IsJSObject()489     inline bool IsJSObject() const
490     {
491         JSType jsType = GetObjectType();
492         return (JSType::JS_OBJECT_FIRST <= jsType && jsType <= JSType::JS_OBJECT_LAST);
493     }
494 
IsECMAObject()495     inline bool IsECMAObject() const
496     {
497         JSType jsType = GetObjectType();
498         return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST);
499     }
500 
IsRealm()501     inline bool IsRealm() const
502     {
503         return GetObjectType() == JSType::JS_REALM;
504     }
505 
IsHClass()506     inline bool IsHClass() const
507     {
508         return GetObjectType() == JSType::HCLASS;
509     }
510 
IsString()511     inline bool IsString() const
512     {
513         JSType jsType = GetObjectType();
514         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST);
515     }
516 
IsLineString()517     inline bool IsLineString() const
518     {
519         return GetObjectType() == JSType::LINE_STRING;
520     }
521 
IsConstantString()522     inline bool IsConstantString() const
523     {
524         return GetObjectType() == JSType::CONSTANT_STRING;
525     }
526 
IsTreeString()527     inline bool IsTreeString() const
528     {
529         return GetObjectType() == JSType::TREE_STRING;
530     }
531 
IsBigInt()532     inline bool IsBigInt() const
533     {
534         return GetObjectType() == JSType::BIGINT;
535     }
536 
IsSymbol()537     inline bool IsSymbol() const
538     {
539         return GetObjectType() == JSType::SYMBOL;
540     }
541 
IsStringOrSymbol()542     inline bool IsStringOrSymbol() const
543     {
544         JSType jsType = GetObjectType();
545         return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST) || (jsType == JSType::SYMBOL);
546     }
547 
IsTaggedArray()548     inline bool IsTaggedArray() const
549     {
550         JSType jsType = GetObjectType();
551         switch (jsType) {
552             case JSType::TAGGED_ARRAY:
553             case JSType::TAGGED_DICTIONARY:
554             case JSType::LEXICAL_ENV:
555             case JSType::CONSTANT_POOL:
556             case JSType::AOT_LITERAL_INFO:
557             case JSType::VTABLE:
558             case JSType::COW_TAGGED_ARRAY:
559                 return true;
560             default:
561                 return false;
562         }
563     }
564 
IsByteArray()565     inline bool IsByteArray() const
566     {
567         return GetObjectType() == JSType::BYTE_ARRAY;
568     }
569 
IsConstantPool()570     inline bool IsConstantPool() const
571     {
572         return GetObjectType() == JSType::CONSTANT_POOL;
573     }
574 
IsDictionary()575     inline bool IsDictionary() const
576     {
577         return GetObjectType() == JSType::TAGGED_DICTIONARY;
578     }
579 
IsCOWArray()580     inline bool IsCOWArray() const
581     {
582         // Copy On Write ARRAY.
583         return GetObjectType() == JSType::COW_TAGGED_ARRAY;
584     }
585 
IsJSNativePointer()586     inline bool IsJSNativePointer() const
587     {
588         return GetObjectType() == JSType::JS_NATIVE_POINTER;
589     }
590 
IsJSSymbol()591     inline bool IsJSSymbol() const
592     {
593         return GetObjectType() == JSType::SYMBOL;
594     }
595 
IsJSArray()596     inline bool IsJSArray() const
597     {
598         return GetObjectType() == JSType::JS_ARRAY;
599     }
600 
IsTypedArray()601     inline bool IsTypedArray() const
602     {
603         JSType jsType = GetObjectType();
604         return (JSType::JS_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_TYPED_ARRAY_LAST);
605     }
606 
HasOrdinaryGet()607     inline bool HasOrdinaryGet() const
608     {
609         return (IsTypedArray() || IsSpecialContainer() || IsModuleNamespace());
610     }
611 
IsJSTypedArray()612     inline bool IsJSTypedArray() const
613     {
614         return GetObjectType() == JSType::JS_TYPED_ARRAY;
615     }
616 
IsJSInt8Array()617     inline bool IsJSInt8Array() const
618     {
619         return GetObjectType() == JSType::JS_INT8_ARRAY;
620     }
621 
IsJSUint8Array()622     inline bool IsJSUint8Array() const
623     {
624         return GetObjectType() == JSType::JS_UINT8_ARRAY;
625     }
626 
IsJSUint8ClampedArray()627     inline bool IsJSUint8ClampedArray() const
628     {
629         return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY;
630     }
631 
IsJSInt16Array()632     inline bool IsJSInt16Array() const
633     {
634         return GetObjectType() == JSType::JS_INT16_ARRAY;
635     }
636 
IsJSUint16Array()637     inline bool IsJSUint16Array() const
638     {
639         return GetObjectType() == JSType::JS_UINT16_ARRAY;
640     }
641 
IsJSInt32Array()642     inline bool IsJSInt32Array() const
643     {
644         return GetObjectType() == JSType::JS_INT32_ARRAY;
645     }
646 
IsJSUint32Array()647     inline bool IsJSUint32Array() const
648     {
649         return GetObjectType() == JSType::JS_UINT32_ARRAY;
650     }
651 
IsJSFloat32Array()652     inline bool IsJSFloat32Array() const
653     {
654         return GetObjectType() == JSType::JS_FLOAT32_ARRAY;
655     }
656 
IsJSFloat64Array()657     inline bool IsJSFloat64Array() const
658     {
659         return GetObjectType() == JSType::JS_FLOAT64_ARRAY;
660     }
661 
IsJSBigInt64Array()662     inline bool IsJSBigInt64Array() const
663     {
664         return GetObjectType() == JSType::JS_BIGINT64_ARRAY;
665     }
666 
IsJSBigUint64Array()667     inline bool IsJSBigUint64Array() const
668     {
669         return GetObjectType() == JSType::JS_BIGUINT64_ARRAY;
670     }
671 
IsJsGlobalEnv()672     inline bool IsJsGlobalEnv() const
673     {
674         return GetObjectType() == JSType::GLOBAL_ENV;
675     }
676 
IsJSFunctionBase()677     inline bool IsJSFunctionBase() const
678     {
679         JSType jsType = GetObjectType();
680         return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION;
681     }
682 
IsJsBoundFunction()683     inline bool IsJsBoundFunction() const
684     {
685         return GetObjectType() == JSType::JS_BOUND_FUNCTION;
686     }
687 
IsJSIntlBoundFunction()688     inline bool IsJSIntlBoundFunction() const
689     {
690         return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION;
691     }
692 
IsJSProxyRevocFunction()693     inline bool IsJSProxyRevocFunction() const
694     {
695         return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION;
696     }
697 
IsJSAsyncFunction()698     inline bool IsJSAsyncFunction() const
699     {
700         return GetObjectType() == JSType::JS_ASYNC_FUNCTION;
701     }
702 
IsJSAsyncAwaitStatusFunction()703     inline bool IsJSAsyncAwaitStatusFunction() const
704     {
705         return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION;
706     }
707 
IsJSPromiseReactionFunction()708     inline bool IsJSPromiseReactionFunction() const
709     {
710         return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION;
711     }
712 
IsJSPromiseExecutorFunction()713     inline bool IsJSPromiseExecutorFunction() const
714     {
715         return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION;
716     }
717 
IsJSAsyncFromSyncIterUnwarpFunction()718     inline bool IsJSAsyncFromSyncIterUnwarpFunction() const
719     {
720         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION;
721     }
722 
IsJSPromiseAllResolveElementFunction()723     inline bool IsJSPromiseAllResolveElementFunction() const
724     {
725         return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION;
726     }
727 
IsJSAsyncGeneratorResNextRetProRstFtn()728     inline bool IsJSAsyncGeneratorResNextRetProRstFtn() const
729     {
730         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN;
731     }
732 
IsJSPromiseAnyRejectElementFunction()733     inline bool IsJSPromiseAnyRejectElementFunction() const
734     {
735         return GetObjectType() == JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION;
736     }
737 
IsJSPromiseAllSettledElementFunction()738     inline bool IsJSPromiseAllSettledElementFunction() const
739     {
740         return GetObjectType() == JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION;
741     }
742 
IsJSPromiseFinallyFunction()743     inline bool IsJSPromiseFinallyFunction() const
744     {
745         return GetObjectType() == JSType::JS_PROMISE_FINALLY_FUNCTION;
746     }
747 
IsJSPromiseValueThunkOrThrowerFunction()748     inline bool IsJSPromiseValueThunkOrThrowerFunction() const
749     {
750         return GetObjectType() == JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION;
751     }
752 
IsMicroJobQueue()753     inline bool IsMicroJobQueue() const
754     {
755         return GetObjectType() == JSType::MICRO_JOB_QUEUE;
756     }
757 
IsPendingJob()758     inline bool IsPendingJob() const
759     {
760         return GetObjectType() == JSType::PENDING_JOB;
761     }
762 
IsJsPrimitiveRef()763     inline bool IsJsPrimitiveRef() const
764     {
765         return GetObjectType() == JSType::JS_PRIMITIVE_REF;
766     }
767 
IsJSSet()768     bool IsJSSet() const
769     {
770         return GetObjectType() == JSType::JS_SET;
771     }
772 
IsJSMap()773     bool IsJSMap() const
774     {
775         return GetObjectType() == JSType::JS_MAP;
776     }
777 
IsJSWeakMap()778     bool IsJSWeakMap() const
779     {
780         return GetObjectType() == JSType::JS_WEAK_MAP;
781     }
782 
IsJSWeakSet()783     bool IsJSWeakSet() const
784     {
785         return GetObjectType() == JSType::JS_WEAK_SET;
786     }
787 
IsJSWeakRef()788     bool IsJSWeakRef() const
789     {
790         return GetObjectType() == JSType::JS_WEAK_REF;
791     }
792 
IsJSFinalizationRegistry()793     bool IsJSFinalizationRegistry() const
794     {
795         return GetObjectType() == JSType::JS_FINALIZATION_REGISTRY;
796     }
797 
IsJSFunction()798     bool IsJSFunction() const
799     {
800         return GetObjectType() >= JSType::JS_FUNCTION_FIRST && GetObjectType() <= JSType::JS_FUNCTION_LAST;
801     }
802 
IsJSError()803     inline bool IsJSError() const
804     {
805         JSType jsType = GetObjectType();
806         return jsType >= JSType::JS_ERROR_FIRST && jsType <= JSType::JS_ERROR_LAST;
807     }
808 
IsArguments()809     inline bool IsArguments() const
810     {
811         return GetObjectType() == JSType::JS_ARGUMENTS;
812     }
813 
IsDate()814     inline bool IsDate() const
815     {
816         return GetObjectType() == JSType::JS_DATE;
817     }
818 
IsJSRegExp()819     inline bool IsJSRegExp() const
820     {
821         return GetObjectType() == JSType::JS_REG_EXP;
822     }
823 
IsJSProxy()824     inline bool IsJSProxy() const
825     {
826         return GetObjectType() == JSType::JS_PROXY;
827     }
828 
IsJSLocale()829     inline bool IsJSLocale() const
830     {
831         return GetObjectType() == JSType::JS_LOCALE;
832     }
833 
IsJSIntl()834     inline bool IsJSIntl() const
835     {
836         return GetObjectType() == JSType::JS_INTL;
837     }
838 
IsJSDateTimeFormat()839     inline bool IsJSDateTimeFormat() const
840     {
841         return GetObjectType() == JSType::JS_DATE_TIME_FORMAT;
842     }
843 
IsJSRelativeTimeFormat()844     inline bool IsJSRelativeTimeFormat() const
845     {
846         return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT;
847     }
848 
IsJSNumberFormat()849     inline bool IsJSNumberFormat() const
850     {
851         return GetObjectType() == JSType::JS_NUMBER_FORMAT;
852     }
853 
IsJSCollator()854     inline bool IsJSCollator() const
855     {
856         return GetObjectType() == JSType::JS_COLLATOR;
857     }
858 
IsJSPluralRules()859     inline bool IsJSPluralRules() const
860     {
861         return GetObjectType() == JSType::JS_PLURAL_RULES;
862     }
863 
IsJSDisplayNames()864     inline bool IsJSDisplayNames() const
865     {
866         return GetObjectType() == JSType::JS_DISPLAYNAMES;
867     }
868 
IsJSListFormat()869     inline bool IsJSListFormat() const
870     {
871         return GetObjectType() == JSType::JS_LIST_FORMAT;
872     }
873 
IsMethod()874     inline bool IsMethod() const
875     {
876         return GetObjectType() == JSType::METHOD;
877     }
878 
IsClassLiteral()879     inline bool IsClassLiteral() const
880     {
881         return GetObjectType() == JSType::CLASS_LITERAL;
882     }
883 
884     // non ECMA standard jsapi containers.
IsSpecialContainer()885     inline bool IsSpecialContainer() const
886     {
887         return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_API_QUEUE;
888     }
889 
IsJSAPIArrayList()890     inline bool IsJSAPIArrayList() const
891     {
892         return GetObjectType() == JSType::JS_API_ARRAY_LIST;
893     }
894 
IsJSAPIArrayListIterator()895     inline bool IsJSAPIArrayListIterator() const
896     {
897         return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
898     }
IsJSAPILightWeightMap()899     inline bool IsJSAPILightWeightMap() const
900     {
901         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP;
902     }
IsJSAPILightWeightMapIterator()903     inline bool IsJSAPILightWeightMapIterator() const
904     {
905         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR;
906     }
IsJSAPILightWeightSet()907     inline bool IsJSAPILightWeightSet() const
908     {
909         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET;
910     }
IsJSAPILightWeightSetIterator()911     inline bool IsJSAPILightWeightSetIterator() const
912     {
913         return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR;
914     }
IsJSAPIStack()915     inline bool IsJSAPIStack() const
916     {
917         return GetObjectType() == JSType::JS_API_STACK;
918     }
IsJSAPIDeque()919     inline bool IsJSAPIDeque() const
920     {
921         return GetObjectType() == JSType::JS_API_DEQUE;
922     }
IsLinkedNode()923     inline bool IsLinkedNode() const
924     {
925         return GetObjectType() == JSType::LINKED_NODE;
926     }
927 
IsRBTreeNode()928     inline bool IsRBTreeNode() const
929     {
930         return GetObjectType() == JSType::RB_TREENODE;
931     }
932 
IsJSAPIHashMap()933     inline bool IsJSAPIHashMap() const
934     {
935         return GetObjectType() == JSType::JS_API_HASH_MAP;
936     }
937 
IsJSAPIHashSet()938     inline bool IsJSAPIHashSet() const
939     {
940         return GetObjectType() == JSType::JS_API_HASH_SET;
941     }
942 
IsJSAPIHashMapIterator()943     inline bool IsJSAPIHashMapIterator() const
944     {
945         return GetObjectType() == JSType::JS_API_HASHMAP_ITERATOR;
946     }
947 
IsJSAPIHashSetIterator()948     inline bool IsJSAPIHashSetIterator() const
949     {
950         return GetObjectType() == JSType::JS_API_HASHSET_ITERATOR;
951     }
IsJSAPIQueue()952     inline bool IsJSAPIQueue() const
953     {
954         return GetObjectType() == JSType::JS_API_QUEUE;
955     }
956 
IsJSAPIPlainArray()957     inline bool IsJSAPIPlainArray() const
958     {
959         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY;
960     }
961 
IsJSAPIQueueIterator()962     inline bool IsJSAPIQueueIterator() const
963     {
964         return GetObjectType() == JSType::JS_API_QUEUE_ITERATOR;
965     }
IsJSAPIList()966     inline bool IsJSAPIList() const
967     {
968         return GetObjectType() == JSType::JS_API_LIST;
969     }
IsJSAPILinkedList()970     inline bool IsJSAPILinkedList() const
971     {
972         return GetObjectType() == JSType::JS_API_LINKED_LIST;
973     }
IsJSAPITreeMap()974     inline bool IsJSAPITreeMap() const
975     {
976         return GetObjectType() == JSType::JS_API_TREE_MAP;
977     }
978 
IsJSAPITreeSet()979     inline bool IsJSAPITreeSet() const
980     {
981         return GetObjectType() == JSType::JS_API_TREE_SET;
982     }
983 
IsJSAPITreeMapIterator()984     inline bool IsJSAPITreeMapIterator() const
985     {
986         return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR;
987     }
988 
IsJSAPITreeSetIterator()989     inline bool IsJSAPITreeSetIterator() const
990     {
991         return GetObjectType() == JSType::JS_API_TREESET_ITERATOR;
992     }
IsJSAPIVector()993     inline bool IsJSAPIVector() const
994     {
995         return GetObjectType() == JSType::JS_API_VECTOR;
996     }
IsJSAPIVectorIterator()997     inline bool IsJSAPIVectorIterator() const
998     {
999         return GetObjectType() == JSType::JS_API_VECTOR_ITERATOR;
1000     }
1001 
IsAccessorData()1002     inline bool IsAccessorData() const
1003     {
1004         return GetObjectType() == JSType::ACCESSOR_DATA;
1005     }
1006 
IsInternalAccessor()1007     inline bool IsInternalAccessor() const
1008     {
1009         return GetObjectType() == JSType::INTERNAL_ACCESSOR;
1010     }
1011 
IsIterator()1012     inline bool IsIterator() const
1013     {
1014         JSType jsType = GetObjectType();
1015         return jsType >= JSType::JS_ITERATOR_FIRST && jsType <= JSType::JS_ITERATOR_LAST;
1016     }
1017 
IsAsyncIterator()1018     inline bool IsAsyncIterator() const
1019     {
1020         return GetObjectType() == JSType::JS_ASYNCITERATOR;
1021     }
1022 
IsAsyncFromSyncIterator()1023     inline bool IsAsyncFromSyncIterator() const
1024     {
1025         return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITERATOR;
1026     }
1027 
IsForinIterator()1028     inline bool IsForinIterator() const
1029     {
1030         return GetObjectType() == JSType::JS_FORIN_ITERATOR;
1031     }
1032 
IsStringIterator()1033     inline bool IsStringIterator() const
1034     {
1035         return GetObjectType() == JSType::JS_STRING_ITERATOR;
1036     }
1037 
IsArrayBuffer()1038     inline bool IsArrayBuffer() const
1039     {
1040         return GetObjectType() == JSType::JS_ARRAY_BUFFER;
1041     }
1042 
IsSharedArrayBuffer()1043     inline bool IsSharedArrayBuffer() const
1044     {
1045         return GetObjectType() == JSType::JS_SHARED_ARRAY_BUFFER;
1046     }
1047 
IsDataView()1048     inline bool IsDataView() const
1049     {
1050         return GetObjectType() == JSType::JS_DATA_VIEW;
1051     }
1052 
IsJSSetIterator()1053     inline bool IsJSSetIterator() const
1054     {
1055         return GetObjectType() == JSType::JS_SET_ITERATOR;
1056     }
1057 
IsJSRegExpIterator()1058     inline bool IsJSRegExpIterator() const
1059     {
1060         return GetObjectType() == JSType::JS_REG_EXP_ITERATOR;
1061     }
1062 
IsJSMapIterator()1063     inline bool IsJSMapIterator() const
1064     {
1065         return GetObjectType() == JSType::JS_MAP_ITERATOR;
1066     }
1067 
IsJSArrayIterator()1068     inline bool IsJSArrayIterator() const
1069     {
1070         return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
1071     }
1072 
IsJSAPIPlainArrayIterator()1073     inline bool IsJSAPIPlainArrayIterator() const
1074     {
1075         return GetObjectType() == JSType::JS_API_PLAIN_ARRAY_ITERATOR;
1076     }
1077 
IsJSAPIDequeIterator()1078     inline bool IsJSAPIDequeIterator() const
1079     {
1080         return GetObjectType() == JSType::JS_API_DEQUE_ITERATOR;
1081     }
1082 
IsJSAPIStackIterator()1083     inline bool IsJSAPIStackIterator() const
1084     {
1085         return GetObjectType() == JSType::JS_API_STACK_ITERATOR;
1086     }
1087 
IsJSAPILinkedListIterator()1088     inline bool IsJSAPILinkedListIterator() const
1089     {
1090         return GetObjectType() == JSType::JS_API_LINKED_LIST_ITERATOR;
1091     }
1092 
IsJSAPIListIterator()1093     inline bool IsJSAPIListIterator() const
1094     {
1095         return GetObjectType() == JSType::JS_API_LIST_ITERATOR;
1096     }
1097 
IsPrototypeHandler()1098     inline bool IsPrototypeHandler() const
1099     {
1100         return GetObjectType() == JSType::PROTOTYPE_HANDLER;
1101     }
1102 
IsTransitionHandler()1103     inline bool IsTransitionHandler() const
1104     {
1105         return GetObjectType() == JSType::TRANSITION_HANDLER;
1106     }
1107 
IsTransWithProtoHandler()1108     inline bool IsTransWithProtoHandler() const
1109     {
1110         return GetObjectType() == JSType::TRANS_WITH_PROTO_HANDLER;
1111     }
1112 
IsStoreTSHandler()1113     inline bool IsStoreTSHandler() const
1114     {
1115         return GetObjectType() == JSType::STORE_TS_HANDLER;
1116     }
1117 
IsPropertyBox()1118     inline bool IsPropertyBox() const
1119     {
1120         return GetObjectType() == JSType::PROPERTY_BOX;
1121     }
IsProtoChangeMarker()1122     inline bool IsProtoChangeMarker() const
1123     {
1124         return GetObjectType() == JSType::PROTO_CHANGE_MARKER;
1125     }
1126 
IsProtoChangeDetails()1127     inline bool IsProtoChangeDetails() const
1128     {
1129         return GetObjectType() == JSType::PROTOTYPE_INFO;
1130     }
1131 
IsProgram()1132     inline bool IsProgram() const
1133     {
1134         return GetObjectType() == JSType::PROGRAM;
1135     }
1136 
IsClassInfoExtractor()1137     inline bool IsClassInfoExtractor() const
1138     {
1139         return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR;
1140     }
1141 
IsCallable()1142     inline bool IsCallable() const
1143     {
1144         uint32_t bits = GetBitField();
1145         return CallableBit::Decode(bits);
1146     }
1147 
IsConstructor()1148     inline bool IsConstructor() const
1149     {
1150         uint32_t bits = GetBitField();
1151         return ConstructorBit::Decode(bits);
1152     }
1153 
IsExtensible()1154     inline bool IsExtensible() const
1155     {
1156         uint32_t bits = GetBitField();
1157         return ExtensibleBit::Decode(bits);
1158     }
1159 
IsPrototype()1160     inline bool IsPrototype() const
1161     {
1162         uint32_t bits = GetBitField();
1163         return IsPrototypeBit::Decode(bits);
1164     }
1165 
IsLiteral()1166     inline bool IsLiteral() const
1167     {
1168         uint32_t bits = GetBitField();
1169         return IsLiteralBit::Decode(bits);
1170     }
1171 
IsClassConstructor()1172     inline bool IsClassConstructor() const
1173     {
1174         uint32_t bits = GetBitField();
1175         return ClassConstructorBit::Decode(bits);
1176     }
1177 
IsJSGlobalObject()1178     inline bool IsJSGlobalObject() const
1179     {
1180         return GetObjectType() == JSType::JS_GLOBAL_OBJECT;
1181     }
1182 
IsClassPrototype()1183     inline bool IsClassPrototype() const
1184     {
1185         uint32_t bits = GetBitField();
1186         return ClassPrototypeBit::Decode(bits);
1187     }
1188 
IsGlobalConstOrBuiltinsObject()1189     inline bool IsGlobalConstOrBuiltinsObject() const
1190     {
1191         uint32_t bits = GetBitField();
1192         return GlobalConstOrBuiltinsObjectBit::Decode(bits);
1193     }
1194 
IsDictionaryMode()1195     inline bool IsDictionaryMode() const
1196     {
1197         uint32_t bits = GetBitField();
1198         return IsDictionaryBit::Decode(bits);
1199     }
1200 
1201     // created from TypeScript Types
IsTS()1202     inline bool IsTS() const
1203     {
1204         uint32_t bits = GetBitField();
1205         return IsTSBit::Decode(bits);
1206     }
1207 
IsJSFunctionFromBitField()1208     inline bool IsJSFunctionFromBitField() const
1209     {
1210         uint32_t bits = GetBitField();
1211         return IsJSFunctionBit::Decode(bits);
1212     }
1213 
IsOptimized()1214     inline bool IsOptimized() const
1215     {
1216         uint32_t bits = GetBitField();
1217         return IsOptimizedBit::Decode(bits);
1218     }
1219 
CanFastCall()1220     inline bool CanFastCall() const
1221     {
1222         uint32_t bits = GetBitField();
1223         return CanFastCallBit::Decode(bits);
1224     }
1225 
IsGeneratorFunction()1226     inline bool IsGeneratorFunction() const
1227     {
1228         return GetObjectType() == JSType::JS_GENERATOR_FUNCTION;
1229     }
1230 
IsAsyncGeneratorFunction()1231     inline bool IsAsyncGeneratorFunction() const
1232     {
1233         return GetObjectType() == JSType::JS_ASYNC_GENERATOR_FUNCTION;
1234     }
1235 
IsGeneratorObject()1236     inline bool IsGeneratorObject() const
1237     {
1238         JSType jsType = GetObjectType();
1239         return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT;
1240     }
1241 
IsAsyncGeneratorObject()1242     inline bool IsAsyncGeneratorObject() const
1243     {
1244         JSType jsType = GetObjectType();
1245         return jsType == JSType::JS_ASYNC_GENERATOR_OBJECT;
1246     }
1247 
IsGeneratorContext()1248     inline bool IsGeneratorContext() const
1249     {
1250         return GetObjectType() == JSType::JS_GENERATOR_CONTEXT;
1251     }
1252 
IsAsyncGeneratorRequest()1253     inline bool IsAsyncGeneratorRequest() const
1254     {
1255         JSType jsType = GetObjectType();
1256         return jsType == JSType::ASYNC_GENERATOR_REQUEST;
1257     }
1258 
IsAsyncIteratorRecord()1259     inline bool IsAsyncIteratorRecord() const
1260     {
1261         JSType jsType = GetObjectType();
1262         return jsType == JSType::ASYNC_ITERATOR_RECORD;
1263     }
1264 
IsAsyncFuncObject()1265     inline bool IsAsyncFuncObject() const
1266     {
1267         return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT;
1268     }
1269 
IsJSPromise()1270     inline bool IsJSPromise() const
1271     {
1272         return GetObjectType() == JSType::JS_PROMISE;
1273     }
1274 
IsResolvingFunctionsRecord()1275     inline bool IsResolvingFunctionsRecord() const
1276     {
1277         return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD;
1278     }
1279 
IsPromiseRecord()1280     inline bool IsPromiseRecord() const
1281     {
1282         return GetObjectType() == JSType::PROMISE_RECORD;
1283     }
1284 
IsPromiseIteratorRecord()1285     inline bool IsPromiseIteratorRecord() const
1286     {
1287         return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD;
1288     }
1289 
IsPromiseCapability()1290     inline bool IsPromiseCapability() const
1291     {
1292         return GetObjectType() == JSType::PROMISE_CAPABILITY;
1293     }
1294 
IsPromiseReaction()1295     inline bool IsPromiseReaction() const
1296     {
1297         return GetObjectType() == JSType::PROMISE_REACTIONS;
1298     }
1299 
IsCellRecord()1300     inline bool IsCellRecord() const
1301     {
1302         return GetObjectType() == JSType::CELL_RECORD;
1303     }
1304 
IsCompletionRecord()1305     inline bool IsCompletionRecord() const
1306     {
1307         return GetObjectType() == JSType::COMPLETION_RECORD;
1308     }
1309 
IsRecord()1310     inline bool IsRecord() const
1311     {
1312         JSType jsType = GetObjectType();
1313         return jsType >= JSType::JS_RECORD_FIRST && jsType <= JSType::JS_RECORD_LAST;
1314     }
1315 
IsTemplateMap()1316     inline bool IsTemplateMap() const
1317     {
1318         return GetObjectType() == JSType::TEMPLATE_MAP;
1319     }
1320 
IsFreeObject()1321     inline bool IsFreeObject() const
1322     {
1323         JSType t = GetObjectType();
1324         return (t >= JSType::FREE_OBJECT_WITH_ONE_FIELD) && (t <= JSType::FREE_OBJECT_WITH_TWO_FIELD);
1325     }
1326 
IsFreeObjectWithShortField()1327     inline bool IsFreeObjectWithShortField() const
1328     {
1329         switch (GetObjectType()) {
1330             case JSType::FREE_OBJECT_WITH_ONE_FIELD:
1331             case JSType::FREE_OBJECT_WITH_NONE_FIELD:
1332                 return true;
1333             default:
1334                 return false;
1335         }
1336     }
1337 
IsFreeObjectWithOneField()1338     inline bool IsFreeObjectWithOneField() const
1339     {
1340         return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD;
1341     }
1342 
IsFreeObjectWithNoneField()1343     inline bool IsFreeObjectWithNoneField() const
1344     {
1345         return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD;
1346     }
1347 
IsFreeObjectWithTwoField()1348     inline bool IsFreeObjectWithTwoField() const
1349     {
1350         return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD;
1351     }
1352 
IsMachineCodeObject()1353     inline bool IsMachineCodeObject() const
1354     {
1355         return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
1356     }
1357 
IsTSType()1358     inline bool IsTSType() const
1359     {
1360         JSType jsType = GetObjectType();
1361         return jsType >= JSType::TS_TYPE_FIRST && jsType <= JSType::TS_TYPE_LAST;
1362     }
1363 
IsTSObjectType()1364     inline bool IsTSObjectType() const
1365     {
1366         return GetObjectType() == JSType::TS_OBJECT_TYPE;
1367     }
1368 
IsTSClassType()1369     inline bool IsTSClassType() const
1370     {
1371         return GetObjectType() == JSType::TS_CLASS_TYPE;
1372     }
1373 
IsTSInterfaceType()1374     inline bool IsTSInterfaceType() const
1375     {
1376         return GetObjectType() == JSType::TS_INTERFACE_TYPE;
1377     }
1378 
IsTSUnionType()1379     inline bool IsTSUnionType() const
1380     {
1381         return GetObjectType() == JSType::TS_UNION_TYPE;
1382     }
1383 
IsTSClassInstanceType()1384     inline bool IsTSClassInstanceType() const
1385     {
1386         return GetObjectType() == JSType::TS_CLASS_INSTANCE_TYPE;
1387     }
1388 
IsTSFunctionType()1389     inline bool IsTSFunctionType() const
1390     {
1391         return GetObjectType() == JSType::TS_FUNCTION_TYPE;
1392     }
1393 
IsTSArrayType()1394     inline bool IsTSArrayType() const
1395     {
1396         return GetObjectType() == JSType::TS_ARRAY_TYPE;
1397     }
1398 
IsTSIteratorInstanceType()1399     inline bool IsTSIteratorInstanceType() const
1400     {
1401         return GetObjectType() == JSType::TS_ITERATOR_INSTANCE_TYPE;
1402     }
1403 
IsTSNamespaceType()1404     inline bool IsTSNamespaceType() const
1405     {
1406         return GetObjectType() == JSType::TS_NAMESPACE_TYPE;
1407     }
1408 
IsAOTLiteralInfo()1409     inline bool IsAOTLiteralInfo() const
1410     {
1411         return GetObjectType() == JSType::AOT_LITERAL_INFO;
1412     }
1413 
IsVTable()1414     inline bool IsVTable() const
1415     {
1416         return GetObjectType() == JSType::VTABLE;
1417     }
1418 
IsModuleRecord()1419     inline bool IsModuleRecord() const
1420     {
1421         JSType jsType = GetObjectType();
1422         return jsType >= JSType::MODULE_RECORD_FIRST && jsType <= JSType::MODULE_RECORD_LAST;
1423     }
1424 
IsSourceTextModule()1425     inline bool IsSourceTextModule() const
1426     {
1427         return GetObjectType() == JSType::SOURCE_TEXT_MODULE_RECORD;
1428     }
1429 
IsCjsExports()1430     inline bool IsCjsExports() const
1431     {
1432         return GetObjectType() == JSType::JS_CJS_EXPORTS;
1433     }
1434 
IsCjsModule()1435     inline bool IsCjsModule() const
1436     {
1437         return GetObjectType() == JSType::JS_CJS_MODULE;
1438     }
1439 
IsCjsRequire()1440     inline bool IsCjsRequire() const
1441     {
1442         return GetObjectType() == JSType::JS_CJS_REQUIRE;
1443     }
1444 
IsImportEntry()1445     inline bool IsImportEntry() const
1446     {
1447         return GetObjectType() == JSType::IMPORTENTRY_RECORD;
1448     }
1449 
IsLocalExportEntry()1450     inline bool IsLocalExportEntry() const
1451     {
1452         return GetObjectType() == JSType::LOCAL_EXPORTENTRY_RECORD;
1453     }
1454 
IsIndirectExportEntry()1455     inline bool IsIndirectExportEntry() const
1456     {
1457         return GetObjectType() == JSType::INDIRECT_EXPORTENTRY_RECORD;
1458     }
1459 
IsStarExportEntry()1460     inline bool IsStarExportEntry() const
1461     {
1462         return GetObjectType() == JSType::STAR_EXPORTENTRY_RECORD;
1463     }
1464 
IsResolvedBinding()1465     inline bool IsResolvedBinding() const
1466     {
1467         return GetObjectType() == JSType::RESOLVEDBINDING_RECORD;
1468     }
1469 
IsResolvedIndexBinding()1470     inline bool IsResolvedIndexBinding() const
1471     {
1472         return GetObjectType() == JSType::RESOLVEDINDEXBINDING_RECORD;
1473     }
1474 
IsModuleNamespace()1475     inline bool IsModuleNamespace() const
1476     {
1477         return GetObjectType() == JSType::JS_MODULE_NAMESPACE;
1478     }
1479 
SetElementsKind(ElementsKind kind)1480     inline void SetElementsKind(ElementsKind kind)
1481     {
1482         uint32_t bits = GetBitField();
1483         uint32_t newVal = ElementsKindBits::Update(bits, kind);
1484         SetBitField(newVal);
1485     }
1486 
GetElementsKind()1487     inline ElementsKind GetElementsKind() const
1488     {
1489         uint32_t bits = GetBitField();
1490         return ElementsKindBits::Decode(bits);
1491     }
1492 
SetLevel(uint8_t level)1493     inline void SetLevel(uint8_t level)
1494     {
1495         uint32_t bits = GetBitField();
1496         uint32_t newVal = LevelBit::Update(bits, level);
1497         SetBitField(newVal);
1498     }
1499 
GetLevel()1500     inline uint8_t GetLevel() const
1501     {
1502         uint32_t bits = GetBitField();
1503         return LevelBit::Decode(bits);
1504     }
1505 
SetIsDictionaryElement(bool value)1506     inline void SetIsDictionaryElement(bool value)
1507     {
1508         uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
1509         SetBitField(newVal);
1510     }
IsDictionaryElement()1511     inline bool IsDictionaryElement() const
1512     {
1513         return DictionaryElementBits::Decode(GetBitField());
1514     }
SetIsStableElements(bool value)1515     inline void SetIsStableElements(bool value)
1516     {
1517         uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value);
1518         SetBitField(newVal);
1519     }
IsStableElements()1520     inline bool IsStableElements() const
1521     {
1522         return IsStableElementsBit::Decode(GetBitField());
1523     }
IsStableJSArguments()1524     inline bool IsStableJSArguments() const
1525     {
1526         uint32_t bits = GetBitField();
1527         auto type = ObjectTypeBits::Decode(bits);
1528         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS);
1529     }
IsStableJSArray()1530     inline bool IsStableJSArray() const
1531     {
1532         uint32_t bits = GetBitField();
1533         auto type = ObjectTypeBits::Decode(bits);
1534         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY);
1535     }
SetHasConstructor(bool value)1536     inline void SetHasConstructor(bool value)
1537     {
1538         JSTaggedType newVal = HasConstructorBits::Update(GetBitField(), value);
1539         SetBitField(newVal);
1540     }
HasConstructor()1541     inline bool HasConstructor() const
1542     {
1543         return HasConstructorBits::Decode(GetBitField());
1544     }
1545 
SetNumberOfProps(uint32_t num)1546     inline void SetNumberOfProps(uint32_t num)
1547     {
1548         uint32_t bits = GetBitField1();
1549         uint32_t newVal = NumberOfPropsBits::Update(bits, num);
1550         SetBitField1(newVal);
1551     }
1552 
IncNumberOfProps()1553     inline void IncNumberOfProps()
1554     {
1555         ASSERT(NumberOfProps() < PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
1556         SetNumberOfProps(NumberOfProps() + 1);
1557     }
1558 
NumberOfProps()1559     inline uint32_t NumberOfProps() const
1560     {
1561         uint32_t bits = GetBitField1();
1562         return NumberOfPropsBits::Decode(bits);
1563     }
1564 
GetNextInlinedPropsIndex()1565     inline int32_t GetNextInlinedPropsIndex() const
1566     {
1567         uint32_t inlinedProperties = GetInlinedProperties();
1568         uint32_t numberOfProps = NumberOfProps();
1569         if (numberOfProps < inlinedProperties) {
1570             return numberOfProps;
1571         }
1572         return -1;
1573     }
1574 
GetNextNonInlinedPropsIndex()1575     inline int32_t GetNextNonInlinedPropsIndex() const
1576     {
1577         uint32_t inlinedProperties = GetInlinedProperties();
1578         uint32_t numberOfProps = NumberOfProps();
1579         if (numberOfProps >= inlinedProperties) {
1580             return numberOfProps - inlinedProperties;
1581         }
1582         return -1;
1583     }
1584 
GetObjectSize()1585     inline uint32_t GetObjectSize() const
1586     {
1587         uint32_t bits = GetBitField1();
1588         return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1589     }
1590 
SetObjectSize(uint32_t num)1591     inline void SetObjectSize(uint32_t num)
1592     {
1593         ASSERT((num / JSTaggedValue::TaggedTypeSize()) <= MAX_OBJECT_SIZE_IN_WORDS);
1594         uint32_t bits = GetBitField1();
1595         uint32_t newVal = ObjectSizeInWordsBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1596         SetBitField1(newVal);
1597     }
1598 
GetInlinedPropertiesOffset(uint32_t index)1599     inline uint32_t GetInlinedPropertiesOffset(uint32_t index) const
1600     {
1601         ASSERT(index < GetInlinedProperties());
1602         return GetInlinedPropertiesIndex(index) * JSTaggedValue::TaggedTypeSize();
1603     }
1604 
GetInlinedPropertiesIndex(uint32_t index)1605     inline uint32_t GetInlinedPropertiesIndex(uint32_t index) const
1606     {
1607         ASSERT(index < GetInlinedProperties());
1608         uint32_t bits = GetBitField1();
1609         return InlinedPropsStartBits::Decode(bits) + index;
1610     }
1611 
SetInlinedPropsStart(uint32_t num)1612     inline void SetInlinedPropsStart(uint32_t num)
1613     {
1614         uint32_t bits = GetBitField1();
1615         uint32_t newVal = InlinedPropsStartBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1616         SetBitField1(newVal);
1617     }
1618 
GetInlinedPropsStartSize()1619     inline uint32_t GetInlinedPropsStartSize() const
1620     {
1621         uint32_t bits = GetBitField1();
1622         return InlinedPropsStartBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1623     }
1624 
GetInlinedProperties()1625     inline uint32_t GetInlinedProperties() const
1626     {
1627         JSType type = GetObjectType();
1628         if (JSType::JS_OBJECT_FIRST <= type && type <= JSType::JS_OBJECT_LAST) {
1629             uint32_t bits = GetBitField1();
1630             return static_cast<uint32_t>(ObjectSizeInWordsBits::Decode(bits) - InlinedPropsStartBits::Decode(bits));
1631         } else {
1632             return 0;
1633         }
1634     }
1635 
SetHasDeleteProperty(bool flag)1636     inline void SetHasDeleteProperty(bool flag) const
1637     {
1638         HasDeletePropertyBit::Set<uint32_t>(flag, GetBitField1Addr());
1639     }
1640 
HasDeleteProperty()1641     inline bool HasDeleteProperty() const
1642     {
1643         uint32_t bits = GetBitField1();
1644         return HasDeletePropertyBit::Decode(bits);
1645     }
1646 
SetIsAllTaggedProp(bool flag)1647     inline void SetIsAllTaggedProp(bool flag) const
1648     {
1649         IsAllTaggedPropBit::Set<uint32_t>(flag, GetBitField1Addr());
1650     }
1651 
IsAllTaggedProp()1652     inline bool IsAllTaggedProp() const
1653     {
1654         uint32_t bits = GetBitField1();
1655         return IsAllTaggedPropBit::Decode(bits);
1656     }
1657 
1658     inline static int FindPropertyEntry(const JSThread *thread, JSHClass *hclass, JSTaggedValue key);
1659 
1660     static PropertyLookupResult LookupPropertyInAotHClass(const JSThread *thread, JSHClass *hclass, JSTaggedValue key);
1661 
1662     static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize();
1663     ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET);
1664     ACCESSORS(Layout, LAYOUT_OFFSET, TRANSTIONS_OFFSET);
1665     ACCESSORS(Transitions, TRANSTIONS_OFFSET, PROTO_CHANGE_MARKER_OFFSET);
1666     ACCESSORS(ProtoChangeMarker, PROTO_CHANGE_MARKER_OFFSET, PROTO_CHANGE_DETAILS_OFFSET);
1667     ACCESSORS(ProtoChangeDetails, PROTO_CHANGE_DETAILS_OFFSET, ENUM_CACHE_OFFSET);
1668     ACCESSORS(EnumCache, ENUM_CACHE_OFFSET, SUPERS_OFFSET);
1669     ACCESSORS(Supers, SUPERS_OFFSET, VTABLE_OFFSET);
1670     ACCESSORS(VTable, VTABLE_OFFSET, BIT_FIELD_OFFSET);
1671     ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD1_OFFSET);
1672     ACCESSORS_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, LAST_OFFSET);
1673     DEFINE_ALIGN_SIZE(LAST_OFFSET);
1674 
1675     void SetPrototype(const JSThread *thread, JSTaggedValue proto);
1676     void SetPrototype(const JSThread *thread, const JSHandle<JSTaggedValue> &proto);
1677     void ShouldUpdateProtoClass(const JSThread *thread, const JSHandle<JSTaggedValue> &proto);
GetPrototype()1678     inline JSTaggedValue GetPrototype() const
1679     {
1680         return GetProto();
1681     }
1682 
1683     inline JSHClass *FindTransitions(const JSTaggedValue &key, const JSTaggedValue &attributes);
1684 
1685     DECL_DUMP()
1686 
1687     static CString DumpJSType(JSType type);
1688     static bool DumpForProfile(const JSHClass *hclass, PGOHClassLayoutDesc &desc, PGOObjKind kind);
1689 
1690     DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, BIT_FIELD_OFFSET);
1691 
1692 private:
1693     static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1694                                       const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
1695                                       PropertyAttributes attr);
1696     static inline void AddExtensionTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1697                                                const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key);
1698     static inline void AddProtoTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1699                                            const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
1700                                            const JSHandle<JSTaggedValue> &proto);
1701 
1702     inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto);
1703 
1704     inline void Copy(const JSThread *thread, const JSHClass *jshclass);
1705 
GetBitFieldAddr()1706     uint32_t *GetBitFieldAddr() const
1707     {
1708         return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET);
1709     }
1710 
GetBitField1Addr()1711     uint32_t *GetBitField1Addr() const
1712     {
1713         return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD1_OFFSET);
1714     }
1715     friend class RuntimeStubs;
1716 };
1717 static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
1718 
1719 // record property look up info in local and vtable
1720 class PropertyLookupResult {
1721 public:
1722     static constexpr uint32_t OFFSET_BITFIELD_NUM = 14;
1723     using IsFoundBit = BitField<bool, 0, 1>;
1724     using IsLocalBit = IsFoundBit::NextFlag;
1725     using IsNotHoleBit = IsLocalBit::NextFlag;
1726     using IsAccessorBit = IsNotHoleBit::NextFlag;
1727     using OffsetBits = IsAccessorBit::NextField<uint32_t, OFFSET_BITFIELD_NUM>;
1728     using WritableField = OffsetBits::NextFlag;
1729     using RepresentationBits = WritableField::NextField<Representation, PropertyAttributes::REPRESENTATION_NUM>;
1730 
data_(data)1731     explicit PropertyLookupResult(uint32_t data = 0) : data_(data) {}
1732     ~PropertyLookupResult() = default;
1733     DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyLookupResult);
1734     DEFAULT_COPY_SEMANTIC(PropertyLookupResult);
1735 
IsFound()1736     inline bool IsFound() const
1737     {
1738         return IsFoundBit::Get(data_);
1739     }
1740 
SetIsFound(bool flag)1741     inline void SetIsFound(bool flag)
1742     {
1743         IsFoundBit::Set(flag, &data_);
1744     }
1745 
IsWritable()1746     inline bool IsWritable() const
1747     {
1748         return WritableField::Get(data_);
1749     }
1750 
SetIsWritable(bool flag)1751     inline void SetIsWritable(bool flag)
1752     {
1753         WritableField::Set(flag, &data_);
1754     }
1755 
IsLocal()1756     inline bool IsLocal() const
1757     {
1758         return IsLocalBit::Get(data_);
1759     }
1760 
SetIsLocal(bool flag)1761     inline void SetIsLocal(bool flag)
1762     {
1763         IsLocalBit::Set(flag, &data_);
1764     }
1765 
IsNotHole()1766     inline bool IsNotHole() const
1767     {
1768         return IsNotHoleBit::Get(data_);
1769     }
1770 
SetIsNotHole(bool flag)1771     inline void SetIsNotHole(bool flag)
1772     {
1773         IsNotHoleBit::Set(flag, &data_);
1774     }
1775 
IsVtable()1776     inline bool IsVtable() const
1777     {
1778         return IsFound() && !IsLocal();
1779     }
1780 
SetIsVtable()1781     inline void SetIsVtable()
1782     {
1783         SetIsFound(true);
1784         SetIsLocal(false);
1785     }
1786 
IsAccessor()1787     inline bool IsAccessor() const
1788     {
1789         return IsAccessorBit::Get(data_);
1790     }
1791 
SetIsAccessor(bool flag)1792     inline void SetIsAccessor(bool flag)
1793     {
1794         IsAccessorBit::Set(flag, &data_);
1795     }
1796 
IsFunction()1797     inline bool IsFunction() const
1798     {
1799         return IsVtable() && !IsAccessor();
1800     }
1801 
GetOffset()1802     inline uint32_t GetOffset() const
1803     {
1804         return OffsetBits::Get(data_);
1805     }
1806 
SetOffset(uint32_t offset)1807     inline void SetOffset(uint32_t offset)
1808     {
1809         OffsetBits::Set<uint32_t>(offset, &data_);
1810     }
1811 
SetRepresentation(Representation rep)1812     inline void SetRepresentation(Representation rep)
1813     {
1814         RepresentationBits::Set(rep, &data_);
1815     }
1816 
GetRepresentation()1817     inline Representation GetRepresentation()
1818     {
1819         return RepresentationBits::Get(data_);
1820     }
1821 
GetData()1822     inline uint32_t GetData() const
1823     {
1824         return data_;
1825     }
1826 
1827 private:
1828     uint32_t data_ {0};
1829 };
1830 static_assert(PropertyLookupResult::OffsetBits::MaxValue() >
1831               (PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES * JSTaggedValue::TaggedTypeSize()));
1832 }  // namespace panda::ecmascript
1833 
1834 #endif  // ECMASCRIPT_JS_HCLASS_H
1835