• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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