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