1 /* 2 * Copyright (c) 2022-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_COMPILER_SHARE_GATE_META_DATA_H 17 #define ECMASCRIPT_COMPILER_SHARE_GATE_META_DATA_H 18 19 #include <string> 20 21 #include "ecmascript/compiler/bytecodes.h" 22 #include "ecmascript/compiler/share_opcodes.h" 23 #include "ecmascript/compiler/type.h" 24 #include "ecmascript/elements.h" 25 #include "ecmascript/js_thread_hclass_entries.h" 26 #include "ecmascript/mem/chunk.h" 27 #include "ecmascript/mem/chunk_containers.h" 28 #include "ecmascript/mem/region.h" 29 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 30 #include "libpandabase/macros.h" 31 32 namespace panda::ecmascript::kungfu { 33 using ProfileType = pgo::ProfileType; 34 using GateRef = int32_t; 35 using PGOTypeRef = pgo::PGOTypeRef; 36 using PGODefineOpType = pgo::PGODefineOpType; 37 using PGOSampleType = pgo::PGOSampleType; 38 using PGORWOpType = pgo::PGORWOpType; 39 enum class TypedBinOp : uint8_t; 40 enum class TypedUnOp : uint8_t; 41 enum class TypedJumpOp : uint8_t; 42 enum class TypedLoadOp : uint8_t; 43 enum class TypedStoreOp : uint8_t; 44 enum class TypedCallTargetCheckOp : uint8_t; 45 46 enum GateFlags : uint8_t { 47 NONE_FLAG = 0, 48 NO_WRITE = 1 << 0, 49 HAS_ROOT = 1 << 1, 50 HAS_FRAME_STATE = 1 << 2, 51 CONTROL = NO_WRITE, 52 CONTROL_ROOT = NO_WRITE | HAS_ROOT, 53 CHECKABLE = NO_WRITE | HAS_FRAME_STATE, 54 ROOT = NO_WRITE | HAS_ROOT, 55 FIXED = NO_WRITE, 56 }; 57 58 class GateMetaData : public ChunkObject { 59 public: 60 enum class Kind : uint8_t { 61 IMMUTABLE = 0, 62 MUTABLE_WITH_SIZE, 63 IMMUTABLE_ONE_PARAMETER, 64 MUTABLE_ONE_PARAMETER, 65 IMMUTABLE_BOOL, 66 MUTABLE_STRING, 67 JSBYTECODE, 68 TYPED_BINARY_OP, 69 TYPED_CALLTARGETCHECK_OP, 70 TYPED_CALL, 71 CALL_NEW, 72 }; 73 GateMetaData() = default; GateMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn)74 GateMetaData(OpCode opcode, GateFlags flags, 75 uint32_t statesIn, uint16_t dependsIn, uint32_t valuesIn) 76 : opcode_(opcode), flags_(flags), 77 statesIn_(statesIn), dependsIn_(dependsIn), valuesIn_(valuesIn) {} 78 equal(const GateMetaData & other)79 virtual bool equal(const GateMetaData &other) const 80 { 81 if (opcode_ == other.opcode_ && kind_ == other.kind_ && flags_ == other.flags_ && 82 statesIn_ == other.statesIn_ && dependsIn_ == other.dependsIn_ && valuesIn_ == other.valuesIn_) { 83 return true; 84 } 85 return false; 86 } 87 GetStateCount()88 size_t GetStateCount() const 89 { 90 return statesIn_; 91 } 92 GetDependCount()93 size_t GetDependCount() const 94 { 95 return dependsIn_; 96 } 97 GetInValueCount()98 size_t GetInValueCount() const 99 { 100 return valuesIn_; 101 } 102 GetRootCount()103 size_t GetRootCount() const 104 { 105 return HasRoot() ? 1 : 0; 106 } 107 GetInFrameStateCount()108 size_t GetInFrameStateCount() const 109 { 110 return HasFrameState() ? 1 : 0; 111 } 112 GetNumIns()113 size_t GetNumIns() const 114 { 115 return GetStateCount() + GetDependCount() + GetInValueCount() 116 + GetInFrameStateCount() + GetRootCount(); 117 } 118 GetInValueStarts()119 size_t GetInValueStarts() const 120 { 121 return GetStateCount() + GetDependCount(); 122 } 123 GetInFrameStateStarts()124 size_t GetInFrameStateStarts() const 125 { 126 return GetInValueStarts() + GetInValueCount(); 127 } 128 GetOpCode()129 OpCode GetOpCode() const 130 { 131 return opcode_; 132 } 133 GetKind()134 Kind GetKind() const 135 { 136 return kind_; 137 } 138 AssertKind(Kind kind)139 void AssertKind([[maybe_unused]] Kind kind) const 140 { 141 ASSERT(GetKind() == kind); 142 } 143 IsOneParameterKind()144 bool IsOneParameterKind() const 145 { 146 return GetKind() == Kind::IMMUTABLE_ONE_PARAMETER || GetKind() == Kind::MUTABLE_ONE_PARAMETER || 147 GetKind() == Kind::TYPED_BINARY_OP || GetKind() == Kind::TYPED_CALLTARGETCHECK_OP || 148 GetKind() == Kind::CALL_NEW; 149 } 150 IsStringType()151 bool IsStringType() const 152 { 153 return GetKind() == Kind::MUTABLE_STRING; 154 } 155 156 bool IsRoot() const; 157 bool IsProlog() const; 158 bool IsFixed() const; 159 bool IsSchedulable() const; 160 bool IsState() const; // note: IsState(STATE_ENTRY) == false 161 bool IsGeneralState() const; 162 bool IsTerminalState() const; 163 bool IsVirtualState() const; 164 bool IsCFGMerge() const; 165 bool IsControlCase() const; 166 bool IsIfOrSwitchRelated() const; 167 bool IsLoopHead() const; 168 bool IsNop() const; 169 bool IsDead() const; 170 bool IsConstant() const; 171 bool IsDependSelector() const; 172 bool IsTypedOperator() const; 173 bool IsCheckWithOneIn() const; 174 bool IsCheckWithTwoIns() const; HasFrameState()175 bool HasFrameState() const 176 { 177 return HasFlag(GateFlags::HAS_FRAME_STATE); 178 } 179 IsNotWrite()180 bool IsNotWrite() const 181 { 182 return HasFlag(GateFlags::NO_WRITE); 183 } 184 185 ~GateMetaData() = default; 186 187 static std::string Str(OpCode opcode); 188 static std::string Str(TypedBinOp op); 189 static std::string Str(TypedUnOp op); 190 static std::string Str(TypedJumpOp op); 191 static std::string Str(TypedLoadOp op); 192 static std::string Str(TypedStoreOp op); 193 static std::string Str(TypedCallTargetCheckOp op); 194 static std::string Str(ValueType type); Str()195 std::string Str() const 196 { 197 return Str(opcode_); 198 } 199 protected: SetKind(Kind kind)200 void SetKind(Kind kind) 201 { 202 kind_ = kind; 203 } 204 SetFlags(GateFlags flags)205 void SetFlags(GateFlags flags) 206 { 207 flags_ = flags; 208 } 209 DecreaseIn(size_t idx)210 void DecreaseIn(size_t idx) 211 { 212 ASSERT(GetKind() == Kind::MUTABLE_WITH_SIZE); 213 if (idx < statesIn_) { 214 statesIn_--; 215 } else if (idx < statesIn_ + dependsIn_) { 216 dependsIn_--; 217 } else { 218 valuesIn_--; 219 } 220 } 221 HasRoot()222 bool HasRoot() const 223 { 224 return HasFlag(GateFlags::HAS_ROOT); 225 } 226 HasFlag(GateFlags flag)227 bool HasFlag(GateFlags flag) const 228 { 229 return (GetFlags() & flag) == flag; 230 } 231 GetFlags()232 GateFlags GetFlags() const 233 { 234 return flags_; 235 } 236 237 private: 238 friend class Gate; 239 friend class Circuit; 240 friend class GateMetaBuilder; 241 242 OpCode opcode_ { OpCode::NOP }; 243 Kind kind_ { Kind::IMMUTABLE }; 244 GateFlags flags_ { GateFlags::NONE_FLAG }; 245 uint32_t statesIn_ { 0 }; 246 uint32_t dependsIn_ { 0 }; 247 uint32_t valuesIn_ { 0 }; 248 }; 249 250 inline std::ostream& operator<<(std::ostream& os, OpCode opcode) 251 { 252 return os << GateMetaData::Str(opcode); 253 } 254 255 class BoolMetaData : public GateMetaData { 256 public: BoolMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn,bool value)257 BoolMetaData(OpCode opcode, GateFlags flags, uint32_t statesIn, 258 uint16_t dependsIn, uint32_t valuesIn, bool value) 259 : GateMetaData(opcode, flags, statesIn, dependsIn, valuesIn), value_(value) 260 { 261 SetKind(GateMetaData::Kind::IMMUTABLE_BOOL); 262 } 263 equal(const GateMetaData & other)264 bool equal(const GateMetaData &other) const override 265 { 266 if (!GateMetaData::equal(other)) { 267 return false; 268 } 269 auto cast_other = static_cast<const BoolMetaData *>(&other); 270 if (value_ == cast_other->value_) { 271 return true; 272 } 273 return false; 274 } 275 Cast(const GateMetaData * meta)276 static const BoolMetaData* Cast(const GateMetaData* meta) 277 { 278 meta->AssertKind(GateMetaData::Kind::IMMUTABLE_BOOL); 279 return static_cast<const BoolMetaData*>(meta); 280 } 281 GetBool()282 bool GetBool() const 283 { 284 return value_; 285 } 286 SetBool(bool value)287 void SetBool(bool value) 288 { 289 value_ = value; 290 } 291 292 private: 293 bool value_ { false }; 294 }; 295 296 class OneParameterMetaData : public GateMetaData { 297 public: OneParameterMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn,uint64_t value)298 OneParameterMetaData(OpCode opcode, GateFlags flags, uint32_t statesIn, 299 uint16_t dependsIn, uint32_t valuesIn, uint64_t value) 300 : GateMetaData(opcode, flags, statesIn, dependsIn, valuesIn), value_(value) 301 { 302 SetKind(GateMetaData::Kind::IMMUTABLE_ONE_PARAMETER); 303 } 304 equal(const GateMetaData & other)305 bool equal(const GateMetaData &other) const override 306 { 307 if (!GateMetaData::equal(other)) { 308 return false; 309 } 310 auto cast_other = static_cast<const OneParameterMetaData *>(&other); 311 if (value_ == cast_other->value_) { 312 return true; 313 } 314 return false; 315 } 316 Cast(const GateMetaData * meta)317 static const OneParameterMetaData* Cast(const GateMetaData* meta) 318 { 319 ASSERT(meta->IsOneParameterKind()); 320 return static_cast<const OneParameterMetaData*>(meta); 321 } 322 GetValue()323 uint64_t GetValue() const 324 { 325 return value_; 326 } 327 SetValue(uint64_t value)328 void SetValue(uint64_t value) 329 { 330 value_ = value; 331 } 332 333 private: 334 uint64_t value_ { 0 }; 335 }; 336 337 class StringMetaData : public GateMetaData { 338 public: StringMetaData(Chunk * chunk,std::string_view str)339 StringMetaData(Chunk* chunk, std::string_view str) 340 : GateMetaData(OpCode::CONSTSTRING, GateFlags::NONE_FLAG, 0, 0, 0), 341 stringData_(str.size() + 1, chunk) 342 { 343 auto srcLength = str.size(); 344 auto destlength = stringData_.size(); 345 auto dest = stringData_.data(); 346 auto src = str.data(); 347 if (destlength <= static_cast<size_t>(srcLength) || strcpy_s(dest, destlength, src) != EOK) { 348 LOG_COMPILER(FATAL) << "StringMetaData strcpy_s failed"; 349 } 350 SetKind(GateMetaData::Kind::MUTABLE_STRING); 351 } equal(const GateMetaData & other)352 bool equal(const GateMetaData &other) const override 353 { 354 if (!GateMetaData::equal(other)) { 355 return false; 356 } 357 auto cast_other = static_cast<const StringMetaData *>(&other); 358 if (stringData_.size() != cast_other->GetString().size()) { 359 return false; 360 } 361 362 if (strncmp(stringData_.data(), cast_other->GetString().data(), stringData_.size()) != 0) { 363 return false; 364 } 365 366 return true; 367 } 368 GetString()369 const ChunkVector<char> &GetString() const 370 { 371 return stringData_; 372 } 373 374 private: 375 ChunkVector<char> stringData_; 376 }; 377 378 class GateTypeAccessor { 379 public: GateTypeAccessor(uint64_t value)380 explicit GateTypeAccessor(uint64_t value) 381 : type_(static_cast<uint32_t>(value)) {} 382 GetGateType()383 GateType GetGateType() const 384 { 385 return GateType(type_); 386 } 387 GetParamType()388 ParamType GetParamType() const 389 { 390 return ParamType(type_); 391 } 392 private: 393 uint32_t type_; 394 }; 395 396 class ValuePairTypeAccessor { 397 public: 398 // type bits shift 399 static constexpr int OPRAND_TYPE_BITS = 8; ValuePairTypeAccessor(uint64_t value)400 explicit ValuePairTypeAccessor(uint64_t value) : bitField_(value) {} 401 GetSrcType()402 ValueType GetSrcType() const 403 { 404 return static_cast<ValueType>(LeftBits::Get(bitField_)); 405 } 406 GetDstType()407 ValueType GetDstType() const 408 { 409 return static_cast<ValueType>(RightBits::Get(bitField_)); 410 } 411 IsConvertSupport()412 bool IsConvertSupport() const 413 { 414 return ConvertSupportBits::Get(bitField_) == ConvertSupport::ENABLE; 415 } 416 417 static uint64_t ToValue(ValueType srcType, ValueType dstType, ConvertSupport support = ConvertSupport::ENABLE) 418 { 419 uint8_t srcVlaue = static_cast<uint8_t>(srcType); 420 uint8_t dstVlaue = static_cast<uint8_t>(dstType); 421 return LeftBits::Encode(srcVlaue) | RightBits::Encode(dstVlaue) | ConvertSupportBits::Encode(support); 422 } 423 424 private: 425 using LeftBits = panda::BitField<uint8_t, 0, OPRAND_TYPE_BITS>; 426 using RightBits = LeftBits::NextField<uint8_t, OPRAND_TYPE_BITS>; 427 using ConvertSupportBits = RightBits::NextField<ConvertSupport, OPRAND_TYPE_BITS>; 428 429 uint64_t bitField_; 430 }; 431 432 class TypeConvertAccessor { 433 public: 434 // type bits shift 435 static constexpr int OPRAND_TYPE_BITS = 32; TypeConvertAccessor(uint64_t value)436 explicit TypeConvertAccessor(uint64_t value) : bitField_(value) {} 437 GetLeftType()438 ParamType GetLeftType() const 439 { 440 return ParamType(LeftBits::Get(bitField_)); 441 } 442 GetRightType()443 GateType GetRightType() const 444 { 445 return GateType(RightBits::Get(bitField_)); 446 } 447 ToValue(ParamType leftType,GateType rightType)448 static uint64_t ToValue(ParamType leftType, GateType rightType) 449 { 450 return LeftBits::Encode(leftType.Value()) | RightBits::Encode(rightType.Value()); 451 } 452 453 private: 454 using LeftBits = panda::BitField<uint32_t, 0, OPRAND_TYPE_BITS>; 455 using RightBits = LeftBits::NextField<uint32_t, OPRAND_TYPE_BITS>; 456 457 uint64_t bitField_; 458 }; 459 460 class UInt32PairAccessor { 461 public: 462 // type bits shift 463 static constexpr int OPRAND_TYPE_BITS = 32; UInt32PairAccessor(uint64_t value)464 explicit UInt32PairAccessor(uint64_t value) : bitField_(value) {} UInt32PairAccessor(uint32_t first,uint32_t second)465 explicit UInt32PairAccessor(uint32_t first, uint32_t second) 466 { 467 bitField_ = FirstBits::Encode(first) | SecondBits::Encode(second); 468 } 469 GetFirstValue()470 uint32_t GetFirstValue() const 471 { 472 return FirstBits::Get(bitField_); 473 } 474 GetSecondValue()475 uint32_t GetSecondValue() const 476 { 477 return SecondBits::Get(bitField_); 478 } 479 ToValue()480 uint64_t ToValue() const 481 { 482 return bitField_; 483 } 484 485 private: 486 using FirstBits = panda::BitField<uint32_t, 0, OPRAND_TYPE_BITS>; 487 using SecondBits = FirstBits::NextField<uint32_t, OPRAND_TYPE_BITS>; 488 489 uint64_t bitField_; 490 }; 491 492 class ArrayMetaDataAccessor { 493 public: 494 enum Mode : uint8_t { 495 CREATE = 0, 496 LOAD_ELEMENT, 497 STORE_ELEMENT, 498 LOAD_LENGTH, 499 CALL_BUILTIN_METHOD 500 }; 501 502 static constexpr int BITS_SIZE = 8; 503 static constexpr int ARRAY_LENGTH_BITS_SIZE = 32; ArrayMetaDataAccessor(uint64_t value)504 explicit ArrayMetaDataAccessor(uint64_t value) : bitField_(value) {} 505 explicit ArrayMetaDataAccessor(ElementsKind kind, Mode mode, 506 uint32_t length = 0, RegionSpaceFlag flag = RegionSpaceFlag::IN_YOUNG_SPACE) 507 { 508 bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode) | 509 ArrayLengthBits::Encode(length) | RegionSpaceFlagBits::Encode(flag); 510 } 511 GetRegionSpaceFlag()512 RegionSpaceFlag GetRegionSpaceFlag() const 513 { 514 return RegionSpaceFlagBits::Get(bitField_); 515 } 516 GetElementsKind()517 ElementsKind GetElementsKind() const 518 { 519 return ElementsKindBits::Get(bitField_); 520 } 521 GetMode()522 Mode GetMode() const 523 { 524 return ModeBits::Get(bitField_); 525 } 526 SetElementsKind(ElementsKind kind)527 void SetElementsKind(ElementsKind kind) 528 { 529 bitField_ = ElementsKindBits::Update(bitField_, kind); 530 } 531 SetArrayLength(uint32_t length)532 void SetArrayLength(uint32_t length) 533 { 534 bitField_ = ArrayLengthBits::Update(bitField_, length); 535 } 536 SetRegionSpaceFlag(RegionSpaceFlag flag)537 void SetRegionSpaceFlag(RegionSpaceFlag flag) 538 { 539 bitField_ = RegionSpaceFlagBits::Update(bitField_, flag); 540 } 541 GetArrayLength()542 uint32_t GetArrayLength() const 543 { 544 return ArrayLengthBits::Get(bitField_); 545 } 546 IsLoadElement()547 bool IsLoadElement() const 548 { 549 return GetMode() == Mode::LOAD_ELEMENT; 550 } 551 IsStoreElement()552 bool IsStoreElement() const 553 { 554 return GetMode() == Mode::STORE_ELEMENT; 555 } 556 ToValue()557 uint64_t ToValue() const 558 { 559 return bitField_; 560 } 561 562 private: 563 using ElementsKindBits = panda::BitField<ElementsKind, 0, BITS_SIZE>; 564 using ModeBits = ElementsKindBits::NextField<Mode, BITS_SIZE>; 565 using ArrayLengthBits = ModeBits::NextField<uint32_t, ARRAY_LENGTH_BITS_SIZE>; 566 using RegionSpaceFlagBits = ArrayLengthBits::NextField<RegionSpaceFlag, BITS_SIZE>; 567 568 uint64_t bitField_; 569 }; 570 571 class CreateArgumentsAccessor { 572 public: 573 enum Mode : uint8_t { 574 REST_ARGUMENTS, 575 UNMAPPED_ARGUMENTS, 576 INVALID, 577 }; 578 579 static constexpr int BITS_SIZE = 8; CreateArgumentsAccessor(uint64_t value)580 explicit CreateArgumentsAccessor(uint64_t value) : bitField_(value) {} CreateArgumentsAccessor(ElementsKind kind,Mode mode)581 explicit CreateArgumentsAccessor(ElementsKind kind, Mode mode) 582 { 583 bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode); 584 } GetMode()585 Mode GetMode() const 586 { 587 return ModeBits::Get(bitField_); 588 } ToValue()589 uint64_t ToValue() const 590 { 591 return bitField_; 592 } 593 private: 594 using ElementsKindBits = panda::BitField<ElementsKind, 0, BITS_SIZE>; 595 using ModeBits = ElementsKindBits::NextField<Mode, BITS_SIZE>; 596 597 uint64_t bitField_; 598 }; 599 600 class ObjectTypeAccessor { 601 public: 602 static constexpr int IS_HEAP_OBJECT_BIT_SIZE = 1; 603 ObjectTypeAccessor(uint64_t value)604 explicit ObjectTypeAccessor(uint64_t value) : bitField_(value) {} 605 explicit ObjectTypeAccessor(bool isHeapObject = false) 606 { 607 bitField_ = IsHeapObjectBit::Encode(isHeapObject); 608 } 609 IsHeapObject()610 bool IsHeapObject() const 611 { 612 return IsHeapObjectBit::Get(bitField_); 613 } 614 ToValue()615 uint64_t ToValue() const 616 { 617 return bitField_; 618 } 619 620 private: 621 using IsHeapObjectBit = panda::BitField<bool, 0, IS_HEAP_OBJECT_BIT_SIZE>; 622 623 uint64_t bitField_; 624 }; 625 626 class BuiltinPrototypeHClassAccessor { 627 public: 628 static constexpr int WORD_BITS_SIZE = 8; 629 static constexpr int IS_PROTOTYPE_OF_PROTOTYPE_BITS_SIZE = 1; 630 BuiltinPrototypeHClassAccessor(uint64_t value)631 explicit BuiltinPrototypeHClassAccessor(uint64_t value): type_(value) {} 632 // Only valid indices accepted BuiltinPrototypeHClassAccessor(BuiltinTypeId type,ElementsKind kind,bool isPrototypeOfPrototype)633 explicit BuiltinPrototypeHClassAccessor(BuiltinTypeId type, ElementsKind kind, 634 bool isPrototypeOfPrototype): type_(0) 635 { 636 type_ = BuiltinTypeIdBits::Encode(type) | ElementsKindBits::Encode(kind) | 637 IsPrototypeOfPrototypeBits::Encode(isPrototypeOfPrototype); 638 type_ = BuiltinTypeIdBits::Encode(type) | ElementsKindBits::Encode(kind); 639 ASSERT(BuiltinHClassEntries::GetEntryIndex(type) < BuiltinHClassEntries::N_ENTRIES); 640 } 641 GetElementsKind()642 ElementsKind GetElementsKind() const 643 { 644 return ElementsKindBits::Get(type_); 645 } 646 GetBuiltinTypeId()647 BuiltinTypeId GetBuiltinTypeId() const 648 { 649 return BuiltinTypeIdBits::Get(type_); 650 } 651 IsPrototypeOfPrototype()652 bool IsPrototypeOfPrototype() const 653 { 654 return IsPrototypeOfPrototypeBits::Get(type_); 655 } 656 ToValue()657 uint64_t ToValue() const 658 { 659 return type_; 660 } 661 662 private: 663 using BuiltinTypeIdBits = panda::BitField<BuiltinTypeId, 0, WORD_BITS_SIZE>; 664 using ElementsKindBits = BuiltinTypeIdBits::NextField<ElementsKind, WORD_BITS_SIZE>; 665 using IsPrototypeOfPrototypeBits = ElementsKindBits::NextField<bool, IS_PROTOTYPE_OF_PROTOTYPE_BITS_SIZE>; 666 667 uint64_t type_; 668 }; 669 670 class TypedArrayMetaDataAccessor { 671 public: 672 enum Mode : uint8_t { 673 ACCESS_ELEMENT = 0, 674 LOAD_LENGTH, 675 }; 676 677 static constexpr int TYPE_BITS_SIZE = 32; 678 static constexpr int MODE_BITS_SIZE = 2; 679 static constexpr int ON_HEAP_MODE_BITS_SIZE = 2; 680 TypedArrayMetaDataAccessor(uint64_t value)681 explicit TypedArrayMetaDataAccessor(uint64_t value) : bitField_(value) {} 682 GetParamType()683 ParamType GetParamType() const 684 { 685 return ParamType(TypeBits::Get(bitField_)); 686 } 687 GetOnHeapMode()688 OnHeapMode GetOnHeapMode() const 689 { 690 return OnHeapModeBits::Get(bitField_); 691 } 692 UpdateOnHeapMode(OnHeapMode mode)693 uint64_t UpdateOnHeapMode(OnHeapMode mode) 694 { 695 return OnHeapModeBits::Update(bitField_, mode); 696 } 697 IsAccessElement()698 bool IsAccessElement() const 699 { 700 return ModeBits::Get(bitField_) == Mode::ACCESS_ELEMENT; 701 } 702 ToValue()703 uint64_t ToValue() 704 { 705 return bitField_; 706 } 707 ToValue(ParamType paramType,Mode mode,OnHeapMode onHeap)708 static uint64_t ToValue(ParamType paramType, Mode mode, OnHeapMode onHeap) 709 { 710 return TypeBits::Encode(paramType.Value()) | ModeBits::Encode(mode) | OnHeapModeBits::Encode(onHeap); 711 } 712 713 private: 714 using TypeBits = panda::BitField<uint32_t, 0, TYPE_BITS_SIZE>; 715 using ModeBits = TypeBits::NextField<Mode, MODE_BITS_SIZE>; 716 using OnHeapModeBits = ModeBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 717 718 uint64_t bitField_; 719 }; 720 721 class LoadElementAccessor { 722 public: 723 static constexpr int TYPED_LOAD_OP_BITS_SIZE = 8; 724 static constexpr int ON_HEAP_MODE_BITS_SIZE = 8; 725 LoadElementAccessor(uint64_t value)726 explicit LoadElementAccessor(uint64_t value): bitField_(value) {} LoadElementAccessor(TypedLoadOp op,OnHeapMode onHeap)727 explicit LoadElementAccessor(TypedLoadOp op, OnHeapMode onHeap) 728 { 729 bitField_ = TypedLoadOpBits::Encode(op) | OnHeapModeBits::Encode(onHeap); 730 } 731 GetTypedLoadOp()732 TypedLoadOp GetTypedLoadOp() const 733 { 734 return TypedLoadOpBits::Get(bitField_); 735 } 736 GetOnHeapMode()737 OnHeapMode GetOnHeapMode() const 738 { 739 return OnHeapModeBits::Get(bitField_); 740 } 741 ToValue()742 uint64_t ToValue() const 743 { 744 return bitField_; 745 } 746 747 private: 748 using TypedLoadOpBits = panda::BitField<TypedLoadOp, 0, TYPED_LOAD_OP_BITS_SIZE>; 749 using OnHeapModeBits = TypedLoadOpBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 750 751 uint64_t bitField_; 752 }; 753 754 class StoreElementAccessor { 755 public: 756 static constexpr int TYPED_STORE_OP_BITS_SIZE = 8; 757 static constexpr int ON_HEAP_MODE_BITS_SIZE = 8; 758 StoreElementAccessor(uint64_t value)759 explicit StoreElementAccessor(uint64_t value): bitField_(value) {} StoreElementAccessor(TypedStoreOp op,OnHeapMode onHeap)760 explicit StoreElementAccessor(TypedStoreOp op, OnHeapMode onHeap) 761 { 762 bitField_ = TypedStoreOpBits::Encode(op) | OnHeapModeBits::Encode(onHeap); 763 } 764 GetTypedStoreOp()765 TypedStoreOp GetTypedStoreOp() const 766 { 767 return TypedStoreOpBits::Get(bitField_); 768 } 769 GetOnHeapMode()770 OnHeapMode GetOnHeapMode() const 771 { 772 return OnHeapModeBits::Get(bitField_); 773 } 774 ToValue()775 uint64_t ToValue() const 776 { 777 return bitField_; 778 } 779 780 private: 781 using TypedStoreOpBits = panda::BitField<TypedStoreOp, 0, TYPED_STORE_OP_BITS_SIZE>; 782 using OnHeapModeBits = TypedStoreOpBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 783 784 uint64_t bitField_; 785 }; 786 787 class StringStatusAccessor { 788 public: type_(value)789 explicit StringStatusAccessor(uint64_t value = 0) : type_(value) {} 790 GetStringStatus()791 uint32_t GetStringStatus() const 792 { 793 return static_cast<uint32_t>(type_); 794 } 795 ToValue()796 uint64_t ToValue() const 797 { 798 return type_; 799 } 800 801 private: 802 uint64_t type_ {0}; 803 }; 804 } // namespace panda::ecmascript::kungfu 805 806 #endif // ECMASCRIPT_COMPILER_SHARE_GATE_META_DATA_H 807