Rust · 1355 bytes Raw Blame History
1 use std::collections::HashMap;
2
3 use crate::resolve::SymbolId;
4
5 pub const THREAD_POINTER_SIZE: u32 = 8;
6 pub const THREAD_VARIABLE_DESCRIPTOR_SIZE: u32 = 24;
7
8 #[derive(Debug, Clone, PartialEq, Eq, Default)]
9 pub struct ThreadPointerSection {
10 pub entries: Vec<ThreadPointerEntry>,
11 pub index: HashMap<SymbolId, usize>,
12 }
13
14 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
15 pub struct ThreadPointerEntry {
16 pub symbol: SymbolId,
17 }
18
19 impl ThreadPointerSection {
20 pub fn intern(&mut self, symbol: SymbolId) -> usize {
21 if let Some(&idx) = self.index.get(&symbol) {
22 return idx;
23 }
24 let idx = self.entries.len();
25 self.entries.push(ThreadPointerEntry { symbol });
26 self.index.insert(symbol, idx);
27 idx
28 }
29
30 pub fn get(&self, symbol: SymbolId) -> Option<(usize, &ThreadPointerEntry)> {
31 let idx = *self.index.get(&symbol)?;
32 Some((idx, &self.entries[idx]))
33 }
34 }
35
36 #[cfg(test)]
37 mod tests {
38 use super::*;
39
40 #[test]
41 fn intern_deduplicates_thread_pointer_slots() {
42 let mut ptrs = ThreadPointerSection::default();
43 let a = ptrs.intern(SymbolId(5));
44 let b = ptrs.intern(SymbolId(5));
45 let c = ptrs.intern(SymbolId(9));
46 assert_eq!(a, 0);
47 assert_eq!(b, 0);
48 assert_eq!(c, 1);
49 assert_eq!(ptrs.entries.len(), 2);
50 }
51 }
52