1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
pub mod ast;
pub mod parser;
pub mod printer;
pub mod traverse;
pub mod wasi;
pub fn update_value<T>(input: &mut Vec<u8>, old_value: &ast::Value<T>, new_value: T) -> usize
where
T: ToBytes + std::fmt::Debug,
{
eprintln!("replace {:?} with {:?}", old_value, new_value);
let old_value_len = old_value.end_offset - old_value.start_offset;
let head = &input[..old_value.start_offset];
let tail = &input[old_value.end_offset..];
let mut new_input = Vec::new();
new_input.extend_from_slice(&head);
let new_bytes = new_value.to_bytes();
new_input.extend_from_slice(&new_bytes);
new_input.extend_from_slice(&tail);
*input = new_input;
new_bytes.len() - old_value_len
}
pub trait ToBytes {
fn to_bytes(&self) -> Vec<u8>;
}
impl ToBytes for u32 {
fn to_bytes(&self) -> Vec<u8> {
let mut buffer = Vec::new();
leb128::write::unsigned(&mut buffer, *self as u64).unwrap();
buffer
}
}
impl ToBytes for ast::Instr {
fn to_bytes(&self) -> Vec<u8> {
match self {
ast::Instr::call(idx) => {
let mut buffer = Vec::new();
buffer.push(0x10);
leb128::write::unsigned(&mut buffer, idx.lock().unwrap().value as u64).unwrap();
buffer
}
n => todo!("ToBytes not yet implemented for node: {:?}", n),
}
}
}