1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_JS_HCLASS_H 17 #define ECMASCRIPT_JS_HCLASS_H 18 19 #include "ecmascript/ecma_macros.h" 20 #include "ecmascript/elements.h" 21 #include "ecmascript/js_tagged_value.h" 22 #include "ecmascript/mem/tagged_object.h" 23 #include "ecmascript/mem/barriers.h" 24 #include "ecmascript/mem/slots.h" 25 #include "ecmascript/mem/visitor.h" 26 #include "ecmascript/property_attributes.h" 27 28 #include "libpandabase/utils/bit_field.h" 29 30 /* 31 * JS Object and JS HClass Layout 32 * 33 * Properties JS Object JS HClass 34 * +------------+ +------------+ +------------------+ 35 * |arrayHClass + <---------| |JS HClass +-------------->| meta hclass | 36 * +------------+ | +------------+ +------------------+ 37 * | property 0 | | |Hash | | hclass level | 38 * +------------+ | +------------+ +------------------+ 39 * | property 1 | |------- |Properties | | supers[] | 40 * +------------+ +------------+ +------------------+ 41 * |... | |------- |Elements | | vtable[] | 42 * +------------+ | +------------+ +------------------+ 43 * | |inl-prop-0 | | prototype | 44 * Elements | +------------+ +------------------+ 45 * +------------+ | |inl-prop-1 | | layout | 46 * |arrayHClass + <---------| +------------+ +------------------+ 47 * +------------+ |... | | transitions | 48 * | value 0 | +------------+ +------------------+ 49 * +------------+ | parent | 50 * | value 1 | +------------------+ 51 * +------------+ |ProtoChangeMarker | 52 * |... | +------------------+ 53 * +------------+ | EnumCache | 54 * +------------------+ 55 * 56 * Proto: [[Prototype]] in Ecma spec 57 * Layout: record key and attr 58 * ProtoChangeMarker, ProtoChangeDetails: monitor [[prototype]] chain 59 * EnumCache: use for for-in syntax 60 * 61 */ 62 namespace panda::ecmascript { 63 class ProtoChangeDetails; 64 class PropertyLookupResult; 65 class SharedHeap; 66 class JSSharedArray; 67 class LayoutInfo; 68 class NameDictionary; 69 namespace pgo { 70 class HClassLayoutDesc; 71 class PGOHClassTreeDesc; 72 class PGOHandler; 73 } // namespace pgo 74 using HClassLayoutDesc = pgo::HClassLayoutDesc; 75 using PGOHClassTreeDesc = pgo::PGOHClassTreeDesc; 76 using PGOHandler = pgo::PGOHandler; 77 78 struct Reference; 79 80 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 81 #define JSTYPE_DECL /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 82 INVALID = 0, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 83 JS_OBJECT, /* JS_OBJECT_FIRST ////////////////////////////////////////////////////////////////////// */ \ 84 JS_SHARED_OBJECT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 85 JS_REALM, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 86 JS_FUNCTION_BASE, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 87 JS_FUNCTION, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 88 JS_SHARED_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 89 JS_PROXY_REVOC_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 90 JS_PROMISE_REACTIONS_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 91 JS_PROMISE_EXECUTOR_FUNCTION, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 92 JS_ASYNC_MODULE_FULFILLED_FUNCTION, /* ////////////////////////////////////////////////////////////-PADDING */ \ 93 JS_ASYNC_MODULE_REJECTED_FUNCTION, /* /////////////////////////////////////////////////////////////-PADDING */ \ 94 JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION, /* //////////////////////////////////////////////////////-PADDING */ \ 95 JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION, /* //////////////////////////////////////////////////////-PADDING */ \ 96 JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN, /* ///////////////////////////////////////-PADDING */ \ 97 JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION, /* ///////////////////////////////////////////////////////-PADDING */ \ 98 JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION, /* //////////////////////////////////////////////////////-PADDING */ \ 99 JS_PROMISE_FINALLY_FUNCTION, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 100 JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION, /* ///////////////////////////////////////////////////-PADDING */ \ 101 JS_GENERATOR_FUNCTION, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \ 102 JS_ASYNC_GENERATOR_FUNCTION, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 103 JS_ASYNC_FUNCTION, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 104 JS_SHARED_ASYNC_FUNCTION, /* //////////////////////////////////////////////////////////////////////-PADDING */ \ 105 JS_INTL_BOUND_FUNCTION, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 106 JS_ASYNC_AWAIT_STATUS_FUNCTION, /* ////////////////////////////////////////////////////////////////-PADDING */ \ 107 JS_BOUND_FUNCTION, /* //////////////////////////////////////////////////////////////////////////////////// */ \ 108 \ 109 JS_ERROR, /* JS_ERROR_FIRST /////////////////////////////////////////////////////////////-PADDING */ \ 110 JS_EVAL_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 111 JS_RANGE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 112 JS_REFERENCE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 113 JS_TYPE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 114 JS_AGGREGATE_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 115 JS_URI_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 116 JS_SYNTAX_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 117 JS_OOM_ERROR, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 118 JS_TERMINATION_ERROR, /* JS_ERROR_LAST //////////////////////////////////////////////////////////////////// */ \ 119 \ 120 JS_REG_EXP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 121 JS_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 122 JS_SHARED_SET, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 123 JS_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 124 JS_SHARED_MAP, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 125 JS_WEAK_MAP, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 126 JS_WEAK_SET, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 127 JS_WEAK_REF, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 128 JS_FINALIZATION_REGISTRY, /* //////////////////////////////////////////////////////////////////////-PADDING */ \ 129 JS_DATE, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 130 JS_ITERATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 131 JS_ASYNCITERATOR, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 132 JS_ASYNC_FROM_SYNC_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 133 JS_FORIN_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 134 JS_MAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 135 JS_SHARED_MAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 136 JS_SET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 137 JS_SHARED_SET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 138 JS_REG_EXP_ITERATOR, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 139 JS_API_ARRAYLIST_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \ 140 JS_API_DEQUE_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 141 JS_API_HASHMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 142 JS_API_HASHSET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 143 JS_API_LIGHT_WEIGHT_MAP_ITERATOR, /* //////////////////////////////////////////////////////////////-PADDING */ \ 144 JS_API_LIGHT_WEIGHT_SET_ITERATOR, /* /////////////////////////////////////////////////////////////-PADDING */ \ 145 JS_API_PLAIN_ARRAY_ITERATOR, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 146 JS_API_QUEUE_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 147 JS_API_STACK_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 148 JS_API_TREEMAP_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 149 JS_API_TREESET_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 150 JS_API_VECTOR_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 151 JS_API_BITVECTOR_ITERATOR, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 152 JS_API_LINKED_LIST_ITERATOR, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 153 JS_API_LIST_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 154 JS_ARRAY_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 155 JS_SHARED_ARRAY_ITERATOR, /* //////////////////////////////////////////////////////////////////////-PADDING */ \ 156 JS_SEGMENT_ITERATOR, /* /////////////////////////////////////////////////////////////////////-PADDING */ \ 157 JS_STRING_ITERATOR, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 158 JS_INTL, /* ///////////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 159 JS_LOCALE, /* /////////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 160 JS_DATE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \ 161 JS_RELATIVE_TIME_FORMAT, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 162 JS_NUMBER_FORMAT, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 163 JS_COLLATOR, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 164 JS_PLURAL_RULES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 165 JS_DISPLAYNAMES, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 166 JS_LIST_FORMAT, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 167 JS_SEGMENTER, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 168 JS_SEGMENTS, /* /////////////////////////////////////////////////////////////////////////// ///////-PADDING */ \ 169 \ 170 JS_ARRAY_BUFFER, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 171 JS_SHARED_ARRAY_BUFFER, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 172 JS_SENDABLE_ARRAY_BUFFER, /* //////////////////////////////////////////////////////////////////////-PADDING */ \ 173 JS_PROMISE, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 174 JS_DATA_VIEW, /* /////////////////////////////////////////////////////////////////////////////////////// */ \ 175 JS_ARGUMENTS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 176 JS_GENERATOR_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 177 JS_ASYNC_GENERATOR_OBJECT, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 178 JS_ASYNC_FUNC_OBJECT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 179 \ 180 /* SPECIAL indexed objects begin, DON'T CHANGE HERE ///////////////////////////////////////////////-PADDING */ \ 181 JS_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 182 JS_SHARED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 183 JS_API_ARRAY_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 184 JS_API_LIGHT_WEIGHT_MAP, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 185 JS_API_LIGHT_WEIGHT_SET, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 186 JS_API_VECTOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 187 JS_API_BITVECTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 188 JS_API_LINKED_LIST, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 189 JS_API_LIST, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 190 JS_API_HASH_MAP, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 191 JS_API_HASH_SET, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 192 JS_API_TREE_MAP, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 193 JS_API_TREE_SET, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 194 JS_API_DEQUE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 195 JS_API_STACK, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 196 JS_API_PLAIN_ARRAY, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 197 JS_API_QUEUE, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 198 JS_TYPED_ARRAY, /* JS_TYPED_ARRAY_FIRST /////////////////////////////////////////////////////////////////// */ \ 199 JS_INT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 200 JS_UINT8_ARRAY, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 201 JS_UINT8_CLAMPED_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 202 JS_INT16_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 203 JS_UINT16_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 204 JS_INT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 205 JS_UINT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 206 JS_FLOAT32_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 207 JS_FLOAT64_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 208 JS_BIGINT64_ARRAY, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 209 JS_BIGUINT64_ARRAY, /* JS_TYPED_ARRAY_LAST //////////////////////////////////////////////////////////// */ \ 210 JS_SHARED_TYPED_ARRAY, /* JS_SHARED_TYPED_ARRAY_FIRST //////////////////////////////////////////////////// */ \ 211 JS_SHARED_INT8_ARRAY, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \ 212 JS_SHARED_UINT8_ARRAY, /* /////////////////////////////////////////////////////////////////////////-PADDING */ \ 213 JS_SHARED_UINT8_CLAMPED_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 214 JS_SHARED_INT16_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 215 JS_SHARED_UINT16_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 216 JS_SHARED_INT32_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 217 JS_SHARED_UINT32_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 218 JS_SHARED_FLOAT32_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 219 JS_SHARED_FLOAT64_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 220 JS_SHARED_BIGINT64_ARRAY, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 221 JS_SHARED_BIGUINT64_ARRAY, /* JS_SHARED_TYPED_ARRAY_LAST ////////////////////////////////////////////// */ \ 222 JS_PRIMITIVE_REF, /* number\boolean\string. SPECIAL indexed objects end, DON'T CHANGE HERE ////////-PADDING */ \ 223 JS_MODULE_NAMESPACE, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \ 224 JS_CJS_MODULE, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 225 JS_CJS_EXPORTS, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 226 JS_CJS_REQUIRE, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 227 NATIVE_MODULE_FAILURE_INFO, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 228 JS_GLOBAL_OBJECT, /* JS_OBJECT_LAST////////////////////////////////////////////////////////////////-PADDING */ \ 229 JS_PROXY, /* ECMA_OBJECT_LAST ///////////////////////////////////////////////////////////////////////////// */ \ 230 \ 231 HCLASS, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 232 LINE_STRING, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 233 CONSTANT_STRING, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 234 SLICED_STRING, /* ////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 235 TREE_STRING, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 236 BIGINT, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 237 TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 238 MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \ 239 BYTE_ARRAY, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 240 LEXICAL_ENV, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 241 SENDABLE_ENV, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */\ 242 TAGGED_DICTIONARY, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 243 CONSTANT_POOL, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 244 PROFILE_TYPE_INFO, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 245 COW_MUTANT_TAGGED_ARRAY, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 246 COW_TAGGED_ARRAY, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 247 LINKED_NODE, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 248 RB_TREENODE, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 249 FREE_OBJECT_WITH_ONE_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 250 FREE_OBJECT_WITH_NONE_FIELD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 251 FREE_OBJECT_WITH_TWO_FIELD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 252 JS_NATIVE_POINTER, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 253 GLOBAL_ENV, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 254 ACCESSOR_DATA, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 255 INTERNAL_ACCESSOR, /* /////////////////////////////////////////////////////////////////////////////-PADDING */ \ 256 SYMBOL, /* ////////////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 257 JS_GENERATOR_CONTEXT, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 258 PROTOTYPE_HANDLER, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 259 TRANSITION_HANDLER, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 260 TRANS_WITH_PROTO_HANDLER, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 261 STORE_TS_HANDLER, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 262 PROPERTY_BOX, /* //////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 263 PROTO_CHANGE_MARKER, /* ///////////////////////////////////////////////////////////////////////////-PADDING */ \ 264 MARKER_CELL, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 265 TRACK_INFO, /* ///////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 266 PROTOTYPE_INFO, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 267 TEMPLATE_MAP, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 268 PROGRAM, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 269 METHOD, /* ////////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 270 CLASS_LITERAL, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 271 \ 272 PROMISE_CAPABILITY, /* JS_RECORD_FIRST //////////////////////////////////////////////////////////////////// */ \ 273 PROMISE_RECORD, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 274 RESOLVING_FUNCTIONS_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 275 PROMISE_REACTIONS, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 276 ASYNC_GENERATOR_REQUEST, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 277 ASYNC_ITERATOR_RECORD, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 278 PROMISE_ITERATOR_RECORD, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 279 MICRO_JOB_QUEUE, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 280 PENDING_JOB, /* ///////////////////////////////////////////////////////////////////////////////-PADDING */ \ 281 MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////////////////-PADDING */ \ 282 SOURCE_TEXT_MODULE_RECORD, /* /////////////////////////////////////////////////////////////////////-PADDING */ \ 283 IMPORTENTRY_RECORD, /* ////////////////////////////////////////////////////////////////////////////-PADDING */ \ 284 LOCAL_EXPORTENTRY_RECORD, /* //////////////////////////////////////////////////////////////////////-PADDING */ \ 285 INDIRECT_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 286 STAR_EXPORTENTRY_RECORD, /* ///////////////////////////////////////////////////////////////////////-PADDING */ \ 287 RESOLVEDBINDING_RECORD, /* ////////////////////////////////////////////////////////////////////////-PADDING */ \ 288 RESOLVEDINDEXBINDING_RECORD, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 289 RESOLVEDRECORDINDEXBINDING_RECORD, /* /////////////////////////////////////////////////////////////-PADDING */ \ 290 RESOLVEDRECORDBINDING_RECORD, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 291 CELL_RECORD, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 292 COMPLETION_RECORD, /* JS_RECORD_LAST ////////////////////////////////////////////////////////////////////// */ \ 293 MACHINE_CODE_OBJECT, \ 294 CLASS_INFO_EXTRACTOR, /* //////////////////////////////////////////////////////////////////////////-PADDING */ \ 295 \ 296 PROFILE_TYPE_INFO_CELL_0, /* PROFILE_TYPE_INFO_CELL_FIRST ////////////////////////////////////////-PADDING */ \ 297 PROFILE_TYPE_INFO_CELL_1, /* /////////////////////////////////////////////////////////////////////-PADDING */ \ 298 PROFILE_TYPE_INFO_CELL_N, /* PROFILE_TYPE_INFO_CELL_LAST /////////////////////////////////////////-PADDING */ \ 299 \ 300 EXTRA_PROFILE_TYPE_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 301 FUNCTION_TEMPLATE, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 302 \ 303 VTABLE, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 304 AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////////////////-PADDING */ \ 305 TYPE_LAST = AOT_LITERAL_INFO, /* //////////////////////////////////////////////////////////////////-PADDING */ \ 306 \ 307 JS_FUNCTION_FIRST = JS_FUNCTION, /* ///////////////////////////////////////////////////////////////-PADDING */ \ 308 JS_FUNCTION_LAST = JS_ASYNC_AWAIT_STATUS_FUNCTION, /* /////////////////////////////////////////////-PADDING */ \ 309 \ 310 JS_OBJECT_FIRST = JS_OBJECT, /* ///////////////////////////////////////////////////////////////////-PADDING */ \ 311 JS_OBJECT_LAST = JS_GLOBAL_OBJECT, /* /////////////////////////////////////////////////////////////-PADDING */ \ 312 \ 313 ECMA_OBJECT_FIRST = JS_OBJECT, /* /////////////////////////////////////////////////////////////////-PADDING */ \ 314 ECMA_OBJECT_LAST = JS_PROXY, /* ////////////////////////////////////////////////////////////////-PADDING */ \ 315 \ 316 JS_ERROR_FIRST = JS_ERROR, /* ////////////////////////////////////////////////////////////////-PADDING */ \ 317 JS_ERROR_LAST = JS_TERMINATION_ERROR, /* ///////////////////////////////////////////////////////-PADDING */ \ 318 \ 319 JS_ITERATOR_FIRST = JS_ITERATOR, /* //////////////////////////////////////////////////////////-PADDING */ \ 320 JS_ITERATOR_LAST = JS_STRING_ITERATOR, /* /////////////////////////////////////////////////////////-PADDING */ \ 321 \ 322 JS_RECORD_FIRST = PROMISE_CAPABILITY, /* //////////////////////////////////////////////////////////-PADDING */ \ 323 JS_RECORD_LAST = COMPLETION_RECORD, /* /////////////////////////////////////////////////////////-PADDING */ \ 324 \ 325 JS_TYPED_ARRAY_FIRST = JS_TYPED_ARRAY, /* /////////////////////////////////////////////////////////-PADDING */ \ 326 JS_TYPED_ARRAY_LAST = JS_BIGUINT64_ARRAY, /* //////////////////////////////////////////////////////-PADDING */ \ 327 \ 328 JS_SHARED_TYPED_ARRAY_FIRST = JS_SHARED_TYPED_ARRAY, /* ///////////////////////////////////////////-PADDING */ \ 329 JS_SHARED_TYPED_ARRAY_LAST = JS_SHARED_BIGUINT64_ARRAY, /* ////////////////////////////////////////-PADDING */ \ 330 \ 331 MODULE_RECORD_FIRST = MODULE_RECORD, /* ///////////////////////////////////////////////////////////-PADDING */ \ 332 MODULE_RECORD_LAST = SOURCE_TEXT_MODULE_RECORD, /* ////////////////////////////////////////////////-PADDING */ \ 333 \ 334 STRING_FIRST = LINE_STRING, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 335 STRING_LAST = TREE_STRING, /* ////////////////////////////////////////////////////////////////////-PADDING */ \ 336 \ 337 PROFILE_TYPE_INFO_CELL_FIRST = PROFILE_TYPE_INFO_CELL_0, /* //////////////////////////////////////-PADDING */ \ 338 PROFILE_TYPE_INFO_CELL_LAST = PROFILE_TYPE_INFO_CELL_N /* //////////////////////////////////////-PADDING */ 339 340 enum class JSType : uint8_t { 341 JSTYPE_DECL, 342 }; 343 344 // EnumCache: 345 // +-----------------+----------------------+ 346 // | value | status | 347 // +-----------------+----------------------+ 348 // | null | uninitialized | 349 // ------------------------------------------ 350 // | undefined | a fast path to check | 351 // | | simple enum cache | 352 // ------------------------------------------ 353 // | empty array | enum keys is empty | 354 // ------------------------------------------ 355 // | non-empty array | non-empty enum keys | 356 // +----------------------------------------+ 357 // structure of non-empty array of EnumCache: 358 // 0: an int value indicating enum cache kind 359 // 1-n: enum keys 360 namespace EnumCache { 361 static constexpr uint32_t ENUM_CACHE_HEADER_SIZE = 1; 362 static constexpr uint32_t ENUM_CACHE_KIND_OFFSET = 0; 363 enum class EnumCacheKind : uint8_t { 364 NONE = 0, 365 SIMPLE, // simple enum cache(used in for-in) 366 // make sure EnumCache is empty array only for SIMPLE 367 PROTOCHAIN, // enum cache with prototype chain info(used in for-in) 368 ONLY_OWN_KEYS // enum cache with only own enum keys(used in Json.stringify and Object.keys) 369 }; 370 371 } // namespace EnumCache 372 373 struct TransitionResult { 374 bool isTagged; 375 bool isTransition; 376 JSTaggedValue value; 377 }; 378 379 class JSHClass : public TaggedObject { 380 public: 381 static constexpr int TYPE_BITFIELD_NUM = 8; 382 static constexpr int LEVEL_BTTFIELD_NUM = 5; 383 static constexpr int ELEMENTS_KIND_BITFIELD_NUM = 5; 384 static constexpr unsigned BITS_PER_BYTE = 8; 385 using ObjectTypeBits = BitField<JSType, 0, TYPE_BITFIELD_NUM>; // 8 386 using CallableBit = ObjectTypeBits::NextFlag; // 9 387 using ConstructorBit = CallableBit::NextFlag; // 10 388 using ExtensibleBit = ConstructorBit::NextFlag; // 11 389 using IsPrototypeBit = ExtensibleBit::NextFlag; // 12 390 using ElementsKindBits = IsPrototypeBit::NextField<ElementsKind, ELEMENTS_KIND_BITFIELD_NUM>; // 13-17 391 using DictionaryElementBits = ElementsKindBits::NextFlag; // 18 392 using IsDictionaryBit = DictionaryElementBits::NextFlag; // 19 393 using IsStableElementsBit = IsDictionaryBit::NextFlag; // 20 394 using HasConstructorBits = IsStableElementsBit::NextFlag; // 21 395 using IsClassConstructorOrPrototypeBit = HasConstructorBits::NextFlag; // 22 396 using IsNativeBindingObjectBit = IsClassConstructorOrPrototypeBit::NextFlag; // 23 397 using IsTSBit = IsNativeBindingObjectBit::NextFlag; // 24 398 using LevelBit = IsTSBit::NextField<uint32_t, LEVEL_BTTFIELD_NUM>; // 25-29 399 using IsJSFunctionBit = LevelBit::NextFlag; // 30 400 using IsOnHeap = IsJSFunctionBit::NextFlag; // 31 401 using IsJSSharedBit = IsOnHeap::NextFlag; // 32 402 using BitFieldLastBit = IsJSSharedBit; 403 static_assert(BitFieldLastBit::START_BIT + BitFieldLastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid"); 404 405 static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4; 406 static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5; 407 static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS = 408 PropertyAttributes::OFFSET_BITFIELD_NUM + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED; 409 static constexpr int MAX_OBJECT_SIZE_IN_WORDS = (1U << OFFSET_MAX_OBJECT_SIZE_IN_WORDS) - 1; 410 411 using NumberOfPropsBits = BitField<uint32_t, 0, PropertyAttributes::OFFSET_BITFIELD_NUM>; // 10 412 using InlinedPropsStartBits = NumberOfPropsBits::NextField<uint32_t, 413 OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED>; // 15 414 using ObjectSizeInWordsBits = InlinedPropsStartBits::NextField<uint32_t, OFFSET_MAX_OBJECT_SIZE_IN_WORDS>; // 30 415 using HasDeletePropertyBit = ObjectSizeInWordsBits::NextFlag; // 416 using IsAllTaggedPropBit = HasDeletePropertyBit::NextFlag; // 32 417 using BitField1LastBit = IsAllTaggedPropBit; 418 static_assert(BitField1LastBit::START_BIT + BitField1LastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid"); 419 Cast(const TaggedObject *object)420 static JSHClass *Cast(const TaggedObject *object) 421 { 422 ASSERT(JSTaggedValue(object).IsJSHClass()); 423 return static_cast<JSHClass *>(const_cast<TaggedObject *>(object)); 424 } 425 426 inline size_t SizeFromJSHClass(TaggedObject *header); 427 inline bool HasReferenceField(); 428 429 // size need to add inlined property numbers 430 void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps); 431 // for sharedHeap 432 void Initialize(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps, 433 const JSHandle<JSTaggedValue> &layout); 434 static JSHandle<JSHClass> Clone(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 435 bool withoutInlinedProperties = false, uint32_t incInlinedProperties = 0); 436 static JSHandle<JSHClass> CloneWithoutInlinedProperties(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 437 static JSHandle<JSHClass> CloneWithElementsKind(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 438 const ElementsKind kind, bool isPrototype); 439 440 static void TransitionElementsToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj); 441 static void OptimizeAsFastElements(const JSThread *thread, JSHandle<JSObject> obj); 442 static void OptimizeAsFastProperties(const JSThread *thread, const JSHandle<JSObject> &obj, 443 const std::vector<int> &indexArray = {}, bool isDictionary = false); 444 template<bool checkDuplicateKeys = false> 445 static JSHandle<JSHClass> SetPropertyOfObjHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass, 446 const JSHandle<JSTaggedValue> &key, 447 const PropertyAttributes &attr, 448 const Representation &rep); 449 static void PUBLIC_API AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj, 450 const JSHandle<JSTaggedValue> &key, const PropertyAttributes &attr, 451 const Representation &rep = Representation::NONE); 452 453 inline static void RestoreElementsKindToGeneric(JSHClass *newJsHClass); 454 455 static JSHandle<JSHClass> TransitionExtension(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 456 static void ReBuildFunctionInheritanceRelationship(const JSThread *thread, 457 const JSHandle<JSTaggedValue> &proto, 458 const JSHandle<JSTaggedValue> &baseIhc, 459 const JSHandle<JSTaggedValue> &transIhc, 460 const JSHandle<JSTaggedValue> &transPhc); 461 static JSHandle<JSHClass> TransitionProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 462 const JSHandle<JSTaggedValue> &proto, bool isChangeProto = false); 463 static JSHClass *FindTransitionProtoForAOT(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 464 const JSHandle<JSTaggedValue> &proto); 465 static JSHandle<JSHClass> TransProtoWithoutLayout(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 466 const JSHandle<JSTaggedValue> &proto); 467 static JSHandle<JSHClass> CloneWithAddProto(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 468 const JSHandle<JSTaggedValue> &key, 469 const JSHandle<JSTaggedValue> &proto); 470 static void TransitionToDictionary(const JSThread *thread, const JSHandle<JSObject> &obj); 471 static void TransitionForRepChange(const JSThread *thread, const JSHandle<JSObject> &receiver, 472 const JSHandle<JSTaggedValue> &key, PropertyAttributes attr); 473 static void TransitionForElementsKindChange(const JSThread *thread, const JSHandle<JSObject> &receiver, 474 const ElementsKind newKind); 475 static bool IsInitialArrayHClassWithElementsKind(const JSThread *thread, const JSHClass *targetHClass, 476 const ElementsKind targetKind); 477 static bool PUBLIC_API TransitToElementsKindUncheck(const JSThread *thread, const JSHandle<JSObject> &obj, 478 ElementsKind newKind); 479 static void PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSArray> &array, 480 ElementsKind newKind = ElementsKind::NONE); 481 static bool PUBLIC_API TransitToElementsKind(const JSThread *thread, const JSHandle<JSObject> &object, 482 const JSHandle<JSTaggedValue> &value, 483 ElementsKind kind = ElementsKind::NONE); 484 static TransitionResult PUBLIC_API ConvertOrTransitionWithRep(const JSThread *thread, 485 const JSHandle<JSObject> &receiver, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value, 486 PropertyAttributes &attr); 487 488 static void UpdateFieldType(JSHClass *hclass, const PropertyAttributes &attr); 489 static JSHClass *FindFieldOwnHClass(JSHClass *hclass, const PropertyAttributes &attr); 490 static void VisitAndUpdateLayout(JSHClass *ownHClass, const PropertyAttributes &attr); 491 492 static JSHandle<JSTaggedValue> EnableProtoChangeMarker(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 493 static JSHandle<JSTaggedValue> EnablePHCProtoChangeMarker( 494 const JSThread *thread, const JSHandle<JSHClass> &protoClass); 495 496 static void NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> oldHclass, JSHandle<JSHClass> newHclass, 497 JSTaggedValue addedKey = JSTaggedValue::Undefined()); 498 499 static void NotifyAccessorChanged(const JSThread *thread, JSHandle<JSHClass> hclass); 500 501 static void RegisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 502 503 static bool UnregisterOnProtoChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 504 505 static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, 506 const JSHandle<JSHClass> &jshclass); 507 508 static JSHandle<ProtoChangeDetails> GetProtoChangeDetails(const JSThread *thread, const JSHandle<JSObject> &obj); 509 510 inline void UpdatePropertyMetaData(const JSThread *thread, const JSTaggedValue &key, 511 const PropertyAttributes &metaData); 512 513 static void MarkProtoChanged(const JSThread *thread, const JSHandle<JSHClass> &jshclass); 514 515 static void NoticeThroughChain(const JSThread *thread, const JSHandle<JSHClass> &jshclass, 516 JSTaggedValue addedKey = JSTaggedValue::Undefined()); 517 518 static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass, 519 const JSHandle<JSHClass> &newHclass); 520 521 static bool IsNeedNotifyHclassChangedForAotTransition(const JSThread *thread, const JSHandle<JSHClass> &hclass, 522 JSTaggedValue key); 523 524 static JSHandle<JSTaggedValue> ParseKeyFromPGOCString(ObjectFactory* factory, 525 const CString& key, 526 const PGOHandler& handler); 527 ClearBitField()528 inline void ClearBitField() 529 { 530 SetProfileType(0ULL); 531 SetBitField(0UL); 532 SetBitField1(0UL); 533 } 534 GetObjectType() const535 inline JSType GetObjectType() const 536 { 537 uint32_t bits = GetBitField(); 538 return ObjectTypeBits::Decode(bits); 539 } 540 SetObjectType(JSType type)541 inline void SetObjectType(JSType type) 542 { 543 uint32_t bits = GetBitField(); 544 uint32_t newVal = ObjectTypeBits::Update(bits, type); 545 SetBitField(newVal); 546 } 547 SetCallable(bool flag)548 inline void SetCallable(bool flag) 549 { 550 CallableBit::Set<uint32_t>(flag, GetBitFieldAddr()); 551 } 552 SetConstructor(bool flag) const553 inline void SetConstructor(bool flag) const 554 { 555 ConstructorBit::Set<uint32_t>(flag, GetBitFieldAddr()); 556 } 557 SetExtensible(bool flag) const558 inline void SetExtensible(bool flag) const 559 { 560 ExtensibleBit::Set<uint32_t>(flag, GetBitFieldAddr()); 561 } 562 SetIsPrototype(bool flag) const563 inline void SetIsPrototype(bool flag) const 564 { 565 IsPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr()); 566 } 567 SetClassConstructor(bool flag) const568 inline void SetClassConstructor(bool flag) const 569 { 570 IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr()); 571 SetConstructor(flag); 572 } 573 SetClassPrototype(bool flag) const574 inline void SetClassPrototype(bool flag) const 575 { 576 IsClassConstructorOrPrototypeBit::Set<uint32_t>(flag, GetBitFieldAddr()); 577 SetIsPrototype(flag); 578 } 579 SetIsNativeBindingObject(bool flag) const580 inline void SetIsNativeBindingObject(bool flag) const 581 { 582 IsNativeBindingObjectBit::Set<uint32_t>(flag, GetBitFieldAddr()); 583 } 584 SetIsDictionaryMode(bool flag) const585 inline void SetIsDictionaryMode(bool flag) const 586 { 587 IsDictionaryBit::Set<uint32_t>(flag, GetBitFieldAddr()); 588 } 589 SetTS(bool flag) const590 inline void SetTS(bool flag) const 591 { 592 IsTSBit::Set<uint32_t>(flag, GetBitFieldAddr()); 593 } 594 SetIsJSFunction(bool flag) const595 inline void SetIsJSFunction(bool flag) const 596 { 597 IsJSFunctionBit::Set<uint32_t>(flag, GetBitFieldAddr()); 598 } 599 SetIsOnHeap(bool flag) const600 inline void SetIsOnHeap(bool flag) const 601 { 602 IsOnHeap::Set<uint32_t>(flag, GetBitFieldAddr()); 603 } 604 IsJSObject() const605 inline bool IsJSObject() const 606 { 607 return IsJSTypeObject(GetObjectType()); 608 } 609 IsOnlyJSObject() const610 inline bool IsOnlyJSObject() const 611 { 612 return GetObjectType() == JSType::JS_OBJECT; 613 } 614 IsECMAObject() const615 inline bool IsECMAObject() const 616 { 617 JSType jsType = GetObjectType(); 618 return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST); 619 } 620 ShouldSetDefaultSupers() const621 inline bool ShouldSetDefaultSupers() const 622 { 623 return IsECMAObject() || IsStringOrSymbol(); 624 } 625 IsRealm() const626 inline bool IsRealm() const 627 { 628 return GetObjectType() == JSType::JS_REALM; 629 } 630 IsHClass() const631 inline bool IsHClass() const 632 { 633 return GetObjectType() == JSType::HCLASS; 634 } 635 IsString() const636 inline bool IsString() const 637 { 638 JSType jsType = GetObjectType(); 639 return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST); 640 } 641 IsLineString() const642 inline bool IsLineString() const 643 { 644 return GetObjectType() == JSType::LINE_STRING; 645 } 646 IsConstantString() const647 inline bool IsConstantString() const 648 { 649 return GetObjectType() == JSType::CONSTANT_STRING; 650 } 651 IsSlicedString() const652 inline bool IsSlicedString() const 653 { 654 return GetObjectType() == JSType::SLICED_STRING; 655 } 656 IsTreeString() const657 inline bool IsTreeString() const 658 { 659 return GetObjectType() == JSType::TREE_STRING; 660 } 661 IsBigInt() const662 inline bool IsBigInt() const 663 { 664 return GetObjectType() == JSType::BIGINT; 665 } 666 IsSymbol() const667 inline bool IsSymbol() const 668 { 669 return GetObjectType() == JSType::SYMBOL; 670 } 671 IsStringOrSymbol() const672 inline bool IsStringOrSymbol() const 673 { 674 JSType jsType = GetObjectType(); 675 return (JSType::STRING_FIRST <= jsType && jsType <= JSType::STRING_LAST) || (jsType == JSType::SYMBOL); 676 } 677 IsTaggedArray() const678 inline bool IsTaggedArray() const 679 { 680 JSType jsType = GetObjectType(); 681 switch (jsType) { 682 case JSType::TAGGED_ARRAY: 683 case JSType::TAGGED_DICTIONARY: 684 case JSType::LEXICAL_ENV: 685 case JSType::SENDABLE_ENV: 686 case JSType::CONSTANT_POOL: 687 case JSType::PROFILE_TYPE_INFO: 688 case JSType::AOT_LITERAL_INFO: 689 case JSType::VTABLE: 690 case JSType::COW_TAGGED_ARRAY: 691 case JSType::MUTANT_TAGGED_ARRAY: 692 case JSType::COW_MUTANT_TAGGED_ARRAY: 693 return true; 694 default: 695 return false; 696 } 697 } 698 IsLexicalEnv() const699 inline bool IsLexicalEnv() const 700 { 701 return GetObjectType() == JSType::LEXICAL_ENV; 702 } IsByteArray() const703 inline bool IsByteArray() const 704 { 705 return GetObjectType() == JSType::BYTE_ARRAY; 706 } 707 IsConstantPool() const708 inline bool IsConstantPool() const 709 { 710 return GetObjectType() == JSType::CONSTANT_POOL; 711 } 712 IsDictionary() const713 inline bool IsDictionary() const 714 { 715 return GetObjectType() == JSType::TAGGED_DICTIONARY; 716 } 717 IsCOWArray() const718 inline bool IsCOWArray() const 719 { 720 // Copy On Write ARRAY. 721 return GetObjectType() == JSType::COW_TAGGED_ARRAY || 722 GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY; 723 } 724 IsMutantTaggedArray() const725 inline bool IsMutantTaggedArray() const 726 { 727 return GetObjectType() == JSType::MUTANT_TAGGED_ARRAY || 728 GetObjectType() == JSType::COW_MUTANT_TAGGED_ARRAY; 729 } 730 IsJSNativePointer() const731 inline bool IsJSNativePointer() const 732 { 733 return GetObjectType() == JSType::JS_NATIVE_POINTER; 734 } 735 IsJSSymbol() const736 inline bool IsJSSymbol() const 737 { 738 return GetObjectType() == JSType::SYMBOL; 739 } 740 IsJSArray() const741 inline bool IsJSArray() const 742 { 743 return GetObjectType() == JSType::JS_ARRAY; 744 } 745 IsTypedArray() const746 inline bool IsTypedArray() const 747 { 748 JSType jsType = GetObjectType(); 749 return (JSType::JS_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_TYPED_ARRAY_LAST); 750 } 751 IsSharedTypedArray() const752 inline bool IsSharedTypedArray() const 753 { 754 JSType jsType = GetObjectType(); 755 return (JSType::JS_SHARED_TYPED_ARRAY_FIRST < jsType && jsType <= JSType::JS_SHARED_TYPED_ARRAY_LAST); 756 } 757 HasOrdinaryGet() const758 inline bool HasOrdinaryGet() const 759 { 760 return (IsSpecialContainer() || IsModuleNamespace() || IsBigInt64Array()); 761 } 762 IsJSTypedArray() const763 inline bool IsJSTypedArray() const 764 { 765 return GetObjectType() == JSType::JS_TYPED_ARRAY; 766 } 767 IsJSInt8Array() const768 inline bool IsJSInt8Array() const 769 { 770 return GetObjectType() == JSType::JS_INT8_ARRAY; 771 } 772 IsJSUint8Array() const773 inline bool IsJSUint8Array() const 774 { 775 return GetObjectType() == JSType::JS_UINT8_ARRAY; 776 } 777 IsJSUint8ClampedArray() const778 inline bool IsJSUint8ClampedArray() const 779 { 780 return GetObjectType() == JSType::JS_UINT8_CLAMPED_ARRAY; 781 } 782 IsJSInt16Array() const783 inline bool IsJSInt16Array() const 784 { 785 return GetObjectType() == JSType::JS_INT16_ARRAY; 786 } 787 IsJSUint16Array() const788 inline bool IsJSUint16Array() const 789 { 790 return GetObjectType() == JSType::JS_UINT16_ARRAY; 791 } 792 IsJSInt32Array() const793 inline bool IsJSInt32Array() const 794 { 795 return GetObjectType() == JSType::JS_INT32_ARRAY; 796 } 797 IsJSUint32Array() const798 inline bool IsJSUint32Array() const 799 { 800 return GetObjectType() == JSType::JS_UINT32_ARRAY; 801 } 802 IsJSFloat32Array() const803 inline bool IsJSFloat32Array() const 804 { 805 return GetObjectType() == JSType::JS_FLOAT32_ARRAY; 806 } 807 IsJSFloat64Array() const808 inline bool IsJSFloat64Array() const 809 { 810 return GetObjectType() == JSType::JS_FLOAT64_ARRAY; 811 } 812 IsJSBigInt64Array() const813 inline bool IsJSBigInt64Array() const 814 { 815 return GetObjectType() == JSType::JS_BIGINT64_ARRAY; 816 } 817 IsJSBigUint64Array() const818 inline bool IsJSBigUint64Array() const 819 { 820 return GetObjectType() == JSType::JS_BIGUINT64_ARRAY; 821 } 822 IsJSSharedTypedArray() const823 inline bool IsJSSharedTypedArray() const 824 { 825 return GetObjectType() == JSType::JS_SHARED_TYPED_ARRAY; 826 } 827 IsJSSharedInt8Array() const828 inline bool IsJSSharedInt8Array() const 829 { 830 return GetObjectType() == JSType::JS_SHARED_INT8_ARRAY; 831 } 832 IsJSSharedUint8Array() const833 inline bool IsJSSharedUint8Array() const 834 { 835 return GetObjectType() == JSType::JS_SHARED_UINT8_ARRAY; 836 } 837 IsJSSharedUint8ClampedArray() const838 inline bool IsJSSharedUint8ClampedArray() const 839 { 840 return GetObjectType() == JSType::JS_SHARED_UINT8_CLAMPED_ARRAY; 841 } 842 IsJSSharedInt16Array() const843 inline bool IsJSSharedInt16Array() const 844 { 845 return GetObjectType() == JSType::JS_SHARED_INT16_ARRAY; 846 } 847 IsJSSharedUint16Array() const848 inline bool IsJSSharedUint16Array() const 849 { 850 return GetObjectType() == JSType::JS_SHARED_UINT16_ARRAY; 851 } 852 IsJSSharedInt32Array() const853 inline bool IsJSSharedInt32Array() const 854 { 855 return GetObjectType() == JSType::JS_SHARED_INT32_ARRAY; 856 } 857 IsJSSharedUint32Array() const858 inline bool IsJSSharedUint32Array() const 859 { 860 return GetObjectType() == JSType::JS_SHARED_UINT32_ARRAY; 861 } 862 IsJSSharedFloat32Array() const863 inline bool IsJSSharedFloat32Array() const 864 { 865 return GetObjectType() == JSType::JS_SHARED_FLOAT32_ARRAY; 866 } 867 IsJSSharedFloat64Array() const868 inline bool IsJSSharedFloat64Array() const 869 { 870 return GetObjectType() == JSType::JS_SHARED_FLOAT64_ARRAY; 871 } 872 IsJSSharedBigInt64Array() const873 inline bool IsJSSharedBigInt64Array() const 874 { 875 return GetObjectType() == JSType::JS_SHARED_BIGINT64_ARRAY; 876 } 877 IsJSSharedBigUint64Array() const878 inline bool IsJSSharedBigUint64Array() const 879 { 880 return GetObjectType() == JSType::JS_SHARED_BIGUINT64_ARRAY; 881 } 882 IsBigInt64Array() const883 inline bool IsBigInt64Array() const 884 { 885 JSType jsType = GetObjectType(); 886 return jsType == JSType::JS_SHARED_BIGUINT64_ARRAY || jsType == JSType::JS_SHARED_BIGINT64_ARRAY || 887 jsType == JSType::JS_BIGUINT64_ARRAY || jsType == JSType::JS_BIGINT64_ARRAY; 888 } 889 IsJsGlobalEnv() const890 inline bool IsJsGlobalEnv() const 891 { 892 return GetObjectType() == JSType::GLOBAL_ENV; 893 } 894 IsJSFunctionBase() const895 inline bool IsJSFunctionBase() const 896 { 897 JSType jsType = GetObjectType(); 898 return jsType >= JSType::JS_FUNCTION_BASE && jsType <= JSType::JS_BOUND_FUNCTION; 899 } 900 IsJsBoundFunction() const901 inline bool IsJsBoundFunction() const 902 { 903 return GetObjectType() == JSType::JS_BOUND_FUNCTION; 904 } 905 IsJSIntlBoundFunction() const906 inline bool IsJSIntlBoundFunction() const 907 { 908 return GetObjectType() == JSType::JS_INTL_BOUND_FUNCTION; 909 } 910 IsJSProxyRevocFunction() const911 inline bool IsJSProxyRevocFunction() const 912 { 913 return GetObjectType() == JSType::JS_PROXY_REVOC_FUNCTION; 914 } 915 IsJSAsyncFunction() const916 inline bool IsJSAsyncFunction() const 917 { 918 return GetObjectType() == JSType::JS_ASYNC_FUNCTION || GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION; 919 } 920 IsJSSharedAsyncFunction() const921 inline bool IsJSSharedAsyncFunction() const 922 { 923 return GetObjectType() == JSType::JS_SHARED_ASYNC_FUNCTION; 924 } 925 IsJSAsyncAwaitStatusFunction() const926 inline bool IsJSAsyncAwaitStatusFunction() const 927 { 928 return GetObjectType() == JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION; 929 } 930 IsJSPromiseReactionFunction() const931 inline bool IsJSPromiseReactionFunction() const 932 { 933 return GetObjectType() == JSType::JS_PROMISE_REACTIONS_FUNCTION; 934 } 935 IsJSPromiseExecutorFunction() const936 inline bool IsJSPromiseExecutorFunction() const 937 { 938 return GetObjectType() == JSType::JS_PROMISE_EXECUTOR_FUNCTION; 939 } 940 IsJSAsyncModuleFulfilledFunction() const941 inline bool IsJSAsyncModuleFulfilledFunction() const 942 { 943 return GetObjectType() == JSType::JS_ASYNC_MODULE_FULFILLED_FUNCTION; 944 } 945 IsJSAsyncModuleRejectedFunction() const946 inline bool IsJSAsyncModuleRejectedFunction() const 947 { 948 return GetObjectType() == JSType::JS_ASYNC_MODULE_REJECTED_FUNCTION; 949 } 950 IsJSAsyncFromSyncIterUnwarpFunction() const951 inline bool IsJSAsyncFromSyncIterUnwarpFunction() const 952 { 953 return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITER_UNWARP_FUNCTION; 954 } 955 IsJSPromiseAllResolveElementFunction() const956 inline bool IsJSPromiseAllResolveElementFunction() const 957 { 958 return GetObjectType() == JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION; 959 } 960 IsJSAsyncGeneratorResNextRetProRstFtn() const961 inline bool IsJSAsyncGeneratorResNextRetProRstFtn() const 962 { 963 return GetObjectType() == JSType::JS_ASYNC_GENERATOR_RESUME_NEXT_RETURN_PROCESSOR_RST_FTN; 964 } 965 IsJSPromiseAnyRejectElementFunction() const966 inline bool IsJSPromiseAnyRejectElementFunction() const 967 { 968 return GetObjectType() == JSType::JS_PROMISE_ANY_REJECT_ELEMENT_FUNCTION; 969 } 970 IsJSPromiseAllSettledElementFunction() const971 inline bool IsJSPromiseAllSettledElementFunction() const 972 { 973 return GetObjectType() == JSType::JS_PROMISE_ALL_SETTLED_ELEMENT_FUNCTION; 974 } 975 IsJSPromiseFinallyFunction() const976 inline bool IsJSPromiseFinallyFunction() const 977 { 978 return GetObjectType() == JSType::JS_PROMISE_FINALLY_FUNCTION; 979 } 980 IsJSPromiseValueThunkOrThrowerFunction() const981 inline bool IsJSPromiseValueThunkOrThrowerFunction() const 982 { 983 return GetObjectType() == JSType::JS_PROMISE_VALUE_THUNK_OR_THROWER_FUNCTION; 984 } 985 IsMicroJobQueue() const986 inline bool IsMicroJobQueue() const 987 { 988 return GetObjectType() == JSType::MICRO_JOB_QUEUE; 989 } 990 IsPendingJob() const991 inline bool IsPendingJob() const 992 { 993 return GetObjectType() == JSType::PENDING_JOB; 994 } 995 IsJsPrimitiveRef() const996 inline bool IsJsPrimitiveRef() const 997 { 998 return GetObjectType() == JSType::JS_PRIMITIVE_REF; 999 } 1000 IsJSSet() const1001 bool IsJSSet() const 1002 { 1003 return GetObjectType() == JSType::JS_SET; 1004 } 1005 IsJSSharedSet() const1006 bool IsJSSharedSet() const 1007 { 1008 return GetObjectType() == JSType::JS_SHARED_SET; 1009 } 1010 IsJSMap() const1011 bool IsJSMap() const 1012 { 1013 return GetObjectType() == JSType::JS_MAP; 1014 } 1015 IsJSSharedMap() const1016 bool IsJSSharedMap() const 1017 { 1018 return GetObjectType() == JSType::JS_SHARED_MAP; 1019 } 1020 IsJSWeakMap() const1021 bool IsJSWeakMap() const 1022 { 1023 return GetObjectType() == JSType::JS_WEAK_MAP; 1024 } 1025 IsJSWeakSet() const1026 bool IsJSWeakSet() const 1027 { 1028 return GetObjectType() == JSType::JS_WEAK_SET; 1029 } 1030 IsJSWeakRef() const1031 bool IsJSWeakRef() const 1032 { 1033 return GetObjectType() == JSType::JS_WEAK_REF; 1034 } 1035 IsJSFinalizationRegistry() const1036 bool IsJSFinalizationRegistry() const 1037 { 1038 return GetObjectType() == JSType::JS_FINALIZATION_REGISTRY; 1039 } 1040 IsJSFunction() const1041 bool IsJSFunction() const 1042 { 1043 return GetObjectType() >= JSType::JS_FUNCTION_FIRST && GetObjectType() <= JSType::JS_FUNCTION_LAST; 1044 } 1045 IsJSSharedFunction() const1046 bool IsJSSharedFunction() const 1047 { 1048 return GetObjectType() == JSType::JS_SHARED_FUNCTION; 1049 } 1050 IsJSShared() const1051 bool IsJSShared() const 1052 { 1053 uint32_t bits = GetBitField(); 1054 return IsJSSharedBit::Decode(bits); 1055 } 1056 SetIsJSShared(bool flag) const1057 inline void SetIsJSShared(bool flag) const 1058 { 1059 IsJSSharedBit::Set<uint32_t>(flag, GetBitFieldAddr()); 1060 } 1061 IsJSError() const1062 inline bool IsJSError() const 1063 { 1064 JSType jsType = GetObjectType(); 1065 return jsType >= JSType::JS_ERROR_FIRST && jsType <= JSType::JS_ERROR_LAST; 1066 } 1067 IsArguments() const1068 inline bool IsArguments() const 1069 { 1070 return GetObjectType() == JSType::JS_ARGUMENTS; 1071 } 1072 IsDate() const1073 inline bool IsDate() const 1074 { 1075 return GetObjectType() == JSType::JS_DATE; 1076 } 1077 IsJSRegExp() const1078 inline bool IsJSRegExp() const 1079 { 1080 return GetObjectType() == JSType::JS_REG_EXP; 1081 } 1082 IsJSProxy() const1083 inline bool IsJSProxy() const 1084 { 1085 return GetObjectType() == JSType::JS_PROXY; 1086 } 1087 IsJSLocale() const1088 inline bool IsJSLocale() const 1089 { 1090 return GetObjectType() == JSType::JS_LOCALE; 1091 } 1092 IsJSIntl() const1093 inline bool IsJSIntl() const 1094 { 1095 return GetObjectType() == JSType::JS_INTL; 1096 } 1097 IsJSDateTimeFormat() const1098 inline bool IsJSDateTimeFormat() const 1099 { 1100 return GetObjectType() == JSType::JS_DATE_TIME_FORMAT; 1101 } 1102 IsJSRelativeTimeFormat() const1103 inline bool IsJSRelativeTimeFormat() const 1104 { 1105 return GetObjectType() == JSType::JS_RELATIVE_TIME_FORMAT; 1106 } 1107 IsJSNumberFormat() const1108 inline bool IsJSNumberFormat() const 1109 { 1110 return GetObjectType() == JSType::JS_NUMBER_FORMAT; 1111 } 1112 IsJSCollator() const1113 inline bool IsJSCollator() const 1114 { 1115 return GetObjectType() == JSType::JS_COLLATOR; 1116 } 1117 IsJSPluralRules() const1118 inline bool IsJSPluralRules() const 1119 { 1120 return GetObjectType() == JSType::JS_PLURAL_RULES; 1121 } 1122 IsJSDisplayNames() const1123 inline bool IsJSDisplayNames() const 1124 { 1125 return GetObjectType() == JSType::JS_DISPLAYNAMES; 1126 } 1127 IsJSSegmenter() const1128 inline bool IsJSSegmenter() const 1129 { 1130 return GetObjectType() == JSType::JS_SEGMENTER; 1131 } 1132 IsJSSegments() const1133 inline bool IsJSSegments() const 1134 { 1135 return GetObjectType() == JSType::JS_SEGMENTS; 1136 } 1137 IsJSSegmentIterator() const1138 inline bool IsJSSegmentIterator() const 1139 { 1140 return GetObjectType() == JSType::JS_SEGMENT_ITERATOR; 1141 } 1142 IsJSListFormat() const1143 inline bool IsJSListFormat() const 1144 { 1145 return GetObjectType() == JSType::JS_LIST_FORMAT; 1146 } 1147 IsMethod() const1148 inline bool IsMethod() const 1149 { 1150 return GetObjectType() == JSType::METHOD; 1151 } 1152 IsClassLiteral() const1153 inline bool IsClassLiteral() const 1154 { 1155 return GetObjectType() == JSType::CLASS_LITERAL; 1156 } 1157 1158 // non ECMA standard jsapi containers. IsSpecialContainer() const1159 inline bool IsSpecialContainer() const 1160 { 1161 return GetObjectType() >= JSType::JS_API_ARRAY_LIST && GetObjectType() <= JSType::JS_API_QUEUE; 1162 } 1163 IsRegularObject() const1164 inline bool IsRegularObject() const 1165 { 1166 return GetObjectType() < JSType::JS_API_ARRAY_LIST; 1167 } 1168 IsJSAPIArrayList() const1169 inline bool IsJSAPIArrayList() const 1170 { 1171 return GetObjectType() == JSType::JS_API_ARRAY_LIST; 1172 } 1173 IsJSAPIArrayListIterator() const1174 inline bool IsJSAPIArrayListIterator() const 1175 { 1176 return GetObjectType() == JSType::JS_API_ARRAYLIST_ITERATOR; 1177 } IsJSAPILightWeightMap() const1178 inline bool IsJSAPILightWeightMap() const 1179 { 1180 return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP; 1181 } IsJSAPILightWeightMapIterator() const1182 inline bool IsJSAPILightWeightMapIterator() const 1183 { 1184 return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_MAP_ITERATOR; 1185 } IsJSAPILightWeightSet() const1186 inline bool IsJSAPILightWeightSet() const 1187 { 1188 return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET; 1189 } IsJSAPILightWeightSetIterator() const1190 inline bool IsJSAPILightWeightSetIterator() const 1191 { 1192 return GetObjectType() == JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR; 1193 } IsJSAPIStack() const1194 inline bool IsJSAPIStack() const 1195 { 1196 return GetObjectType() == JSType::JS_API_STACK; 1197 } IsJSAPIDeque() const1198 inline bool IsJSAPIDeque() const 1199 { 1200 return GetObjectType() == JSType::JS_API_DEQUE; 1201 } IsLinkedNode() const1202 inline bool IsLinkedNode() const 1203 { 1204 return GetObjectType() == JSType::LINKED_NODE; 1205 } 1206 IsRBTreeNode() const1207 inline bool IsRBTreeNode() const 1208 { 1209 return GetObjectType() == JSType::RB_TREENODE; 1210 } 1211 IsJSAPIHashMap() const1212 inline bool IsJSAPIHashMap() const 1213 { 1214 return GetObjectType() == JSType::JS_API_HASH_MAP; 1215 } 1216 IsJSAPIHashSet() const1217 inline bool IsJSAPIHashSet() const 1218 { 1219 return GetObjectType() == JSType::JS_API_HASH_SET; 1220 } 1221 IsJSAPIHashMapIterator() const1222 inline bool IsJSAPIHashMapIterator() const 1223 { 1224 return GetObjectType() == JSType::JS_API_HASHMAP_ITERATOR; 1225 } 1226 IsJSAPIHashSetIterator() const1227 inline bool IsJSAPIHashSetIterator() const 1228 { 1229 return GetObjectType() == JSType::JS_API_HASHSET_ITERATOR; 1230 } IsJSAPIQueue() const1231 inline bool IsJSAPIQueue() const 1232 { 1233 return GetObjectType() == JSType::JS_API_QUEUE; 1234 } 1235 IsJSAPIPlainArray() const1236 inline bool IsJSAPIPlainArray() const 1237 { 1238 return GetObjectType() == JSType::JS_API_PLAIN_ARRAY; 1239 } 1240 IsJSAPIQueueIterator() const1241 inline bool IsJSAPIQueueIterator() const 1242 { 1243 return GetObjectType() == JSType::JS_API_QUEUE_ITERATOR; 1244 } IsJSAPIList() const1245 inline bool IsJSAPIList() const 1246 { 1247 return GetObjectType() == JSType::JS_API_LIST; 1248 } IsJSAPILinkedList() const1249 inline bool IsJSAPILinkedList() const 1250 { 1251 return GetObjectType() == JSType::JS_API_LINKED_LIST; 1252 } IsJSAPITreeMap() const1253 inline bool IsJSAPITreeMap() const 1254 { 1255 return GetObjectType() == JSType::JS_API_TREE_MAP; 1256 } 1257 IsJSAPITreeSet() const1258 inline bool IsJSAPITreeSet() const 1259 { 1260 return GetObjectType() == JSType::JS_API_TREE_SET; 1261 } 1262 IsJSAPITreeMapIterator() const1263 inline bool IsJSAPITreeMapIterator() const 1264 { 1265 return GetObjectType() == JSType::JS_API_TREEMAP_ITERATOR; 1266 } 1267 IsJSAPITreeSetIterator() const1268 inline bool IsJSAPITreeSetIterator() const 1269 { 1270 return GetObjectType() == JSType::JS_API_TREESET_ITERATOR; 1271 } IsJSAPIVector() const1272 inline bool IsJSAPIVector() const 1273 { 1274 return GetObjectType() == JSType::JS_API_VECTOR; 1275 } IsJSAPIVectorIterator() const1276 inline bool IsJSAPIVectorIterator() const 1277 { 1278 return GetObjectType() == JSType::JS_API_VECTOR_ITERATOR; 1279 } IsJSAPIBitVector() const1280 inline bool IsJSAPIBitVector() const 1281 { 1282 return GetObjectType() == JSType::JS_API_BITVECTOR; 1283 } IsJSAPIBitVectorIterator() const1284 inline bool IsJSAPIBitVectorIterator() const 1285 { 1286 return GetObjectType() == JSType::JS_API_BITVECTOR_ITERATOR; 1287 } 1288 IsAccessorData() const1289 inline bool IsAccessorData() const 1290 { 1291 return GetObjectType() == JSType::ACCESSOR_DATA; 1292 } 1293 IsInternalAccessor() const1294 inline bool IsInternalAccessor() const 1295 { 1296 return GetObjectType() == JSType::INTERNAL_ACCESSOR; 1297 } 1298 IsIterator() const1299 inline bool IsIterator() const 1300 { 1301 JSType jsType = GetObjectType(); 1302 return jsType >= JSType::JS_ITERATOR_FIRST && jsType <= JSType::JS_ITERATOR_LAST; 1303 } 1304 IsAsyncIterator() const1305 inline bool IsAsyncIterator() const 1306 { 1307 return GetObjectType() == JSType::JS_ASYNCITERATOR; 1308 } 1309 IsAsyncFromSyncIterator() const1310 inline bool IsAsyncFromSyncIterator() const 1311 { 1312 return GetObjectType() == JSType::JS_ASYNC_FROM_SYNC_ITERATOR; 1313 } 1314 IsForinIterator() const1315 inline bool IsForinIterator() const 1316 { 1317 return GetObjectType() == JSType::JS_FORIN_ITERATOR; 1318 } 1319 IsStringIterator() const1320 inline bool IsStringIterator() const 1321 { 1322 return GetObjectType() == JSType::JS_STRING_ITERATOR; 1323 } 1324 IsArrayBuffer() const1325 inline bool IsArrayBuffer() const 1326 { 1327 return GetObjectType() == JSType::JS_ARRAY_BUFFER; 1328 } 1329 IsSharedArrayBuffer() const1330 inline bool IsSharedArrayBuffer() const 1331 { 1332 return GetObjectType() == JSType::JS_SHARED_ARRAY_BUFFER; 1333 } 1334 IsSendableArrayBuffer() const1335 inline bool IsSendableArrayBuffer() const 1336 { 1337 return GetObjectType() == JSType::JS_SENDABLE_ARRAY_BUFFER; 1338 } 1339 IsDataView() const1340 inline bool IsDataView() const 1341 { 1342 return GetObjectType() == JSType::JS_DATA_VIEW; 1343 } 1344 IsJSSetIterator() const1345 inline bool IsJSSetIterator() const 1346 { 1347 return GetObjectType() == JSType::JS_SET_ITERATOR; 1348 } 1349 1350 // iterator of shared set IsJSSharedSetIterator() const1351 inline bool IsJSSharedSetIterator() const 1352 { 1353 return GetObjectType() == JSType::JS_SHARED_SET_ITERATOR; 1354 } 1355 IsJSRegExpIterator() const1356 inline bool IsJSRegExpIterator() const 1357 { 1358 return GetObjectType() == JSType::JS_REG_EXP_ITERATOR; 1359 } 1360 IsJSMapIterator() const1361 inline bool IsJSMapIterator() const 1362 { 1363 return GetObjectType() == JSType::JS_MAP_ITERATOR; 1364 } 1365 1366 // iterator of shared map IsJSSharedMapIterator() const1367 inline bool IsJSSharedMapIterator() const 1368 { 1369 return GetObjectType() == JSType::JS_SHARED_MAP_ITERATOR; 1370 } 1371 IsJSArrayIterator() const1372 inline bool IsJSArrayIterator() const 1373 { 1374 return GetObjectType() == JSType::JS_ARRAY_ITERATOR; 1375 } 1376 IsJSSharedArrayIterator() const1377 inline bool IsJSSharedArrayIterator() const 1378 { 1379 return GetObjectType() == JSType::JS_SHARED_ARRAY_ITERATOR; 1380 } 1381 IsJSAPIPlainArrayIterator() const1382 inline bool IsJSAPIPlainArrayIterator() const 1383 { 1384 return GetObjectType() == JSType::JS_API_PLAIN_ARRAY_ITERATOR; 1385 } 1386 IsJSAPIDequeIterator() const1387 inline bool IsJSAPIDequeIterator() const 1388 { 1389 return GetObjectType() == JSType::JS_API_DEQUE_ITERATOR; 1390 } 1391 IsJSAPIStackIterator() const1392 inline bool IsJSAPIStackIterator() const 1393 { 1394 return GetObjectType() == JSType::JS_API_STACK_ITERATOR; 1395 } 1396 IsJSAPILinkedListIterator() const1397 inline bool IsJSAPILinkedListIterator() const 1398 { 1399 return GetObjectType() == JSType::JS_API_LINKED_LIST_ITERATOR; 1400 } 1401 IsJSAPIListIterator() const1402 inline bool IsJSAPIListIterator() const 1403 { 1404 return GetObjectType() == JSType::JS_API_LIST_ITERATOR; 1405 } 1406 IsPrototypeHandler() const1407 inline bool IsPrototypeHandler() const 1408 { 1409 return GetObjectType() == JSType::PROTOTYPE_HANDLER; 1410 } 1411 IsTransitionHandler() const1412 inline bool IsTransitionHandler() const 1413 { 1414 return GetObjectType() == JSType::TRANSITION_HANDLER; 1415 } 1416 IsTransWithProtoHandler() const1417 inline bool IsTransWithProtoHandler() const 1418 { 1419 return GetObjectType() == JSType::TRANS_WITH_PROTO_HANDLER; 1420 } 1421 IsStoreTSHandler() const1422 inline bool IsStoreTSHandler() const 1423 { 1424 return GetObjectType() == JSType::STORE_TS_HANDLER; 1425 } 1426 IsPropertyBox() const1427 inline bool IsPropertyBox() const 1428 { 1429 return GetObjectType() == JSType::PROPERTY_BOX; 1430 } IsProtoChangeMarker() const1431 inline bool IsProtoChangeMarker() const 1432 { 1433 return GetObjectType() == JSType::PROTO_CHANGE_MARKER; 1434 } 1435 IsMarkerCell() const1436 inline bool IsMarkerCell() const 1437 { 1438 return GetObjectType() == JSType::MARKER_CELL; 1439 } 1440 IsTrackInfoObject() const1441 inline bool IsTrackInfoObject() const 1442 { 1443 return GetObjectType() == JSType::TRACK_INFO; 1444 } 1445 IsProtoChangeDetails() const1446 inline bool IsProtoChangeDetails() const 1447 { 1448 return GetObjectType() == JSType::PROTOTYPE_INFO; 1449 } 1450 IsProgram() const1451 inline bool IsProgram() const 1452 { 1453 return GetObjectType() == JSType::PROGRAM; 1454 } 1455 IsClassInfoExtractor() const1456 inline bool IsClassInfoExtractor() const 1457 { 1458 return GetObjectType() == JSType::CLASS_INFO_EXTRACTOR; 1459 } 1460 IsCallable() const1461 inline bool IsCallable() const 1462 { 1463 uint32_t bits = GetBitField(); 1464 return CallableBit::Decode(bits); 1465 } 1466 IsConstructor() const1467 inline bool IsConstructor() const 1468 { 1469 uint32_t bits = GetBitField(); 1470 return ConstructorBit::Decode(bits); 1471 } 1472 IsExtensible() const1473 inline bool IsExtensible() const 1474 { 1475 uint32_t bits = GetBitField(); 1476 return ExtensibleBit::Decode(bits); 1477 } 1478 IsPrototype() const1479 inline bool IsPrototype() const 1480 { 1481 uint32_t bits = GetBitField(); 1482 return IsPrototypeBit::Decode(bits); 1483 } 1484 IsClassConstructor() const1485 inline bool IsClassConstructor() const 1486 { 1487 uint32_t bits = GetBitField(); 1488 return IsClassConstructorOrPrototypeBit::Decode(bits) && IsConstructor(); 1489 } 1490 IsJSGlobalObject() const1491 inline bool IsJSGlobalObject() const 1492 { 1493 return GetObjectType() == JSType::JS_GLOBAL_OBJECT; 1494 } 1495 IsClassPrototype() const1496 inline bool IsClassPrototype() const 1497 { 1498 uint32_t bits = GetBitField(); 1499 return IsClassConstructorOrPrototypeBit::Decode(bits) && IsPrototype(); 1500 } 1501 IsNativeBindingObject() const1502 inline bool IsNativeBindingObject() const 1503 { 1504 uint32_t bits = GetBitField(); 1505 return IsNativeBindingObjectBit::Decode(bits); 1506 } 1507 IsDictionaryMode() const1508 inline bool IsDictionaryMode() const 1509 { 1510 uint32_t bits = GetBitField(); 1511 return IsDictionaryBit::Decode(bits); 1512 } 1513 1514 // created from TypeScript Types IsTS() const1515 inline bool IsTS() const 1516 { 1517 uint32_t bits = GetBitField(); 1518 return IsTSBit::Decode(bits); 1519 } 1520 IsJSFunctionFromBitField() const1521 inline bool IsJSFunctionFromBitField() const 1522 { 1523 uint32_t bits = GetBitField(); 1524 return IsJSFunctionBit::Decode(bits); 1525 } 1526 IsOnHeapFromBitField() const1527 inline bool IsOnHeapFromBitField() const 1528 { 1529 uint32_t bits = GetBitField(); 1530 return IsOnHeap::Decode(bits); 1531 } 1532 IsGeneratorFunction() const1533 inline bool IsGeneratorFunction() const 1534 { 1535 return GetObjectType() == JSType::JS_GENERATOR_FUNCTION; 1536 } 1537 IsAsyncGeneratorFunction() const1538 inline bool IsAsyncGeneratorFunction() const 1539 { 1540 return GetObjectType() == JSType::JS_ASYNC_GENERATOR_FUNCTION; 1541 } 1542 IsGeneratorObject() const1543 inline bool IsGeneratorObject() const 1544 { 1545 JSType jsType = GetObjectType(); 1546 return jsType == JSType::JS_GENERATOR_OBJECT || jsType == JSType::JS_ASYNC_FUNC_OBJECT; 1547 } 1548 IsAsyncGeneratorObject() const1549 inline bool IsAsyncGeneratorObject() const 1550 { 1551 JSType jsType = GetObjectType(); 1552 return jsType == JSType::JS_ASYNC_GENERATOR_OBJECT; 1553 } 1554 IsGeneratorContext() const1555 inline bool IsGeneratorContext() const 1556 { 1557 return GetObjectType() == JSType::JS_GENERATOR_CONTEXT; 1558 } 1559 IsAsyncGeneratorRequest() const1560 inline bool IsAsyncGeneratorRequest() const 1561 { 1562 JSType jsType = GetObjectType(); 1563 return jsType == JSType::ASYNC_GENERATOR_REQUEST; 1564 } 1565 IsAsyncIteratorRecord() const1566 inline bool IsAsyncIteratorRecord() const 1567 { 1568 JSType jsType = GetObjectType(); 1569 return jsType == JSType::ASYNC_ITERATOR_RECORD; 1570 } 1571 IsAsyncFuncObject() const1572 inline bool IsAsyncFuncObject() const 1573 { 1574 return GetObjectType() == JSType::JS_ASYNC_FUNC_OBJECT; 1575 } 1576 IsJSPromise() const1577 inline bool IsJSPromise() const 1578 { 1579 return GetObjectType() == JSType::JS_PROMISE; 1580 } 1581 IsResolvingFunctionsRecord() const1582 inline bool IsResolvingFunctionsRecord() const 1583 { 1584 return GetObjectType() == JSType::RESOLVING_FUNCTIONS_RECORD; 1585 } 1586 IsPromiseRecord() const1587 inline bool IsPromiseRecord() const 1588 { 1589 return GetObjectType() == JSType::PROMISE_RECORD; 1590 } 1591 IsPromiseIteratorRecord() const1592 inline bool IsPromiseIteratorRecord() const 1593 { 1594 return GetObjectType() == JSType::PROMISE_ITERATOR_RECORD; 1595 } 1596 IsPromiseCapability() const1597 inline bool IsPromiseCapability() const 1598 { 1599 return GetObjectType() == JSType::PROMISE_CAPABILITY; 1600 } 1601 IsPromiseReaction() const1602 inline bool IsPromiseReaction() const 1603 { 1604 return GetObjectType() == JSType::PROMISE_REACTIONS; 1605 } 1606 IsCellRecord() const1607 inline bool IsCellRecord() const 1608 { 1609 return GetObjectType() == JSType::CELL_RECORD; 1610 } 1611 IsCompletionRecord() const1612 inline bool IsCompletionRecord() const 1613 { 1614 return GetObjectType() == JSType::COMPLETION_RECORD; 1615 } 1616 IsRecord() const1617 inline bool IsRecord() const 1618 { 1619 JSType jsType = GetObjectType(); 1620 return jsType >= JSType::JS_RECORD_FIRST && jsType <= JSType::JS_RECORD_LAST; 1621 } 1622 IsTemplateMap() const1623 inline bool IsTemplateMap() const 1624 { 1625 return GetObjectType() == JSType::TEMPLATE_MAP; 1626 } 1627 IsFreeObject() const1628 inline bool IsFreeObject() const 1629 { 1630 JSType t = GetObjectType(); 1631 return (t >= JSType::FREE_OBJECT_WITH_ONE_FIELD) && (t <= JSType::FREE_OBJECT_WITH_TWO_FIELD); 1632 } 1633 IsFreeObjectWithShortField() const1634 inline bool IsFreeObjectWithShortField() const 1635 { 1636 switch (GetObjectType()) { 1637 case JSType::FREE_OBJECT_WITH_ONE_FIELD: 1638 case JSType::FREE_OBJECT_WITH_NONE_FIELD: 1639 return true; 1640 default: 1641 return false; 1642 } 1643 } 1644 IsFreeObjectWithOneField() const1645 inline bool IsFreeObjectWithOneField() const 1646 { 1647 return GetObjectType() == JSType::FREE_OBJECT_WITH_ONE_FIELD; 1648 } 1649 IsFreeObjectWithNoneField() const1650 inline bool IsFreeObjectWithNoneField() const 1651 { 1652 return GetObjectType() == JSType::FREE_OBJECT_WITH_NONE_FIELD; 1653 } 1654 IsFreeObjectWithTwoField() const1655 inline bool IsFreeObjectWithTwoField() const 1656 { 1657 return GetObjectType() == JSType::FREE_OBJECT_WITH_TWO_FIELD; 1658 } 1659 IsMachineCodeObject() const1660 inline bool IsMachineCodeObject() const 1661 { 1662 return GetObjectType() == JSType::MACHINE_CODE_OBJECT; 1663 } 1664 IsAOTLiteralInfo() const1665 inline bool IsAOTLiteralInfo() const 1666 { 1667 return GetObjectType() == JSType::AOT_LITERAL_INFO; 1668 } 1669 IsExtraProfileTypeInfo() const1670 inline bool IsExtraProfileTypeInfo() const 1671 { 1672 return GetObjectType() == JSType::EXTRA_PROFILE_TYPE_INFO; 1673 } 1674 IsProfileTypeInfoCell() const1675 inline bool IsProfileTypeInfoCell() const 1676 { 1677 JSType jsType = GetObjectType(); 1678 return jsType >= JSType::PROFILE_TYPE_INFO_CELL_FIRST && jsType <= JSType::PROFILE_TYPE_INFO_CELL_LAST; 1679 } 1680 IsProfileTypeInfoCell0() const1681 inline bool IsProfileTypeInfoCell0() const 1682 { 1683 JSType jsType = GetObjectType(); 1684 return jsType == JSType::PROFILE_TYPE_INFO_CELL_0; 1685 } 1686 IsFunctionTemplate() const1687 inline bool IsFunctionTemplate() const 1688 { 1689 JSType jsType = GetObjectType(); 1690 return jsType == JSType::FUNCTION_TEMPLATE; 1691 } 1692 IsVTable() const1693 inline bool IsVTable() const 1694 { 1695 return GetObjectType() == JSType::VTABLE; 1696 } 1697 IsModuleRecord() const1698 inline bool IsModuleRecord() const 1699 { 1700 JSType jsType = GetObjectType(); 1701 return jsType >= JSType::MODULE_RECORD_FIRST && jsType <= JSType::MODULE_RECORD_LAST; 1702 } 1703 IsSourceTextModule() const1704 inline bool IsSourceTextModule() const 1705 { 1706 return GetObjectType() == JSType::SOURCE_TEXT_MODULE_RECORD; 1707 } 1708 IsCjsExports() const1709 inline bool IsCjsExports() const 1710 { 1711 return GetObjectType() == JSType::JS_CJS_EXPORTS; 1712 } 1713 IsCjsModule() const1714 inline bool IsCjsModule() const 1715 { 1716 return GetObjectType() == JSType::JS_CJS_MODULE; 1717 } 1718 IsCjsRequire() const1719 inline bool IsCjsRequire() const 1720 { 1721 return GetObjectType() == JSType::JS_CJS_REQUIRE; 1722 } 1723 IsImportEntry() const1724 inline bool IsImportEntry() const 1725 { 1726 return GetObjectType() == JSType::IMPORTENTRY_RECORD; 1727 } 1728 IsLocalExportEntry() const1729 inline bool IsLocalExportEntry() const 1730 { 1731 return GetObjectType() == JSType::LOCAL_EXPORTENTRY_RECORD; 1732 } 1733 IsIndirectExportEntry() const1734 inline bool IsIndirectExportEntry() const 1735 { 1736 return GetObjectType() == JSType::INDIRECT_EXPORTENTRY_RECORD; 1737 } 1738 IsStarExportEntry() const1739 inline bool IsStarExportEntry() const 1740 { 1741 return GetObjectType() == JSType::STAR_EXPORTENTRY_RECORD; 1742 } 1743 IsResolvedBinding() const1744 inline bool IsResolvedBinding() const 1745 { 1746 return GetObjectType() == JSType::RESOLVEDBINDING_RECORD; 1747 } 1748 IsResolvedIndexBinding() const1749 inline bool IsResolvedIndexBinding() const 1750 { 1751 return GetObjectType() == JSType::RESOLVEDINDEXBINDING_RECORD; 1752 } 1753 IsResolvedRecordIndexBinding() const1754 inline bool IsResolvedRecordIndexBinding() const 1755 { 1756 return GetObjectType() == JSType::RESOLVEDRECORDINDEXBINDING_RECORD; 1757 } 1758 IsResolvedRecordBinding() const1759 inline bool IsResolvedRecordBinding() const 1760 { 1761 return GetObjectType() == JSType::RESOLVEDRECORDBINDING_RECORD; 1762 } 1763 IsModuleNamespace() const1764 inline bool IsModuleNamespace() const 1765 { 1766 return GetObjectType() == JSType::JS_MODULE_NAMESPACE; 1767 } 1768 IsNativeModuleFailureInfo() const1769 inline bool IsNativeModuleFailureInfo() const 1770 { 1771 return GetObjectType() == JSType::NATIVE_MODULE_FAILURE_INFO; 1772 } 1773 IsJSSharedObject() const1774 inline bool IsJSSharedObject() const 1775 { 1776 return GetObjectType() == JSType::JS_SHARED_OBJECT; 1777 } 1778 IsJSSharedArray() const1779 inline bool IsJSSharedArray() const 1780 { 1781 return GetObjectType() == JSType::JS_SHARED_ARRAY; 1782 } 1783 SetElementsKind(ElementsKind kind)1784 inline void SetElementsKind(ElementsKind kind) 1785 { 1786 uint32_t bits = GetBitField(); 1787 uint32_t newVal = ElementsKindBits::Update(bits, kind); 1788 SetBitField(newVal); 1789 } 1790 GetElementsKind() const1791 inline ElementsKind GetElementsKind() const 1792 { 1793 uint32_t bits = GetBitField(); 1794 return ElementsKindBits::Decode(bits); 1795 } 1796 SetLevel(uint8_t level)1797 inline void SetLevel(uint8_t level) 1798 { 1799 uint32_t bits = GetBitField(); 1800 uint32_t newVal = LevelBit::Update(bits, level); 1801 SetBitField(newVal); 1802 } 1803 GetLevel() const1804 inline uint8_t GetLevel() const 1805 { 1806 uint32_t bits = GetBitField(); 1807 return LevelBit::Decode(bits); 1808 } 1809 SetIsDictionaryElement(bool value)1810 inline void SetIsDictionaryElement(bool value) 1811 { 1812 uint32_t newVal = DictionaryElementBits::Update(GetBitField(), value); 1813 SetBitField(newVal); 1814 } IsDictionaryElement() const1815 inline bool IsDictionaryElement() const 1816 { 1817 return DictionaryElementBits::Decode(GetBitField()); 1818 } SetIsStableElements(bool value)1819 inline void SetIsStableElements(bool value) 1820 { 1821 uint32_t newVal = IsStableElementsBit::Update(GetBitField(), value); 1822 SetBitField(newVal); 1823 } IsStableElements() const1824 inline bool IsStableElements() const 1825 { 1826 return IsStableElementsBit::Decode(GetBitField()); 1827 } IsStableJSArguments() const1828 inline bool IsStableJSArguments() const 1829 { 1830 uint32_t bits = GetBitField(); 1831 auto type = ObjectTypeBits::Decode(bits); 1832 return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARGUMENTS); 1833 } IsStableJSArray() const1834 inline bool IsStableJSArray() const 1835 { 1836 uint32_t bits = GetBitField(); 1837 auto type = ObjectTypeBits::Decode(bits); 1838 return IsStableElementsBit::Decode(bits) && (type == JSType::JS_ARRAY); 1839 } SetHasConstructor(bool value)1840 inline void SetHasConstructor(bool value) 1841 { 1842 JSTaggedType newVal = HasConstructorBits::Update(GetBitField(), value); 1843 SetBitField(newVal); 1844 } HasConstructor() const1845 inline bool HasConstructor() const 1846 { 1847 return HasConstructorBits::Decode(GetBitField()); 1848 } 1849 SetNumberOfProps(uint32_t num)1850 inline void SetNumberOfProps(uint32_t num) 1851 { 1852 uint32_t bits = GetBitField1(); 1853 uint32_t newVal = NumberOfPropsBits::Update(bits, num); 1854 SetBitField1(newVal); 1855 } 1856 IncNumberOfProps()1857 inline void IncNumberOfProps() 1858 { 1859 ASSERT(NumberOfProps() < PropertyAttributes::MAX_FAST_PROPS_CAPACITY); 1860 SetNumberOfProps(NumberOfProps() + 1); 1861 } 1862 NumberOfProps() const1863 inline uint32_t NumberOfProps() const 1864 { 1865 uint32_t bits = GetBitField1(); 1866 return NumberOfPropsBits::Decode(bits); 1867 } 1868 HasProps() const1869 inline bool HasProps() const 1870 { 1871 return NumberOfProps() > 0; 1872 } 1873 PropsIsEmpty() const1874 inline bool PropsIsEmpty() const 1875 { 1876 return NumberOfProps() == 0; 1877 } 1878 LastPropIndex() const1879 inline uint32_t LastPropIndex() const 1880 { 1881 ASSERT(NumberOfProps() > 0); 1882 return NumberOfProps() - 1; 1883 } 1884 GetNextInlinedPropsIndex() const1885 inline int32_t GetNextInlinedPropsIndex() const 1886 { 1887 uint32_t inlinedProperties = GetInlinedProperties(); 1888 uint32_t numberOfProps = NumberOfProps(); 1889 if (numberOfProps < inlinedProperties) { 1890 return numberOfProps; 1891 } 1892 return -1; 1893 } 1894 GetNextNonInlinedPropsIndex() const1895 inline int32_t GetNextNonInlinedPropsIndex() const 1896 { 1897 uint32_t inlinedProperties = GetInlinedProperties(); 1898 uint32_t numberOfProps = NumberOfProps(); 1899 if (numberOfProps >= inlinedProperties) { 1900 return numberOfProps - inlinedProperties; 1901 } 1902 return -1; 1903 } 1904 GetObjectSize() const1905 inline uint32_t GetObjectSize() const 1906 { 1907 uint32_t bits = GetBitField1(); 1908 return ObjectSizeInWordsBits::Decode(bits) * JSTaggedValue::TaggedTypeSize(); 1909 } 1910 GetObjectSizeExcludeInlinedProps() const1911 inline uint32_t GetObjectSizeExcludeInlinedProps() const 1912 { 1913 return GetObjectSize() - GetInlinedProperties() * JSTaggedValue::TaggedTypeSize(); 1914 } 1915 SetObjectSize(uint32_t num)1916 inline void SetObjectSize(uint32_t num) 1917 { 1918 ASSERT((num / JSTaggedValue::TaggedTypeSize()) <= MAX_OBJECT_SIZE_IN_WORDS); 1919 uint32_t bits = GetBitField1(); 1920 uint32_t newVal = ObjectSizeInWordsBits::Update(bits, num / JSTaggedValue::TaggedTypeSize()); 1921 SetBitField1(newVal); 1922 } 1923 GetInlinedPropertiesOffset(uint32_t index) const1924 inline uint32_t GetInlinedPropertiesOffset(uint32_t index) const 1925 { 1926 ASSERT(index < GetInlinedProperties()); 1927 return GetInlinedPropertiesIndex(index) * JSTaggedValue::TaggedTypeSize(); 1928 } 1929 1930 inline uint32_t GetInlinedPropertiesIndex(uint32_t index) const 1931 { 1932 ASSERT(index < GetInlinedProperties()); 1933 uint32_t bits = GetBitField1(); 1934 return InlinedPropsStartBits::Decode(bits) + index; 1935 } 1936 1937 inline void SetInlinedPropsStart(uint32_t num) 1938 { 1939 uint32_t bits = GetBitField1(); 1940 uint32_t newVal = InlinedPropsStartBits::Update(bits, num / JSTaggedValue::TaggedTypeSize()); 1941 SetBitField1(newVal); 1942 } 1943 1944 inline uint32_t GetInlinedPropsStartSize() const 1945 { 1946 uint32_t bits = GetBitField1(); 1947 return InlinedPropsStartBits::Decode(bits) * JSTaggedValue::TaggedTypeSize(); 1948 } 1949 1950 inline uint32_t GetInlinedProperties() const 1951 { 1952 if (IsJSObject()) { 1953 uint32_t bits = GetBitField1(); 1954 return static_cast<uint32_t>(ObjectSizeInWordsBits::Decode(bits) - InlinedPropsStartBits::Decode(bits)); 1955 } else { 1956 return 0; 1957 } 1958 } 1959 1960 inline void SetHasDeleteProperty(bool flag) const 1961 { 1962 HasDeletePropertyBit::Set<uint32_t>(flag, GetBitField1Addr()); 1963 } 1964 1965 inline bool HasDeleteProperty() const 1966 { 1967 uint32_t bits = GetBitField1(); 1968 return HasDeletePropertyBit::Decode(bits); 1969 } 1970 1971 inline void SetIsAllTaggedProp(bool flag) const 1972 { 1973 IsAllTaggedPropBit::Set<uint32_t>(flag, GetBitField1Addr()); 1974 } 1975 1976 inline bool IsAllTaggedProp() const 1977 { 1978 uint32_t bits = GetBitField1(); 1979 return IsAllTaggedPropBit::Decode(bits); 1980 } 1981 1982 inline static JSHClass *FindRootHClass(JSHClass *hclass); 1983 inline static JSTaggedValue FindProtoHClass(JSHClass *hclass); 1984 inline static JSTaggedValue FindProtoRootHClass(JSHClass *hclass); 1985 inline static void UpdateRootHClass(const JSThread *thread, const JSHandle<JSHClass> &parent, 1986 const JSHandle<JSHClass> &child); 1987 1988 inline static int FindPropertyEntry(const JSThread *thread, JSHClass *hclass, JSTaggedValue key); 1989 1990 static PUBLIC_API PropertyLookupResult LookupPropertyInAotHClass(const JSThread *thread, JSHClass *hclass, 1991 JSTaggedValue key); 1992 static PUBLIC_API PropertyLookupResult LookupPropertyInPGOHClass(const JSThread *thread, JSHClass *hclass, 1993 JSTaggedValue key); 1994 static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinPrototypeHClass(const JSThread *thread, 1995 JSHClass *hclass, JSTaggedValue key); 1996 static PUBLIC_API PropertyLookupResult LookupPropertyInBuiltinHClass(const JSThread *thread, JSHClass *hclass, 1997 JSTaggedValue key); 1998 1999 static constexpr size_t PROTOTYPE_OFFSET = TaggedObjectSize(); 2000 ACCESSORS(Proto, PROTOTYPE_OFFSET, LAYOUT_OFFSET); 2001 ACCESSORS_SYNCHRONIZED(Layout, LAYOUT_OFFSET, TRANSTIONS_OFFSET); 2002 ACCESSORS(Transitions, TRANSTIONS_OFFSET, PARENT_OFFSET); 2003 ACCESSORS(Parent, PARENT_OFFSET, PROTO_CHANGE_MARKER_OFFSET); 2004 ACCESSORS(ProtoChangeMarker, PROTO_CHANGE_MARKER_OFFSET, PROTO_CHANGE_DETAILS_OFFSET); 2005 ACCESSORS(ProtoChangeDetails, PROTO_CHANGE_DETAILS_OFFSET, ENUM_CACHE_OFFSET); 2006 ACCESSORS(EnumCache, ENUM_CACHE_OFFSET, PROFILE_TYPE); 2007 ACCESSORS_PRIMITIVE_FIELD(ProfileType, uint64_t, PROFILE_TYPE, BIT_FIELD_OFFSET); 2008 ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, BIT_FIELD1_OFFSET); 2009 ACCESSORS_PRIMITIVE_FIELD(BitField1, uint32_t, BIT_FIELD1_OFFSET, LAST_OFFSET); 2010 DEFINE_ALIGN_SIZE(LAST_OFFSET); 2011 2012 static JSHandle<JSHClass> SetPrototypeWithNotification(const JSThread *thread, 2013 const JSHandle<JSHClass> &hclass, 2014 const JSHandle<JSTaggedValue> &proto, 2015 bool isChangeProto = false); 2016 static void SetPrototypeTransition(JSThread *thread, const JSHandle<JSObject> &object, 2017 const JSHandle<JSTaggedValue> &proto, 2018 bool isChangeProto = false); 2019 void SetPrototype(const JSThread *thread, JSTaggedValue proto, bool isChangeProto = false); 2020 void PUBLIC_API SetPrototype(const JSThread *thread, 2021 const JSHandle<JSTaggedValue> &proto, 2022 bool isChangeProto = false); 2023 static void OptimizePrototypeForIC(const JSThread *thread, 2024 const JSHandle<JSTaggedValue> &proto, 2025 bool isChangeProto = false); 2026 inline JSTaggedValue GetPrototype() const 2027 { 2028 return GetProto(); 2029 } 2030 2031 inline JSHClass *FindTransitions(const JSTaggedValue &key, 2032 const JSTaggedValue &metaData, 2033 const Representation &rep); 2034 inline JSHClass *CheckHClassForRep(JSHClass *hclass, const Representation &rep); 2035 2036 DECL_DUMP() 2037 2038 static CString DumpJSType(JSType type); 2039 2040 static JSHandle<JSHClass> CreateRootHClassFromPGO(const JSThread* thread, 2041 const HClassLayoutDesc* desc, 2042 uint32_t maxNum, 2043 bool isCache); 2044 static JSHandle<JSHClass> CreateRootHClassWithCached(const JSThread* thread, 2045 const HClassLayoutDesc* desc, 2046 uint32_t maxNum); 2047 static JSHandle<JSHClass> CreateChildHClassFromPGO(const JSThread* thread, 2048 const JSHandle<JSHClass>& parent, 2049 const HClassLayoutDesc* desc); 2050 static bool DumpRootHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc); 2051 static bool DumpChildHClassByPGO(const JSHClass* hclass, HClassLayoutDesc* desc); 2052 static bool UpdateRootLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* rootDesc); 2053 static bool UpdateChildLayoutDescByPGO(const JSHClass* hclass, HClassLayoutDesc* childDesc); 2054 static CString DumpToString(JSTaggedType hclassVal); 2055 2056 DECL_VISIT_OBJECT(PROTOTYPE_OFFSET, PROFILE_TYPE); 2057 inline JSHClass *FindProtoTransitions(const JSTaggedValue &key, const JSTaggedValue &proto); 2058 inline bool HasTransitions() const 2059 { 2060 return !GetTransitions().IsUndefined(); 2061 } 2062 2063 static JSHandle<JSHClass> CreateSHClass(JSThread *thread, 2064 const std::vector<PropertyDescriptor> &descs, 2065 const JSHClass *parentHClass = nullptr, 2066 bool isFunction = false); 2067 static JSHandle<JSHClass> CreateSConstructorHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs); 2068 static JSHandle<JSHClass> CreateSPrototypeHClass(JSThread *thread, const std::vector<PropertyDescriptor> &descs); 2069 2070 private: 2071 2072 static inline bool ProtoIsFastJSArray(const JSThread *thread, const JSHandle<JSTaggedValue> proto, 2073 const JSHandle<JSHClass> hclass); 2074 2075 static void CreateSInlinedLayout(JSThread *thread, 2076 const std::vector<PropertyDescriptor> &descs, 2077 const JSHandle<JSHClass> &hclass, 2078 const JSHClass *parentHClass = nullptr); 2079 static void CreateSDictLayout(JSThread *thread, 2080 const std::vector<PropertyDescriptor> &descs, 2081 const JSHandle<JSHClass> &hclass, 2082 const JSHClass *parentHClass = nullptr); 2083 static inline void AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent, 2084 const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key, 2085 PropertyAttributes attr); 2086 static inline void AddExtensionTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent, 2087 const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key); 2088 static inline void AddProtoTransitions(const JSThread *thread, const JSHandle<JSHClass> &parent, 2089 const JSHandle<JSHClass> &child, const JSHandle<JSTaggedValue> &key, 2090 const JSHandle<JSTaggedValue> &proto); 2091 template<bool checkDuplicateKeys = false> 2092 static inline void AddPropertyToNewHClass(const JSThread *thread, JSHandle<JSHClass> &jshclass, 2093 JSHandle<JSHClass> &newJsHClass, const JSHandle<JSTaggedValue> &key, 2094 const PropertyAttributes &attr); 2095 2096 void InitializeWithDefaultValue(const JSThread *thread, uint32_t size, JSType type, uint32_t inlinedProps); 2097 2098 static bool IsJSTypeObject(JSType type) 2099 { 2100 return JSType::JS_OBJECT_FIRST <= type && type <= JSType::JS_OBJECT_LAST; 2101 } 2102 2103 static bool IsJSTypeShared(JSType type); 2104 2105 inline void Copy(const JSThread *thread, const JSHClass *jshclass); 2106 2107 uint32_t *GetBitFieldAddr() const 2108 { 2109 return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET); 2110 } 2111 2112 uint32_t *GetBitField1Addr() const 2113 { 2114 return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD1_OFFSET); 2115 } 2116 friend class RuntimeStubs; 2117 }; 2118 static_assert(JSHClass::BIT_FIELD_OFFSET % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT) == 0); 2119 2120 // record property look up info in local and vtable 2121 class PropertyLookupResult { 2122 public: 2123 static constexpr uint32_t OFFSET_BITFIELD_NUM = 14; 2124 using IsFoundBit = BitField<bool, 0, 1>; 2125 using IsLocalBit = IsFoundBit::NextFlag; 2126 using IsNotHoleBit = IsLocalBit::NextFlag; 2127 using IsAccessorBit = IsNotHoleBit::NextFlag; 2128 using OffsetBits = IsAccessorBit::NextField<uint32_t, OFFSET_BITFIELD_NUM>; 2129 using WritableField = OffsetBits::NextFlag; 2130 using RepresentationBits = WritableField::NextField<Representation, PropertyAttributes::REPRESENTATION_NUM>; 2131 using IsInlinedPropsBits = RepresentationBits::NextFlag; 2132 2133 explicit PropertyLookupResult(uint32_t data = 0) : data_(data) {} 2134 ~PropertyLookupResult() = default; 2135 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PropertyLookupResult); 2136 DEFAULT_COPY_SEMANTIC(PropertyLookupResult); 2137 2138 inline bool IsFound() const 2139 { 2140 return IsFoundBit::Get(data_); 2141 } 2142 2143 inline void SetIsFound(bool flag) 2144 { 2145 IsFoundBit::Set(flag, &data_); 2146 } 2147 2148 inline bool IsWritable() const 2149 { 2150 return WritableField::Get(data_); 2151 } 2152 2153 inline void SetIsWritable(bool flag) 2154 { 2155 WritableField::Set(flag, &data_); 2156 } 2157 2158 inline bool IsLocal() const 2159 { 2160 return IsLocalBit::Get(data_); 2161 } 2162 2163 inline void SetIsLocal(bool flag) 2164 { 2165 IsLocalBit::Set(flag, &data_); 2166 } 2167 2168 inline bool IsNotHole() const 2169 { 2170 return IsNotHoleBit::Get(data_); 2171 } 2172 2173 inline void SetIsNotHole(bool flag) 2174 { 2175 IsNotHoleBit::Set(flag, &data_); 2176 } 2177 2178 inline bool IsVtable() const 2179 { 2180 return IsFound() && !IsLocal(); 2181 } 2182 2183 inline void SetIsVtable() 2184 { 2185 SetIsFound(true); 2186 SetIsLocal(false); 2187 } 2188 2189 inline bool IsAccessor() const 2190 { 2191 return IsAccessorBit::Get(data_); 2192 } 2193 2194 inline void SetIsAccessor(bool flag) 2195 { 2196 IsAccessorBit::Set(flag, &data_); 2197 } 2198 2199 inline bool IsFunction() const 2200 { 2201 return IsVtable() && !IsAccessor(); 2202 } 2203 2204 inline uint32_t GetOffset() const 2205 { 2206 return OffsetBits::Get(data_); 2207 } 2208 2209 inline void SetOffset(uint32_t offset) 2210 { 2211 OffsetBits::Set<uint32_t>(offset, &data_); 2212 } 2213 2214 inline void SetRepresentation(Representation rep) 2215 { 2216 RepresentationBits::Set(rep, &data_); 2217 } 2218 2219 inline Representation GetRepresentation() 2220 { 2221 return RepresentationBits::Get(data_); 2222 } 2223 2224 inline void SetIsInlinedProps(bool flag) 2225 { 2226 IsInlinedPropsBits::Set(flag, &data_); 2227 } 2228 2229 inline bool IsInlinedProps() 2230 { 2231 return IsInlinedPropsBits::Get(data_); 2232 } 2233 2234 inline uint32_t GetData() const 2235 { 2236 return data_; 2237 } 2238 2239 private: 2240 uint32_t data_ {0}; 2241 }; 2242 static_assert(PropertyLookupResult::OffsetBits::MaxValue() > 2243 (PropertyAttributes::MAX_FAST_PROPS_CAPACITY * JSTaggedValue::TaggedTypeSize())); 2244 } // namespace panda::ecmascript 2245 2246 #endif // ECMASCRIPT_JS_HCLASS_H 2247