wasmer_types/compilation/
symbols.rs1use crate::{
3 entity::{EntityRef, PrimaryMap},
4 CompileModuleInfo, DeserializeError, FunctionIndex, LocalFunctionIndex, OwnedDataInitializer,
5 SectionIndex, SerializeError, SignatureIndex,
6};
7use rkyv::{
8 archived_value, check_archived_value, de::deserializers::SharedDeserializeMap,
9 ser::serializers::AllocSerializer, ser::Serializer as RkyvSerializer, Archive,
10 Deserialize as RkyvDeserialize, Serialize as RkyvSerialize,
11};
12#[cfg(feature = "enable-serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(
17 RkyvSerialize, RkyvDeserialize, Archive, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug,
18)]
19#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
20#[archive(as = "Self")]
21pub enum Symbol {
22 Metadata,
25
26 LocalFunction(LocalFunctionIndex),
28
29 Section(SectionIndex),
31
32 FunctionCallTrampoline(SignatureIndex),
34
35 DynamicFunctionTrampoline(FunctionIndex),
37}
38
39pub trait SymbolRegistry: Send + Sync {
41 fn symbol_to_name(&self, symbol: Symbol) -> String;
43
44 fn name_to_symbol(&self, name: &str) -> Option<Symbol>;
48}
49
50#[derive(Debug, RkyvSerialize, RkyvDeserialize, Archive)]
52#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
53#[archive_attr(derive(rkyv::CheckBytes, Debug))]
54pub struct ModuleMetadata {
55 pub compile_info: CompileModuleInfo,
57 pub prefix: String,
59 pub data_initializers: Box<[OwnedDataInitializer]>,
61 pub function_body_lengths: PrimaryMap<LocalFunctionIndex, u64>,
63 pub cpu_features: u64,
65}
66
67pub struct ModuleMetadataSymbolRegistry {
69 pub prefix: String,
71}
72
73impl ModuleMetadata {
74 pub fn split(&mut self) -> (&mut CompileModuleInfo, ModuleMetadataSymbolRegistry) {
76 let compile_info = &mut self.compile_info;
77 let symbol_registry = ModuleMetadataSymbolRegistry {
78 prefix: self.prefix.clone(),
79 };
80 (compile_info, symbol_registry)
81 }
82
83 pub fn get_symbol_registry(&self) -> ModuleMetadataSymbolRegistry {
85 ModuleMetadataSymbolRegistry {
86 prefix: self.prefix.clone(),
87 }
88 }
89 pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
93 let mut serializer = AllocSerializer::<4096>::default();
94 let pos = serializer
95 .serialize_value(self)
96 .map_err(|err| SerializeError::Generic(format!("{}", err)))? as u64;
97 let mut serialized_data = serializer.into_serializer().into_inner();
98 serialized_data.extend_from_slice(&pos.to_le_bytes());
99 Ok(serialized_data.to_vec())
100 }
101
102 pub unsafe fn deserialize_unchecked(metadata_slice: &[u8]) -> Result<Self, DeserializeError> {
114 let archived = Self::archive_from_slice(metadata_slice)?;
115 Self::deserialize_from_archive(archived)
116 }
117
118 pub fn deserialize(metadata_slice: &[u8]) -> Result<Self, DeserializeError> {
122 let archived = Self::archive_from_slice_checked(metadata_slice)?;
123 Self::deserialize_from_archive(archived)
124 }
125
126 unsafe fn archive_from_slice(
131 metadata_slice: &[u8],
132 ) -> Result<&ArchivedModuleMetadata, DeserializeError> {
133 if metadata_slice.len() < 8 {
134 return Err(DeserializeError::Incompatible(
135 "invalid serialized ModuleMetadata".into(),
136 ));
137 }
138 let mut pos: [u8; 8] = Default::default();
139 pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]);
140 let pos: u64 = u64::from_le_bytes(pos);
141 Ok(archived_value::<Self>(
142 &metadata_slice[..metadata_slice.len() - 8],
143 pos as usize,
144 ))
145 }
146
147 fn archive_from_slice_checked(
152 metadata_slice: &[u8],
153 ) -> Result<&ArchivedModuleMetadata, DeserializeError> {
154 if metadata_slice.len() < 8 {
155 return Err(DeserializeError::Incompatible(
156 "invalid serialized ModuleMetadata".into(),
157 ));
158 }
159 let mut pos: [u8; 8] = Default::default();
160 pos.copy_from_slice(&metadata_slice[metadata_slice.len() - 8..metadata_slice.len()]);
161 let pos: u64 = u64::from_le_bytes(pos);
162 check_archived_value::<Self>(&metadata_slice[..metadata_slice.len() - 8], pos as usize)
163 .map_err(|e| DeserializeError::CorruptedBinary(e.to_string()))
164 }
165
166 pub fn deserialize_from_archive(
168 archived: &ArchivedModuleMetadata,
169 ) -> Result<Self, DeserializeError> {
170 let mut deserializer = SharedDeserializeMap::new();
171 RkyvDeserialize::deserialize(archived, &mut deserializer)
172 .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))
173 }
174}
175
176impl SymbolRegistry for ModuleMetadataSymbolRegistry {
177 fn symbol_to_name(&self, symbol: Symbol) -> String {
178 match symbol {
179 Symbol::Metadata => {
180 format!("WASMER_METADATA_{}", self.prefix.to_uppercase())
181 }
182 Symbol::LocalFunction(index) => {
183 format!("wasmer_function_{}_{}", self.prefix, index.index())
184 }
185 Symbol::Section(index) => format!("wasmer_section_{}_{}", self.prefix, index.index()),
186 Symbol::FunctionCallTrampoline(index) => {
187 format!(
188 "wasmer_trampoline_function_call_{}_{}",
189 self.prefix,
190 index.index()
191 )
192 }
193 Symbol::DynamicFunctionTrampoline(index) => {
194 format!(
195 "wasmer_trampoline_dynamic_function_{}_{}",
196 self.prefix,
197 index.index()
198 )
199 }
200 }
201 }
202
203 fn name_to_symbol(&self, name: &str) -> Option<Symbol> {
204 if name == self.symbol_to_name(Symbol::Metadata) {
205 Some(Symbol::Metadata)
206 } else if let Some(index) = name.strip_prefix(&format!("wasmer_function_{}_", self.prefix))
207 {
208 index
209 .parse::<u32>()
210 .ok()
211 .map(|index| Symbol::LocalFunction(LocalFunctionIndex::from_u32(index)))
212 } else if let Some(index) = name.strip_prefix(&format!("wasmer_section_{}_", self.prefix)) {
213 index
214 .parse::<u32>()
215 .ok()
216 .map(|index| Symbol::Section(SectionIndex::from_u32(index)))
217 } else if let Some(index) =
218 name.strip_prefix(&format!("wasmer_trampoline_function_call_{}_", self.prefix))
219 {
220 index
221 .parse::<u32>()
222 .ok()
223 .map(|index| Symbol::FunctionCallTrampoline(SignatureIndex::from_u32(index)))
224 } else if let Some(index) = name.strip_prefix(&format!(
225 "wasmer_trampoline_dynamic_function_{}_",
226 self.prefix
227 )) {
228 index
229 .parse::<u32>()
230 .ok()
231 .map(|index| Symbol::DynamicFunctionTrampoline(FunctionIndex::from_u32(index)))
232 } else {
233 None
234 }
235 }
236}