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