• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/property_attributes.h"
23 #include "include/hclass.h"
24 #include "utils/bit_field.h"
25 
26 /*
27  *                         JS Object and JS HClass Layout
28  *
29  *      Properties                         JS Object                    JS HClass
30  *      +------------+                     +------------+               +------------------+
31  *      |arrayClass  + <---------|         |JS HClass   +-------------->|HClass class      |
32  *      +------------+           |         +------------+               +------------------+
33  *      |property 0  |           |         |Hash        |               |BitField          |
34  *      +------------+           |         +------------+               +------------------+
35  *      |property 1  |           |-------  |Properties  |               |BitField1         |
36  *      +------------+                     +------------+               +------------------+
37  *      |...         |           |-------  |Elements    |               |Proto             |
38  *      +------------+           |         +------------+               +------------------+
39  *                               |         |in-obj 0    |               |Layout            |
40  *      Elements                 |         +------------+               +------------------+
41  *      +------------+           |         |in-obj 1    |               |Transitions       |
42  *      |arrayClass  + <---------|         +------------+               +------------------+
43  *      +------------+                     |...         |               |Parent            |
44  *      |value 0     |                     +------------+               +------------------+
45  *      +------------+                                                  |ProtoChangeMarker |
46  *      |value 1     |                                                  +------------------+
47  *      +------------+                                                  |ProtoChangeDetails|
48  *      |...         |                                                  +------------------+
49  *      +------------+                                                  |EnumCache         |
50  *                                                                      +------------------+
51  *
52  *                          Proto: [[Prototype]] in Ecma spec
53  *                          Layout: record key and attr
54  *                          ProtoChangeMarker, ProtoChangeDetails: monitor [[prototype]] chain
55  *                          EnumCache: use for for-in syntax
56  *
57  */
58 namespace panda::ecmascript {
59 class ProtoChangeDetails;
60 
61 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
62 #define JSTYPE_DECL       /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
63     INVALID = 0,          /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
64         JS_OBJECT,        /* JS_OBJECT_BEGIN ////////////////////////////////////////////////////////////////////// */ \
65         JS_REALM,         /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
66         JS_FUNCTION_BASE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
67         JS_FUNCTION,      /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
68         JS_PROXY_REVOC_FUNCTION,       /* /////////////////////////////////////////////////////////////////-PADDING */ \
69         JS_PROMISE_REACTIONS_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \
70         JS_PROMISE_EXECUTOR_FUNCTION,  /* /////////////////////////////////////////////////////////////////-PADDING */ \
71         JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION,  /* //////////////////////////////////////////////////////-PADDING */ \
72         JS_GENERATOR_FUNCTION, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \
73         JS_ASYNC_FUNCTION, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
74         JS_INTL_BOUND_FUNCTION, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
75         JS_ASYNC_AWAIT_STATUS_FUNCTION, /* ////////////////////////////////////////////////////////////////-PADDING */ \
76         JS_BOUND_FUNCTION, /*  //////////////////////////////////////////////////////////////////////////////////// */ \
77                                                                                                                        \
78         JS_ERROR,           /* JS_ERROR_BEGIN /////////////////////////////////////////////////////////////-PADDING */ \
79         JS_EVAL_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
80         JS_RANGE_ERROR,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
81         JS_REFERENCE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
82         JS_TYPE_ERROR,      /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
83         JS_URI_ERROR,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
84         JS_SYNTAX_ERROR,    /* JS_ERROR_END /////////////////////////////////////////////////////////////////////// */ \
85                                                                                                                        \
86         JS_REG_EXP,  /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
87         JS_SET,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
88         JS_MAP,      /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
89         JS_WEAK_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
90         JS_WEAK_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
91         JS_DATE,     /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
92         JS_ITERATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
93         JS_FORIN_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
94         JS_MAP_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
95         JS_SET_ITERATOR,         /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
96         JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \
97         JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
98         JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
99         JS_ARRAY_ITERATOR,       /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
100         JS_STRING_ITERATOR,      /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
101         JS_INTL, /* ///////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
102         JS_LOCALE, /* /////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
103         JS_DATE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
104         JS_RELATIVE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
105         JS_NUMBER_FORMAT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
106         JS_COLLATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
107         JS_PLURAL_RULES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
108                                                                                                                        \
109         JS_ARRAY_BUFFER, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
110         JS_PROMISE,      /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
111         JS_DATA_VIEW,    /* /////////////////////////////////////////////////////////////////////////////////////// */ \
112         JS_ARGUMENTS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
113         JS_GENERATOR_OBJECT,  /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
114         JS_ASYNC_FUNC_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
115                                                                                                                        \
116         /* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \
117         JS_ARRAY,       /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
118         JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
119         JS_API_VECTOR,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
120         JS_API_TREE_MAP,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
121         JS_API_TREE_SET,   /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
122         JS_QUEUE,          /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
123         JS_TYPED_ARRAY, /* JS_TYPED_ARRAY_BEGIN /////////////////////////////////////////////////////////////////// */ \
124         JS_INT8_ARRAY,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
125         JS_UINT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
126         JS_UINT8_CLAMPED_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
127         JS_INT16_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
128         JS_UINT16_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
129         JS_INT32_ARRAY,         /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
130         JS_UINT32_ARRAY,        /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
131         JS_FLOAT32_ARRAY,       /* ////////////////////////////////////////////////////////////////////////-PADDING */ \
132         JS_FLOAT64_ARRAY,       /* JS_TYPED_ARRAY_END ///////////////////////////////////////////////////////////// */ \
133         JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \
134         JS_GLOBAL_OBJECT, /* JS_OBJECT_END/////////////////////////////////////////////////////////////////-PADDING */ \
135         JS_PROXY, /* ECMA_OBJECT_END ////////////////////////////////////////////////////////////////////////////// */ \
136                                                                                                                        \
137         HCLASS,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
138         STRING,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
139         BIGINT,       /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
140         TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \
141         TAGGED_DICTIONARY, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
142         FREE_OBJECT_WITH_ONE_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
143         FREE_OBJECT_WITH_NONE_FIELD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
144         FREE_OBJECT_WITH_TWO_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
145         JS_NATIVE_POINTER, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
146         GLOBAL_ENV,        /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
147         ACCESSOR_DATA,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
148         INTERNAL_ACCESSOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \
149         SYMBOL, /* ////////////////////////////////////////////////////////////////////////////////////////-PADDING */ \
150         JS_GENERATOR_CONTEXT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
151         PROTOTYPE_HANDLER,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
152         TRANSITION_HANDLER,   /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
153         PROPERTY_BOX, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */  \
154         PROTO_CHANGE_MARKER, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \
155         PROTOTYPE_INFO,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
156         TEMPLATE_MAP,       /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
157         PROGRAM, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */       \
158                                                                                                                        \
159         PROMISE_CAPABILITY, /* JS_RECORD_BEGIN //////////////////////////////////////////////////////////////////// */ \
160         PROMISE_RECORD,     /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \
161         RESOLVING_FUNCTIONS_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \
162         PROMISE_REACTIONS,          /* ////////////////////////////////////////////////////////////////////-PADDING */ \
163         PROMISE_ITERATOR_RECORD,    /* ////////////////////////////////////////////////////////////////////-PADDING */ \
164         MICRO_JOB_QUEUE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */   \
165         PENDING_JOB,     /* /////////////////////////////////////////////////////////////////////////////-PADDING */   \
166         COMPLETION_RECORD, /* JS_RECORD_END /////////////////////////////////////////////////////////////////////// */ \
167         MACHINE_CODE_OBJECT,                                                                                           \
168         ECMA_MODULE, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \
169         CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
170         TS_UNION_TYPE,  /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \
171         TS_OBJECT_TYPE,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
172         TS_IMPORT_TYPE,  /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \
173         TS_CLASS_TYPE,    /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \
174         TS_CLASS_INSTANCE_TYPE,  /* ///////////////////////////////////////////////////////////////////////-PADDING */ \
175         TS_INTERFACE_TYPE,    /* //////////////////////////////////////////////////////////////////////////-PADDING */ \
176         TYPE_LAST = TS_INTERFACE_TYPE, /* /////////////////////////////////////////////////////////////////-PADDING */ \
177                                                                                                                        \
178         JS_FUNCTION_BEGIN = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \
179         JS_FUNCTION_END = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* //////////////////////////////////////////////-PADDING */ \
180                                                                                                                        \
181         JS_OBJECT_BEGIN = JS_OBJECT, /* ///////////////////////////////////////////////////////////////////-PADDING */ \
182         JS_OBJECT_END = JS_GLOBAL_OBJECT, /* //////////////////////////////////////////////////////////////-PADDING */ \
183                                                                                                                        \
184         ECMA_OBJECT_BEGIN = JS_OBJECT, /* /////////////////////////////////////////////////////////////////-PADDING */ \
185         ECMA_OBJECT_END = JS_PROXY,    /* /////////////////////////////////////////////////////////////////-PADDING */ \
186                                                                                                                        \
187         JS_ERROR_BEGIN = JS_ERROR,      /* ////////////////////////////////////////////////////////////////-PADDING */ \
188         JS_ERROR_END = JS_SYNTAX_ERROR, /* ////////////////////////////////////////////////////////////////-PADDING */ \
189                                                                                                                        \
190         JS_ITERATOR_BEGIN = JS_ITERATOR,      /* //////////////////////////////////////////////////////////-PADDING */ \
191         JS_ITERATOR_END = JS_STRING_ITERATOR, /* //////////////////////////////////////////////////////////-PADDING */ \
192                                                                                                                        \
193         JS_RECORD_BEGIN = PROMISE_CAPABILITY, /* //////////////////////////////////////////////////////////-PADDING */ \
194         JS_RECORD_END = COMPLETION_RECORD,    /* ///////////////////////////////////////////////////////-PADDING */    \
195                                                                                                                        \
196         JS_TYPED_ARRAY_BEGIN = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \
197         JS_TYPED_ARRAY_END = JS_FLOAT64_ARRAY  /* /////////////////////////////////////////////////////////-PADDING */
198 
199 enum class JSType : uint8_t {
200     JSTYPE_DECL,
201 };
202 
203 class JSHClass : public TaggedObject {
204 public:
205     static constexpr int TYPE_BITFIELD_NUM = 8;
206     using ObjectTypeBits = BitField<JSType, 0, TYPE_BITFIELD_NUM>;  // 7
207     using CallableBit = ObjectTypeBits::NextFlag;
208     using ConstrutorBit = CallableBit::NextFlag;      // 9
209     using BuiltinsCtorBit = ConstrutorBit::NextFlag;  // 10
210     using ExtensibleBit = BuiltinsCtorBit::NextFlag;
211     using IsPrototypeBit = ExtensibleBit::NextFlag;
212     using ElementRepresentationBits = IsPrototypeBit::NextField<Representation, 3>;        // 3 means next 3 bit
213     using DictionaryElementBits = ElementRepresentationBits::NextFlag;                     // 16
214     using IsDictionaryBit = DictionaryElementBits::NextFlag;                               // 17
215     using IsStableElementsBit = IsDictionaryBit::NextFlag;                                 // 18
216     using HasConstructorBits = IsStableElementsBit::NextFlag;                              // 19
217     using IsLiteralBit = HasConstructorBits::NextFlag;                                     // 20
218     using ClassConstructorBit = IsLiteralBit::NextFlag;                                    // 21
219     using ClassPrototypeBit = ClassConstructorBit::NextFlag;                               // 22
220 
221     static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4;
222     static constexpr int MAX_CAPACITY_OF_OUT_OBJECTS =
223         PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES - DEFAULT_CAPACITY_OF_IN_OBJECTS;
224     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5;
225     static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS =
226         PropertyAttributes::OFFSET_BITFIELD_NUM + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED;
227     static constexpr int MAX_OBJECT_SIZE_IN_WORDS = (1U << OFFSET_MAX_OBJECT_SIZE_IN_WORDS) - 1;
228 
229     using NumberOfPropsBits = BitField<uint32_t, 0, PropertyAttributes::OFFSET_BITFIELD_NUM>; // 10
230     using InlinedPropsStartBits = NumberOfPropsBits::NextField<uint32_t,
231             OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED>; // 15
232     using ObjectSizeInWordsBits = InlinedPropsStartBits::NextField<uint32_t, OFFSET_MAX_OBJECT_SIZE_IN_WORDS>; // 30
233 
234     static JSHClass *Cast(const TaggedObject *object);
235 
236     inline size_t SizeFromJSHClass(TaggedObject *header);
237     inline bool HasReferenceField();
238 
239     // size need to add inlined property numbers
240     void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps);
241 
242     static JSHandle<JSHClass> Clone(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
243                                     bool withoutInlinedProperties = false);
244     static JSHandle<JSHClass> CloneWithoutInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
245 
246     static void TransitionElementsToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
247     static void AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
248                             const PropertyAttributes &attr);
249 
250     static JSHandle<JSHClass> TransitionExtension(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
251     static JSHandle<JSHClass> TransitionProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass,
252                                               const JSHandle<JSTaggedValue> &proto);
253     static void TransitionToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj);
254 
255     static JSHandle<JSTaggedValue> EnableProtoChangeMarker(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
256 
257     static void NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> oldHclass, JSHandle<JSHClass> newHclass);
258 
259     static void RegisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
260 
261     static bool UnregisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
262 
263     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread,
264                                                               const JSHandle<JSHClass> &jshclass);
265 
266     static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, const JSHandle<JSObject> &obj);
267 
268     inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key,
269                                       const PropertyAttributes &metaData);
270 
271     static void NoticeRegisteredUser(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
272 
273     static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass);
274 
275     static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass,
276                              const JSHandle<JSHClass> &newHclass);
277 
ClearBitField()278     inline void ClearBitField()
279     {
280         SetBitField(0UL);
281         SetBitField1(0UL);
282     }
283 
GetObjectType()284     inline JSType GetObjectType() const
285     {
286         uint32_t bits = GetBitField();
287         return ObjectTypeBits::Decode(bits);
288     }
289 
SetObjectType(JSType type)290     inline void SetObjectType(JSType type)
291     {
292         uint32_t bits = GetBitField();
293         uint32_t newVal = ObjectTypeBits::Update(bits, type);
294         SetBitField(newVal);
295     }
296 
SetCallable(bool flag)297     inline void SetCallable(bool flag)
298     {
299         CallableBit::Set<uint32_t>(flag, GetBitFieldAddr());
300     }
301 
SetConstructor(bool flag)302     inline void SetConstructor(bool flag) const
303     {
304         ConstrutorBit::Set<uint32_t>(flag, GetBitFieldAddr());
305     }
306 
SetBuiltinsCtor(bool flag)307     inline void SetBuiltinsCtor(bool flag) const
308     {
309         BuiltinsCtorBit::Set<uint32_t>(flag, GetBitFieldAddr());
310     }
311 
SetExtensible(bool flag)312     inline void SetExtensible(bool flag) const
313     {
314         ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr());
315     }
316 
SetIsPrototype(bool flag)317     inline void SetIsPrototype(bool flag) const
318     {
319         IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
320     }
321 
SetIsLiteral(bool flag)322     inline void SetIsLiteral(bool flag) const
323     {
324         IsLiteralBit::Set<uint32_t>(flag, GetBitFieldAddr());
325     }
326 
SetClassConstructor(bool flag)327     inline void SetClassConstructor(bool flag) const
328     {
329         ClassConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr());
330     }
331 
SetClassPrototype(bool flag)332     inline void SetClassPrototype(bool flag) const
333     {
334         ClassPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr());
335     }
336 
SetIsDictionaryMode(bool flag)337     inline void SetIsDictionaryMode(bool flag) const
338     {
339         IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr());
340     }
341 
IsJSObject()342     inline bool IsJSObject() const
343     {
344         JSType jsType = GetObjectType();
345         return (JSType::JS_OBJECT_BEGIN <= jsType && jsType <= JSType::JS_OBJECT_END);
346     }
347 
IsECMAObject()348     inline bool IsECMAObject() const
349     {
350         JSType jsType = GetObjectType();
351         return (JSType::ECMA_OBJECT_BEGIN <= jsType && jsType <= JSType::ECMA_OBJECT_END);
352     }
353 
IsRealm()354     inline bool IsRealm() const
355     {
356         return GetObjectType() == JSType::JS_REALM;
357     }
358 
IsHClass()359     inline bool IsHClass() const
360     {
361         return GetObjectType() == JSType::HCLASS;
362     }
363 
IsString()364     inline bool IsString() const
365     {
366         return GetObjectType() == JSType::STRING;
367     }
368 
IsBigInt()369     inline bool IsBigInt() const
370     {
371         return GetObjectType() == JSType::BIGINT;
372     }
373 
IsSymbol()374     inline bool IsSymbol() const
375     {
376         return GetObjectType() == JSType::SYMBOL;
377     }
378 
IsStringOrSymbol()379     inline bool IsStringOrSymbol() const
380     {
381         JSType jsType = GetObjectType();
382         return (jsType == JSType::STRING) || (jsType == JSType::SYMBOL);
383     }
384 
IsTaggedArray()385     inline bool IsTaggedArray() const
386     {
387         JSType jsType = GetObjectType();
388         return jsType == JSType::TAGGED_ARRAY || jsType == JSType::TAGGED_DICTIONARY;
389     }
390 
IsDictionary()391     inline bool IsDictionary() const
392     {
393         return GetObjectType() == JSType::TAGGED_DICTIONARY;
394     }
395 
IsJSNativePointer()396     inline bool IsJSNativePointer() const
397     {
398         return GetObjectType() == JSType::JS_NATIVE_POINTER;
399     }
400 
IsJSSymbol()401     inline bool IsJSSymbol() const
402     {
403         return GetObjectType() == JSType::SYMBOL;
404     }
405 
IsJSArray()406     inline bool IsJSArray() const
407     {
408         return GetObjectType() == JSType::JS_ARRAY;
409     }
410 
IsTypedArray()411     inline bool IsTypedArray() const
412     {
413         JSType jsType = GetObjectType();
414         return (JSType::JS_TYPED_ARRAY_BEGIN < jsType && jsType <= JSType::JS_TYPED_ARRAY_END);
415     }
416 
IsJSTypedArray()417     inline bool IsJSTypedArray() const
418     {
419         return GetObjectType() == JSType::JS_TYPED_ARRAY;
420     }
421 
IsJSInt8Array()422     inline bool IsJSInt8Array() const
423     {
424         return GetObjectType() == JSType::JS_INT8_ARRAY;
425     }
426 
IsJSUint8Array()427     inline bool IsJSUint8Array() const
428     {
429         return GetObjectType() == JSType::JS_UINT8_ARRAY;
430     }
431 
IsJSUint8ClampedArray()432     inline bool IsJSUint8ClampedArray() const
433     {
434         return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY;
435     }
436 
IsJSInt16Array()437     inline bool IsJSInt16Array() const
438     {
439         return GetObjectType() == JSType::JS_INT16_ARRAY;
440     }
441 
IsJSUint16Array()442     inline bool IsJSUint16Array() const
443     {
444         return GetObjectType() == JSType::JS_UINT16_ARRAY;
445     }
446 
IsJSInt32Array()447     inline bool IsJSInt32Array() const
448     {
449         return GetObjectType() == JSType::JS_INT32_ARRAY;
450     }
451 
IsJSUint32Array()452     inline bool IsJSUint32Array() const
453     {
454         return GetObjectType() == JSType::JS_UINT32_ARRAY;
455     }
456 
IsJSFloat32Array()457     inline bool IsJSFloat32Array() const
458     {
459         return GetObjectType() == JSType::JS_FLOAT32_ARRAY;
460     }
461 
IsJSFloat64Array()462     inline bool IsJSFloat64Array() const
463     {
464         return GetObjectType() == JSType::JS_FLOAT64_ARRAY;
465     }
466 
IsJsGlobalEnv()467     inline bool IsJsGlobalEnv() const
468     {
469         return GetObjectType() == JSType::GLOBAL_ENV;
470     }
471 
IsJSFunctionBase()472     inline bool IsJSFunctionBase() const
473     {
474         JSType jsType = GetObjectType();
475         return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION;
476     }
477 
IsJsBoundFunction()478     inline bool IsJsBoundFunction() const
479     {
480         return GetObjectType() == JSType::JS_BOUND_FUNCTION;
481     }
482 
IsJSIntlBoundFunction()483     inline bool IsJSIntlBoundFunction() const
484     {
485         return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION;
486     }
487 
IsJSProxyRevocFunction()488     inline bool IsJSProxyRevocFunction() const
489     {
490         return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION;
491     }
492 
IsJSAsyncFunction()493     inline bool IsJSAsyncFunction() const
494     {
495         return GetObjectType() == JSType::JS_ASYNC_FUNCTION;
496     }
497 
IsJSAsyncAwaitStatusFunction()498     inline bool IsJSAsyncAwaitStatusFunction() const
499     {
500         return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION;
501     }
502 
IsJSPromiseReactionFunction()503     inline bool IsJSPromiseReactionFunction() const
504     {
505         return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION;
506     }
507 
IsJSPromiseExecutorFunction()508     inline bool IsJSPromiseExecutorFunction() const
509     {
510         return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION;
511     }
512 
IsJSPromiseAllResolveElementFunction()513     inline bool IsJSPromiseAllResolveElementFunction() const
514     {
515         return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION;
516     }
517 
IsMicroJobQueue()518     inline bool IsMicroJobQueue() const
519     {
520         return GetObjectType() == JSType::MICRO_JOB_QUEUE;
521     }
522 
IsPendingJob()523     inline bool IsPendingJob() const
524     {
525         return GetObjectType() == JSType::PENDING_JOB;
526     }
527 
IsJsPrimitiveRef()528     inline bool IsJsPrimitiveRef() const
529     {
530         return GetObjectType() == JSType::JS_PRIMITIVE_REF;
531     };
532 
IsJSSet()533     bool IsJSSet() const
534     {
535         return GetObjectType() == JSType::JS_SET;
536     }
537 
IsJSMap()538     bool IsJSMap() const
539     {
540         return GetObjectType() == JSType::JS_MAP;
541     }
542 
IsJSWeakMap()543     bool IsJSWeakMap() const
544     {
545         return GetObjectType() == JSType::JS_WEAK_MAP;
546     }
547 
IsJSWeakSet()548     bool IsJSWeakSet() const
549     {
550         return GetObjectType() == JSType::JS_WEAK_SET;
551     }
552 
IsJSFunction()553     bool IsJSFunction() const
554     {
555         return GetObjectType() >= JSType::JS_FUNCTION_BEGIN && GetObjectType() <= JSType::JS_FUNCTION_END;
556     }
557 
IsJSError()558     inline bool IsJSError() const
559     {
560         JSType jsType = GetObjectType();
561         return jsType >= JSType::JS_ERROR_BEGIN && jsType <= JSType::JS_ERROR_END;
562     }
563 
IsArguments()564     inline bool IsArguments() const
565     {
566         return GetObjectType() == JSType::JS_ARGUMENTS;
567     }
568 
IsDate()569     inline bool IsDate() const
570     {
571         return GetObjectType() == JSType::JS_DATE;
572     }
573 
IsJSRegExp()574     inline bool IsJSRegExp() const
575     {
576         return GetObjectType() == JSType::JS_REG_EXP;
577     }
578 
IsJSProxy()579     inline bool IsJSProxy() const
580     {
581         return GetObjectType() == JSType::JS_PROXY;
582     }
583 
IsJSLocale()584     inline bool IsJSLocale() const
585     {
586         return GetObjectType() == JSType::JS_LOCALE;
587     }
588 
IsJSIntl()589     inline bool IsJSIntl() const
590     {
591         return GetObjectType() == JSType::JS_INTL;
592     }
593 
IsJSDateTimeFormat()594     inline bool IsJSDateTimeFormat() const
595     {
596         return GetObjectType() == JSType::JS_DATE_TIME_FORMAT;
597     }
598 
IsJSRelativeTimeFormat()599     inline bool IsJSRelativeTimeFormat() const
600     {
601         return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT;
602     }
603 
IsJSNumberFormat()604     inline bool IsJSNumberFormat() const
605     {
606         return GetObjectType() == JSType::JS_NUMBER_FORMAT;
607     }
608 
IsJSCollator()609     inline bool IsJSCollator() const
610     {
611         return GetObjectType() == JSType::JS_COLLATOR;
612     }
613 
IsJSPluralRules()614     inline bool IsJSPluralRules() const
615     {
616         return GetObjectType() == JSType::JS_PLURAL_RULES;
617     }
618 
619     // non ECMA standard jsapi containers.
IsSpecialContainer()620     inline bool IsSpecialContainer() const
621     {
622         return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_QUEUE;
623     }
IsJSAPIArrayList()624     inline bool IsJSAPIArrayList() const
625     {
626         return GetObjectType() == JSType::JS_API_ARRAY_LIST;
627     }
IsJSAPIArrayListIterator()628     inline bool IsJSAPIArrayListIterator() const
629     {
630         return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR;
631     }
IsJSQueue()632     inline bool IsJSQueue() const
633     {
634         return GetObjectType() == JSType::JS_QUEUE;
635     }
IsJSAPITreeMap()636     inline bool IsJSAPITreeMap() const
637     {
638         return GetObjectType() == JSType::JS_API_TREE_MAP;
639     }
IsJSAPITreeSet()640     inline bool IsJSAPITreeSet() const
641     {
642         return GetObjectType() == JSType::JS_API_TREE_SET;
643     }
IsJSAPITreeMapIterator()644     inline bool IsJSAPITreeMapIterator() const
645     {
646         return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR;
647     }
IsJSAPITreeSetIterator()648     inline bool IsJSAPITreeSetIterator() const
649     {
650         return GetObjectType() == JSType::JS_API_TREESET_ITERATOR;
651     }
652 
IsAccessorData()653     inline bool IsAccessorData() const
654     {
655         return GetObjectType() == JSType::ACCESSOR_DATA;
656     }
657 
IsInternalAccessor()658     inline bool IsInternalAccessor() const
659     {
660         return GetObjectType() == JSType::INTERNAL_ACCESSOR;
661     }
662 
IsIterator()663     inline bool IsIterator() const
664     {
665         JSType jsType = GetObjectType();
666         return jsType >= JSType::JS_ITERATOR_BEGIN && jsType <= JSType::JS_ITERATOR_END;
667     }
668 
IsForinIterator()669     inline bool IsForinIterator() const
670     {
671         return GetObjectType() == JSType::JS_FORIN_ITERATOR;
672     }
673 
IsStringIterator()674     inline bool IsStringIterator() const
675     {
676         return GetObjectType() == JSType::JS_STRING_ITERATOR;
677     }
678 
IsArrayBuffer()679     inline bool IsArrayBuffer() const
680     {
681         return GetObjectType() == JSType::JS_ARRAY_BUFFER;
682     }
683 
IsDataView()684     inline bool IsDataView() const
685     {
686         return GetObjectType() == JSType::JS_DATA_VIEW;
687     }
688 
IsJSSetIterator()689     inline bool IsJSSetIterator() const
690     {
691         return GetObjectType() == JSType::JS_SET_ITERATOR;
692     }
693 
IsJSMapIterator()694     inline bool IsJSMapIterator() const
695     {
696         return GetObjectType() == JSType::JS_MAP_ITERATOR;
697     }
698 
IsJSArrayIterator()699     inline bool IsJSArrayIterator() const
700     {
701         return GetObjectType() == JSType::JS_ARRAY_ITERATOR;
702     }
703 
IsPrototypeHandler()704     inline bool IsPrototypeHandler() const
705     {
706         return GetObjectType() == JSType::PROTOTYPE_HANDLER;
707     }
708 
IsTransitionHandler()709     inline bool IsTransitionHandler() const
710     {
711         return GetObjectType() == JSType::TRANSITION_HANDLER;
712     }
713 
IsPropertyBox()714     inline bool IsPropertyBox() const
715     {
716         return GetObjectType() == JSType::PROPERTY_BOX;
717     }
IsProtoChangeMarker()718     inline bool IsProtoChangeMarker() const
719     {
720         return GetObjectType() == JSType::PROTO_CHANGE_MARKER;
721     }
722 
IsProtoChangeDetails()723     inline bool IsProtoChangeDetails() const
724     {
725         return GetObjectType() == JSType::PROTOTYPE_INFO;
726     }
727 
IsProgram()728     inline bool IsProgram() const
729     {
730         return GetObjectType() == JSType::PROGRAM;
731     }
732 
IsEcmaModule()733     inline bool IsEcmaModule() const
734     {
735         return GetObjectType() == JSType::ECMA_MODULE;
736     }
737 
IsClassInfoExtractor()738     inline bool IsClassInfoExtractor() const
739     {
740         return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR;
741     }
742 
IsCallable()743     inline bool IsCallable() const
744     {
745         uint32_t bits = GetBitField();
746         return CallableBit::Decode(bits);
747     }
748 
IsConstructor()749     inline bool IsConstructor() const
750     {
751         uint32_t bits = GetBitField();
752         return ConstrutorBit::Decode(bits);
753     }
754 
IsBuiltinsCtor()755     inline bool IsBuiltinsCtor() const
756     {
757         uint32_t bits = GetBitField();
758         return BuiltinsCtorBit::Decode(bits);
759     }
760 
IsExtensible()761     inline bool IsExtensible() const
762     {
763         uint32_t bits = GetBitField();
764         return ExtensibleBit::Decode(bits);
765     }
766 
IsPrototype()767     inline bool IsPrototype() const
768     {
769         uint32_t bits = GetBitField();
770         return IsPrototypeBit::Decode(bits);
771     }
772 
IsLiteral()773     inline bool IsLiteral() const
774     {
775         uint32_t bits = GetBitField();
776         return IsLiteralBit::Decode(bits);
777     }
778 
IsClassConstructor()779     inline bool IsClassConstructor() const
780     {
781         uint32_t bits = GetBitField();
782         return ClassConstructorBit::Decode(bits);
783     }
784 
IsJSGlobalObject()785     inline bool IsJSGlobalObject() const
786     {
787         return GetObjectType() == JSType::JS_GLOBAL_OBJECT;
788     }
789 
IsClassPrototype()790     inline bool IsClassPrototype() const
791     {
792         uint32_t bits = GetBitField();
793         return ClassPrototypeBit::Decode(bits);
794     }
795 
IsDictionaryMode()796     inline bool IsDictionaryMode() const
797     {
798         uint32_t bits = GetBitField();
799         return IsDictionaryBit::Decode(bits);
800     }
801 
IsGeneratorFunction()802     inline bool IsGeneratorFunction() const
803     {
804         return GetObjectType() == JSType::JS_GENERATOR_FUNCTION;
805     }
806 
IsGeneratorObject()807     inline bool IsGeneratorObject() const
808     {
809         JSType jsType = GetObjectType();
810         return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT;
811     }
812 
IsGeneratorContext()813     inline bool IsGeneratorContext() const
814     {
815         return GetObjectType() == JSType::JS_GENERATOR_CONTEXT;
816     }
817 
IsAsyncFuncObject()818     inline bool IsAsyncFuncObject() const
819     {
820         return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT;
821     }
822 
IsJSPromise()823     inline bool IsJSPromise() const
824     {
825         return GetObjectType() == JSType::JS_PROMISE;
826     }
827 
IsResolvingFunctionsRecord()828     inline bool IsResolvingFunctionsRecord() const
829     {
830         return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD;
831     }
832 
IsPromiseRecord()833     inline bool IsPromiseRecord() const
834     {
835         return GetObjectType() == JSType::PROMISE_RECORD;
836     }
837 
IsPromiseIteratorRecord()838     inline bool IsPromiseIteratorRecord() const
839     {
840         return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD;
841     }
842 
IsPromiseCapability()843     inline bool IsPromiseCapability() const
844     {
845         return GetObjectType() == JSType::PROMISE_CAPABILITY;
846     }
847 
IsPromiseReaction()848     inline bool IsPromiseReaction() const
849     {
850         return GetObjectType() == JSType::PROMISE_REACTIONS;
851     }
852 
IsCompletionRecord()853     inline bool IsCompletionRecord() const
854     {
855         return GetObjectType() == JSType::COMPLETION_RECORD;
856     }
857 
IsRecord()858     inline bool IsRecord() const
859     {
860         JSType jsType = GetObjectType();
861         return jsType >= JSType::JS_RECORD_BEGIN && jsType <= JSType::JS_RECORD_END;
862     }
863 
IsTemplateMap()864     inline bool IsTemplateMap() const
865     {
866         return GetObjectType() == JSType::TEMPLATE_MAP;
867     }
868 
IsFreeObject()869     inline bool IsFreeObject() const
870     {
871         switch (GetObjectType()) {
872             case JSType::FREE_OBJECT_WITH_ONE_FIELD:
873             case JSType::FREE_OBJECT_WITH_NONE_FIELD:
874             case JSType::FREE_OBJECT_WITH_TWO_FIELD:
875                 return true;
876             default:
877                 return false;
878         }
879     }
880 
IsFreeObjectWithShortField()881     inline bool IsFreeObjectWithShortField() const
882     {
883         switch (GetObjectType()) {
884             case JSType::FREE_OBJECT_WITH_ONE_FIELD:
885             case JSType::FREE_OBJECT_WITH_NONE_FIELD:
886                 return true;
887             default:
888                 return false;
889         }
890     }
891 
IsFreeObjectWithOneField()892     inline bool IsFreeObjectWithOneField() const
893     {
894         return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD;
895     }
896 
IsFreeObjectWithNoneField()897     inline bool IsFreeObjectWithNoneField() const
898     {
899         return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD;
900     }
901 
IsFreeObjectWithTwoField()902     inline bool IsFreeObjectWithTwoField() const
903     {
904         return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD;
905     }
906 
IsMachineCodeObject()907     inline bool IsMachineCodeObject() const
908     {
909         return GetObjectType() == JSType::MACHINE_CODE_OBJECT;
910     }
911 
IsTSObjectType()912     inline bool IsTSObjectType() const
913     {
914         return GetObjectType() == JSType::TS_OBJECT_TYPE;
915     }
916 
IsTSClassType()917     inline bool IsTSClassType() const
918     {
919         return GetObjectType() == JSType::TS_CLASS_TYPE;
920     }
921 
IsTSInterfaceType()922     inline bool IsTSInterfaceType() const
923     {
924         return GetObjectType() == JSType::TS_INTERFACE_TYPE;
925     }
926 
IsTSUnionType()927     inline bool IsTSUnionType() const
928     {
929         return GetObjectType() == JSType::TS_UNION_TYPE;
930     }
931 
IsTSClassInstanceType()932     inline bool IsTSClassInstanceType() const
933     {
934         return GetObjectType() == JSType::TS_CLASS_INSTANCE_TYPE;
935     }
936 
IsTSImportType()937     inline bool IsTSImportType() const
938     {
939         return GetObjectType() == JSType::TS_IMPORT_TYPE;
940     }
941 
SetElementRepresentation(Representation representation)942     inline void SetElementRepresentation(Representation representation)
943     {
944         uint32_t bits = GetBitField();
945         uint32_t newVal = ElementRepresentationBits::Update(bits, representation);
946         SetBitField(newVal);
947     }
948 
GetElementRepresentation()949     inline Representation GetElementRepresentation() const
950     {
951         uint32_t bits = GetBitField();
952         return ElementRepresentationBits::Decode(bits);
953     }
954 
UpdateRepresentation(JSTaggedValue value)955     inline void UpdateRepresentation(JSTaggedValue value)
956     {
957         Representation rep = PropertyAttributes::UpdateRepresentation(GetElementRepresentation(), value);
958         SetElementRepresentation(rep);
959     }
960 
SetIsDictionaryElement(bool value)961     inline void SetIsDictionaryElement(bool value)
962     {
963         uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value);
964         SetBitField(newVal);
965     }
IsDictionaryElement()966     inline bool IsDictionaryElement() const
967     {
968         return DictionaryElementBits::Decode(GetBitField());
969     }
SetIsStableElements(bool value)970     inline void SetIsStableElements(bool value)
971     {
972         uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value);
973         SetBitField(newVal);
974     }
IsStableElements()975     inline bool IsStableElements() const
976     {
977         return IsStableElementsBit::Decode(GetBitField());
978     }
IsStableJSArguments()979     inline bool IsStableJSArguments() const
980     {
981         uint32_t bits = GetBitField();
982         auto type = ObjectTypeBits::Decode(bits);
983         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS);
984     }
IsStableJSArray()985     inline bool IsStableJSArray() const
986     {
987         uint32_t bits = GetBitField();
988         auto type = ObjectTypeBits::Decode(bits);
989         return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY);
990     }
SetHasConstructor(bool value)991     inline void SetHasConstructor(bool value)
992     {
993         TaggedType newVal = HasConstructorBits::Update(GetBitField(), value);
994         SetBitField(newVal);
995     }
HasConstructor()996     inline bool HasConstructor() const
997     {
998         return HasConstructorBits::Decode(GetBitField());
999     }
1000 
SetNumberOfProps(uint32_t num)1001     inline void SetNumberOfProps(uint32_t num)
1002     {
1003         uint32_t bits = GetBitField1();
1004         uint32_t newVal = NumberOfPropsBits::Update(bits, num);
1005         SetBitField1(newVal);
1006     }
1007 
IncNumberOfProps()1008     inline void IncNumberOfProps()
1009     {
1010         ASSERT(NumberOfProps() < PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
1011         SetNumberOfProps(NumberOfProps() + 1);
1012     }
1013 
NumberOfProps()1014     inline uint32_t NumberOfProps() const
1015     {
1016         uint32_t bits = GetBitField1();
1017         return NumberOfPropsBits::Decode(bits);
1018     }
1019 
GetNextInlinedPropsIndex()1020     inline int32_t GetNextInlinedPropsIndex() const
1021     {
1022         uint32_t inlinedProperties = GetInlinedProperties();
1023         uint32_t numberOfProps = NumberOfProps();
1024         if (numberOfProps < inlinedProperties) {
1025             return numberOfProps;
1026         }
1027         return -1;
1028     }
1029 
GetNextNonInlinedPropsIndex()1030     inline int32_t GetNextNonInlinedPropsIndex() const
1031     {
1032         uint32_t inlinedProperties = GetInlinedProperties();
1033         uint32_t numberOfProps = NumberOfProps();
1034         if (numberOfProps >= inlinedProperties) {
1035             return numberOfProps - inlinedProperties;
1036         }
1037         return -1;
1038     }
1039 
GetObjectSize()1040     inline uint32_t GetObjectSize() const
1041     {
1042         uint32_t bits = GetBitField1();
1043         return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1044     }
1045 
SetObjectSize(uint32_t num)1046     inline void SetObjectSize(uint32_t num)
1047     {
1048         ASSERT((num / JSTaggedValue::TaggedTypeSize()) <= MAX_OBJECT_SIZE_IN_WORDS);
1049         uint32_t bits = GetBitField1();
1050         uint32_t newVal = ObjectSizeInWordsBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1051         SetBitField1(newVal);
1052     }
1053 
GetInlinedPropertiesOffset(uint32_t index)1054     inline uint32_t GetInlinedPropertiesOffset(uint32_t index) const
1055     {
1056         ASSERT(index < GetInlinedProperties());
1057         return GetInlinedPropertiesIndex(index) * JSTaggedValue::TaggedTypeSize();
1058     }
1059 
GetInlinedPropertiesIndex(uint32_t index)1060     inline uint32_t GetInlinedPropertiesIndex(uint32_t index) const
1061     {
1062         ASSERT(index < GetInlinedProperties());
1063         uint32_t bits = GetBitField1();
1064         return InlinedPropsStartBits::Decode(bits) + index;
1065     }
1066 
SetInlinedPropsStart(uint32_t num)1067     inline void SetInlinedPropsStart(uint32_t num)
1068     {
1069         uint32_t bits = GetBitField1();
1070         uint32_t newVal = InlinedPropsStartBits::Update(bits, num / JSTaggedValue::TaggedTypeSize());
1071         SetBitField1(newVal);
1072     }
1073 
GetInlinedPropsStartSize()1074     inline uint32_t GetInlinedPropsStartSize() const
1075     {
1076         uint32_t bits = GetBitField1();
1077         return InlinedPropsStartBits::Decode(bits) * JSTaggedValue::TaggedTypeSize();
1078     }
1079 
GetInlinedProperties()1080     inline uint32_t GetInlinedProperties() const
1081     {
1082         JSType type = GetObjectType();
1083         if (JSType::JS_OBJECT_BEGIN <= type && type <= JSType::JS_OBJECT_END) {
1084             uint32_t bits = GetBitField1();
1085             return static_cast<uint32_t>(ObjectSizeInWordsBits::Decode(bits) - InlinedPropsStartBits::Decode(bits));
1086         } else {
1087             return 0;
1088         }
1089     }
1090 
1091     JSTaggedValue GetAccessor(const JSTaggedValue &key);
1092 
1093     static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize();
1094     ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET);
1095     ACCESSORS(Layout, LAYOUT_OFFSET, TRANSTIONS_OFFSET);
1096     ACCESSORS(Transitions, TRANSTIONS_OFFSET, PROTO_CHANGE_MARKER_OFFSET);
1097     ACCESSORS(ProtoChangeMarker, PROTO_CHANGE_MARKER_OFFSET, PROTO_CHANGE_DETAILS_OFFSET);
1098     ACCESSORS(ProtoChangeDetails, PROTO_CHANGE_DETAILS_OFFSET, ENUM_CACHE_OFFSET);
1099     ACCESSORS(EnumCache, ENUM_CACHE_OFFSET, BIT_FIELD_OFFSET);
1100     ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD1_OFFSET);
1101     ACCESSORS_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, LAST_OFFSET)
1102     DEFINE_ALIGN_SIZE(LAST_OFFSET);
1103 
1104     void SetPrototype(const JSThread *thread, JSTaggedValue proto);
1105     void SetPrototype(const JSThread *thread, const JSHandle<JSTaggedValue> &proto);
GetPrototype()1106     inline JSTaggedValue GetPrototype() const
1107     {
1108         return GetProto();
1109     }
1110     DECL_DUMP()
1111 
1112     static CString DumpJSType(JSType type);
1113 
1114     DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, BIT_FIELD_OFFSET);
1115 
1116 private:
1117     static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1118                                       const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
1119                                       PropertyAttributes attr);
1120     static inline void AddExtensionTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1121                                                const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key);
1122     static inline void AddProtoTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent,
1123                                            const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key,
1124                                            const JSHandle<JSTaggedValue> &proto);
1125     inline JSHClass *FindTransitions(const JSTaggedValue &key, const JSTaggedValue &attributes);
1126     inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto);
1127 
1128     inline void Copy(const JSThread *thread, const JSHClass *jshcalss);
1129 
GetBitFieldAddr()1130     uint32_t *GetBitFieldAddr() const
1131     {
1132         return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET);
1133     }
1134     friend class RuntimeTrampolines;
1135 };
1136 static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0);
1137 }  // namespace panda::ecmascript
1138 
1139 #endif  // ECMASCRIPT_JS_HCLASS_H
1140