| @@ -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" }; |