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)]
8pub 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
74impl 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; 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 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 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}