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