use super::{io::to_wasm_ptr, runtime::RuntimeInstanceData};
use crate::common::mem::FatPtr;
use rmp_serde::{decode::ReadReader, Deserializer, Serializer};
use serde::{Deserialize, Serialize};
use wasmer::WasmCell;
pub fn serialize_to_vec<T: Serialize>(value: &T) -> Vec<u8> {
let mut buffer = Vec::new();
let mut serializer = Serializer::new(&mut buffer)
.with_struct_map()
.with_human_readable();
value.serialize(&mut serializer).unwrap();
buffer
}
pub fn deserialize_from_slice<'a, T: Deserialize<'a>>(slice: &'a [u8]) -> T {
let mut deserializer = rmp_serde::Deserializer::new(slice).with_human_readable();
T::deserialize(&mut deserializer).unwrap()
}
pub fn import_from_guest<'de, T: Deserialize<'de>>(
env: &RuntimeInstanceData,
fat_ptr: FatPtr,
) -> T {
let value = import_from_guest_raw(env, fat_ptr);
let mut deserializer =
Deserializer::<ReadReader<&[u8]>>::new(value.as_ref()).with_human_readable();
T::deserialize(&mut deserializer).unwrap()
}
pub fn import_from_guest_raw(env: &RuntimeInstanceData, fat_ptr: FatPtr) -> Vec<u8> {
if fat_ptr == 0 {
return Vec::new();
}
let memory = unsafe { env.memory.get_unchecked() };
let (ptr, len) = to_wasm_ptr::<u8>(fat_ptr);
if len & 0xff000000 != 0 {
panic!("Unknown extension bits");
}
let value: Vec<u8> = {
let view = ptr.deref(memory, 0, len).unwrap();
view.iter().map(WasmCell::get).collect()
};
env.free(fat_ptr);
value
}
pub fn export_to_guest<T: Serialize>(env: &RuntimeInstanceData, value: &T) -> FatPtr {
export_to_guest_raw(env, rmp_serde::to_vec(value).unwrap())
}
pub fn export_to_guest_raw(env: &RuntimeInstanceData, buffer: Vec<u8>) -> FatPtr {
let memory = unsafe { env.memory.get_unchecked() };
let len = buffer.len() as u32;
if len & 0xff000000 != 0 {
panic!("Buffer too large ({} bytes)", len);
}
let fat_ptr = env.malloc(len);
let (ptr, len) = to_wasm_ptr(fat_ptr);
let values = ptr.deref(memory, 0, len).unwrap();
for (i, val) in buffer.iter().enumerate() {
values[i].set(*val);
}
fat_ptr
}