wasmer_engine_dylib/
serialize.rs1use loupe::MemoryUsage;
2use rkyv::{
3 archived_value, de::deserializers::SharedDeserializeMap, ser::serializers::AllocSerializer,
4 ser::Serializer as RkyvSerializer, Archive, Deserialize as RkyvDeserialize,
5 Serialize as RkyvSerialize,
6};
7use serde::{Deserialize, Serialize};
8use std::error::Error;
9use wasmer_compiler::{
10 CompileError, CompileModuleInfo, CompiledFunctionFrameInfo, SectionIndex, Symbol,
11 SymbolRegistry,
12};
13use wasmer_engine::DeserializeError;
14use wasmer_types::entity::{EntityRef, PrimaryMap};
15use wasmer_types::{FunctionIndex, LocalFunctionIndex, OwnedDataInitializer, SignatureIndex};
16
17fn to_compile_error(err: impl Error) -> CompileError {
18 CompileError::Codegen(format!("{}", err))
19}
20
21#[derive(
23 Serialize,
24 Deserialize,
25 Debug,
26 MemoryUsage,
27 RkyvSerialize,
28 RkyvDeserialize,
29 Archive,
30 PartialEq,
31 Eq,
32)]
33pub struct ModuleMetadata {
34 pub compile_info: CompileModuleInfo,
35 pub function_frame_info: Option<PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>>,
36 pub prefix: String,
37 pub data_initializers: Box<[OwnedDataInitializer]>,
38 pub function_body_lengths: PrimaryMap<LocalFunctionIndex, u64>,
40 pub cpu_features: u64,
41}
42
43pub struct ModuleMetadataSymbolRegistry<'a> {
44 pub prefix: &'a String,
45}
46
47impl ModuleMetadata {
48 pub fn split(&'_ mut self) -> (&'_ mut CompileModuleInfo, ModuleMetadataSymbolRegistry<'_>) {
49 let compile_info = &mut self.compile_info;
50 let symbol_registry = ModuleMetadataSymbolRegistry {
51 prefix: &self.prefix,
52 };
53 (compile_info, symbol_registry)
54 }
55
56 pub fn get_symbol_registry(&'_ self) -> ModuleMetadataSymbolRegistry<'_> {
57 ModuleMetadataSymbolRegistry {
58 prefix: &self.prefix,
59 }
60 }
61
62 pub fn serialize(&mut self) -> Result<Vec<u8>, CompileError> {
63 let mut serializer = AllocSerializer::<4096>::default();
64 let pos = serializer.serialize_value(self).map_err(to_compile_error)? as u64;
65 let mut serialized_data = serializer.into_serializer().into_inner();
66 serialized_data.extend_from_slice(&pos.to_le_bytes());
67 Ok(serialized_data.to_vec())
68 }
69
70 pub unsafe fn deserialize(metadata_slice: &[u8]) -> Result<Self, DeserializeError> {
71 let archived = Self::archive_from_slice(metadata_slice)?;
72 Self::deserialize_from_archive(archived)
73 }
74
75 unsafe fn archive_from_slice(
76 metadata_slice: &[u8],
77 ) -> Result<&ArchivedModuleMetadata, DeserializeError> {
78 let mut pos: [u8; 8] = Default::default();
79 pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]);
80 let pos: u64 = u64::from_le_bytes(pos);
81 Ok(archived_value::<Self>(
82 &metadata_slice[..metadata_slice.len() - 8],
83 pos as usize,
84 ))
85 }
86
87 pub fn deserialize_from_archive(
88 archived: &ArchivedModuleMetadata,
89 ) -> Result<Self, DeserializeError> {
90 let mut deserializer = SharedDeserializeMap::new();
91 RkyvDeserialize::deserialize(archived, &mut deserializer)
92 .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))
93 }
94}
95
96impl<'a> SymbolRegistry for ModuleMetadataSymbolRegistry<'a> {
97 fn symbol_to_name(&self, symbol: Symbol) -> String {
98 match symbol {
99 Symbol::LocalFunction(index) => {
100 format!("wasmer_function_{}_{}", self.prefix, index.index())
101 }
102 Symbol::Section(index) => format!("wasmer_section_{}_{}", self.prefix, index.index()),
103 Symbol::FunctionCallTrampoline(index) => {
104 format!(
105 "wasmer_trampoline_function_call_{}_{}",
106 self.prefix,
107 index.index()
108 )
109 }
110 Symbol::DynamicFunctionTrampoline(index) => {
111 format!(
112 "wasmer_trampoline_dynamic_function_{}_{}",
113 self.prefix,
114 index.index()
115 )
116 }
117 }
118 }
119
120 fn name_to_symbol(&self, name: &str) -> Option<Symbol> {
121 if let Some(index) = name.strip_prefix(&format!("wasmer_function_{}_", self.prefix)) {
122 index
123 .parse::<u32>()
124 .ok()
125 .map(|index| Symbol::LocalFunction(LocalFunctionIndex::from_u32(index)))
126 } else if let Some(index) = name.strip_prefix(&format!("wasmer_section_{}_", self.prefix)) {
127 index
128 .parse::<u32>()
129 .ok()
130 .map(|index| Symbol::Section(SectionIndex::from_u32(index)))
131 } else if let Some(index) =
132 name.strip_prefix(&format!("wasmer_trampoline_function_call_{}_", self.prefix))
133 {
134 index
135 .parse::<u32>()
136 .ok()
137 .map(|index| Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(index)))
138 } else if let Some(index) = name.strip_prefix(&format!(
139 "wasmer_trampoline_dynamic_function_{}_",
140 self.prefix
141 )) {
142 index
143 .parse::<u32>()
144 .ok()
145 .map(|index| Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(index)))
146 } else {
147 None
148 }
149 }
150}