• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 PANDA_LIBPANDAFILE_FILE_ITEMS_H_
17 #define PANDA_LIBPANDAFILE_FILE_ITEMS_H_
18 
19 #include "file.h"
20 #include "file_format_version.h"
21 #include "file_writer.h"
22 #include "macros.h"
23 #include "modifiers.h"
24 #include "type.h"
25 
26 #include <cstddef>
27 #include <cstdint>
28 
29 #include <algorithm>
30 #include <memory>
31 #include <string>
32 #include <variant>
33 #include <vector>
34 #include <list>
35 
36 namespace panda::panda_file {
37 
38 enum class ClassTag : uint8_t {
39     NOTHING = 0x00,
40     INTERFACES = 0x01,
41     SOURCE_LANG = 0x02,
42     RUNTIME_ANNOTATION = 0x03,
43     ANNOTATION = 0x04,
44     SOURCE_FILE = 0x05,
45     RUNTIME_TYPE_ANNOTATION = 0x06,
46     TYPE_ANNOTATION = 0x07
47 };
48 
49 enum class MethodTag : uint8_t {
50     NOTHING = 0x00,
51     CODE = 0x01,
52     SOURCE_LANG = 0x02,
53     RUNTIME_ANNOTATION = 0x03,
54     RUNTIME_PARAM_ANNOTATION = 0x04,
55     DEBUG_INFO = 0x05,
56     ANNOTATION = 0x06,
57     PARAM_ANNOTATION = 0x07,
58     TYPE_ANNOTATION = 0x08,
59     RUNTIME_TYPE_ANNOTATION = 0x09
60 };
61 
62 enum class FieldTag : uint8_t {
63     NOTHING = 0x00,
64     INT_VALUE = 0x01,
65     VALUE = 0x02,
66     RUNTIME_ANNOTATION = 0x03,
67     ANNOTATION = 0x04,
68     RUNTIME_TYPE_ANNOTATION = 0x05,
69     TYPE_ANNOTATION = 0x06
70 };
71 
72 enum class SourceLang : uint8_t { ECMASCRIPT, PANDA_ASSEMBLY, LAST = PANDA_ASSEMBLY };
73 
74 static constexpr size_t ID_SIZE = File::EntityId::GetSize();
75 static constexpr size_t IDX_SIZE = sizeof(uint16_t);
76 static constexpr size_t TAG_SIZE = 1;
77 static constexpr uint32_t INVALID_OFFSET = std::numeric_limits<uint32_t>::max();
78 static constexpr uint32_t INVALID_INDEX = std::numeric_limits<uint32_t>::max();
79 static constexpr uint32_t MAX_INDEX_16 = std::numeric_limits<uint16_t>::max();
80 static constexpr uint32_t MAX_INDEX_32 = std::numeric_limits<uint32_t>::max();
81 
82 enum class IndexType {
83     // 16-bit indexes
84     CLASS = 0x0,
85     METHOD = 0x1,
86     FIELD = 0x2,
87     PROTO = 0x3,
88     LAST_16 = PROTO,
89 
90     // 32-bit indexes
91     LINE_NUMBER_PROG = 0x04,
92     LAST_32 = LINE_NUMBER_PROG,
93 
94     NONE
95 };
96 
97 static constexpr size_t INDEX_COUNT_16 = static_cast<size_t>(IndexType::LAST_16) + 1;
98 
99 class IndexedItem;
100 
101 class BaseItem {
102 public:
103     using VisitorCallBack = std::function<bool(BaseItem *)>;
104 
105     BaseItem() = default;
106     virtual ~BaseItem() = default;
107 
108     DEFAULT_COPY_SEMANTIC(BaseItem);
109     DEFAULT_MOVE_SEMANTIC(BaseItem);
110 
GetSize()111     size_t GetSize() const
112     {
113         return CalculateSize();
114     }
115 
116     virtual size_t CalculateSize() const = 0;
117 
ComputeLayout()118     virtual void ComputeLayout() {};
119 
Alignment()120     virtual size_t Alignment()
121     {
122         return 1;
123     }
124 
IsForeign()125     virtual bool IsForeign() const
126     {
127         return false;
128     }
129 
GetOffset()130     uint32_t GetOffset() const
131     {
132         return offset_;
133     }
134 
GetFileId()135     panda_file::File::EntityId GetFileId() const
136     {
137         return panda_file::File::EntityId(offset_);
138     }
139 
SetOffset(uint32_t offset)140     void SetOffset(uint32_t offset)
141     {
142         offset_ = offset;
143     }
144 
NeedsEmit()145     bool NeedsEmit() const
146     {
147         return needs_emit_;
148     }
149 
SetNeedsEmit(bool needs_emit)150     void SetNeedsEmit(bool needs_emit)
151     {
152         needs_emit_ = needs_emit;
153     }
154 
GetIndexDependencies()155     const std::list<IndexedItem *> &GetIndexDependencies() const
156     {
157         return index_deps_;
158     }
159 
AddIndexDependency(IndexedItem * item)160     void AddIndexDependency(IndexedItem *item)
161     {
162         ASSERT(item != nullptr);
163         index_deps_.push_back(item);
164     }
165 
SetOrderIndex(uint32_t order)166     void SetOrderIndex(uint32_t order)
167     {
168         order_ = order;
169     }
170 
GetOrderIndex()171     uint32_t GetOrderIndex() const
172     {
173         return order_;
174     }
175 
HasOrderIndex()176     bool HasOrderIndex() const
177     {
178         return order_ != INVALID_INDEX;
179     }
180 
181     virtual bool Write(Writer *writer) = 0;
182 
183     virtual std::string GetName() const = 0;
184 
Dump(std::ostream & os)185     virtual void Dump([[maybe_unused]] std::ostream &os) const {}
186 
Visit(const VisitorCallBack & cb)187     virtual void Visit([[maybe_unused]] const VisitorCallBack &cb) {}
188 
189 private:
190     bool needs_emit_ {true};
191     uint32_t offset_ {0};
192     uint32_t order_ {INVALID_INDEX};
193     std::list<IndexedItem *> index_deps_;
194 };
195 
196 class IndexedItem : public BaseItem {
197 public:
IndexedItem()198     IndexedItem()
199     {
200         item_index_ = indexed_item_count_++;
201     }
202 
GetIndex(const BaseItem * item)203     uint32_t GetIndex(const BaseItem *item) const
204     {
205         auto *idx = FindIndex(item);
206         ASSERT(idx != nullptr);
207         return idx->index;
208     }
209 
HasIndex(const BaseItem * item)210     bool HasIndex(const BaseItem *item) const
211     {
212         return FindIndex(item) != nullptr;
213     }
214 
SetIndex(const BaseItem * start,const BaseItem * end,uint32_t index)215     void SetIndex(const BaseItem *start, const BaseItem *end, uint32_t index)
216     {
217         ASSERT(FindIndex(start, end) == nullptr);
218         indexes_.push_back({start, end, index});
219     }
220 
ClearIndexes()221     void ClearIndexes()
222     {
223         indexes_.clear();
224     }
225 
IncRefCount()226     void IncRefCount()
227     {
228         ++ref_count_;
229     }
230 
DecRefCount()231     void DecRefCount()
232     {
233         ASSERT(ref_count_ != 0);
234         --ref_count_;
235     }
236 
GetRefCount()237     size_t GetRefCount() const
238     {
239         return ref_count_;
240     }
241 
GetIndexType()242     virtual IndexType GetIndexType() const
243     {
244         return IndexType::NONE;
245     }
246 
GetIndexedItemCount()247     size_t GetIndexedItemCount() const
248     {
249         return item_index_;
250     }
251 
252 private:
253     struct Index {
254         const BaseItem *start;
255         const BaseItem *end;
256         uint32_t index;
257     };
258 
FindIndex(const BaseItem * start,const BaseItem * end)259     const Index *FindIndex(const BaseItem *start, const BaseItem *end) const
260     {
261         auto it = std::find_if(indexes_.cbegin(), indexes_.cend(),
262                                [start, end](const Index &idx) { return idx.start == start && idx.end == end; });
263 
264         return it != indexes_.cend() ? &*it : nullptr;
265     }
266 
FindIndex(const BaseItem * item)267     const Index *FindIndex(const BaseItem *item) const
268     {
269         ASSERT(item->HasOrderIndex());
270         auto order_idx = item->GetOrderIndex();
271 
272         auto it = std::find_if(indexes_.cbegin(), indexes_.cend(), [order_idx](const Index &idx) {
273             if (idx.start == nullptr && idx.end == nullptr) {
274                 return true;
275             }
276 
277             if (idx.start == nullptr || idx.end == nullptr) {
278                 return false;
279             }
280 
281             ASSERT(idx.start->HasOrderIndex());
282             ASSERT(idx.end->HasOrderIndex());
283             return idx.start->GetOrderIndex() <= order_idx && order_idx < idx.end->GetOrderIndex();
284         });
285 
286         return it != indexes_.cend() ? &*it : nullptr;
287     }
288 
289     std::vector<Index> indexes_;
290     size_t ref_count_ {1};
291     size_t item_index_ {0};
292     static size_t indexed_item_count_;
293 };
294 
295 class TypeItem : public IndexedItem {
296 public:
TypeItem(Type type)297     explicit TypeItem(Type type) : type_(type) {}
298 
TypeItem(Type::TypeId type_id)299     explicit TypeItem(Type::TypeId type_id) : type_(type_id) {}
300 
301     ~TypeItem() override = default;
302 
GetType()303     Type GetType() const
304     {
305         return type_;
306     }
307 
GetIndexType()308     IndexType GetIndexType() const override
309     {
310         return IndexType::CLASS;
311     }
312 
313     DEFAULT_MOVE_SEMANTIC(TypeItem);
314     DEFAULT_COPY_SEMANTIC(TypeItem);
315 
316 private:
317     Type type_;
318 };
319 
320 class PrimitiveTypeItem : public TypeItem {
321 public:
PrimitiveTypeItem(Type type)322     explicit PrimitiveTypeItem(Type type) : PrimitiveTypeItem(type.GetId()) {}
323 
PrimitiveTypeItem(Type::TypeId type_id)324     explicit PrimitiveTypeItem(Type::TypeId type_id) : TypeItem(type_id)
325     {
326         ASSERT(GetType().IsPrimitive());
327         SetNeedsEmit(false);
328         SetOffset(GetType().GetFieldEncoding());
329     }
330 
331     ~PrimitiveTypeItem() override = default;
332 
CalculateSize()333     size_t CalculateSize() const override
334     {
335         return 0;
336     }
337 
Write(Writer * writer)338     bool Write([[maybe_unused]] Writer *writer) override
339     {
340         return true;
341     }
342 
GetName()343     std::string GetName() const override
344     {
345         return "primitive_type_item";
346     }
347 
348     DEFAULT_MOVE_SEMANTIC(PrimitiveTypeItem);
349     DEFAULT_COPY_SEMANTIC(PrimitiveTypeItem);
350 };
351 
352 class StringItem : public BaseItem {
353 public:
354     explicit StringItem(std::string str);
355 
356     ~StringItem() override = default;
357 
358     size_t CalculateSize() const override;
359 
360     bool Write(Writer *writer) override;
361 
GetName()362     std::string GetName() const override
363     {
364         return "string_item";
365     }
366 
GetData()367     const std::string &GetData() const
368     {
369         return str_;
370     }
371 
372     DEFAULT_MOVE_SEMANTIC(StringItem);
373     DEFAULT_COPY_SEMANTIC(StringItem);
374 
375 private:
376     std::string str_;
377     size_t utf16_length_ {0};
378     size_t is_ascii_ {0};
379 };
380 
381 class AnnotationItem;
382 class BaseClassItem;
383 class ClassItem;
384 class ForeignClassItem;
385 class ValueItem;
386 
387 class BaseFieldItem : public IndexedItem {
388 public:
GetIndexType()389     IndexType GetIndexType() const override
390     {
391         return IndexType::FIELD;
392     }
393 
394     ~BaseFieldItem() override = default;
395 
396     DEFAULT_MOVE_SEMANTIC(BaseFieldItem);
397     DEFAULT_COPY_SEMANTIC(BaseFieldItem);
398 
399 protected:
400     BaseFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type);
401 
402     size_t CalculateSize() const override;
403 
404     bool Write(Writer *writer) override;
405 
406 private:
407     BaseClassItem *class_ {nullptr};
408     StringItem *name_ {nullptr};
409     TypeItem *type_ {nullptr};
410 };
411 
412 class FieldItem : public BaseFieldItem {
413 public:
414     FieldItem(ClassItem *cls, StringItem *name, TypeItem *type, uint32_t access_flags);
415 
416     ~FieldItem() override = default;
417 
418     void SetValue(ValueItem *value);
419 
AddRuntimeAnnotation(AnnotationItem * runtime_annotation)420     void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
421     {
422         runtime_annotations_.push_back(runtime_annotation);
423     }
424 
AddAnnotation(AnnotationItem * annotation)425     void AddAnnotation(AnnotationItem *annotation)
426     {
427         annotations_.push_back(annotation);
428     }
429 
AddRuntimeTypeAnnotation(AnnotationItem * runtime_type_annotation)430     void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
431     {
432         runtime_type_annotations_.push_back(runtime_type_annotation);
433     }
434 
AddTypeAnnotation(AnnotationItem * type_annotation)435     void AddTypeAnnotation(AnnotationItem *type_annotation)
436     {
437         type_annotations_.push_back(type_annotation);
438     }
439 
440     size_t CalculateSize() const override;
441 
442     bool Write(Writer *writer) override;
443 
GetName()444     std::string GetName() const override
445     {
446         return "field_item";
447     }
448 
GetRuntimeAnnotations()449     std::vector<AnnotationItem *> *GetRuntimeAnnotations()
450     {
451         return &runtime_annotations_;
452     }
453 
GetAnnotations()454     std::vector<AnnotationItem *> *GetAnnotations()
455     {
456         return &annotations_;
457     }
458 
GetTypeAnnotations()459     std::vector<AnnotationItem *> *GetTypeAnnotations()
460     {
461         return &type_annotations_;
462     }
463 
GetRuntimeTypeAnnotations()464     std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
465     {
466         return &runtime_type_annotations_;
467     }
468 
469     DEFAULT_MOVE_SEMANTIC(FieldItem);
470     DEFAULT_COPY_SEMANTIC(FieldItem);
471 
472 private:
473     bool WriteValue(Writer *writer);
474 
475     bool WriteAnnotations(Writer *writer);
476 
477     bool WriteTaggedData(Writer *writer);
478 
479     uint32_t access_flags_ {0};
480     ValueItem *value_ {nullptr};
481     std::vector<AnnotationItem *> runtime_annotations_;
482     std::vector<AnnotationItem *> annotations_;
483     std::vector<AnnotationItem *> type_annotations_;
484     std::vector<AnnotationItem *> runtime_type_annotations_;
485 };
486 
487 class ProtoItem;
488 class CodeItem;
489 
490 class LineNumberProgramItem : public IndexedItem {
491 public:
492     enum class Opcode : uint8_t {
493         END_SEQUENCE = 0x00,
494         ADVANCE_PC = 0x01,
495         ADVANCE_LINE = 0x02,
496         START_LOCAL = 0x03,
497         START_LOCAL_EXTENDED = 0x04,
498         END_LOCAL = 0x05,
499         RESTART_LOCAL = 0x06,
500         SET_PROLOGUE_END = 0x07,
501         SET_EPILOGUE_BEGIN = 0x08,
502         SET_FILE = 0x09,
503         SET_SOURCE_CODE = 0x0a,
504         SET_COLUMN = 0X0b, // The SET_COLUMN opcode takes a single unsigned LEB128 operand and
505                            // stores it in the column register of the state machine.
506         LAST
507     };
508 
509     static constexpr uint8_t OPCODE_BASE = static_cast<uint8_t>(Opcode::LAST);
510     static constexpr int32_t LINE_RANGE = 15;
511     static constexpr int32_t LINE_BASE = -4;
512 
513     void EmitEnd();
514 
515     void EmitAdvancePc(std::vector<uint8_t> *constant_pool, uint32_t value);
516 
517     void EmitAdvanceLine(std::vector<uint8_t> *constant_pool, int32_t value);
518 
519     void EmitStartLocal(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name,
520                         StringItem *type);
521 
522     void EmitStartLocalExtended(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name,
523                                 StringItem *type, StringItem *type_signature);
524 
525     void EmitEndLocal(int32_t register_number);
526 
527     void EmitRestartLocal(int32_t register_number);
528 
529     bool EmitSpecialOpcode(uint32_t pc_inc, int32_t line_inc);
530 
531     void EmitColumn(std::vector<uint8_t> *constant_pool, uint32_t pc_inc, int32_t column);
532 
533     void EmitPrologEnd();
534 
535     void EmitEpilogBegin();
536 
537     void EmitSetFile(std::vector<uint8_t> *constant_pool, StringItem *source_file);
538 
539     void EmitSetSourceCode(std::vector<uint8_t> *constant_pool, StringItem *source_code);
540 
541     bool Write(Writer *writer) override;
542 
543     size_t CalculateSize() const override;
544 
GetName()545     std::string GetName() const override
546     {
547         return "line_number_program_item";
548     }
549 
GetData()550     const std::vector<uint8_t> &GetData() const
551     {
552         return data_;
553     }
554 
GetIndexType()555     IndexType GetIndexType() const override
556     {
557         return IndexType::LINE_NUMBER_PROG;
558     }
559 
560 private:
561     void EmitOpcode(Opcode opcode);
562     void EmitRegister(int32_t register_number);
563 
564     static void EmitUleb128(std::vector<uint8_t> *data, uint32_t value);
565 
566     static void EmitSleb128(std::vector<uint8_t> *data, int32_t value);
567 
568     std::vector<uint8_t> data_;
569 };
570 
571 class DebugInfoItem : public BaseItem {
572 public:
DebugInfoItem(LineNumberProgramItem * item)573     explicit DebugInfoItem(LineNumberProgramItem *item) : program_(item) {}
574 
575     ~DebugInfoItem() override = default;
576 
577     DEFAULT_MOVE_SEMANTIC(DebugInfoItem);
578     DEFAULT_COPY_SEMANTIC(DebugInfoItem);
579 
GetLineNumber()580     size_t GetLineNumber() const
581     {
582         return line_num_;
583     }
584 
SetLineNumber(size_t line_num)585     void SetLineNumber(size_t line_num)
586     {
587         line_num_ = line_num;
588     }
589 
GetLineNumberProgram()590     LineNumberProgramItem *GetLineNumberProgram() const
591     {
592         return program_;
593     }
594 
SetLineNumberProgram(LineNumberProgramItem * program)595     void SetLineNumberProgram(LineNumberProgramItem *program)
596     {
597         ASSERT(program->GetOffset() != 0);
598         program_ = program;
599     }
600 
AddParameter(StringItem * name)601     void AddParameter(StringItem *name)
602     {
603         parameters_.push_back(name);
604     }
605 
GetConstantPool()606     std::vector<uint8_t> *GetConstantPool()
607     {
608         return &constant_pool_;
609     }
610 
611     size_t CalculateSize() const override;
612 
613     bool Write(Writer *writer) override;
614 
GetName()615     std::string GetName() const override
616     {
617         return "debug_info_item";
618     }
619 
620     void Dump(std::ostream &os) const override;
621 
622 private:
623     size_t line_num_ {0};
624     LineNumberProgramItem *program_;
625     std::vector<uint8_t> constant_pool_;
626     std::vector<StringItem *> parameters_;
627 };
628 
629 class BaseMethodItem : public IndexedItem {
630 public:
GetProto()631     ProtoItem *GetProto() const
632     {
633         return proto_;
634     }
635 
IsStatic()636     bool IsStatic() const
637     {
638         return (access_flags_ & ACC_STATIC) != 0;
639     }
640 
GetIndexType()641     IndexType GetIndexType() const override
642     {
643         return IndexType::METHOD;
644     }
645 
GetNameItem()646     StringItem *GetNameItem() const
647     {
648         return name_;
649     }
650 
651     ~BaseMethodItem() override = default;
652 
653     DEFAULT_MOVE_SEMANTIC(BaseMethodItem);
654     DEFAULT_COPY_SEMANTIC(BaseMethodItem);
655 
656 protected:
657     BaseMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags);
658 
659     size_t CalculateSize() const override;
660 
661     bool Write(Writer *writer) override;
662 
663 private:
664     BaseClassItem *class_ {nullptr};
665     StringItem *name_ {nullptr};
666     ProtoItem *proto_ {nullptr};
667     uint32_t access_flags_ {0};
668 };
669 
670 class MethodParamItem {
671 public:
MethodParamItem(TypeItem * type)672     explicit MethodParamItem(TypeItem *type) : type_(type) {}
673     ~MethodParamItem() = default;
674     DEFAULT_MOVE_SEMANTIC(MethodParamItem);
675     DEFAULT_COPY_SEMANTIC(MethodParamItem);
676 
AddRuntimeAnnotation(AnnotationItem * runtime_annotation)677     void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
678     {
679         runtime_annotations_.push_back(runtime_annotation);
680     }
681 
AddAnnotation(AnnotationItem * annotation)682     void AddAnnotation(AnnotationItem *annotation)
683     {
684         annotations_.push_back(annotation);
685     }
686 
AddRuntimeTypeAnnotation(AnnotationItem * runtime_type_annotation)687     void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
688     {
689         runtime_type_annotations_.push_back(runtime_type_annotation);
690     }
691 
AddTypeAnnotation(AnnotationItem * type_annotation)692     void AddTypeAnnotation(AnnotationItem *type_annotation)
693     {
694         type_annotations_.push_back(type_annotation);
695     }
696 
GetType()697     TypeItem *GetType() const
698     {
699         return type_;
700     }
701 
GetRuntimeAnnotations()702     const std::vector<AnnotationItem *> &GetRuntimeAnnotations() const
703     {
704         return runtime_annotations_;
705     }
706 
GetAnnotations()707     const std::vector<AnnotationItem *> &GetAnnotations() const
708     {
709         return annotations_;
710     }
711 
HasAnnotations()712     bool HasAnnotations() const
713     {
714         return !annotations_.empty();
715     }
716 
HasRuntimeAnnotations()717     bool HasRuntimeAnnotations() const
718     {
719         return !runtime_annotations_.empty();
720     }
721 
722 private:
723     TypeItem *type_;
724     std::vector<AnnotationItem *> runtime_annotations_;
725     std::vector<AnnotationItem *> annotations_;
726     std::vector<AnnotationItem *> type_annotations_;
727     std::vector<AnnotationItem *> runtime_type_annotations_;
728 };
729 
730 class ParamAnnotationsItem;
731 
732 class MethodItem : public BaseMethodItem {
733 public:
734     MethodItem(ClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags,
735                std::vector<MethodParamItem> params);
736 
737     ~MethodItem() override = default;
738 
739     DEFAULT_MOVE_SEMANTIC(MethodItem);
740     DEFAULT_COPY_SEMANTIC(MethodItem);
741 
SetSourceLang(SourceLang lang)742     void SetSourceLang(SourceLang lang)
743     {
744         source_lang_ = lang;
745     }
746 
SetCode(CodeItem * code)747     void SetCode(CodeItem *code)
748     {
749         code_ = code;
750     }
751 
SetDebugInfo(DebugInfoItem * debug_info)752     void SetDebugInfo(DebugInfoItem *debug_info)
753     {
754         debug_info_ = debug_info;
755     }
756 
AddRuntimeAnnotation(AnnotationItem * runtime_annotation)757     void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
758     {
759         runtime_annotations_.push_back(runtime_annotation);
760     }
761 
AddAnnotation(AnnotationItem * annotation)762     void AddAnnotation(AnnotationItem *annotation)
763     {
764         annotations_.push_back(annotation);
765     }
766 
AddRuntimeTypeAnnotation(AnnotationItem * runtime_type_annotation)767     void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
768     {
769         runtime_type_annotations_.push_back(runtime_type_annotation);
770     }
771 
AddTypeAnnotation(AnnotationItem * type_annotation)772     void AddTypeAnnotation(AnnotationItem *type_annotation)
773     {
774         type_annotations_.push_back(type_annotation);
775     }
776 
SetRuntimeParamAnnotationItem(ParamAnnotationsItem * annotations)777     void SetRuntimeParamAnnotationItem(ParamAnnotationsItem *annotations)
778     {
779         runtime_param_annotations_ = annotations;
780     }
781 
SetParamAnnotationItem(ParamAnnotationsItem * annotations)782     void SetParamAnnotationItem(ParamAnnotationsItem *annotations)
783     {
784         param_annotations_ = annotations;
785     }
786 
HasRuntimeParamAnnotations()787     bool HasRuntimeParamAnnotations() const
788     {
789         return std::any_of(params_.cbegin(), params_.cend(),
790                            [](const MethodParamItem &item) { return item.HasRuntimeAnnotations(); });
791     }
792 
HasParamAnnotations()793     bool HasParamAnnotations() const
794     {
795         return std::any_of(params_.cbegin(), params_.cend(),
796                            [](const MethodParamItem &item) { return item.HasAnnotations(); });
797     }
798 
GetCode()799     CodeItem *GetCode() const
800     {
801         return code_;
802     }
803 
GetDebugInfo()804     DebugInfoItem *GetDebugInfo() const
805     {
806         return debug_info_;
807     }
808 
809     size_t CalculateSize() const override;
810 
811     bool Write(Writer *writer) override;
812 
GetName()813     std::string GetName() const override
814     {
815         return "method_item";
816     }
817 
GetParams()818     std::vector<MethodParamItem> &GetParams()
819     {
820         return params_;
821     }
822 
GetRuntimeAnnotations()823     std::vector<AnnotationItem *> *GetRuntimeAnnotations()
824     {
825         return &runtime_annotations_;
826     }
827 
GetAnnotations()828     std::vector<AnnotationItem *> *GetAnnotations()
829     {
830         return &annotations_;
831     }
832 
GetTypeAnnotations()833     std::vector<AnnotationItem *> *GetTypeAnnotations()
834     {
835         return &type_annotations_;
836     }
837 
GetRuntimeTypeAnnotations()838     std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
839     {
840         return &runtime_type_annotations_;
841     }
842 
843 private:
844     bool WriteRuntimeAnnotations(Writer *writer);
845 
846     bool WriteTypeAnnotations(Writer *writer);
847 
848     bool WriteTaggedData(Writer *writer);
849 
850     std::vector<MethodParamItem> params_;
851 
852     SourceLang source_lang_;
853     CodeItem *code_;
854     DebugInfoItem *debug_info_;
855     std::vector<AnnotationItem *> runtime_annotations_;
856     std::vector<AnnotationItem *> annotations_;
857     std::vector<AnnotationItem *> type_annotations_;
858     std::vector<AnnotationItem *> runtime_type_annotations_;
859     ParamAnnotationsItem *runtime_param_annotations_ {nullptr};
860     ParamAnnotationsItem *param_annotations_ {nullptr};
861 };
862 
863 class BaseClassItem : public TypeItem {
864 public:
GetNameItem()865     StringItem *GetNameItem()
866     {
867         return &name_;
868     }
869 
870 protected:
BaseClassItem(const std::string & name)871     explicit BaseClassItem(const std::string &name) : TypeItem(Type::TypeId::REFERENCE), name_(name) {}
872 
873     ~BaseClassItem() override = default;
874 
875     size_t CalculateSize() const override;
876 
877     void ComputeLayout() override;
878 
879     bool Write(Writer *writer) override;
880 
881     DEFAULT_MOVE_SEMANTIC(BaseClassItem);
882     DEFAULT_COPY_SEMANTIC(BaseClassItem);
883 
884 private:
885     StringItem name_;
886 };
887 
888 class ClassItem : public BaseClassItem {
889 public:
ClassItem(const std::string & name)890     explicit ClassItem(const std::string &name)
891         : BaseClassItem(name),
892           super_class_(nullptr),
893           access_flags_(0),
894           source_lang_(SourceLang::PANDA_ASSEMBLY),
895           source_file_(nullptr)
896     {
897     }
898 
899     ~ClassItem() override = default;
900 
SetAccessFlags(uint32_t access_flags)901     void SetAccessFlags(uint32_t access_flags)
902     {
903         access_flags_ = access_flags;
904     }
905 
SetSourceLang(SourceLang lang)906     void SetSourceLang(SourceLang lang)
907     {
908         source_lang_ = lang;
909     }
910 
SetSuperClass(BaseClassItem * super_class)911     void SetSuperClass(BaseClassItem *super_class)
912     {
913         super_class_ = super_class;
914     }
915 
AddInterface(BaseClassItem * iface)916     void AddInterface(BaseClassItem *iface)
917     {
918         AddIndexDependency(iface);
919         ifaces_.push_back(iface);
920     }
921 
AddRuntimeAnnotation(AnnotationItem * runtime_annotation)922     void AddRuntimeAnnotation(AnnotationItem *runtime_annotation)
923     {
924         runtime_annotations_.push_back(runtime_annotation);
925     }
926 
AddAnnotation(AnnotationItem * annotation)927     void AddAnnotation(AnnotationItem *annotation)
928     {
929         annotations_.push_back(annotation);
930     }
931 
AddRuntimeTypeAnnotation(AnnotationItem * runtime_type_annotation)932     void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)
933     {
934         runtime_type_annotations_.push_back(runtime_type_annotation);
935     }
936 
AddTypeAnnotation(AnnotationItem * type_annotation)937     void AddTypeAnnotation(AnnotationItem *type_annotation)
938     {
939         type_annotations_.push_back(type_annotation);
940     }
941 
942     template <class... Args>
AddField(Args...args)943     FieldItem *AddField(Args... args)
944     {
945         fields_.emplace_back(std::make_unique<FieldItem>(this, std::forward<Args>(args)...));
946         return fields_.back().get();
947     }
948 
949     template <class... Args>
AddMethod(Args...args)950     MethodItem *AddMethod(Args... args)
951     {
952         methods_.emplace_back(std::make_unique<MethodItem>(this, std::forward<Args>(args)...));
953         return methods_.back().get();
954     }
955 
SetSourceFile(StringItem * item)956     void SetSourceFile(StringItem *item)
957     {
958         source_file_ = item;
959     }
960 
961     size_t CalculateSizeWithoutFieldsAndMethods() const;
962 
963     size_t CalculateSize() const override;
964 
965     void ComputeLayout() override;
966 
967     bool Write(Writer *writer) override;
968 
GetName()969     std::string GetName() const override
970     {
971         return "class_item";
972     }
973 
VisitFields(const VisitorCallBack & cb)974     void VisitFields(const VisitorCallBack &cb)
975     {
976         for (auto &field : fields_) {
977             cb(field.get());
978         }
979     }
980 
VisitMethods(const VisitorCallBack & cb)981     void VisitMethods(const VisitorCallBack &cb)
982     {
983         for (auto &method : methods_) {
984             cb(method.get());
985         }
986     }
987 
Visit(const VisitorCallBack & cb)988     void Visit(const VisitorCallBack &cb) override
989     {
990         VisitFields(cb);
991         VisitMethods(cb);
992     }
993 
GetRuntimeAnnotations()994     std::vector<AnnotationItem *> *GetRuntimeAnnotations()
995     {
996         return &runtime_annotations_;
997     }
998 
GetAnnotations()999     std::vector<AnnotationItem *> *GetAnnotations()
1000     {
1001         return &annotations_;
1002     }
1003 
GetTypeAnnotations()1004     std::vector<AnnotationItem *> *GetTypeAnnotations()
1005     {
1006         return &type_annotations_;
1007     }
1008 
GetRuntimeTypeAnnotations()1009     std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations()
1010     {
1011         return &runtime_type_annotations_;
1012     }
1013 
1014     DEFAULT_MOVE_SEMANTIC(ClassItem);
1015     DEFAULT_COPY_SEMANTIC(ClassItem);
1016 
1017 private:
1018     bool WriteIfaces(Writer *writer);
1019 
1020     bool WriteAnnotations(Writer *writer);
1021 
1022     bool WriteTaggedData(Writer *writer);
1023 
1024     BaseClassItem *super_class_;
1025     uint32_t access_flags_;
1026     SourceLang source_lang_;
1027     std::vector<BaseClassItem *> ifaces_;
1028     std::vector<AnnotationItem *> runtime_annotations_;
1029     std::vector<AnnotationItem *> annotations_;
1030     std::vector<AnnotationItem *> type_annotations_;
1031     std::vector<AnnotationItem *> runtime_type_annotations_;
1032     StringItem *source_file_;
1033     std::vector<std::unique_ptr<FieldItem>> fields_;
1034     std::vector<std::unique_ptr<MethodItem>> methods_;
1035 };
1036 
1037 class ForeignClassItem : public BaseClassItem {
1038 public:
ForeignClassItem(const std::string & name)1039     explicit ForeignClassItem(const std::string &name) : BaseClassItem(name) {}
1040 
1041     ~ForeignClassItem() override = default;
1042 
IsForeign()1043     bool IsForeign() const override
1044     {
1045         return true;
1046     }
1047 
GetName()1048     std::string GetName() const override
1049     {
1050         return "foreign_class_item";
1051     }
1052 
1053     DEFAULT_MOVE_SEMANTIC(ForeignClassItem);
1054     DEFAULT_COPY_SEMANTIC(ForeignClassItem);
1055 };
1056 
1057 class ForeignFieldItem : public BaseFieldItem {
1058 public:
ForeignFieldItem(BaseClassItem * cls,StringItem * name,TypeItem * type)1059     ForeignFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type) : BaseFieldItem(cls, name, type) {}
1060 
1061     ~ForeignFieldItem() override = default;
1062 
IsForeign()1063     bool IsForeign() const override
1064     {
1065         return true;
1066     }
1067 
GetName()1068     std::string GetName() const override
1069     {
1070         return "foreign_field_item";
1071     }
1072 
1073     DEFAULT_MOVE_SEMANTIC(ForeignFieldItem);
1074     DEFAULT_COPY_SEMANTIC(ForeignFieldItem);
1075 };
1076 
1077 class ForeignMethodItem : public BaseMethodItem {
1078 public:
ForeignMethodItem(BaseClassItem * cls,StringItem * name,ProtoItem * proto,uint32_t access_flags)1079     ForeignMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags)
1080         : BaseMethodItem(cls, name, proto, access_flags)
1081     {
1082     }
1083 
1084     ~ForeignMethodItem() override = default;
1085 
IsForeign()1086     bool IsForeign() const override
1087     {
1088         return true;
1089     }
1090 
GetName()1091     std::string GetName() const override
1092     {
1093         return "foreign_method_item";
1094     }
1095 
1096     DEFAULT_MOVE_SEMANTIC(ForeignMethodItem);
1097     DEFAULT_COPY_SEMANTIC(ForeignMethodItem);
1098 };
1099 
1100 class ProtoItem;
1101 
1102 class ParamAnnotationsItem : public BaseItem {
1103 public:
1104     ParamAnnotationsItem(MethodItem *method, bool is_runtime_annotations);
1105 
1106     ~ParamAnnotationsItem() override = default;
1107 
GetName()1108     std::string GetName() const override
1109     {
1110         return "param_annotations_item";
1111     }
1112 
1113     size_t CalculateSize() const override;
1114 
1115     bool Write(Writer *writer) override;
1116 
1117     DEFAULT_MOVE_SEMANTIC(ParamAnnotationsItem);
1118     DEFAULT_COPY_SEMANTIC(ParamAnnotationsItem);
1119 
1120 private:
1121     std::vector<std::vector<AnnotationItem *>> annotations_;
1122 };
1123 
1124 class ProtoItem : public IndexedItem {
1125 public:
1126     ProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> &params);
1127 
1128     ~ProtoItem() override = default;
1129 
1130     DEFAULT_MOVE_SEMANTIC(ProtoItem);
1131     DEFAULT_COPY_SEMANTIC(ProtoItem);
1132 
CalculateSize()1133     size_t CalculateSize() const override
1134     {
1135         size_t size = shorty_.size() * sizeof(uint16_t);
1136         size += reference_types_.size() * IDX_SIZE;
1137         return size;
1138     }
1139 
1140     bool Write(Writer *writer) override;
1141 
GetName()1142     std::string GetName() const override
1143     {
1144         return "proto_item";
1145     }
1146 
GetIndexType()1147     IndexType GetIndexType() const override
1148     {
1149         return IndexType::PROTO;
1150     }
1151 
Alignment()1152     size_t Alignment() override
1153     {
1154         return sizeof(uint16_t);
1155     }
1156 
1157 private:
1158     static constexpr size_t SHORTY_ELEM_SIZE = 4;
1159 
1160     void AddType(TypeItem *type, size_t *n);
1161 
1162     std::vector<uint16_t> shorty_;
1163     std::vector<TypeItem *> reference_types_;
1164 };
1165 
1166 class CodeItem : public BaseItem {
1167 public:
1168     class CatchBlock : public BaseItem {
1169     public:
1170         CatchBlock(MethodItem *method, BaseClassItem *type, size_t handler_pc, size_t code_size = 0)
method_(method)1171             : method_(method), type_(type), handler_pc_(handler_pc), code_size_(code_size)
1172         {
1173         }
1174 
1175         ~CatchBlock() override = default;
1176 
1177         DEFAULT_MOVE_SEMANTIC(CatchBlock);
1178         DEFAULT_COPY_SEMANTIC(CatchBlock);
1179 
1180         size_t CalculateSize() const override;
1181 
1182         bool Write(Writer *writer) override;
1183 
GetName()1184         std::string GetName() const override
1185         {
1186             return "catch_block_item";
1187         }
1188 
1189     private:
1190         MethodItem *method_;
1191         BaseClassItem *type_;
1192         size_t handler_pc_;
1193         size_t code_size_;
1194     };
1195 
1196     class TryBlock : public BaseItem {
1197     public:
TryBlock(size_t start_pc,size_t length,std::vector<CatchBlock> catch_blocks)1198         TryBlock(size_t start_pc, size_t length, std::vector<CatchBlock> catch_blocks)
1199             : start_pc_(start_pc), length_(length), catch_blocks_(std::move(catch_blocks))
1200         {
1201         }
1202 
1203         ~TryBlock() override = default;
1204 
1205         DEFAULT_MOVE_SEMANTIC(TryBlock);
1206         DEFAULT_COPY_SEMANTIC(TryBlock);
1207 
1208         size_t CalculateSizeWithoutCatchBlocks() const;
1209 
1210         void ComputeLayout() override;
1211 
1212         size_t CalculateSize() const override;
1213 
1214         bool Write(Writer *writer) override;
1215 
GetName()1216         std::string GetName() const override
1217         {
1218             return "try_block_item";
1219         }
1220 
1221     private:
1222         size_t start_pc_;
1223         size_t length_;
1224         std::vector<CatchBlock> catch_blocks_;
1225     };
1226 
CodeItem(size_t num_vregs,size_t num_args,std::vector<uint8_t> instructions)1227     CodeItem(size_t num_vregs, size_t num_args, std::vector<uint8_t> instructions)
1228         : num_vregs_(num_vregs), num_args_(num_args), instructions_(std::move(instructions))
1229     {
1230     }
1231 
1232     CodeItem() = default;
1233 
1234     ~CodeItem() override = default;
1235 
SetNumVregs(size_t num_vregs)1236     void SetNumVregs(size_t num_vregs)
1237     {
1238         num_vregs_ = num_vregs;
1239     }
1240 
SetNumArgs(size_t num_args)1241     void SetNumArgs(size_t num_args)
1242     {
1243         num_args_ = num_args;
1244     }
1245 
GetInstructions()1246     std::vector<uint8_t> *GetInstructions()
1247     {
1248         return &instructions_;
1249     }
1250 
SetNumInstructions(size_t num_ins)1251     void SetNumInstructions(size_t num_ins)
1252     {
1253         num_ins_ = num_ins;
1254     }
1255 
GetNumInstructions()1256     size_t GetNumInstructions() const
1257     {
1258         return num_ins_;
1259     }
1260 
AddTryBlock(const TryBlock & try_block)1261     void AddTryBlock(const TryBlock &try_block)
1262     {
1263         try_blocks_.push_back(try_block);
1264     }
1265 
1266     size_t CalculateSizeWithoutTryBlocks() const;
1267 
1268     void ComputeLayout() override;
1269 
1270     size_t CalculateSize() const override;
1271 
1272     size_t GetCodeSize() const;
1273 
1274     bool Write(Writer *writer) override;
1275 
GetName()1276     std::string GetName() const override
1277     {
1278         return "code_item";
1279     }
1280 
1281     DEFAULT_MOVE_SEMANTIC(CodeItem);
1282     DEFAULT_COPY_SEMANTIC(CodeItem);
1283 
1284 private:
1285     size_t num_vregs_ {0};
1286     size_t num_args_ {0};
1287     size_t num_ins_ {0};
1288     std::vector<uint8_t> instructions_;
1289     std::vector<TryBlock> try_blocks_;
1290 };
1291 
1292 class ScalarValueItem;
1293 class ArrayValueItem;
1294 
1295 class ValueItem : public BaseItem {
1296 public:
1297     enum class Type { INTEGER, LONG, FLOAT, DOUBLE, ID, ARRAY };
1298 
ValueItem(Type type)1299     explicit ValueItem(Type type) : type_(type) {}
1300 
1301     ~ValueItem() override = default;
1302 
1303     DEFAULT_MOVE_SEMANTIC(ValueItem);
1304     DEFAULT_COPY_SEMANTIC(ValueItem);
1305 
GetType()1306     Type GetType() const
1307     {
1308         return type_;
1309     }
1310 
IsArray()1311     bool IsArray() const
1312     {
1313         return type_ == Type::ARRAY;
1314     }
1315 
Is32bit()1316     bool Is32bit() const
1317     {
1318         return type_ == Type::INTEGER || type_ == Type::FLOAT || type_ == Type::ID;
1319     }
1320 
GetName()1321     std::string GetName() const override
1322     {
1323         return "value_item";
1324     }
1325 
1326     const ScalarValueItem *GetAsScalar() const;
1327 
1328     const ArrayValueItem *GetAsArray() const;
1329 
1330 private:
1331     Type type_;
1332 };
1333 
1334 class ScalarValueItem : public ValueItem {
1335 public:
ScalarValueItem(uint32_t v)1336     explicit ScalarValueItem(uint32_t v) : ValueItem(Type::INTEGER), value_(v) {}
1337 
ScalarValueItem(uint64_t v)1338     explicit ScalarValueItem(uint64_t v) : ValueItem(Type::LONG), value_(v) {}
1339 
ScalarValueItem(float v)1340     explicit ScalarValueItem(float v) : ValueItem(Type::FLOAT), value_(v) {}
1341 
ScalarValueItem(double v)1342     explicit ScalarValueItem(double v) : ValueItem(Type::DOUBLE), value_(v) {}
1343 
ScalarValueItem(BaseItem * v)1344     explicit ScalarValueItem(BaseItem *v) : ValueItem(Type::ID), value_(v) {}
1345 
1346     ~ScalarValueItem() override = default;
1347 
1348     DEFAULT_MOVE_SEMANTIC(ScalarValueItem);
1349     DEFAULT_COPY_SEMANTIC(ScalarValueItem);
1350 
1351     template <class T>
GetValue()1352     T GetValue() const
1353     {
1354         return std::get<T>(value_);
1355     }
1356 
GetId()1357     File::EntityId GetId() const
1358     {
1359         return File::EntityId(GetValue<BaseItem *>()->GetOffset());
1360     }
1361 
1362     size_t GetULeb128EncodedSize();
1363 
1364     size_t GetSLeb128EncodedSize() const;
1365 
1366     size_t CalculateSize() const override;
1367 
1368     size_t Alignment() override;
1369 
1370     bool Write(Writer *writer) override;
1371 
1372     bool WriteAsUleb128(Writer *writer);
1373 
1374 private:
1375     std::variant<uint32_t, uint64_t, float, double, BaseItem *> value_;
1376 };
1377 
1378 class ArrayValueItem : public ValueItem {
1379 public:
ArrayValueItem(panda_file::Type component_type,std::vector<ScalarValueItem> items)1380     ArrayValueItem(panda_file::Type component_type, std::vector<ScalarValueItem> items)
1381         : ValueItem(Type::ARRAY), component_type_(component_type), items_(std::move(items))
1382     {
1383     }
1384 
1385     ~ArrayValueItem() override = default;
1386 
1387     DEFAULT_MOVE_SEMANTIC(ArrayValueItem);
1388     DEFAULT_COPY_SEMANTIC(ArrayValueItem);
1389 
1390     size_t CalculateSize() const override;
1391 
1392     void ComputeLayout() override;
1393 
1394     bool Write(Writer *writer) override;
1395 
1396 private:
1397     size_t GetComponentSize() const;
1398 
1399     panda_file::Type component_type_;
1400     std::vector<ScalarValueItem> items_;
1401 };
1402 
1403 class LiteralItem;
1404 class LiteralArrayItem;
1405 
1406 class LiteralItem : public BaseItem {
1407 public:
1408     enum class Type { B1, B2, B4, B8, STRING, METHOD };
1409 
LiteralItem(uint8_t v)1410     explicit LiteralItem(uint8_t v) : type_(Type::B1), value_(v) {}
1411 
LiteralItem(uint16_t v)1412     explicit LiteralItem(uint16_t v) : type_(Type::B2), value_(v) {}
1413 
LiteralItem(uint32_t v)1414     explicit LiteralItem(uint32_t v) : type_(Type::B4), value_(v) {}
1415 
LiteralItem(uint64_t v)1416     explicit LiteralItem(uint64_t v) : type_(Type::B8), value_(v) {}
1417 
LiteralItem(StringItem * v)1418     explicit LiteralItem(StringItem *v) : type_(Type::STRING), value_(v) {}
1419 
LiteralItem(MethodItem * v)1420     explicit LiteralItem(MethodItem *v) : type_(Type::METHOD), value_(v) {}
1421 
1422     ~LiteralItem() override = default;
1423 
1424     DEFAULT_MOVE_SEMANTIC(LiteralItem);
1425     DEFAULT_COPY_SEMANTIC(LiteralItem);
1426 
GetType()1427     Type GetType() const
1428     {
1429         return type_;
1430     }
1431 
GetName()1432     std::string GetName() const override
1433     {
1434         return "literal_item";
1435     }
1436 
1437     template <class T>
GetValue()1438     T GetValue() const
1439     {
1440         return std::get<T>(value_);
1441     }
1442 
1443     size_t CalculateSize() const override;
1444 
1445     size_t Alignment() override;
1446 
GetId()1447     File::EntityId GetId() const
1448     {
1449         return File::EntityId(GetValue<StringItem *>()->GetOffset());
1450     }
1451 
GetMethodId()1452     File::EntityId GetMethodId() const
1453     {
1454         return File::EntityId(GetValue<MethodItem *>()->GetFileId());
1455     }
1456 
1457     bool Write(Writer *writer) override;
1458 
1459 private:
1460     Type type_;
1461     std::variant<uint8_t, uint16_t, uint32_t, uint64_t, StringItem *, MethodItem *> value_;
1462 };
1463 
1464 class LiteralArrayItem : public ValueItem {
1465 public:
LiteralArrayItem()1466     explicit LiteralArrayItem() : ValueItem(Type::ARRAY) {}
1467 
1468     ~LiteralArrayItem() override = default;
1469 
1470     DEFAULT_MOVE_SEMANTIC(LiteralArrayItem);
1471     DEFAULT_COPY_SEMANTIC(LiteralArrayItem);
1472 
1473     void AddItems(const std::vector<LiteralItem> &item);
1474 
1475     size_t CalculateSize() const override;
1476 
1477     void ComputeLayout() override;
1478 
1479     bool Write(Writer *writer) override;
1480 
1481 private:
1482     std::vector<LiteralItem> items_;
1483 };
1484 
1485 class AnnotationItem : public BaseItem {
1486 public:
1487     class Elem {
1488     public:
Elem(StringItem * name,ValueItem * value)1489         Elem(StringItem *name, ValueItem *value) : name_(name), value_(value)
1490         {
1491             value_->SetNeedsEmit(!value_->Is32bit());
1492         }
1493 
1494         ~Elem() = default;
1495 
1496         DEFAULT_MOVE_SEMANTIC(Elem);
1497         DEFAULT_COPY_SEMANTIC(Elem);
1498 
GetName()1499         StringItem *GetName()
1500         {
1501             return name_;
1502         }
1503 
GetValue()1504         ValueItem *GetValue()
1505         {
1506             return value_;
1507         }
1508 
SetValue(ValueItem * item)1509         void SetValue(ValueItem *item)
1510         {
1511             value_ = item;
1512         }
1513 
1514     private:
1515         StringItem *name_;
1516         ValueItem *value_;
1517     };
1518 
1519     class Tag {
1520     public:
Tag(char item)1521         explicit Tag(char item) : item_(item) {}
1522 
1523         ~Tag() = default;
1524 
1525         DEFAULT_MOVE_SEMANTIC(Tag);
1526         DEFAULT_COPY_SEMANTIC(Tag);
1527 
GetItem()1528         uint8_t GetItem() const
1529         {
1530             return item_;
1531         }
1532 
1533     private:
1534         uint8_t item_;
1535     };
1536 
AnnotationItem(BaseClassItem * cls,std::vector<Elem> elements,std::vector<Tag> tags)1537     AnnotationItem(BaseClassItem *cls, std::vector<Elem> elements, std::vector<Tag> tags)
1538         : class_(cls), elements_(std::move(elements)), tags_(std::move(tags))
1539     {
1540         AddIndexDependency(cls);
1541     }
1542 
1543     ~AnnotationItem() override = default;
1544 
1545     DEFAULT_MOVE_SEMANTIC(AnnotationItem);
1546     DEFAULT_COPY_SEMANTIC(AnnotationItem);
1547 
1548     size_t CalculateSize() const override;
1549 
1550     bool Write(Writer *writer) override;
1551 
GetName()1552     std::string GetName() const override
1553     {
1554         return "annotation_item";
1555     }
1556 
GetElements()1557     std::vector<Elem> *GetElements()
1558     {
1559         return &elements_;
1560     }
1561 
GetTags()1562     const std::vector<Tag> &GetTags() const
1563     {
1564         return tags_;
1565     }
1566 
1567 private:
1568     BaseClassItem *class_;
1569     std::vector<Elem> elements_;
1570     std::vector<Tag> tags_;
1571 };
1572 
1573 enum class MethodHandleType : uint8_t {
1574     PUT_STATIC = 0x00,
1575     GET_STATIC = 0x01,
1576     PUT_INSTANCE = 0x02,
1577     GET_INSTANCE = 0x03,
1578     INVOKE_STATIC = 0x04,
1579     INVOKE_INSTANCE = 0x05,
1580     INVOKE_CONSTRUCTOR = 0x06,
1581     INVOKE_DIRECT = 0x07,
1582     INVOKE_INTERFACE = 0x08
1583 };
1584 
1585 class MethodHandleItem : public BaseItem {
1586 public:
MethodHandleItem(MethodHandleType type,BaseItem * entity)1587     MethodHandleItem(MethodHandleType type, BaseItem *entity) : type_(type), entity_(entity) {}
1588 
1589     ~MethodHandleItem() override = default;
1590 
1591     DEFAULT_MOVE_SEMANTIC(MethodHandleItem);
1592     DEFAULT_COPY_SEMANTIC(MethodHandleItem);
1593 
CalculateSize()1594     size_t CalculateSize() const override
1595     {
1596         return sizeof(uint8_t) + leb128::UnsignedEncodingSize(entity_->GetOffset());
1597     }
1598 
1599     bool Write(Writer *writer) override;
1600 
GetName()1601     std::string GetName() const override
1602     {
1603         return "method_handle_item";
1604     }
1605 
GetType()1606     MethodHandleType GetType() const
1607     {
1608         return type_;
1609     }
1610 
1611 private:
1612     MethodHandleType type_;
1613     BaseItem *entity_;
1614 };
1615 
1616 enum class ArgumentType : uint8_t {
1617     INTEGER = 0x00,
1618     LONG = 0x01,
1619     FLOAT = 0x02,
1620     DOUBLE = 0x03,
1621     STRING = 0x04,
1622     CLASS = 0x05,
1623     METHOD_HANDLE = 0x06,
1624     METHOD_TYPE = 0x07
1625 };
1626 
1627 }  // namespace panda::panda_file
1628 
1629 #endif  // PANDA_LIBPANDAFILE_FILE_ITEMS_H_
1630