firedbg_rust_debugger/
reader.rs

1use crate::{
2    Addr, ArrayType, Bytes, PValue, RVal, RValue, RValueLift, RefAddr, StringType, UnionType, Val,
3};
4use firedbg_protocol::IndexMap;
5use std::collections::HashMap;
6
7#[derive(Debug)]
8/// Stream Reader
9pub struct Reader {
10    source: SourceReader,
11    context: ReaderContext,
12}
13
14#[derive(Debug)]
15struct SourceReader {
16    source: Bytes,
17    cur: usize,
18}
19
20#[derive(Debug)]
21struct ReaderContext {
22    env: HashMap<Addr, RValue>,
23}
24
25#[derive(Debug)]
26enum Token {
27    Str(String),
28    Bytes(Bytes),
29    Int(u64),
30    Op(String),
31}
32
33impl Reader {
34    pub fn new() -> Self {
35        Self {
36            source: SourceReader::new(),
37            context: ReaderContext::new(),
38        }
39    }
40
41    pub fn read_values(&mut self) -> Vec<(String, RValue)> {
42        self.source.read_values(&mut self.context)
43    }
44
45    pub fn read_string(&mut self) -> Option<String> {
46        match self.source.next_token() {
47            Some(Token::Str(string)) => Some(string),
48            Some(other) => panic!("Expected String, got {other:?}"),
49            None => None,
50        }
51    }
52
53    pub fn read_int(&mut self) -> Option<u64> {
54        match self.source.next_token() {
55            Some(Token::Int(i)) => Some(i),
56            Some(other) => panic!("Expected Integer, got {other:?}"),
57            None => None,
58        }
59    }
60
61    pub fn set_source(&mut self, source: Bytes, offset: usize) {
62        self.source.set_source(source, offset)
63    }
64}
65
66impl ReaderContext {
67    pub fn new() -> Self {
68        Self {
69            env: Default::default(),
70        }
71    }
72}
73
74/// Reader and Writer uses the same interface. How brilliant is that?
75impl Val<ReaderContext> for ReaderContext {
76    type E = RValue;
77
78    fn alloc_env(&mut self, _: Addr) -> bool {
79        panic!("Should not be called by Reader");
80    }
81
82    fn set_env(&mut self, addr: Addr, val: RValue) {
83        self.env.insert(addr, val);
84    }
85
86    fn prim_v(&self, ty: &str, b: &[u8]) -> RValue {
87        RValue::Prim(match ty {
88            "bool" => PValue::bool(b[0] != 0),
89            "char" => PValue::char(
90                match char::from_u32(u32::from_ne_bytes(b[..].try_into().unwrap())) {
91                    Some(c) => c,
92                    None => return RValue::Opaque,
93                },
94            ),
95            "u8" => PValue::u8(u8::from_ne_bytes(b[..].try_into().unwrap())),
96            "i8" => PValue::i8(i8::from_ne_bytes(b[..].try_into().unwrap())),
97            "u16" => PValue::u16(u16::from_ne_bytes(b[..].try_into().unwrap())),
98            "i16" => PValue::i16(i16::from_ne_bytes(b[..].try_into().unwrap())),
99            "u32" => PValue::u32(u32::from_ne_bytes(b[..].try_into().unwrap())),
100            "i32" => PValue::i32(i32::from_ne_bytes(b[..].try_into().unwrap())),
101            "u64" => PValue::u64(u64::from_ne_bytes(b[..].try_into().unwrap())),
102            "i64" => PValue::i64(i64::from_ne_bytes(b[..].try_into().unwrap())),
103            "usize" => PValue::usize(match b.len() {
104                4 => u32::from_ne_bytes(b[..].try_into().unwrap()) as u64,
105                8 => u64::from_ne_bytes(b[..].try_into().unwrap()),
106                _ => panic!("Not a usize: {b:?}"),
107            }),
108            "isize" => PValue::isize(match b.len() {
109                4 => i32::from_ne_bytes(b[..].try_into().unwrap()) as i64,
110                8 => i64::from_ne_bytes(b[..].try_into().unwrap()),
111                _ => panic!("Not a isize: {b:?}"),
112            }),
113            "u128" => PValue::u128(u128::from_ne_bytes(b[..].try_into().unwrap())),
114            "i128" => PValue::i128(i128::from_ne_bytes(b[..].try_into().unwrap())),
115            "f32" => PValue::f32(f32::from_ne_bytes(b[..].try_into().unwrap())),
116            "f64" => PValue::f64(f64::from_ne_bytes(b[..].try_into().unwrap())),
117            _ => panic!("unknown ty `{ty}`"),
118        })
119    }
120
121    fn bytes_v(&self, ty: &str, val: Bytes) -> RValue {
122        RValue::Bytes {
123            typename: ty.into(),
124            value: val.into_bytes(),
125        }
126    }
127
128    fn arr_v<I: Iterator<Item = RValue>>(&self, iter: I) -> RValue {
129        RValue::Array {
130            typename: ArrayType::Arr,
131            data: iter.collect(),
132        }
133    }
134
135    fn ref_v(&self, ty: &str, addr: Addr) -> RValue {
136        if let Some(val) = self.env.get(&addr) {
137            RValue::Ref {
138                typename: ty.parse().unwrap(),
139                addr: RefAddr::Addr(addr),
140                value: Box::new(val.clone()),
141            }
142        } else {
143            RValue::UnresolvedRef {
144                addr: RefAddr::Addr(addr),
145            }
146        }
147    }
148
149    fn struct_v<I: Iterator<Item = (String, RValue)>>(&self, _: &str, _: I) -> RValue {
150        panic!("Please pass ownership");
151    }
152
153    fn enumerate_v(&self, _: &str, _: &str) -> RValue {
154        panic!("Please pass ownership");
155    }
156
157    fn unit_v(&self) -> RValue {
158        RValue::Unit
159    }
160
161    fn opaque_v(&self) -> RValue {
162        RValue::Opaque
163    }
164}
165
166impl ReaderContext {
167    fn strlit_v(&self, v: Vec<u8>) -> Option<RValue> {
168        Some(RValue::String {
169            typename: StringType::StrLit,
170            value: string_from_utf8(v)?,
171        })
172    }
173
174    fn enumerate_v(&self, ty: String, variant: String) -> RValue {
175        RValue::Enum {
176            typename: ty,
177            variant: variant,
178        }
179    }
180
181    fn struct_v<I: Iterator<Item = (String, RValue)>>(&self, ty: String, fields: I) -> RValue {
182        let mut f = IndexMap::new();
183        fields.for_each(|p| {
184            f.insert(p.0, p.1);
185        });
186        if ty.as_str() == "()" && f.is_empty() {
187            return RValue::Unit;
188        }
189        if ty.as_str() == "alloc::string::String" && f.len() == 1 && f.contains_key("vec") {
190            return RValue::String {
191                typename: StringType::String,
192                value: match match f.into_values().next() {
193                    Some(RValue::Opaque) => None,
194                    Some(RValue::Bytes { value, .. }) => string_from_utf8(value),
195                    _ => None,
196                } {
197                    Some(value) => value,
198                    None => return RValue::Opaque,
199                },
200            };
201        }
202        RValue::Struct {
203            typename: ty,
204            fields: f,
205        }
206    }
207}
208
209impl RVal<ReaderContext> for ReaderContext {
210    fn strlit_v(&self, _: &[u8]) -> RValue {
211        panic!("Please pass ownership");
212    }
213
214    fn union_v<I: Iterator<Item = (String, RValue)>>(
215        &mut self,
216        t: &UnionType,
217        index: usize,
218        fields: I,
219    ) -> RValue {
220        let mut f = IndexMap::new();
221        fields.for_each(|p| {
222            f.insert(p.0, p.1);
223        });
224        RValue::Union {
225            typeinfo: t.clone(),
226            variant: t.variants[index].clone(),
227            fields: f,
228        }
229    }
230
231    fn vector_v<I: Iterator<Item = RValue>>(&self, iter: I) -> RValue {
232        RValue::Array {
233            typename: ArrayType::Vec,
234            data: iter.collect(),
235        }
236    }
237
238    fn slice_v<I: Iterator<Item = RValue>>(&self, iter: I) -> RValue {
239        RValue::Array {
240            typename: ArrayType::Slice,
241            data: iter.collect(),
242        }
243    }
244}
245
246impl SourceReader {
247    pub fn new() -> SourceReader {
248        SourceReader {
249            source: Bytes::new(),
250            cur: 0,
251        }
252    }
253
254    pub fn set_source(&mut self, source: Bytes, offset: usize) {
255        self.source = source;
256        self.cur = offset;
257    }
258
259    fn next_token(&mut self) -> Option<Token> {
260        if self.cur >= self.source.len() {
261            return None;
262        }
263        let p = self.cur;
264        let q = self.next_char(b' ');
265        let tok = self.source.slice(p, q);
266        if matches!(tok, &[b'"']) {
267            self.cur += 2;
268            let r = self.next_char(b'"');
269            let bytes = self.source.slice(self.cur, r).to_owned();
270            self.cur = r + 1;
271            let tok = String::from_utf8(bytes).unwrap();
272            return Some(Token::Str(tok));
273        }
274        if matches!(tok, &[b'#']) {
275            self.cur += 2;
276            let len = u32::from_ne_bytes([
277                self.source.get(self.cur),
278                self.source.get(self.cur + 1),
279                self.source.get(self.cur + 2),
280                self.source.get(self.cur + 3),
281            ]);
282            self.cur += 4;
283            let bytes = self
284                .source
285                .slice(self.cur, self.cur + len as usize)
286                .to_owned();
287            self.cur += len as usize;
288            return Some(Token::Bytes(Bytes::from(bytes)));
289        }
290        self.cur = q + 1; // assume one space as delimiter
291        let tok = std::str::from_utf8(tok).unwrap();
292        return Some(match tok.parse() {
293            Ok(n) => Token::Int(n),
294            Err(_) => Token::Op(tok.to_owned()),
295        });
296    }
297
298    fn next_char(&self, c: u8) -> usize {
299        let mut q = self.cur;
300        while q < self.source.len() - 1 {
301            if self.source.get(q) == c {
302                break;
303            }
304            q += 1;
305        }
306        q
307    }
308
309    /// First, tokenize the binary stream.
310    /// Then, push some primitives onto the value stack.
311    /// When we read an `op` token, pop off some values from the stack based on the `op`.
312    pub fn read_values(&mut self, ctx: &mut ReaderContext) -> Vec<(String, RValue)> {
313        let mut str_stack = Vec::<String>::new();
314        let mut byte_stack = Vec::<Bytes>::new();
315        let mut int_stack = Vec::<u64>::new();
316        let mut val_stack = Vec::<RValue>::new();
317        let mut names = Vec::<String>::new();
318
319        while let Some(tok) = self.next_token() {
320            match tok {
321                Token::Str(s) => str_stack.push(s),
322                Token::Bytes(s) => byte_stack.push(s),
323                Token::Int(x) => int_stack.push(x),
324                Token::Op(op) => {
325                    if op == "setenv" {
326                        let addr = Addr::new(byte_stack.pop().unwrap().as_bytes());
327                        let val = val_stack.pop().unwrap();
328                        ctx.set_env(addr, val);
329                    } else if op == "prim" {
330                        let val = byte_stack.pop().unwrap();
331                        let ty = str_stack.pop().unwrap();
332                        val_stack.push(ctx.prim_v(&ty, val.as_bytes()));
333                    } else if op == "bytes" {
334                        let val = byte_stack.pop().unwrap();
335                        let ty = str_stack.pop().unwrap();
336                        val_stack.push(ctx.bytes_v(&ty, val));
337                    } else if op == "arr" {
338                        let size = int_stack.pop().unwrap();
339                        let mut elem = Vec::new();
340                        for _ in 0..size {
341                            elem.push(val_stack.pop().unwrap());
342                        }
343                        val_stack.push(ctx.arr_v(elem.into_iter().rev()));
344                    } else if op == "ref" {
345                        let addr = Addr::new(byte_stack.pop().unwrap().as_bytes());
346                        let ty = str_stack.pop().unwrap();
347                        val_stack.push(ctx.ref_v(&ty, addr));
348                    } else if op == "struct" {
349                        let name = str_stack.pop().unwrap();
350                        let fc = int_stack.pop().unwrap();
351                        let mut field = Vec::new();
352                        for _ in 0..fc {
353                            let val = val_stack.pop().unwrap();
354                            let n = str_stack.pop().unwrap();
355                            field.push((n, val));
356                        }
357                        val_stack.push(ctx.struct_v(name, field.into_iter().rev()));
358                    } else if op == "enum" {
359                        let variant = str_stack.pop().unwrap();
360                        let name = str_stack.pop().unwrap();
361                        val_stack.push(ctx.enumerate_v(name, variant));
362                    } else if op == "unit" {
363                        val_stack.push(ctx.unit_v());
364                    } else if op == "opaque" {
365                        val_stack.push(ctx.opaque_v());
366                    } else if op == "strlit" {
367                        let val = byte_stack.pop().unwrap();
368                        val_stack.push(
369                            ctx.strlit_v(val.into_bytes())
370                                .unwrap_or_else(|| ctx.opaque_v()),
371                        );
372                    } else if op == "union_decl" {
373                        let vc = int_stack.pop().unwrap();
374                        let mut variants = Vec::new();
375                        for _ in 0..vc {
376                            variants.push(str_stack.pop().unwrap());
377                        }
378                        variants.reverse();
379                        let name = str_stack.pop().unwrap();
380                        let ty = UnionType {
381                            name: name,
382                            variants,
383                        };
384                        let index = int_stack.pop().unwrap() as usize;
385                        let fc = int_stack.pop().unwrap();
386                        let mut field = Vec::new();
387                        for _ in 0..fc {
388                            let val = val_stack.pop().unwrap();
389                            let n = str_stack.pop().unwrap();
390                            field.push((n, val));
391                        }
392                        val_stack.push(ctx.union_v(&ty, index, field.into_iter().rev()));
393                    } else if op == "vec" {
394                        let size = int_stack.pop().unwrap();
395                        let mut elem = Vec::new();
396                        for _ in 0..size {
397                            elem.push(val_stack.pop().unwrap());
398                        }
399                        val_stack.push(ctx.vector_v(elem.into_iter().rev()));
400                    } else if op == "slice" {
401                        let size = int_stack.pop().unwrap();
402                        let mut elem = Vec::new();
403                        for _ in 0..size {
404                            elem.push(val_stack.pop().unwrap());
405                        }
406                        val_stack.push(ctx.slice_v(elem.into_iter().rev()));
407                    } else if op == "name" {
408                        names.push(str_stack.pop().unwrap());
409                    }
410                }
411            }
412        }
413
414        val_stack.iter_mut().for_each(|v| {
415            v.lift();
416        });
417        assert_eq!(names.len(), val_stack.len());
418        names.into_iter().zip(val_stack.into_iter()).collect()
419    }
420}
421
422fn string_from_utf8(mut bytes: Vec<u8>) -> Option<String> {
423    // we'd truncate the raw bytes when sending
424    // so the last char may be incomplete
425    for _ in 0..4 {
426        match String::from_utf8(bytes) {
427            Ok(s) => return Some(s),
428            Err(e) => {
429                bytes = e.into_bytes();
430                bytes.pop();
431            }
432        }
433    }
434    None
435}