#![allow(missing_docs)]
use crate::types::{
function::{CompiledFunctionFrameInfo, Dwarf, FunctionBody},
module::CompileModuleInfo,
relocation::Relocation,
section::{CustomSection, SectionIndex},
target::CpuFeature,
};
use enumset::EnumSet;
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
use wasmer_types::{
entity::PrimaryMap, DeserializeError, Features, FunctionIndex, LocalFunctionIndex, MemoryIndex,
MemoryStyle, ModuleInfo, OwnedDataInitializer, SerializeError, SignatureIndex, TableIndex,
TableStyle,
};
pub use wasmer_types::MetadataHeader;
#[derive(Archive, Default, RkyvDeserialize, RkyvSerialize)]
#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
#[allow(missing_docs)]
#[rkyv(derive(Debug))]
pub struct SerializableCompilation {
pub function_bodies: PrimaryMap<LocalFunctionIndex, FunctionBody>,
pub function_relocations: PrimaryMap<LocalFunctionIndex, Vec<Relocation>>,
pub function_frame_info: PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>,
pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,
pub custom_sections: PrimaryMap<SectionIndex, CustomSection>,
pub custom_section_relocations: PrimaryMap<SectionIndex, Vec<Relocation>>,
pub debug: Option<Dwarf>,
pub libcall_trampolines: SectionIndex,
pub libcall_trampoline_len: u32,
}
impl SerializableCompilation {
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
rkyv::to_bytes::<rkyv::rancor::Error>(self)
.map(|v| v.into_vec())
.map_err(|e| SerializeError::Generic(e.to_string()))
}
}
#[derive(Archive, RkyvDeserialize, RkyvSerialize)]
#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
#[allow(missing_docs)]
#[rkyv(derive(Debug))]
pub struct SerializableModule {
pub compilation: SerializableCompilation,
pub compile_info: CompileModuleInfo,
pub data_initializers: Box<[OwnedDataInitializer]>,
pub cpu_features: u64,
}
impl SerializableModule {
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
rkyv::to_bytes::<rkyv::rancor::Error>(self)
.map(|v| v.into_vec())
.map_err(|e| SerializeError::Generic(e.to_string()))
}
pub unsafe fn deserialize_unchecked(metadata_slice: &[u8]) -> Result<Self, DeserializeError> {
let archived = Self::archive_from_slice(metadata_slice)?;
Self::deserialize_from_archive(archived)
}
pub unsafe fn deserialize(metadata_slice: &[u8]) -> Result<Self, DeserializeError> {
let archived = Self::archive_from_slice_checked(metadata_slice)?;
Self::deserialize_from_archive(archived)
}
pub unsafe fn archive_from_slice(
metadata_slice: &[u8],
) -> Result<&ArchivedSerializableModule, DeserializeError> {
Ok(rkyv::access_unchecked(metadata_slice))
}
pub fn archive_from_slice_checked(
metadata_slice: &[u8],
) -> Result<&ArchivedSerializableModule, DeserializeError> {
rkyv::access::<_, rkyv::rancor::Error>(metadata_slice)
.map_err(|e| DeserializeError::CorruptedBinary(e.to_string()))
}
pub fn deserialize_from_archive(
archived: &ArchivedSerializableModule,
) -> Result<Self, DeserializeError> {
rkyv::deserialize::<_, rkyv::rancor::Error>(archived)
.map_err(|e| DeserializeError::CorruptedBinary(e.to_string()))
}
pub fn create_module_info(&self) -> ModuleInfo {
self.compile_info.module.as_ref().clone()
}
pub fn module_info(&self) -> &ModuleInfo {
&self.compile_info.module
}
pub fn features(&self) -> &Features {
&self.compile_info.features
}
pub fn cpu_features(&self) -> EnumSet<CpuFeature> {
EnumSet::from_u64(self.cpu_features)
}
pub fn data_initializers(&self) -> &[OwnedDataInitializer] {
&self.data_initializers
}
pub fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
&self.compile_info.memory_styles
}
pub fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
&self.compile_info.table_styles
}
}