fix code serialization

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-01-25 15:51:25 +01:00
parent 3a9499cc5c
commit c46faa1b18
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2

View file

@ -152,6 +152,7 @@ impl Serializable for CodeItem {
self.outs_size.serialize(output)?; self.outs_size.serialize(output)?;
self.tries_size_field().serialize(output)?; self.tries_size_field().serialize(output)?;
self.debug_info_off.serialize(output)?; self.debug_info_off.serialize(output)?;
(self.insns.iter().map(|i| i.size() as u32).sum::<u32>() / 2).serialize(output)?;
for insn in &self.insns { for insn in &self.insns {
insn.serialize(output)?; insn.serialize(output)?;
} }
@ -179,6 +180,18 @@ impl Serializable for CodeItem {
let mut serialized_insns_size = 0; let mut serialized_insns_size = 0;
while serialized_insns_size < insns_size { while serialized_insns_size < insns_size {
let ins = Instruction::deserialize(input).map_err(|err| { let ins = Instruction::deserialize(input).map_err(|err| {
println!(
"{:#?}",
Self {
registers_size,
ins_size,
outs_size,
debug_info_off,
insns: insns.clone(),
tries: vec![],
handlers: None
}
);
Error::DeserializationError(format!( Error::DeserializationError(format!(
"Failed to deserialize instruction at 0x{serialized_insns_size:x}: {err}" "Failed to deserialize instruction at 0x{serialized_insns_size:x}: {err}"
)) ))
@ -401,6 +414,7 @@ pub struct EncodedTypeAddrPair {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::instructions::Instruction::*;
const CODE_ITEM_RAW_1: &[u8] = &[ const CODE_ITEM_RAW_1: &[u8] = &[
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x3d, 0x25, 0x4f, 0x00, 0x15, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x3d, 0x25, 0x4f, 0x00, 0x15, 0x00, 0x00,
@ -465,6 +479,21 @@ mod test {
0x02, 0xd9, 0x09, 0x87, 0x02, 0x01, 0xc7, 0x08, 0xee, 0x01, 0x02, 0xd9, 0x09, 0x87, 0x02, 0x01, 0xc7, 0x08, 0xee, 0x01,
]; ];
fn insns_from_bin(raw: &[u16]) -> Vec<Instruction> {
let mut insns = vec![];
let raw: Vec<u8> = raw
.iter()
.map(|w| w.to_le_bytes().into_iter())
.flatten()
.collect();
let len = raw.len() as u64;
let mut buffer = std::io::Cursor::new(raw);
while buffer.position() < len {
insns.push(Instruction::deserialize(&mut buffer).unwrap());
}
insns
}
#[test] #[test]
fn test_deserialize_code_item() { fn test_deserialize_code_item() {
assert_eq!( assert_eq!(
@ -474,10 +503,10 @@ mod test {
ins_size: 1, ins_size: 1,
outs_size: 2, outs_size: 2,
debug_info_off: 5186877, debug_info_off: 5186877,
insns: vec![ insns: insns_from_bin(&[
0x3054, 0x16c, 0x1071, 0xcb1, 0x0, 0xe28, 0xd, 0x106e, 0x8526, 0x0, 0x10c, 0x3054, 0x16c, 0x1071, 0xcb1, 0x0, 0xe28, 0xd, 0x106e, 0x8526, 0x0, 0x10c,
0x21a, 0x15cb, 0x2071, 0x5e3, 0x21, 0x10a, 0x138, 0x3, 0xe, 0x27 0x21a, 0x15cb, 0x2071, 0x5e3, 0x21, 0x10a, 0x138, 0x3, 0xe, 0x27
], ]),
tries: vec![TryItem { tries: vec![TryItem {
start_addr: 0, start_addr: 0,
insn_count: 5, insn_count: 5,
@ -501,7 +530,7 @@ mod test {
ins_size: 4, ins_size: 4,
outs_size: 3, outs_size: 3,
debug_info_off: 5187799, debug_info_off: 5187799,
insns: vec![ insns: insns_from_bin(&[
0x1070, 0x848b, 0x0005, 0x0022, 0x242d, 0x1070, 0x8751, 0x0000, 0x505b, 0x0654, 0x1070, 0x848b, 0x0005, 0x0022, 0x242d, 0x1070, 0x8751, 0x0000, 0x505b, 0x0654,
0x575b, 0x0658, 0x0022, 0x0584, 0x1070, 0x1c09, 0x0000, 0x505b, 0x0656, 0x7754, 0x575b, 0x0658, 0x0022, 0x0584, 0x1070, 0x1c09, 0x0000, 0x505b, 0x0656, 0x7754,
0x09cc, 0x2071, 0x18ed, 0x0076, 0x070c, 0x575b, 0x0655, 0x1071, 0x17b9, 0x0006, 0x09cc, 0x2071, 0x18ed, 0x0076, 0x070c, 0x575b, 0x0655, 0x1071, 0x17b9, 0x0006,
@ -531,7 +560,7 @@ mod test {
0x1884, 0x0067, 0x0727, 0x060d, 0x0722, 0x051e, 0x2070, 0x1ac2, 0x0067, 0x0727, 0x1884, 0x0067, 0x0727, 0x060d, 0x0722, 0x051e, 0x2070, 0x1ac2, 0x0067, 0x0727,
0x060d, 0x0722, 0x051e, 0x1071, 0x48ff, 0x0006, 0x060c, 0x2070, 0x1ac2, 0x0067, 0x060d, 0x0722, 0x051e, 0x1071, 0x48ff, 0x0006, 0x060c, 0x2070, 0x1ac2, 0x0067,
0x0727, 0x0727,
], ]),
tries: vec![ tries: vec![
TryItem { TryItem {
start_addr: 33, start_addr: 33,
@ -1109,6 +1138,81 @@ mod test {
0x20, 0xc2, 0x1a, 0x67, 0x00, 0x27, 0x07, 0x20, 0xc2, 0x1a, 0x67, 0x00, 0x27, 0x07,
]; ];
//#[test] #[test]
//fn test_insn_parsing() {} fn test_code() {
let code = CodeItem {
registers_size: 3,
ins_size: 1,
outs_size: 2,
debug_info_off: 1205,
insns: vec![
Format35C {
a: 1,
vg: 0,
op: 112,
b: 2,
vf: 0,
ve: 0,
vd: 0,
vc: 2,
},
Format21C {
va: 0,
op: 34,
b: 2,
},
Format35C {
a: 1,
vg: 0,
op: 112,
b: 0,
vf: 0,
ve: 0,
vd: 0,
vc: 0,
},
Format22C {
vb: 2,
va: 0,
op: 91,
c: 1,
},
Format21C {
va: 1,
op: 26,
b: 18,
},
Format35C {
a: 2,
vg: 0,
op: 110,
b: 1,
vf: 0,
ve: 0,
vd: 1,
vc: 0,
},
Format10X { op: 14 },
],
tries: vec![],
handlers: None,
};
let raw = vec![
0x03, 0x00, // registers_size
0x01, 0x00, // ins_size
0x02, 0x00, // outs_size
0x00, 0x00, // tries_size
0xb5, 0x04, 0x00, 0x00, // debug_info_off
0x10, 0x00, 0x00, 0x00, // insns_size
0x70, 0x10, 0x02, 0x00, 0x02, 0x00, // Format35C
0x22, 0x00, 0x02, 0x00, // Format21C
0x70, 0x10, 0x00, 0x00, 0x00, 0x00, // Format35C
0x5b, 0x20, 0x01, 0x00, // Format22C
0x1a, 0x01, 0x12, 0x00, // Format21C
0x6e, 0x20, 0x01, 0x00, 0x10, 0x00, // Format35C
0x0e, 0x00, // Format10X
];
assert_eq!(code.serialize_to_vec().unwrap(), raw);
assert_eq!(code, CodeItem::deserialize_from_slice(&raw).unwrap());
}
} }