swamp_vm_debug_info/
lib.rs1use seq_map::SeqMap;
6use swamp_vm_isa::InstructionPosition;
7use swamp_vm_types::Meta;
8use swamp_vm_types::types::FunctionInfo;
9
10pub struct FileOffsetEntry {
11 pub start_pc: u32, pub pc_count: u8, pub file_id: u16, pub line_row: u16, }
16
17pub struct FileOffsetTable {
18 pub entries: Vec<FileOffsetEntry>,
19}
20
21impl Default for FileOffsetTable {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl FileOffsetTable {
28 #[must_use]
29 pub const fn new() -> Self {
30 Self { entries: vec![] }
31 }
32 #[must_use]
33 pub fn find(&self, ip: InstructionPosition) -> Option<&FileOffsetEntry> {
34 let pc = ip.0;
35 self.entries
36 .iter()
37 .find(|&entry| pc >= entry.start_pc && pc <= entry.start_pc + u32::from(entry.pc_count))
38 }
39}
40
41pub struct FunctionDebugInfo {
42 pub start_pc: u32,
43 pub function_id: u16,
44}
45
46pub struct FunctionTable {
47 pub entries: Vec<FunctionDebugInfo>,
48}
49
50impl Default for FunctionTable {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl FunctionTable {
57 #[must_use]
58 pub const fn new() -> Self {
59 Self { entries: vec![] }
60 }
61 pub(crate) fn find(&self, ip: InstructionPosition) -> Option<&FunctionDebugInfo> {
62 let pc = ip.0;
63 let mut last_info = None;
64 for entry in &self.entries {
65 if entry.start_pc > pc {
66 return last_info;
67 }
68 last_info = Some(entry);
69 }
70 last_info
71 }
72}
73
74pub struct DebugInfo {
75 pub function_lookup: SeqMap<u32, u8>,
76 pub file_offsets: FileOffsetTable,
77 pub function_table: FunctionTable,
78 pub info_for_each_instruction: Vec<Meta>,
79 pub function_infos: SeqMap<u16, FunctionInfo>,
80}
81
82pub struct DebugInfoForPc {
83 pub meta: Meta,
84 pub function_debug_info: FunctionInfo,
85}
86
87impl Default for DebugInfo {
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93impl DebugInfo {
94 #[must_use]
95 pub fn new() -> Self {
96 Self {
97 function_lookup: SeqMap::default(),
98 file_offsets: FileOffsetTable::new(),
99 function_table: FunctionTable::new(),
100 info_for_each_instruction: vec![],
101 function_infos: SeqMap::default(),
102 }
103 }
104
105 #[must_use]
106 pub fn fetch(&self, pc: usize) -> Option<DebugInfoForPc> {
107 let ip = InstructionPosition(pc as u32);
108 let function = self.function_table.find(ip)?;
109
110 let meta = &self.info_for_each_instruction[ip.0 as usize];
111
112 let func_info = self.function_infos.get(&function.function_id)?;
113
114 let info = DebugInfoForPc {
115 meta: Meta {
116 comment: meta.comment.clone(),
117 node: meta.node.clone(),
118 },
119 function_debug_info: func_info.clone(),
120 };
121
122 Some(info)
123 }
124}