1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef LIBPANDAFILE_FILE_ITEMS_H 17 #define LIBPANDAFILE_FILE_ITEMS_H 18 19 #include "file.h" 20 #include "file_writer.h" 21 #include "macros.h" 22 #include "modifiers.h" 23 #include "type.h" 24 #include "file_format_version.h" 25 #include "source_lang_enum.h" 26 27 #include <cstddef> 28 #include <cstdint> 29 30 #include <algorithm> 31 #include <memory> 32 #include <string> 33 #include <variant> 34 #include <vector> 35 #include <list> 36 #include <set> 37 38 namespace panda::panda_file { 39 40 enum class ClassTag : uint8_t { 41 NOTHING = 0x00, 42 INTERFACES = 0x01, 43 SOURCE_LANG = 0x02, 44 RUNTIME_ANNOTATION = 0x03, 45 ANNOTATION = 0x04, 46 RUNTIME_TYPE_ANNOTATION = 0x05, 47 TYPE_ANNOTATION = 0x06, 48 SOURCE_FILE = 0x07 49 }; 50 51 enum class MethodTag : uint8_t { 52 NOTHING = 0x00, 53 CODE = 0x01, 54 SOURCE_LANG = 0x02, 55 RUNTIME_ANNOTATION = 0x03, 56 RUNTIME_PARAM_ANNOTATION = 0x04, 57 DEBUG_INFO = 0x05, 58 ANNOTATION = 0x06, 59 PARAM_ANNOTATION = 0x07, 60 TYPE_ANNOTATION = 0x08, 61 RUNTIME_TYPE_ANNOTATION = 0x09 62 }; 63 64 enum class FieldTag : uint8_t { 65 NOTHING = 0x00, 66 INT_VALUE = 0x01, 67 VALUE = 0x02, 68 RUNTIME_ANNOTATION = 0x03, 69 ANNOTATION = 0x04, 70 RUNTIME_TYPE_ANNOTATION = 0x05, 71 TYPE_ANNOTATION = 0x06 72 }; 73 74 enum class FunctionKind : uint8_t { 75 NONE = 0x0, 76 FUNCTION = 0x1, 77 NC_FUNCTION = 0x2, 78 GENERATOR_FUNCTION = 0x3, 79 ASYNC_FUNCTION = 0x4, 80 ASYNC_GENERATOR_FUNCTION = 0x5, 81 ASYNC_NC_FUNCTION = 0x6, 82 CONCURRENT_FUNCTION = 0x7, 83 // Use bit operation to support both sendable function and async sendable function 84 SENDABLE_FUNCTION = 1 << 3 85 }; 86 87 enum class ItemRank : uint8_t { 88 DEFAULT_RANK = 0x0, 89 STRING_ITEM_RANK = 0x1, 90 CLASS_ITEM_RANK = 0x2 91 }; 92 93 enum class ItemTypes { 94 ANNOTATION_ITEM, 95 CATCH_BLOCK_ITEM, 96 CLASS_INDEX_ITEM, 97 CLASS_ITEM, 98 CODE_ITEM, 99 DEBUG_INFO_ITEM, 100 END_ITEM, 101 FIELD_INDEX_ITEM, 102 FIELD_ITEM, 103 FOREIGN_CLASS_ITEM, 104 FOREIGN_FIELD_ITEM, 105 FOREIGN_METHOD_ITEM, 106 INDEX_HEADER, 107 INDEX_SECTION, 108 LINE_NUMBER_PROGRAM_INDEX_ITEM, 109 LINE_NUMBER_PROGRAM_ITEM, 110 LITERAL_ARRAY_ITEM, 111 LITERAL_ITEM, 112 METHOD_HANDLE_ITEM, 113 METHOD_INDEX_ITEM, 114 METHOD_ITEM, 115 PARAM_ANNOTATIONS_ITEM, 116 PRIMITIVE_TYPE_ITEM, 117 PROTO_INDEX_ITEM, 118 PROTO_ITEM, 119 STRING_ITEM, 120 TRY_BLOCK_ITEM, 121 VALUE_ITEM 122 }; 123 124 bool IsDynamicLanguage(panda::panda_file::SourceLang lang); 125 std::optional<panda::panda_file::SourceLang> LanguageFromString(const std::string_view &lang); 126 const char *LanguageToString(panda::panda_file::SourceLang lang); 127 const char *GetCtorName(panda::panda_file::SourceLang lang); 128 const char *GetCctorName(panda::panda_file::SourceLang lang); 129 const char *GetStringClassDescriptor(panda::panda_file::SourceLang lang); 130 std::string ItemTypeToString(ItemTypes type); 131 132 static constexpr size_t ID_SIZE = File::EntityId::GetSize(); 133 static constexpr size_t IDX_SIZE = sizeof(uint16_t); 134 static constexpr size_t TAG_SIZE = 1; 135 static constexpr uint32_t INVALID_OFFSET = std::numeric_limits<uint32_t>::max(); 136 static constexpr uint32_t INVALID_INDEX = std::numeric_limits<uint32_t>::max(); 137 static constexpr uint32_t MAX_INDEX_32 = std::numeric_limits<uint32_t>::max(); 138 static constexpr uint32_t FLAG_WIDTH = 8; 139 static constexpr uint32_t FUNTION_KIND_WIDTH = 8; 140 static constexpr uint32_t FUNCTION_KIND_MASK = 0xFF00; 141 static constexpr uint32_t FLAG_MASK = 0xFF; 142 143 constexpr uint16_t INVALID_INDEX_16 = std::numeric_limits<uint16_t>::max(); 144 constexpr uint32_t MAX_INDEX_16 = std::numeric_limits<uint16_t>::max() - 1; 145 146 constexpr uint32_t PGO_STRING_DEFAULT_COUNT = 5; 147 constexpr uint32_t PGO_CLASS_DEFAULT_COUNT = 3; 148 constexpr uint32_t PGO_CODE_DEFAULT_COUNT = 1; 149 150 constexpr std::string_view STRING_ITEM = "string_item"; 151 constexpr std::string_view CLASS_ITEM = "class_item"; 152 constexpr std::string_view CODE_ITEM = "code_item"; 153 154 enum class IndexType { 155 // 16-bit indexes 156 CLASS = 0x0, 157 METHOD_STRING_LITERAL = 0x1, 158 FIELD = 0x2, 159 PROTO = 0x3, 160 LAST_16 = PROTO, 161 // 32-bit indexes 162 LINE_NUMBER_PROG = 0x04, 163 LAST_32 = LINE_NUMBER_PROG, 164 165 NONE 166 }; 167 168 static constexpr size_t INDEX_COUNT_16 = static_cast<size_t>(IndexType::LAST_16) + 1; 169 170 class IndexedItem; 171 class ItemContainer; 172 173 class BaseItem { 174 public: 175 using VisitorCallBack = std::function<bool(BaseItem *)>; 176 177 BaseItem() = default; 178 virtual ~BaseItem() = default; 179 180 DEFAULT_COPY_SEMANTIC(BaseItem); 181 DEFAULT_MOVE_SEMANTIC(BaseItem); 182 GetSize() const183 size_t GetSize() const 184 { 185 return CalculateSize(); 186 } 187 188 virtual size_t CalculateSize() const = 0; 189 ComputeLayout()190 virtual void ComputeLayout() {} 191 Alignment()192 virtual size_t Alignment() 193 { 194 return 1; 195 } 196 IsForeign() const197 virtual bool IsForeign() const 198 { 199 return false; 200 } 201 GetOffset() const202 uint32_t GetOffset() const 203 { 204 return offset_; 205 } 206 GetFileId() const207 panda_file::File::EntityId GetFileId() const 208 { 209 return panda_file::File::EntityId(offset_); 210 } 211 SetOffset(uint32_t offset)212 void SetOffset(uint32_t offset) 213 { 214 offset_ = offset; 215 } 216 NeedsEmit() const217 bool NeedsEmit() const 218 { 219 return needs_emit_; 220 } 221 SetNeedsEmit(bool needs_emit)222 void SetNeedsEmit(bool needs_emit) 223 { 224 needs_emit_ = needs_emit; 225 } 226 GetIndexDependencies() const227 const std::list<IndexedItem *> &GetIndexDependencies() const 228 { 229 return index_deps_; 230 } 231 AddIndexDependency(IndexedItem *item)232 void AddIndexDependency(IndexedItem *item) 233 { 234 ASSERT(item != nullptr); 235 index_deps_.push_back(item); 236 } 237 SetOrderIndex(uint32_t order)238 void SetOrderIndex(uint32_t order) 239 { 240 order_ = order; 241 } 242 GetOrderIndex() const243 uint32_t GetOrderIndex() const 244 { 245 return order_; 246 } 247 HasOrderIndex() const248 bool HasOrderIndex() const 249 { 250 return order_ != INVALID_INDEX; 251 } 252 253 virtual bool Write(Writer *writer) = 0; 254 255 std::string GetName() const; 256 257 virtual ItemTypes GetItemType() const = 0; 258 Dump([[maybe_unused]] std::ostream &os) const259 virtual void Dump([[maybe_unused]] std::ostream &os) const {} 260 Visit([[maybe_unused]] const VisitorCallBack &cb)261 virtual void Visit([[maybe_unused]] const VisitorCallBack &cb) {} 262 SetPGORank(uint32_t rank)263 void SetPGORank(uint32_t rank) 264 { 265 pgo_rank_ = rank; 266 } 267 GetPGORank() const268 uint32_t GetPGORank() const 269 { 270 return pgo_rank_; 271 } 272 SetOriginalRank(uint32_t rank)273 void SetOriginalRank(uint32_t rank) 274 { 275 original_rank_ = rank; 276 } 277 GetOriginalRank() const278 uint32_t GetOriginalRank() const 279 { 280 return original_rank_; 281 } 282 SetReLayoutRank(ItemRank rank)283 void SetReLayoutRank(ItemRank rank) 284 { 285 re_layout_rank_ = rank; 286 } 287 GetReLayoutRank() const288 ItemRank GetReLayoutRank() const 289 { 290 return re_layout_rank_; 291 } 292 293 private: 294 bool needs_emit_ {true}; 295 uint32_t offset_ {0}; 296 uint32_t order_ {INVALID_INDEX}; 297 std::list<IndexedItem *> index_deps_; 298 uint32_t pgo_rank_ {0}; 299 uint32_t original_rank_ {0}; 300 ItemRank re_layout_rank_ {ItemRank::DEFAULT_RANK}; 301 }; 302 303 class IndexedItem : public BaseItem { 304 public: 305 explicit IndexedItem(ItemContainer *container); 306 GetIndex(const BaseItem *item) const307 uint32_t GetIndex(const BaseItem *item) const 308 { 309 auto *idx = FindIndex(item); 310 ASSERT(idx != nullptr); 311 return idx->index; 312 } 313 HasIndex(const BaseItem *item) const314 bool HasIndex(const BaseItem *item) const 315 { 316 return FindIndex(item) != nullptr; 317 } 318 SetIndex(const BaseItem *start, const BaseItem *end, uint32_t index)319 void SetIndex(const BaseItem *start, const BaseItem *end, uint32_t index) 320 { 321 ASSERT(FindIndex(start, end) == nullptr); 322 indexes_.push_back({start, end, index}); 323 } 324 ClearIndexes()325 void ClearIndexes() 326 { 327 indexes_.clear(); 328 } 329 IncRefCount()330 void IncRefCount() 331 { 332 ++ref_count_; 333 } 334 DecRefCount()335 void DecRefCount() 336 { 337 ASSERT(ref_count_ != 0); 338 --ref_count_; 339 } 340 GetRefCount() const341 size_t GetRefCount() const 342 { 343 return ref_count_; 344 } 345 GetIndexType() const346 virtual IndexType GetIndexType() const 347 { 348 return IndexType::NONE; 349 } 350 GetIndexedItemCount() const351 size_t GetIndexedItemCount() const 352 { 353 return item_global_index_; 354 } 355 356 private: 357 struct Index { 358 const BaseItem *start; 359 const BaseItem *end; 360 uint32_t index; 361 }; 362 FindIndex(const BaseItem *start, const BaseItem *end) const363 const Index *FindIndex(const BaseItem *start, const BaseItem *end) const 364 { 365 auto it = std::find_if(indexes_.cbegin(), indexes_.cend(), 366 [start, end](const Index &idx) { return idx.start == start && idx.end == end; }); 367 368 return it != indexes_.cend() ? &*it : nullptr; 369 } 370 FindIndex(const BaseItem *item) const371 const Index *FindIndex(const BaseItem *item) const 372 { 373 ASSERT(item->HasOrderIndex()); 374 auto order_idx = item->GetOrderIndex(); 375 376 auto it = std::find_if(indexes_.cbegin(), indexes_.cend(), [order_idx](const Index &idx) { 377 if (idx.start == nullptr && idx.end == nullptr) { 378 return true; 379 } 380 381 if (idx.start == nullptr || idx.end == nullptr) { 382 return false; 383 } 384 385 ASSERT(idx.start->HasOrderIndex()); 386 ASSERT(idx.end->HasOrderIndex()); 387 return idx.start->GetOrderIndex() <= order_idx && order_idx < idx.end->GetOrderIndex(); 388 }); 389 390 return it != indexes_.cend() ? &*it : nullptr; 391 } 392 393 std::vector<Index> indexes_; 394 size_t ref_count_ {1}; 395 size_t item_global_index_ {0}; 396 }; 397 398 class TypeItem : public IndexedItem { 399 public: TypeItem(Type type, ItemContainer *container)400 explicit TypeItem(Type type, ItemContainer *container) : IndexedItem(container), type_(type) {} 401 TypeItem(Type::TypeId type_id, ItemContainer *container)402 explicit TypeItem(Type::TypeId type_id, ItemContainer *container) : IndexedItem(container), type_(type_id) {} 403 404 ~TypeItem() override = default; 405 GetType() const406 Type GetType() const 407 { 408 return type_; 409 } 410 411 IndexType GetIndexType() const override 412 { 413 return IndexType::CLASS; 414 } 415 416 DEFAULT_MOVE_SEMANTIC(TypeItem); 417 DEFAULT_COPY_SEMANTIC(TypeItem); 418 419 private: 420 Type type_; 421 }; 422 423 class PrimitiveTypeItem : public TypeItem { 424 public: PrimitiveTypeItem(Type type, ItemContainer *container)425 explicit PrimitiveTypeItem(Type type, ItemContainer *container) : PrimitiveTypeItem(type.GetId(), container) {} 426 PrimitiveTypeItem(Type::TypeId type_id, ItemContainer *container)427 explicit PrimitiveTypeItem(Type::TypeId type_id, ItemContainer *container) : TypeItem(type_id, container) 428 { 429 ASSERT(GetType().IsPrimitive()); 430 SetNeedsEmit(false); 431 SetOffset(GetType().GetFieldEncoding()); 432 } 433 434 ~PrimitiveTypeItem() override = default; 435 436 size_t CalculateSize() const override 437 { 438 return 0; 439 } 440 441 bool Write([[maybe_unused]] Writer *writer) override 442 { 443 return true; 444 } 445 446 ItemTypes GetItemType() const override 447 { 448 return ItemTypes::PRIMITIVE_TYPE_ITEM; 449 } 450 451 DEFAULT_MOVE_SEMANTIC(PrimitiveTypeItem); 452 DEFAULT_COPY_SEMANTIC(PrimitiveTypeItem); 453 }; 454 455 class StringItem : public IndexedItem { 456 public: 457 explicit StringItem(std::string str, ItemContainer *container); 458 459 explicit StringItem(File::StringData data, ItemContainer *container); 460 461 ~StringItem() override = default; 462 463 size_t CalculateSize() const override; 464 465 bool Write(Writer *writer) override; 466 467 ItemTypes GetItemType() const override 468 { 469 return ItemTypes::STRING_ITEM; 470 } 471 GetData() const472 const std::string &GetData() const 473 { 474 return str_; 475 } 476 GetUtf16Len() const477 size_t GetUtf16Len() const 478 { 479 return utf16_length_; 480 } 481 482 IndexType GetIndexType() const override 483 { 484 return IndexType::METHOD_STRING_LITERAL; 485 } 486 487 DEFAULT_MOVE_SEMANTIC(StringItem); 488 DEFAULT_COPY_SEMANTIC(StringItem); 489 490 private: 491 std::string str_; 492 size_t utf16_length_; 493 size_t is_ascii_ = 0; 494 }; 495 496 class AnnotationItem; 497 class BaseClassItem; 498 class ClassItem; 499 class ForeignClassItem; 500 class ValueItem; 501 502 class BaseFieldItem : public IndexedItem { 503 public: 504 IndexType GetIndexType() const override 505 { 506 return IndexType::FIELD; 507 } 508 GetNameItem() const509 StringItem *GetNameItem() const 510 { 511 return name_; 512 } 513 514 ~BaseFieldItem() override = default; 515 516 DEFAULT_MOVE_SEMANTIC(BaseFieldItem); 517 DEFAULT_COPY_SEMANTIC(BaseFieldItem); 518 519 protected: 520 BaseFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type, ItemContainer *container); 521 522 size_t CalculateSize() const override; 523 524 bool Write(Writer *writer) override; 525 526 private: 527 BaseClassItem *class_; 528 StringItem *name_; 529 TypeItem *type_; 530 }; 531 532 class FieldItem : public BaseFieldItem { 533 public: 534 FieldItem(ClassItem *cls, StringItem *name, TypeItem *type, uint32_t access_flags, ItemContainer *container); 535 536 ~FieldItem() override = default; 537 538 void SetValue(ValueItem *value); 539 GetValue() const540 ValueItem *GetValue() const 541 { 542 return value_; 543 } 544 AddRuntimeAnnotation(AnnotationItem *runtime_annotation)545 void AddRuntimeAnnotation(AnnotationItem *runtime_annotation) 546 { 547 runtime_annotations_.push_back(runtime_annotation); 548 } 549 AddAnnotation(AnnotationItem *annotation)550 void AddAnnotation(AnnotationItem *annotation) 551 { 552 annotations_.push_back(annotation); 553 } 554 AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)555 void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation) 556 { 557 runtime_type_annotations_.push_back(runtime_type_annotation); 558 } 559 AddTypeAnnotation(AnnotationItem *type_annotation)560 void AddTypeAnnotation(AnnotationItem *type_annotation) 561 { 562 type_annotations_.push_back(type_annotation); 563 } 564 565 size_t CalculateSize() const override; 566 567 bool Write(Writer *writer) override; 568 569 ItemTypes GetItemType() const override 570 { 571 return ItemTypes::FIELD_ITEM; 572 } 573 GetRuntimeAnnotations()574 std::vector<AnnotationItem *> *GetRuntimeAnnotations() 575 { 576 return &runtime_annotations_; 577 } 578 GetAnnotations()579 std::vector<AnnotationItem *> *GetAnnotations() 580 { 581 return &annotations_; 582 } 583 GetTypeAnnotations()584 std::vector<AnnotationItem *> *GetTypeAnnotations() 585 { 586 return &type_annotations_; 587 } 588 GetRuntimeTypeAnnotations()589 std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations() 590 { 591 return &runtime_type_annotations_; 592 } 593 594 DEFAULT_MOVE_SEMANTIC(FieldItem); 595 DEFAULT_COPY_SEMANTIC(FieldItem); 596 597 private: 598 bool WriteValue(Writer *writer); 599 600 bool WriteAnnotations(Writer *writer); 601 602 bool WriteTaggedData(Writer *writer); 603 604 uint32_t access_flags_; 605 ValueItem *value_; 606 std::vector<AnnotationItem *> runtime_annotations_; 607 std::vector<AnnotationItem *> annotations_; 608 std::vector<AnnotationItem *> type_annotations_; 609 std::vector<AnnotationItem *> runtime_type_annotations_; 610 }; 611 612 class ProtoItem; 613 class CodeItem; 614 615 class LineNumberProgramItem : public IndexedItem { 616 public: 617 enum class Opcode : uint8_t { 618 END_SEQUENCE = 0x00, 619 ADVANCE_PC = 0x01, 620 ADVANCE_LINE = 0x02, 621 START_LOCAL = 0x03, 622 START_LOCAL_EXTENDED = 0x04, 623 END_LOCAL = 0x05, 624 RESTART_LOCAL = 0x06, 625 SET_PROLOGUE_END = 0x07, 626 SET_EPILOGUE_BEGIN = 0x08, 627 SET_FILE = 0x09, 628 SET_SOURCE_CODE = 0x0a, 629 SET_COLUMN = 0X0b, 630 LAST 631 }; 632 633 static constexpr uint8_t OPCODE_BASE = static_cast<uint8_t>(Opcode::LAST); 634 static constexpr int32_t LINE_RANGE = 15; 635 static constexpr int32_t LINE_BASE = -4; 636 LineNumberProgramItem(ItemContainer *container)637 explicit LineNumberProgramItem(ItemContainer *container) : IndexedItem(container) {} 638 639 void EmitEnd(); 640 641 void EmitAdvancePc(std::vector<uint8_t> *constant_pool, uint32_t value); 642 643 void EmitAdvanceLine(std::vector<uint8_t> *constant_pool, int32_t value); 644 645 void EmitColumn(std::vector<uint8_t> *constant_pool, uint32_t pc_inc, uint32_t column); 646 647 void EmitStartLocal(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name, 648 StringItem *type); 649 650 void EmitStartLocalExtended(std::vector<uint8_t> *constant_pool, int32_t register_number, StringItem *name, 651 StringItem *type, StringItem *type_signature); 652 653 void EmitEndLocal(int32_t register_number); 654 655 void EmitRestartLocal(int32_t register_number); 656 657 bool EmitSpecialOpcode(uint32_t pc_inc, int32_t line_inc); 658 659 void EmitPrologEnd(); 660 661 void EmitEpilogBegin(); 662 663 void EmitSetFile(std::vector<uint8_t> *constant_pool, StringItem *source_file); 664 665 void EmitSetSourceCode(std::vector<uint8_t> *constant_pool, StringItem *source_code); 666 667 bool Write(Writer *writer) override; 668 669 size_t CalculateSize() const override; 670 671 ItemTypes GetItemType() const override 672 { 673 return ItemTypes::LINE_NUMBER_PROGRAM_ITEM; 674 } 675 GetData() const676 const std::vector<uint8_t> &GetData() const 677 { 678 return data_; 679 } 680 681 IndexType GetIndexType() const override 682 { 683 return IndexType::LINE_NUMBER_PROG; 684 } 685 686 void SetData(std::vector<uint8_t> &&data); 687 688 private: 689 void EmitOpcode(Opcode opcode); 690 void EmitRegister(int32_t register_number); 691 692 static void EmitUleb128(std::vector<uint8_t> *data, uint32_t value); 693 694 static void EmitSleb128(std::vector<uint8_t> *data, int32_t value); 695 696 std::vector<uint8_t> data_; 697 }; 698 699 class DebugInfoItem : public BaseItem { 700 public: DebugInfoItem(LineNumberProgramItem *item)701 explicit DebugInfoItem(LineNumberProgramItem *item) : program_(item) {} 702 703 ~DebugInfoItem() override = default; 704 705 DEFAULT_MOVE_SEMANTIC(DebugInfoItem); 706 DEFAULT_COPY_SEMANTIC(DebugInfoItem); 707 GetLineNumber() const708 size_t GetLineNumber() const 709 { 710 return line_num_; 711 } 712 SetLineNumber(size_t line_num)713 void SetLineNumber(size_t line_num) 714 { 715 line_num_ = line_num; 716 } 717 GetLineNumberProgram() const718 LineNumberProgramItem *GetLineNumberProgram() const 719 { 720 return program_; 721 } 722 SetLineNumberProgram(LineNumberProgramItem *program)723 void SetLineNumberProgram(LineNumberProgramItem *program) 724 { 725 ASSERT(program->GetOffset() != 0); 726 program_ = program; 727 } 728 AddParameter(StringItem *name)729 void AddParameter(StringItem *name) 730 { 731 parameters_.push_back(name); 732 } 733 GetConstantPool()734 std::vector<uint8_t> *GetConstantPool() 735 { 736 return &constant_pool_; 737 } 738 739 size_t CalculateSize() const override; 740 741 bool Write(Writer *writer) override; 742 743 ItemTypes GetItemType() const override 744 { 745 return ItemTypes::DEBUG_INFO_ITEM; 746 } 747 748 void Dump(std::ostream &os) const override; 749 750 private: 751 size_t line_num_ {0}; 752 LineNumberProgramItem *program_; 753 std::vector<uint8_t> constant_pool_; 754 std::vector<StringItem *> parameters_; 755 }; 756 757 class BaseMethodItem : public IndexedItem { 758 public: GetProto() const759 ProtoItem *GetProto() const 760 { 761 return proto_; 762 } 763 IsStatic() const764 bool IsStatic() const 765 { 766 return (access_flags_ & ACC_STATIC) != 0; 767 } 768 769 IndexType GetIndexType() const override 770 { 771 return IndexType::METHOD_STRING_LITERAL; 772 } 773 GetNameItem() const774 StringItem *GetNameItem() const 775 { 776 return name_; 777 } 778 GetClassItem() const779 BaseClassItem *GetClassItem() const 780 { 781 return class_; 782 } 783 SetFunctionKind(FunctionKind kind)784 void SetFunctionKind(FunctionKind kind) 785 { 786 access_flags_ &= (~FUNCTION_KIND_MASK); 787 access_flags_ |= (static_cast<uint32_t>(kind) << FLAG_WIDTH); 788 } 789 SetHeaderIndex(uint16_t idx)790 void SetHeaderIndex(uint16_t idx) 791 { 792 access_flags_ &= (FUNCTION_KIND_MASK | FLAG_MASK); 793 access_flags_ |= (static_cast<uint32_t>(idx) << (FUNTION_KIND_WIDTH + FLAG_WIDTH)); 794 } 795 796 ~BaseMethodItem() override = default; 797 798 DEFAULT_MOVE_SEMANTIC(BaseMethodItem); 799 DEFAULT_COPY_SEMANTIC(BaseMethodItem); 800 801 protected: 802 BaseMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags, 803 ItemContainer *container); 804 805 size_t CalculateSize() const override; 806 807 bool Write(Writer *writer) override; 808 809 private: 810 BaseClassItem *class_; 811 StringItem *name_; 812 ProtoItem *proto_; 813 uint32_t access_flags_; // layout: |<- 16-bit header index ->|<- 8-bit FunctionKind ->|<- 8-bit flag ->| 814 }; 815 816 class MethodParamItem { 817 public: MethodParamItem(TypeItem *type)818 explicit MethodParamItem(TypeItem *type) : type_(type) {} 819 820 ~MethodParamItem() = default; 821 822 DEFAULT_MOVE_SEMANTIC(MethodParamItem); 823 DEFAULT_COPY_SEMANTIC(MethodParamItem); 824 AddRuntimeAnnotation(AnnotationItem *runtime_annotation)825 void AddRuntimeAnnotation(AnnotationItem *runtime_annotation) 826 { 827 runtime_annotations_.push_back(runtime_annotation); 828 } 829 AddAnnotation(AnnotationItem *annotation)830 void AddAnnotation(AnnotationItem *annotation) 831 { 832 annotations_.push_back(annotation); 833 } 834 AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)835 void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation) 836 { 837 runtime_type_annotations_.push_back(runtime_type_annotation); 838 } 839 AddTypeAnnotation(AnnotationItem *type_annotation)840 void AddTypeAnnotation(AnnotationItem *type_annotation) 841 { 842 type_annotations_.push_back(type_annotation); 843 } 844 GetType() const845 TypeItem *GetType() const 846 { 847 return type_; 848 } 849 GetRuntimeAnnotations() const850 const std::vector<AnnotationItem *> &GetRuntimeAnnotations() const 851 { 852 return runtime_annotations_; 853 } 854 GetAnnotations() const855 const std::vector<AnnotationItem *> &GetAnnotations() const 856 { 857 return annotations_; 858 } 859 HasAnnotations() const860 bool HasAnnotations() const 861 { 862 return !annotations_.empty(); 863 } 864 HasRuntimeAnnotations() const865 bool HasRuntimeAnnotations() const 866 { 867 return !runtime_annotations_.empty(); 868 } 869 870 private: 871 TypeItem *type_; 872 std::vector<AnnotationItem *> runtime_annotations_; 873 std::vector<AnnotationItem *> annotations_; 874 std::vector<AnnotationItem *> type_annotations_; 875 std::vector<AnnotationItem *> runtime_type_annotations_; 876 }; 877 878 class ParamAnnotationsItem; 879 class BaseClassItem; 880 881 class MethodItem : public BaseMethodItem { 882 public: 883 MethodItem(ClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags, 884 std::vector<MethodParamItem> params, ItemContainer *container); 885 886 ~MethodItem() override = default; 887 888 DEFAULT_MOVE_SEMANTIC(MethodItem); 889 DEFAULT_COPY_SEMANTIC(MethodItem); 890 SetSourceLang(SourceLang lang)891 void SetSourceLang(SourceLang lang) 892 { 893 source_lang_ = lang; 894 } 895 SetCode(CodeItem *code)896 void SetCode(CodeItem *code) 897 { 898 code_ = code; 899 } 900 SetDebugInfo(DebugInfoItem *debug_info)901 void SetDebugInfo(DebugInfoItem *debug_info) 902 { 903 debug_info_ = debug_info; 904 } 905 AddRuntimeAnnotation(AnnotationItem *runtime_annotation)906 void AddRuntimeAnnotation(AnnotationItem *runtime_annotation) 907 { 908 runtime_annotations_.push_back(runtime_annotation); 909 } 910 AddAnnotation(AnnotationItem *annotation)911 void AddAnnotation(AnnotationItem *annotation) 912 { 913 annotations_.push_back(annotation); 914 } 915 AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)916 void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation) 917 { 918 runtime_type_annotations_.push_back(runtime_type_annotation); 919 } 920 AddTypeAnnotation(AnnotationItem *type_annotation)921 void AddTypeAnnotation(AnnotationItem *type_annotation) 922 { 923 type_annotations_.push_back(type_annotation); 924 } 925 SetRuntimeParamAnnotationItem(ParamAnnotationsItem *annotations)926 void SetRuntimeParamAnnotationItem(ParamAnnotationsItem *annotations) 927 { 928 runtime_param_annotations_ = annotations; 929 } 930 SetParamAnnotationItem(ParamAnnotationsItem *annotations)931 void SetParamAnnotationItem(ParamAnnotationsItem *annotations) 932 { 933 param_annotations_ = annotations; 934 } 935 HasRuntimeParamAnnotations() const936 bool HasRuntimeParamAnnotations() const 937 { 938 return std::any_of(params_.cbegin(), params_.cend(), 939 [](const MethodParamItem &item) { return item.HasRuntimeAnnotations(); }); 940 } 941 HasParamAnnotations() const942 bool HasParamAnnotations() const 943 { 944 return std::any_of(params_.cbegin(), params_.cend(), 945 [](const MethodParamItem &item) { return item.HasAnnotations(); }); 946 } 947 GetCode() const948 CodeItem *GetCode() const 949 { 950 return code_; 951 } 952 GetDebugInfo() const953 DebugInfoItem *GetDebugInfo() const 954 { 955 return debug_info_; 956 } 957 958 size_t CalculateSize() const override; 959 960 bool Write(Writer *writer) override; 961 962 ItemTypes GetItemType() const override 963 { 964 return ItemTypes::METHOD_ITEM; 965 } 966 GetParams()967 std::vector<MethodParamItem> &GetParams() 968 { 969 return params_; 970 } 971 GetRuntimeAnnotations()972 std::vector<AnnotationItem *> *GetRuntimeAnnotations() 973 { 974 return &runtime_annotations_; 975 } 976 GetAnnotations()977 std::vector<AnnotationItem *> *GetAnnotations() 978 { 979 return &annotations_; 980 } 981 GetTypeAnnotations()982 std::vector<AnnotationItem *> *GetTypeAnnotations() 983 { 984 return &type_annotations_; 985 } 986 GetRuntimeTypeAnnotations()987 std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations() 988 { 989 return &runtime_type_annotations_; 990 } 991 992 private: 993 bool WriteRuntimeAnnotations(Writer *writer); 994 995 bool WriteTypeAnnotations(Writer *writer); 996 997 bool WriteTaggedData(Writer *writer); 998 999 std::vector<MethodParamItem> params_; 1000 1001 SourceLang source_lang_; 1002 CodeItem *code_; 1003 DebugInfoItem *debug_info_; 1004 std::vector<AnnotationItem *> runtime_annotations_; 1005 std::vector<AnnotationItem *> annotations_; 1006 std::vector<AnnotationItem *> type_annotations_; 1007 std::vector<AnnotationItem *> runtime_type_annotations_; 1008 ParamAnnotationsItem *runtime_param_annotations_ {nullptr}; 1009 ParamAnnotationsItem *param_annotations_ {nullptr}; 1010 }; 1011 1012 class BaseClassItem : public TypeItem { 1013 public: GetNameItem()1014 StringItem *GetNameItem() 1015 { 1016 return &name_; 1017 } 1018 1019 protected: BaseClassItem(const std::string &name, ItemContainer *container)1020 explicit BaseClassItem(const std::string &name, ItemContainer *container) 1021 : TypeItem(Type::TypeId::REFERENCE, container), name_(name, container) {} 1022 1023 ~BaseClassItem() override = default; 1024 1025 size_t CalculateSize() const override; 1026 1027 void ComputeLayout() override; 1028 1029 bool Write(Writer *writer) override; 1030 1031 DEFAULT_MOVE_SEMANTIC(BaseClassItem); 1032 DEFAULT_COPY_SEMANTIC(BaseClassItem); 1033 1034 private: 1035 StringItem name_; 1036 }; 1037 1038 class ClassItem : public BaseClassItem { 1039 public: ClassItem(const std::string &name, ItemContainer *container)1040 explicit ClassItem(const std::string &name, ItemContainer *container) 1041 : BaseClassItem(name, container), 1042 super_class_(nullptr), 1043 access_flags_(0), 1044 source_lang_(SourceLang::PANDA_ASSEMBLY), 1045 source_file_(nullptr), 1046 container_(container) 1047 { 1048 } 1049 1050 ~ClassItem() override = default; 1051 SetAccessFlags(uint32_t access_flags)1052 void SetAccessFlags(uint32_t access_flags) 1053 { 1054 access_flags_ = access_flags; 1055 } 1056 SetSourceLang(SourceLang lang)1057 void SetSourceLang(SourceLang lang) 1058 { 1059 source_lang_ = lang; 1060 } 1061 SetSuperClass(BaseClassItem *super_class)1062 void SetSuperClass(BaseClassItem *super_class) 1063 { 1064 super_class_ = super_class; 1065 } 1066 AddInterface(BaseClassItem *iface)1067 void AddInterface(BaseClassItem *iface) 1068 { 1069 AddIndexDependency(iface); 1070 ifaces_.push_back(iface); 1071 } 1072 AddRuntimeAnnotation(AnnotationItem *runtime_annotation)1073 void AddRuntimeAnnotation(AnnotationItem *runtime_annotation) 1074 { 1075 runtime_annotations_.push_back(runtime_annotation); 1076 } 1077 AddAnnotation(AnnotationItem *annotation)1078 void AddAnnotation(AnnotationItem *annotation) 1079 { 1080 annotations_.push_back(annotation); 1081 } 1082 AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation)1083 void AddRuntimeTypeAnnotation(AnnotationItem *runtime_type_annotation) 1084 { 1085 runtime_type_annotations_.push_back(runtime_type_annotation); 1086 } 1087 AddTypeAnnotation(AnnotationItem *type_annotation)1088 void AddTypeAnnotation(AnnotationItem *type_annotation) 1089 { 1090 type_annotations_.push_back(type_annotation); 1091 } 1092 1093 template <class... Args> AddField(Args.... args)1094 FieldItem *AddField(Args... args) 1095 { 1096 fields_.emplace_back(std::make_unique<FieldItem>(this, std::forward<Args>(args)..., container_)); 1097 return fields_.back().get(); 1098 } 1099 1100 template <class... Args> AddMethod(Args.... args)1101 MethodItem *AddMethod(Args... args) 1102 { 1103 // insert new method to set ordered by method name 1104 return methods_.insert(std::make_unique<MethodItem>(this, std::forward<Args>(args)..., container_))->get(); 1105 } 1106 SetSourceFile(StringItem *item)1107 void SetSourceFile(StringItem *item) 1108 { 1109 source_file_ = item; 1110 } 1111 1112 size_t CalculateSizeWithoutFieldsAndMethods() const; 1113 1114 size_t CalculateSize() const override; 1115 1116 void ComputeLayout() override; 1117 1118 bool Write(Writer *writer) override; 1119 1120 ItemTypes GetItemType() const override 1121 { 1122 return ItemTypes::CLASS_ITEM; 1123 } 1124 VisitFields(const VisitorCallBack &cb)1125 void VisitFields(const VisitorCallBack &cb) 1126 { 1127 for (auto &field : fields_) { 1128 if (!cb(field.get())) { 1129 break; 1130 } 1131 } 1132 } 1133 VisitMethods(const VisitorCallBack &cb)1134 void VisitMethods(const VisitorCallBack &cb) 1135 { 1136 for (auto &method : methods_) { 1137 if (!cb(method.get())) { 1138 break; 1139 } 1140 } 1141 } 1142 1143 void Visit(const VisitorCallBack &cb) override 1144 { 1145 VisitFields(cb); 1146 VisitMethods(cb); 1147 } 1148 GetRuntimeAnnotations()1149 std::vector<AnnotationItem *> *GetRuntimeAnnotations() 1150 { 1151 return &runtime_annotations_; 1152 } 1153 GetAnnotations()1154 std::vector<AnnotationItem *> *GetAnnotations() 1155 { 1156 return &annotations_; 1157 } 1158 GetTypeAnnotations()1159 std::vector<AnnotationItem *> *GetTypeAnnotations() 1160 { 1161 return &type_annotations_; 1162 } 1163 GetRuntimeTypeAnnotations()1164 std::vector<AnnotationItem *> *GetRuntimeTypeAnnotations() 1165 { 1166 return &runtime_type_annotations_; 1167 } 1168 1169 DEFAULT_MOVE_SEMANTIC(ClassItem); 1170 DEFAULT_COPY_SEMANTIC(ClassItem); 1171 1172 private: 1173 struct MethodCompByName { operator ()panda::panda_file::ClassTag::MethodTag::FieldTag::ClassItem::MethodCompByName1174 bool operator()(const std::unique_ptr<MethodItem> &m1, const std::unique_ptr<MethodItem> &m2) const 1175 { 1176 auto *str1 = m1->GetNameItem(); 1177 auto *str2 = m2->GetNameItem(); 1178 if (str1->GetUtf16Len() == str2->GetUtf16Len()) { 1179 return str1->GetData() < str2->GetData(); 1180 } 1181 return str1->GetUtf16Len() < str2->GetUtf16Len(); 1182 } 1183 }; 1184 1185 bool WriteIfaces(Writer *writer); 1186 1187 bool WriteAnnotations(Writer *writer); 1188 1189 bool WriteTaggedData(Writer *writer); 1190 1191 BaseClassItem *super_class_; 1192 uint32_t access_flags_; 1193 SourceLang source_lang_; 1194 std::vector<BaseClassItem *> ifaces_; 1195 std::vector<AnnotationItem *> runtime_annotations_; 1196 std::vector<AnnotationItem *> annotations_; 1197 std::vector<AnnotationItem *> type_annotations_; 1198 std::vector<AnnotationItem *> runtime_type_annotations_; 1199 StringItem *source_file_; 1200 std::vector<std::unique_ptr<FieldItem>> fields_; 1201 std::multiset<std::unique_ptr<MethodItem>, MethodCompByName> methods_; 1202 ItemContainer *container_; 1203 }; 1204 1205 class ForeignClassItem : public BaseClassItem { 1206 public: ForeignClassItem(const std::string &name, ItemContainer *container)1207 explicit ForeignClassItem(const std::string &name, ItemContainer *container) : BaseClassItem(name, container) {} 1208 1209 ~ForeignClassItem() override = default; 1210 1211 bool IsForeign() const override 1212 { 1213 return true; 1214 } 1215 1216 ItemTypes GetItemType() const override 1217 { 1218 return ItemTypes::FOREIGN_CLASS_ITEM; 1219 } 1220 1221 DEFAULT_MOVE_SEMANTIC(ForeignClassItem); 1222 DEFAULT_COPY_SEMANTIC(ForeignClassItem); 1223 }; 1224 1225 class ForeignFieldItem : public BaseFieldItem { 1226 public: ForeignFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type, ItemContainer *container)1227 ForeignFieldItem(BaseClassItem *cls, StringItem *name, TypeItem *type, ItemContainer *container) 1228 : BaseFieldItem(cls, name, type, container) {} 1229 1230 ~ForeignFieldItem() override = default; 1231 1232 bool IsForeign() const override 1233 { 1234 return true; 1235 } 1236 1237 ItemTypes GetItemType() const override 1238 { 1239 return ItemTypes::FOREIGN_FIELD_ITEM; 1240 } 1241 1242 DEFAULT_MOVE_SEMANTIC(ForeignFieldItem); 1243 DEFAULT_COPY_SEMANTIC(ForeignFieldItem); 1244 }; 1245 1246 class ForeignMethodItem : public BaseMethodItem { 1247 public: ForeignMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags, ItemContainer *container)1248 ForeignMethodItem(BaseClassItem *cls, StringItem *name, ProtoItem *proto, uint32_t access_flags, 1249 ItemContainer *container) : BaseMethodItem(cls, name, proto, access_flags, container) 1250 { 1251 } 1252 1253 ~ForeignMethodItem() override = default; 1254 1255 bool IsForeign() const override 1256 { 1257 return true; 1258 } 1259 1260 ItemTypes GetItemType() const override 1261 { 1262 return ItemTypes::FOREIGN_METHOD_ITEM; 1263 } 1264 1265 DEFAULT_MOVE_SEMANTIC(ForeignMethodItem); 1266 DEFAULT_COPY_SEMANTIC(ForeignMethodItem); 1267 }; 1268 1269 class ProtoItem; 1270 1271 class ParamAnnotationsItem : public BaseItem { 1272 public: 1273 ParamAnnotationsItem(MethodItem *method, bool is_runtime_annotations); 1274 1275 ~ParamAnnotationsItem() override = default; 1276 1277 ItemTypes GetItemType() const override 1278 { 1279 return ItemTypes::PARAM_ANNOTATIONS_ITEM; 1280 } 1281 1282 size_t CalculateSize() const override; 1283 1284 bool Write(Writer *writer) override; 1285 1286 DEFAULT_MOVE_SEMANTIC(ParamAnnotationsItem); 1287 DEFAULT_COPY_SEMANTIC(ParamAnnotationsItem); 1288 1289 private: 1290 std::vector<std::vector<AnnotationItem *>> annotations_; 1291 }; 1292 1293 class ProtoItem : public IndexedItem { 1294 public: 1295 ProtoItem(TypeItem *ret_type, const std::vector<MethodParamItem> ¶ms, ItemContainer *itemContainer); 1296 1297 ~ProtoItem() override = default; 1298 1299 DEFAULT_MOVE_SEMANTIC(ProtoItem); 1300 DEFAULT_COPY_SEMANTIC(ProtoItem); 1301 1302 size_t CalculateSize() const override 1303 { 1304 size_t size = shorty_.size() * sizeof(uint16_t); 1305 size += reference_types_.size() * IDX_SIZE; 1306 return size; 1307 } 1308 1309 bool Write(Writer *writer) override; 1310 1311 ItemTypes GetItemType() const override 1312 { 1313 return ItemTypes::PROTO_ITEM; 1314 } 1315 1316 IndexType GetIndexType() const override 1317 { 1318 return IndexType::PROTO; 1319 } 1320 1321 size_t Alignment() override 1322 { 1323 return sizeof(uint16_t); 1324 } 1325 1326 private: 1327 static constexpr size_t SHORTY_ELEM_SIZE = 4; 1328 1329 void AddType(TypeItem *type, size_t *n); 1330 1331 std::vector<uint16_t> shorty_; 1332 std::vector<TypeItem *> reference_types_; 1333 }; 1334 1335 class CodeItem : public BaseItem { 1336 public: 1337 class CatchBlock : public BaseItem { 1338 public: CatchBlock(MethodItem *method, BaseClassItem *type, size_t handler_pc, size_t code_size = 0)1339 CatchBlock(MethodItem *method, BaseClassItem *type, size_t handler_pc, size_t code_size = 0) 1340 : method_(method), type_(type), handler_pc_(handler_pc), code_size_(code_size) 1341 { 1342 } 1343 1344 ~CatchBlock() override = default; 1345 1346 DEFAULT_MOVE_SEMANTIC(CatchBlock); 1347 DEFAULT_COPY_SEMANTIC(CatchBlock); 1348 1349 size_t CalculateSize() const override; 1350 1351 bool Write(Writer *writer) override; 1352 1353 ItemTypes GetItemType() const override 1354 { 1355 return ItemTypes::CATCH_BLOCK_ITEM; 1356 } 1357 1358 private: 1359 MethodItem *method_; 1360 BaseClassItem *type_; 1361 size_t handler_pc_; 1362 size_t code_size_; 1363 }; 1364 1365 class TryBlock : public BaseItem { 1366 public: TryBlock(size_t start_pc, size_t length, std::vector<CatchBlock> catch_blocks)1367 TryBlock(size_t start_pc, size_t length, std::vector<CatchBlock> catch_blocks) 1368 : start_pc_(start_pc), length_(length), catch_blocks_(std::move(catch_blocks)) 1369 { 1370 } 1371 1372 ~TryBlock() override = default; 1373 1374 DEFAULT_MOVE_SEMANTIC(TryBlock); 1375 DEFAULT_COPY_SEMANTIC(TryBlock); 1376 1377 size_t CalculateSizeWithoutCatchBlocks() const; 1378 1379 void ComputeLayout() override; 1380 1381 size_t CalculateSize() const override; 1382 1383 bool Write(Writer *writer) override; 1384 1385 ItemTypes GetItemType() const override 1386 { 1387 return ItemTypes::TRY_BLOCK_ITEM; 1388 } 1389 1390 private: 1391 size_t start_pc_; 1392 size_t length_; 1393 std::vector<CatchBlock> catch_blocks_; 1394 }; 1395 CodeItem(size_t num_vregs, size_t num_args, std::vector<uint8_t> instructions)1396 CodeItem(size_t num_vregs, size_t num_args, std::vector<uint8_t> instructions) 1397 : num_vregs_(num_vregs), num_args_(num_args), instructions_(std::move(instructions)) 1398 { 1399 } 1400 1401 CodeItem() = default; 1402 1403 ~CodeItem() override = default; 1404 SetNumVregs(size_t num_vregs)1405 void SetNumVregs(size_t num_vregs) 1406 { 1407 num_vregs_ = num_vregs; 1408 } 1409 SetNumArgs(size_t num_args)1410 void SetNumArgs(size_t num_args) 1411 { 1412 num_args_ = num_args; 1413 } 1414 GetInstructions()1415 std::vector<uint8_t> *GetInstructions() 1416 { 1417 return &instructions_; 1418 } 1419 SetNumInstructions(size_t num_ins)1420 void SetNumInstructions(size_t num_ins) 1421 { 1422 num_ins_ = num_ins; 1423 } 1424 GetNumInstructions() const1425 size_t GetNumInstructions() const 1426 { 1427 return num_ins_; 1428 } 1429 AddTryBlock(const TryBlock &try_block)1430 void AddTryBlock(const TryBlock &try_block) 1431 { 1432 try_blocks_.push_back(try_block); 1433 } 1434 1435 size_t CalculateSizeWithoutTryBlocks() const; 1436 1437 void ComputeLayout() override; 1438 1439 size_t CalculateSize() const override; 1440 1441 size_t GetCodeSize() const; 1442 1443 bool Write(Writer *writer) override; 1444 1445 ItemTypes GetItemType() const override 1446 { 1447 return ItemTypes::CODE_ITEM; 1448 } 1449 AddMethod(BaseMethodItem *method)1450 void AddMethod(BaseMethodItem *method) 1451 { 1452 methods_.emplace_back(method); 1453 } 1454 GetMethodNames() const1455 std::vector<std::string> GetMethodNames() const 1456 { 1457 std::vector<std::string> names; 1458 for (const auto *method : methods_) { 1459 if (method == nullptr) { 1460 continue; 1461 } 1462 std::string class_name; 1463 if (method->GetClassItem() != nullptr) { 1464 class_name = method->GetClassItem()->GetNameItem()->GetData(); 1465 class_name.pop_back(); // remove '\0' 1466 ASSERT(class_name.size() > 2); // 2 - L and ; 1467 class_name.erase(0, 1); 1468 class_name.pop_back(); 1469 class_name.append("::"); 1470 } 1471 class_name.append(method->GetNameItem()->GetData()); 1472 class_name.pop_back(); // remove '\0' 1473 names.emplace_back(class_name); 1474 } 1475 return names; 1476 } 1477 1478 DEFAULT_MOVE_SEMANTIC(CodeItem); 1479 DEFAULT_COPY_SEMANTIC(CodeItem); 1480 1481 private: 1482 size_t num_vregs_ {0}; 1483 size_t num_args_ {0}; 1484 size_t num_ins_ {0}; 1485 std::vector<uint8_t> instructions_; 1486 std::vector<TryBlock> try_blocks_; 1487 std::vector<BaseMethodItem *> methods_; 1488 }; 1489 1490 class ScalarValueItem; 1491 class ArrayValueItem; 1492 1493 class ValueItem : public IndexedItem { 1494 public: 1495 enum class Type { INTEGER, LONG, FLOAT, DOUBLE, ID, ARRAY }; 1496 ValueItem(Type type, ItemContainer *container)1497 explicit ValueItem(Type type, ItemContainer *container) : IndexedItem(container), type_(type) {} 1498 1499 ~ValueItem() override = default; 1500 1501 DEFAULT_MOVE_SEMANTIC(ValueItem); 1502 DEFAULT_COPY_SEMANTIC(ValueItem); 1503 GetType() const1504 Type GetType() const 1505 { 1506 return type_; 1507 } 1508 IsArray() const1509 bool IsArray() const 1510 { 1511 return type_ == Type::ARRAY; 1512 } 1513 Is32bit() const1514 bool Is32bit() const 1515 { 1516 return type_ == Type::INTEGER || type_ == Type::FLOAT || type_ == Type::ID; 1517 } 1518 1519 ItemTypes GetItemType() const override 1520 { 1521 return ItemTypes::VALUE_ITEM; 1522 } 1523 1524 ScalarValueItem *GetAsScalar(); 1525 1526 ArrayValueItem *GetAsArray(); 1527 1528 private: 1529 Type type_; 1530 }; 1531 1532 class ScalarValueItem : public ValueItem { 1533 public: ScalarValueItem(uint32_t v, ItemContainer *container)1534 explicit ScalarValueItem(uint32_t v, ItemContainer *container) : ValueItem(Type::INTEGER, container), value_(v) {} 1535 ScalarValueItem(uint64_t v, ItemContainer *container)1536 explicit ScalarValueItem(uint64_t v, ItemContainer *container) : ValueItem(Type::LONG, container), value_(v) {} 1537 ScalarValueItem(float v, ItemContainer *container)1538 explicit ScalarValueItem(float v, ItemContainer *container) : ValueItem(Type::FLOAT, container), value_(v) {} 1539 ScalarValueItem(double v, ItemContainer *container)1540 explicit ScalarValueItem(double v, ItemContainer *container) : ValueItem(Type::DOUBLE, container), value_(v) {} 1541 ScalarValueItem(BaseItem *v, ItemContainer *container)1542 explicit ScalarValueItem(BaseItem *v, ItemContainer *container) : ValueItem(Type::ID, container), value_(v) {} 1543 1544 ~ScalarValueItem() override = default; 1545 1546 DEFAULT_MOVE_SEMANTIC(ScalarValueItem); 1547 DEFAULT_COPY_SEMANTIC(ScalarValueItem); 1548 1549 template <class T> GetValue() const1550 T GetValue() const 1551 { 1552 return std::get<T>(value_); 1553 } 1554 GetId() const1555 File::EntityId GetId() const 1556 { 1557 return File::EntityId(GetValue<BaseItem *>()->GetOffset()); 1558 } 1559 1560 size_t GetULeb128EncodedSize(); 1561 1562 size_t GetSLeb128EncodedSize(); 1563 1564 size_t CalculateSize() const override; 1565 1566 size_t Alignment() override; 1567 1568 bool Write(Writer *writer) override; 1569 1570 bool WriteAsUleb128(Writer *writer); 1571 1572 private: 1573 std::variant<uint32_t, uint64_t, float, double, BaseItem *> value_; 1574 }; 1575 1576 class ArrayValueItem : public ValueItem { 1577 public: ArrayValueItem(panda_file::Type component_type, std::vector<ScalarValueItem> items, ItemContainer *container)1578 ArrayValueItem(panda_file::Type component_type, std::vector<ScalarValueItem> items, ItemContainer *container) 1579 : ValueItem(Type::ARRAY, container), component_type_(component_type), items_(std::move(items)) 1580 { 1581 } 1582 1583 ~ArrayValueItem() override = default; 1584 1585 DEFAULT_MOVE_SEMANTIC(ArrayValueItem); 1586 DEFAULT_COPY_SEMANTIC(ArrayValueItem); 1587 1588 size_t CalculateSize() const override; 1589 1590 void ComputeLayout() override; 1591 1592 bool Write(Writer *writer) override; 1593 1594 private: 1595 size_t GetComponentSize() const; 1596 1597 panda_file::Type component_type_; 1598 std::vector<ScalarValueItem> items_; 1599 }; 1600 1601 class LiteralItem; 1602 class LiteralArrayItem; 1603 1604 class LiteralItem : public BaseItem { 1605 public: 1606 enum class Type { B1, B2, B4, B8, STRING, METHOD, LITERALARRAY }; 1607 LiteralItem(uint8_t v)1608 explicit LiteralItem(uint8_t v) : type_(Type::B1), value_(v) {} 1609 LiteralItem(uint16_t v)1610 explicit LiteralItem(uint16_t v) : type_(Type::B2), value_(v) {} 1611 LiteralItem(uint32_t v)1612 explicit LiteralItem(uint32_t v) : type_(Type::B4), value_(v) {} 1613 LiteralItem(uint64_t v)1614 explicit LiteralItem(uint64_t v) : type_(Type::B8), value_(v) {} 1615 LiteralItem(StringItem *v)1616 explicit LiteralItem(StringItem *v) : type_(Type::STRING), value_(v) {} 1617 LiteralItem(MethodItem *v)1618 explicit LiteralItem(MethodItem *v) : type_(Type::METHOD), value_(v) {} 1619 LiteralItem(LiteralArrayItem *v)1620 explicit LiteralItem(LiteralArrayItem *v) : type_(Type::LITERALARRAY), value_(v) {} 1621 1622 ~LiteralItem() override = default; 1623 1624 DEFAULT_MOVE_SEMANTIC(LiteralItem); 1625 DEFAULT_COPY_SEMANTIC(LiteralItem); 1626 GetType() const1627 Type GetType() const 1628 { 1629 return type_; 1630 } 1631 1632 ItemTypes GetItemType() const override 1633 { 1634 return ItemTypes::LITERAL_ITEM; 1635 } 1636 1637 template <class T> GetValue() const1638 T GetValue() const 1639 { 1640 return std::get<T>(value_); 1641 } 1642 1643 size_t CalculateSize() const override; 1644 1645 size_t Alignment() override; 1646 GetId() const1647 File::EntityId GetId() const 1648 { 1649 return File::EntityId(GetValue<StringItem *>()->GetOffset()); 1650 } 1651 1652 File::EntityId GetLiteralArrayFileId() const; 1653 GetMethodId() const1654 File::EntityId GetMethodId() const 1655 { 1656 return File::EntityId(GetValue<MethodItem *>()->GetFileId()); 1657 } 1658 1659 bool Write(Writer *writer) override; 1660 1661 private: 1662 Type type_; 1663 std::variant<uint8_t, uint16_t, uint32_t, uint64_t, StringItem *, MethodItem *, LiteralArrayItem *> value_; 1664 }; 1665 1666 class LiteralArrayItem : public ValueItem { 1667 public: LiteralArrayItem(ItemContainer *container)1668 explicit LiteralArrayItem(ItemContainer *container) : ValueItem(Type::ARRAY, container) {} 1669 1670 ~LiteralArrayItem() override = default; 1671 1672 DEFAULT_MOVE_SEMANTIC(LiteralArrayItem); 1673 DEFAULT_COPY_SEMANTIC(LiteralArrayItem); 1674 1675 void AddItems(const std::vector<LiteralItem> &item); 1676 1677 size_t CalculateSize() const override; 1678 1679 void ComputeLayout() override; 1680 1681 bool Write(Writer *writer) override; 1682 1683 IndexType GetIndexType() const override 1684 { 1685 return IndexType::METHOD_STRING_LITERAL; 1686 } 1687 1688 ItemTypes GetItemType() const override 1689 { 1690 return ItemTypes::LITERAL_ARRAY_ITEM; 1691 } 1692 1693 private: 1694 std::vector<LiteralItem> items_; 1695 }; 1696 1697 class AnnotationItem : public BaseItem { 1698 public: 1699 class Elem { 1700 public: Elem(StringItem *name, ValueItem *value)1701 Elem(StringItem *name, ValueItem *value) : name_(name), value_(value) 1702 { 1703 value_->SetNeedsEmit(!value_->Is32bit()); 1704 } 1705 1706 ~Elem() = default; 1707 1708 DEFAULT_MOVE_SEMANTIC(Elem); 1709 DEFAULT_COPY_SEMANTIC(Elem); 1710 GetName()1711 const StringItem *GetName() 1712 { 1713 return name_; 1714 } 1715 GetValue()1716 ValueItem *GetValue() 1717 { 1718 return value_; 1719 } 1720 SetValue(ValueItem *item)1721 void SetValue(ValueItem *item) 1722 { 1723 value_ = item; 1724 } 1725 1726 private: 1727 StringItem *name_; 1728 ValueItem *value_; 1729 }; 1730 1731 class Tag { 1732 public: Tag(char item)1733 explicit Tag(char item) : item_(item) {} 1734 1735 ~Tag() = default; 1736 1737 DEFAULT_MOVE_SEMANTIC(Tag); 1738 DEFAULT_COPY_SEMANTIC(Tag); 1739 GetItem() const1740 uint8_t GetItem() const 1741 { 1742 return item_; 1743 } 1744 1745 private: 1746 uint8_t item_; 1747 }; 1748 AnnotationItem(BaseClassItem *cls, std::vector<Elem> elements, std::vector<Tag> tags)1749 AnnotationItem(BaseClassItem *cls, std::vector<Elem> elements, std::vector<Tag> tags) 1750 : class_(cls), elements_(std::move(elements)), tags_(std::move(tags)) 1751 { 1752 AddIndexDependency(cls); 1753 } 1754 1755 ~AnnotationItem() override = default; 1756 1757 DEFAULT_MOVE_SEMANTIC(AnnotationItem); 1758 DEFAULT_COPY_SEMANTIC(AnnotationItem); 1759 1760 size_t CalculateSize() const override; 1761 1762 bool Write(Writer *writer) override; 1763 1764 ItemTypes GetItemType() const override 1765 { 1766 return ItemTypes::ANNOTATION_ITEM; 1767 } 1768 GetElements()1769 std::vector<Elem> *GetElements() 1770 { 1771 return &elements_; 1772 } 1773 SetElements(std::vector<Elem> &&elements)1774 void SetElements(std::vector<Elem> &&elements) 1775 { 1776 elements_ = std::move(elements); 1777 } 1778 GetTags() const1779 const std::vector<Tag> &GetTags() const 1780 { 1781 return tags_; 1782 } 1783 SetTags(std::vector<Tag> &&tags)1784 void SetTags(std::vector<Tag> &&tags) 1785 { 1786 tags_ = std::move(tags); 1787 } 1788 1789 private: 1790 BaseClassItem *class_; 1791 std::vector<Elem> elements_; 1792 std::vector<Tag> tags_; 1793 }; 1794 1795 enum class MethodHandleType : uint8_t { 1796 PUT_STATIC = 0x00, 1797 GET_STATIC = 0x01, 1798 PUT_INSTANCE = 0x02, 1799 GET_INSTANCE = 0x03, 1800 INVOKE_STATIC = 0x04, 1801 INVOKE_INSTANCE = 0x05, 1802 INVOKE_CONSTRUCTOR = 0x06, 1803 INVOKE_DIRECT = 0x07, 1804 INVOKE_INTERFACE = 0x08 1805 }; 1806 1807 class MethodHandleItem : public BaseItem { 1808 public: MethodHandleItem(MethodHandleType type, BaseItem *entity)1809 MethodHandleItem(MethodHandleType type, BaseItem *entity) : type_(type), entity_(entity) {} 1810 1811 ~MethodHandleItem() override = default; 1812 1813 DEFAULT_MOVE_SEMANTIC(MethodHandleItem); 1814 DEFAULT_COPY_SEMANTIC(MethodHandleItem); 1815 1816 size_t CalculateSize() const override 1817 { 1818 return sizeof(uint8_t) + leb128::UnsignedEncodingSize(entity_->GetOffset()); 1819 } 1820 1821 bool Write(Writer *writer) override; 1822 1823 ItemTypes GetItemType() const override 1824 { 1825 return ItemTypes::METHOD_HANDLE_ITEM; 1826 } 1827 GetType() const1828 MethodHandleType GetType() const 1829 { 1830 return type_; 1831 } 1832 1833 private: 1834 MethodHandleType type_; 1835 BaseItem *entity_; 1836 }; 1837 1838 enum class ArgumentType : uint8_t { 1839 INTEGER = 0x00, 1840 LONG = 0x01, 1841 FLOAT = 0x02, 1842 DOUBLE = 0x03, 1843 STRING = 0x04, 1844 CLASS = 0x05, 1845 METHOD_HANDLE = 0x06, 1846 METHOD_TYPE = 0x07 1847 }; 1848 1849 } // namespace panda::panda_file 1850 1851 #endif // LIBPANDAFILE_FILE_ITEMS_H 1852