History

Update stack walk in debugger to show source file name. Format function name to include full type signature.

arr committed 9 years ago

Commit 2b710fc1 parent 72f24ec3 files · +173 −13Browse files

Showing the changes to src/asm/sbl_reader.cpp (1 of 3 files). Show all

Unified · Split

src/asm/sbl_reader.cpp+135−8
@@ -127,11 +127,21 @@ namespace · 126 unmodified lines
127127 template<>
128128 const type_t &type_table_t::resolve_table_index<type_t>(int32_t idx) const
129129 {
130− const auto idx_local = idx & ~inner_type_table_mask;
131− if (0 > idx_local || idx_local >= inner_type_table.size())
132− throw std::out_of_range{ "Invalid inner type table index" };
130+ if ((static_cast<uint32_t>(idx) & inner_type_table_mask) != 0)
131+ {
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" };
133142
134− return inner_type_table[idx_local];
143+ return types[idx];
144+ }
135145 }
136146
137147 template<>
@@ -571,6 +581,114 @@ namespace · 433 unmodified lines
571581
572582 namespace
573583 {
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+
574692 class sbl_symbol_debug final : public symbol_debug_t
575693 {
576694 public:
@@ -632,12 +750,21 @@ namespace · 55 unmodified lines
632750 return true;
633751 }
634752
635− const std::string &current_function_name() const override
753+ std::string current_function_name(function_name_format_t f) const override
636754 {
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)
638764 {
639− if (e.entry_pc <= _current_pc && _current_pc <= e.limit_pc)
640− return e.name;
765+ // Avoid crashing during debugging
766+ assert(false && "The SBL file appears to be corrupt or inconsistent");
767+ throw std::runtime_error{ e.what() };
641768 }
642769
643770 throw std::runtime_error{ "Unknown function" };