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