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