use crate::common::mem::*;
use rmp_serde::{Deserializer, Serializer};
use serde::{Deserialize, Serialize};
use std::alloc::Layout;
#[doc(hidden)]
pub fn export_value_to_host<T: Serialize>(value: &T) -> FatPtr {
let mut buffer = Vec::new();
value
.serialize(
&mut Serializer::new(&mut buffer)
.with_struct_map()
.with_human_readable(),
)
.expect("Serialization error");
let len = buffer.len();
if buffer.capacity() > len {
buffer.shrink_to_fit();
if buffer.capacity() > len {
buffer = {
let mut exact_buffer = Vec::with_capacity(len);
exact_buffer.append(&mut buffer);
exact_buffer
}
}
}
if len & 0xff000000 != 0 {
panic!("Buffer too large ({} bytes)", len);
}
let ptr = buffer.as_ptr();
std::mem::forget(buffer);
to_fat_ptr(ptr, len as u32)
}
#[doc(hidden)]
pub unsafe fn import_value_from_host<'de, T: Deserialize<'de>>(fat_ptr: FatPtr) -> T {
let (ptr, len) = from_fat_ptr(fat_ptr);
if len & 0xff000000 != 0 {
panic!("Unknown extension bits");
}
let slice = std::slice::from_raw_parts(ptr, len as usize);
let mut deserializer = Deserializer::new(slice).with_human_readable();
let value = T::deserialize(&mut deserializer).unwrap();
__fp_free(fat_ptr);
value
}
const MALLOC_ALIGNMENT: usize = 16;
#[doc(hidden)]
#[no_mangle]
pub fn __fp_malloc(len: u32) -> FatPtr {
let ptr = unsafe {
std::alloc::alloc(
Layout::from_size_align(len as usize, MALLOC_ALIGNMENT)
.expect("Allocation failed unexpectedly, check requested allocation size"),
)
};
to_fat_ptr(ptr, len)
}
#[doc(hidden)]
#[no_mangle]
pub unsafe fn __fp_free(ptr: FatPtr) {
let (ptr, len) = from_fat_ptr(ptr);
assert_eq!(
len & 0xff000000,
0,
"__fp_free() failed: unknown extension bits"
);
std::alloc::dealloc(
ptr as *mut u8,
Layout::from_size_align(len as usize, MALLOC_ALIGNMENT)
.expect("Deallocation failed unexpectedly, check the pointer is valid"),
);
}