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