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> ¶ms); 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