Showing the changes to src/asm/sbl_reader.cpp (1 of 3 files). Show all
Unified · Split
| @@ -127,11 +127,21 @@ namespace · 126 unmodified lines | |||
| 127 | template<> | 127 | template<> |
| 128 | const type_t &type_table_t::resolve_table_index<type_t>(int32_t idx) const | 128 | const type_t &type_table_t::resolve_table_index<type_t>(int32_t idx) const |
| 129 | { | 129 | { |
| 130 | const auto idx_local = idx & ~inner_type_table_mask; | 130 | if ((static_cast<uint32_t>(idx) & inner_type_table_mask) != 0) |
| 131 | if (0 > idx_local || idx_local >= inner_type_table.size()) | 131 | { |
| 132 | throw std::out_of_range{ "Invalid inner type table index" }; | 132 | const auto idx_local = idx & ~inner_type_table_mask; |
| 133 | if (0 > idx_local || idx_local >= inner_type_table.size()) | ||
| 134 | throw std::out_of_range{ "Invalid inner type table index" }; | ||
| 135 | |||
| 136 | return inner_type_table[idx_local]; | ||
| 137 | } | ||
| 138 | else | ||
| 139 | { | ||
| 140 | if (0 > idx || static_cast<uint32_t>(idx) >= types.size()) | ||
| 141 | throw std::out_of_range{ "Invalid type table index" }; | ||
| 133 | 142 | ||
| 134 | return inner_type_table[idx_local]; | 143 | return types[idx]; |
| 144 | } | ||
| 135 | } | 145 | } |
| 136 | 146 | ||
| 137 | template<> | 147 | template<> |
| @@ -571,6 +581,114 @@ namespace · 433 unmodified lines | |||
| 571 | 581 | ||
| 572 | namespace | 582 | namespace |
| 573 | { | 583 | { |
| 584 | std::string to_string(const type_t &t, const type_table_t &tt) | ||
| 585 | { | ||
| 586 | switch (t.type_class) | ||
| 587 | { | ||
| 588 | case type_class_t::none: return "<none>"; | ||
| 589 | case type_class_t::nil: return "nil"; | ||
| 590 | case type_class_t::big: return "big"; | ||
| 591 | case type_class_t::byte: return "byte"; | ||
| 592 | case type_class_t::integer: return "int"; | ||
| 593 | case type_class_t::real: return "real"; | ||
| 594 | case type_class_t::string: return "string"; | ||
| 595 | |||
| 596 | case type_class_t::poly: | ||
| 597 | assert(false && "Not fully implemented"); | ||
| 598 | return "poly<T>"; | ||
| 599 | |||
| 600 | case type_class_t::array: | ||
| 601 | return to_string(tt.resolve_table_index<type_t>(t.value_index_1), tt) + "[]"; | ||
| 602 | case type_class_t::channel: | ||
| 603 | return "chan of " + to_string(tt.resolve_table_index<type_t>(t.value_index_1), tt); | ||
| 604 | case type_class_t::list: | ||
| 605 | return "list of " + to_string(tt.resolve_table_index<type_t>(t.value_index_1), tt); | ||
| 606 | case type_class_t::ref: | ||
| 607 | return "ref " + to_string(tt.resolve_table_index<type_t>(t.value_index_1), tt); | ||
| 608 | case type_class_t::type_index: | ||
| 609 | return to_string(tt.resolve_table_index<type_t>(t.value_index_1), tt); | ||
| 610 | |||
| 611 | case type_class_t::adt: | ||
| 612 | case type_class_t::adt_pick: | ||
| 613 | { | ||
| 614 | const auto &adt = tt.resolve_table_index<name_source_size_t>(t.value_index_1); | ||
| 615 | return adt.name; | ||
| 616 | } | ||
| 617 | case type_class_t::tuple: | ||
| 618 | { | ||
| 619 | const auto &tuple = tt.resolve_table_index<tuple_item_t>(t.value_index_1); | ||
| 620 | |||
| 621 | std::stringstream ss; | ||
| 622 | ss << '('; | ||
| 623 | |||
| 624 | auto first = true; | ||
| 625 | for (const auto &t_t : tuple.id_table) | ||
| 626 | { | ||
| 627 | if (!first) | ||
| 628 | ss << ','; | ||
| 629 | |||
| 630 | ss << to_string(t_t.type, tt); | ||
| 631 | first = false; | ||
| 632 | } | ||
| 633 | |||
| 634 | ss << ')'; | ||
| 635 | return ss.str(); | ||
| 636 | } | ||
| 637 | case type_class_t::module: | ||
| 638 | return tt.resolve_table_index<std::string>(t.value_index_1); | ||
| 639 | |||
| 640 | case type_class_t::function: | ||
| 641 | { | ||
| 642 | std::stringstream ss; | ||
| 643 | ss << tt.resolve_table_index<std::string>(t.value_index_1) | ||
| 644 | << ' ' | ||
| 645 | << to_string(tt.resolve_table_index<type_t>(t.value_index_2), tt); | ||
| 646 | |||
| 647 | return ss.str(); | ||
| 648 | } | ||
| 649 | |||
| 650 | default: | ||
| 651 | throw std::runtime_error{ "Invalid type value" }; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | std::string to_string(const func_item_t &f, const type_table_t &tt, function_name_format_t fmt) | ||
| 656 | { | ||
| 657 | std::stringstream ss; | ||
| 658 | |||
| 659 | if (util::has_flag(fmt, function_name_format_t::name)) | ||
| 660 | ss << f.name; | ||
| 661 | |||
| 662 | auto has_argument = false; | ||
| 663 | if (util::has_flag(fmt, function_name_format_t::arguments)) | ||
| 664 | { | ||
| 665 | has_argument = true; | ||
| 666 | ss << '('; | ||
| 667 | |||
| 668 | auto first = true; | ||
| 669 | for (const auto &at : f.args) | ||
| 670 | { | ||
| 671 | if (!first) | ||
| 672 | ss << ','; | ||
| 673 | |||
| 674 | ss << to_string(at.type, tt); | ||
| 675 | first = false; | ||
| 676 | } | ||
| 677 | |||
| 678 | ss << ')'; | ||
| 679 | } | ||
| 680 | |||
| 681 | if (util::has_flag(fmt, function_name_format_t::return_type)) | ||
| 682 | { | ||
| 683 | if (has_argument) | ||
| 684 | ss << ':'; | ||
| 685 | |||
| 686 | ss << to_string(f.return_type, tt); | ||
| 687 | } | ||
| 688 | |||
| 689 | return ss.str(); | ||
| 690 | } | ||
| 691 | |||
| 574 | class sbl_symbol_debug final : public symbol_debug_t | 692 | class sbl_symbol_debug final : public symbol_debug_t |
| 575 | { | 693 | { |
| 576 | public: | 694 | public: |
| @@ -632,12 +750,21 @@ namespace · 55 unmodified lines | |||
| 632 | return true; | 750 | return true; |
| 633 | } | 751 | } |
| 634 | 752 | ||
| 635 | const std::string ¤t_function_name() const override | 753 | std::string current_function_name(function_name_format_t f) const override |
| 636 | { | 754 | { |
| 637 | for (auto &e : _file->func_table) | 755 | try |
| 756 | { | ||
| 757 | for (auto &e : _file->func_table) | ||
| 758 | { | ||
| 759 | if (e.entry_pc <= _current_pc && _current_pc <= e.limit_pc) | ||
| 760 | return to_string(e, _file->type_table, f); | ||
| 761 | } | ||
| 762 | } | ||
| 763 | catch (const std::exception &e) | ||
| 638 | { | 764 | { |
| 639 | if (e.entry_pc <= _current_pc && _current_pc <= e.limit_pc) | 765 | // Avoid crashing during debugging |
| 640 | return e.name; | 766 | assert(false && "The SBL file appears to be corrupt or inconsistent"); |
| 767 | throw std::runtime_error{ e.what() }; | ||
| 641 | } | 768 | } |
| 642 | 769 | ||
| 643 | throw std::runtime_error{ "Unknown function" }; | 770 | throw std::runtime_error{ "Unknown function" }; |