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