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