wasm_edit/
lib.rs

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