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