wasmer_compiler/artifact_builders/
artifact_builder.rs1#[cfg(feature = "compiler")]
5use super::trampoline::{libcall_trampoline_len, make_libcall_trampolines};
6
7#[cfg(feature = "compiler")]
8use crate::{
9 serialize::SerializableCompilation, EngineInner, ModuleEnvironment, ModuleMiddlewareChain,
10};
11use crate::{
12 serialize::{
13 ArchivedSerializableCompilation, ArchivedSerializableModule, MetadataHeader,
14 SerializableModule,
15 },
16 types::{
17 function::{CompiledFunctionFrameInfo, FunctionBody, UnwindInfo, GOT},
18 module::CompileModuleInfo,
19 relocation::Relocation,
20 section::{CustomSection, SectionIndex},
21 },
22 ArtifactCreate, Features,
23};
24#[cfg(feature = "compiler")]
25use wasmer_types::target::Target;
26
27use core::mem::MaybeUninit;
28use enumset::EnumSet;
29use rkyv::rancor::Error as RkyvError;
30use self_cell::self_cell;
31use shared_buffer::OwnedBuffer;
32use std::sync::Arc;
33use wasmer_types::{
34 entity::{ArchivedPrimaryMap, PrimaryMap},
35 target::CpuFeature,
36 DeserializeError,
37};
38
39#[allow(unused)]
41use wasmer_types::*;
42
43#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
45pub struct ArtifactBuild {
46 serializable: SerializableModule,
47}
48
49impl ArtifactBuild {
50 pub const MAGIC_HEADER: &'static [u8; 16] = b"wasmer-universal";
52
53 pub fn is_deserializable(bytes: &[u8]) -> bool {
55 bytes.starts_with(Self::MAGIC_HEADER)
56 }
57
58 #[cfg(feature = "compiler")]
60 pub fn new(
61 inner_engine: &mut EngineInner,
62 data: &[u8],
63 target: &Target,
64 memory_styles: PrimaryMap<MemoryIndex, MemoryStyle>,
65 table_styles: PrimaryMap<TableIndex, TableStyle>,
66 hash_algorithm: Option<HashAlgorithm>,
67 ) -> Result<Self, CompileError> {
68 let environ = ModuleEnvironment::new();
69 let features = inner_engine.features().clone();
70
71 let translation = environ.translate(data).map_err(CompileError::Wasm)?;
72
73 let compiler = inner_engine.compiler()?;
74
75 let mut module = translation.module;
77 let middlewares = compiler.get_middlewares();
78 middlewares
79 .apply_on_module_info(&mut module)
80 .map_err(|err| CompileError::MiddlewareError(err.to_string()))?;
81
82 if let Some(hash_algorithm) = hash_algorithm {
83 let hash = match hash_algorithm {
84 HashAlgorithm::Sha256 => ModuleHash::sha256(data),
85 HashAlgorithm::XXHash => ModuleHash::xxhash(data),
86 };
87
88 module.hash = Some(hash);
89 }
90
91 let compile_info = CompileModuleInfo {
92 module: Arc::new(module),
93 features,
94 memory_styles,
95 table_styles,
96 };
97
98 let compilation = compiler.compile_module(
100 target,
101 &compile_info,
102 translation.module_translation_state.as_ref().unwrap(),
106 translation.function_body_inputs,
107 )?;
108
109 let data_initializers = translation
110 .data_initializers
111 .iter()
112 .map(OwnedDataInitializer::new)
113 .collect::<Vec<_>>()
114 .into_boxed_slice();
115
116 let mut function_frame_info = PrimaryMap::with_capacity(compilation.functions.len());
118 let mut function_bodies = PrimaryMap::with_capacity(compilation.functions.len());
119 let mut function_relocations = PrimaryMap::with_capacity(compilation.functions.len());
120 for (_, func) in compilation.functions.into_iter() {
121 function_bodies.push(func.body);
122 function_relocations.push(func.relocations);
123 function_frame_info.push(func.frame_info);
124 }
125 let mut custom_sections = compilation.custom_sections.clone();
126 let mut custom_section_relocations = compilation
127 .custom_sections
128 .iter()
129 .map(|(_, section)| section.relocations.clone())
130 .collect::<PrimaryMap<SectionIndex, _>>();
131 let libcall_trampolines_section = make_libcall_trampolines(target);
132 custom_section_relocations.push(libcall_trampolines_section.relocations.clone());
133 let libcall_trampolines = custom_sections.push(libcall_trampolines_section);
134 let libcall_trampoline_len = libcall_trampoline_len(target) as u32;
135 let cpu_features = compiler.get_cpu_features_used(target.cpu_features());
136
137 let serializable_compilation = SerializableCompilation {
138 function_bodies,
139 function_relocations,
140 function_frame_info,
141 function_call_trampolines: compilation.function_call_trampolines,
142 dynamic_function_trampolines: compilation.dynamic_function_trampolines,
143 custom_sections,
144 custom_section_relocations,
145 unwind_info: compilation.unwind_info,
146 libcall_trampolines,
147 libcall_trampoline_len,
148 got: compilation.got,
149 };
150 let serializable = SerializableModule {
151 compilation: serializable_compilation,
152 compile_info,
153 data_initializers,
154 cpu_features: cpu_features.as_u64(),
155 };
156 Ok(Self { serializable })
157 }
158
159 pub fn from_serializable(serializable: SerializableModule) -> Self {
161 Self { serializable }
162 }
163
164 pub fn get_function_bodies_ref(&self) -> &PrimaryMap<LocalFunctionIndex, FunctionBody> {
166 &self.serializable.compilation.function_bodies
167 }
168
169 pub fn get_function_call_trampolines_ref(&self) -> &PrimaryMap<SignatureIndex, FunctionBody> {
171 &self.serializable.compilation.function_call_trampolines
172 }
173
174 pub fn get_dynamic_function_trampolines_ref(&self) -> &PrimaryMap<FunctionIndex, FunctionBody> {
176 &self.serializable.compilation.dynamic_function_trampolines
177 }
178
179 pub fn get_custom_sections_ref(&self) -> &PrimaryMap<SectionIndex, CustomSection> {
181 &self.serializable.compilation.custom_sections
182 }
183
184 pub fn get_function_relocations(&self) -> &PrimaryMap<LocalFunctionIndex, Vec<Relocation>> {
186 &self.serializable.compilation.function_relocations
187 }
188
189 pub fn get_custom_section_relocations_ref(&self) -> &PrimaryMap<SectionIndex, Vec<Relocation>> {
191 &self.serializable.compilation.custom_section_relocations
192 }
193
194 pub fn get_libcall_trampolines(&self) -> SectionIndex {
196 self.serializable.compilation.libcall_trampolines
197 }
198
199 pub fn get_libcall_trampoline_len(&self) -> usize {
201 self.serializable.compilation.libcall_trampoline_len as usize
202 }
203
204 pub fn get_unwind_info(&self) -> &UnwindInfo {
206 &self.serializable.compilation.unwind_info
207 }
208
209 pub fn get_got_ref(&self) -> &GOT {
211 &self.serializable.compilation.got
212 }
213
214 pub fn get_frame_info_ref(&self) -> &PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
216 &self.serializable.compilation.function_frame_info
217 }
218}
219
220impl<'a> ArtifactCreate<'a> for ArtifactBuild {
221 type OwnedDataInitializer = &'a OwnedDataInitializer;
222 type OwnedDataInitializerIterator = core::slice::Iter<'a, OwnedDataInitializer>;
223
224 fn create_module_info(&self) -> Arc<ModuleInfo> {
225 self.serializable.compile_info.module.clone()
226 }
227
228 fn set_module_info_name(&mut self, name: String) -> bool {
229 Arc::get_mut(&mut self.serializable.compile_info.module).map_or(false, |module_info| {
230 module_info.name = Some(name.to_string());
231 true
232 })
233 }
234
235 fn module_info(&self) -> &ModuleInfo {
236 &self.serializable.compile_info.module
237 }
238
239 fn features(&self) -> &Features {
240 &self.serializable.compile_info.features
241 }
242
243 fn cpu_features(&self) -> EnumSet<CpuFeature> {
244 EnumSet::from_u64(self.serializable.cpu_features)
245 }
246
247 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
248 self.serializable.data_initializers.iter()
249 }
250
251 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
252 &self.serializable.compile_info.memory_styles
253 }
254
255 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
256 &self.serializable.compile_info.table_styles
257 }
258
259 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
260 serialize_module(&self.serializable)
261 }
262}
263
264#[derive(Debug)]
267pub struct ModuleFromArchive<'a> {
268 pub compilation: &'a ArchivedSerializableCompilation,
270 pub data_initializers: &'a rkyv::Archived<Box<[OwnedDataInitializer]>>,
272 pub cpu_features: u64,
274
275 original_module: &'a ArchivedSerializableModule,
277}
278
279impl<'a> ModuleFromArchive<'a> {
280 pub fn from_serializable_module(
282 module: &'a ArchivedSerializableModule,
283 ) -> Result<Self, DeserializeError> {
284 Ok(Self {
285 compilation: &module.compilation,
286 data_initializers: &module.data_initializers,
287 cpu_features: module.cpu_features.to_native(),
288 original_module: module,
289 })
290 }
291}
292
293self_cell!(
294 struct ArtifactBuildFromArchiveCell {
295 owner: OwnedBuffer,
296
297 #[covariant]
298 dependent: ModuleFromArchive,
299 }
300
301 impl {Debug}
302);
303
304#[cfg(feature = "artifact-size")]
305impl loupe::MemoryUsage for ArtifactBuildFromArchiveCell {
306 fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
307 std::mem::size_of_val(self.borrow_owner()) + std::mem::size_of_val(self.borrow_dependent())
308 }
309}
310
311#[derive(Clone, Debug)]
313#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
314pub struct ArtifactBuildFromArchive {
315 cell: Arc<ArtifactBuildFromArchiveCell>,
316
317 compile_info: CompileModuleInfo,
319}
320
321impl ArtifactBuildFromArchive {
322 #[allow(unused)]
323 pub(crate) fn try_new(
324 buffer: OwnedBuffer,
325 module_builder: impl FnOnce(
326 &OwnedBuffer,
327 ) -> Result<&ArchivedSerializableModule, DeserializeError>,
328 ) -> Result<Self, DeserializeError> {
329 let mut compile_info = MaybeUninit::uninit();
330
331 let cell = ArtifactBuildFromArchiveCell::try_new(buffer, |buffer| {
332 let module = module_builder(buffer)?;
333 compile_info = MaybeUninit::new(
334 rkyv::deserialize::<_, RkyvError>(&module.compile_info)
335 .map_err(|e| DeserializeError::CorruptedBinary(format!("{e:?}")))?,
336 );
337 ModuleFromArchive::from_serializable_module(module)
338 })?;
339
340 let compile_info = unsafe { compile_info.assume_init() };
342 Ok(Self {
343 cell: Arc::new(cell),
344 compile_info,
345 })
346 }
347
348 pub fn owned_buffer(&self) -> &OwnedBuffer {
350 self.cell.borrow_owner()
351 }
352
353 pub fn get_function_bodies_ref(&self) -> &ArchivedPrimaryMap<LocalFunctionIndex, FunctionBody> {
355 &self.cell.borrow_dependent().compilation.function_bodies
356 }
357
358 pub fn get_function_call_trampolines_ref(
360 &self,
361 ) -> &ArchivedPrimaryMap<SignatureIndex, FunctionBody> {
362 &self
363 .cell
364 .borrow_dependent()
365 .compilation
366 .function_call_trampolines
367 }
368
369 pub fn get_dynamic_function_trampolines_ref(
371 &self,
372 ) -> &ArchivedPrimaryMap<FunctionIndex, FunctionBody> {
373 &self
374 .cell
375 .borrow_dependent()
376 .compilation
377 .dynamic_function_trampolines
378 }
379
380 pub fn get_custom_sections_ref(&self) -> &ArchivedPrimaryMap<SectionIndex, CustomSection> {
382 &self.cell.borrow_dependent().compilation.custom_sections
383 }
384
385 pub fn get_function_relocations(
387 &self,
388 ) -> &ArchivedPrimaryMap<LocalFunctionIndex, Vec<Relocation>> {
389 &self
390 .cell
391 .borrow_dependent()
392 .compilation
393 .function_relocations
394 }
395
396 pub fn get_custom_section_relocations_ref(
398 &self,
399 ) -> &ArchivedPrimaryMap<SectionIndex, Vec<Relocation>> {
400 &self
401 .cell
402 .borrow_dependent()
403 .compilation
404 .custom_section_relocations
405 }
406
407 pub fn get_libcall_trampolines(&self) -> SectionIndex {
409 rkyv::deserialize::<_, RkyvError>(
410 &self.cell.borrow_dependent().compilation.libcall_trampolines,
411 )
412 .unwrap()
413 }
414
415 pub fn get_libcall_trampoline_len(&self) -> usize {
417 self.cell
418 .borrow_dependent()
419 .compilation
420 .libcall_trampoline_len
421 .to_native() as usize
422 }
423
424 pub fn get_unwind_info(&self) -> UnwindInfo {
426 rkyv::deserialize::<_, rkyv::rancor::Error>(
427 &self.cell.borrow_dependent().compilation.unwind_info,
428 )
429 .unwrap()
430 }
431
432 pub fn get_got_ref(&self) -> GOT {
434 rkyv::deserialize::<_, rkyv::rancor::Error>(&self.cell.borrow_dependent().compilation.got)
435 .unwrap()
436 }
437
438 pub fn get_frame_info_ref(
440 &self,
441 ) -> &ArchivedPrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
442 &self.cell.borrow_dependent().compilation.function_frame_info
443 }
444
445 pub fn deserialize_frame_info_ref(
447 &self,
448 ) -> Result<PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>, DeserializeError> {
449 rkyv::deserialize::<_, RkyvError>(
450 &self.cell.borrow_dependent().compilation.function_frame_info,
451 )
452 .map_err(|e| DeserializeError::CorruptedBinary(format!("{e:?}")))
453 }
454}
455
456impl<'a> ArtifactCreate<'a> for ArtifactBuildFromArchive {
457 type OwnedDataInitializer = &'a ArchivedOwnedDataInitializer;
458 type OwnedDataInitializerIterator = core::slice::Iter<'a, ArchivedOwnedDataInitializer>;
459
460 fn create_module_info(&self) -> Arc<ModuleInfo> {
461 self.compile_info.module.clone()
462 }
463
464 fn set_module_info_name(&mut self, name: String) -> bool {
465 Arc::get_mut(&mut self.compile_info.module).map_or(false, |module_info| {
466 module_info.name = Some(name.to_string());
467 true
468 })
469 }
470
471 fn module_info(&self) -> &ModuleInfo {
472 &self.compile_info.module
473 }
474
475 fn features(&self) -> &Features {
476 &self.compile_info.features
477 }
478
479 fn cpu_features(&self) -> EnumSet<CpuFeature> {
480 EnumSet::from_u64(self.cell.borrow_dependent().cpu_features)
481 }
482
483 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
484 self.cell.borrow_dependent().data_initializers.iter()
485 }
486
487 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
488 &self.compile_info.memory_styles
489 }
490
491 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
492 &self.compile_info.table_styles
493 }
494
495 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
496 let mut module: SerializableModule =
504 rkyv::deserialize::<_, RkyvError>(self.cell.borrow_dependent().original_module)
505 .map_err(|e| SerializeError::Generic(e.to_string()))?;
506 module.compile_info = self.compile_info.clone();
507 serialize_module(&module)
508 }
509}
510
511fn serialize_module(module: &SerializableModule) -> Result<Vec<u8>, SerializeError> {
512 let serialized_data = module.serialize()?;
513 assert!(std::mem::align_of::<SerializableModule>() <= MetadataHeader::ALIGN);
514
515 let mut metadata_binary = vec![];
516 metadata_binary.extend(ArtifactBuild::MAGIC_HEADER);
517 metadata_binary.extend(MetadataHeader::new(serialized_data.len()).into_bytes());
518 metadata_binary.extend(serialized_data);
519 Ok(metadata_binary)
520}