wasmer_compiler/artifact_builders/
artifact_builder.rs1#[cfg(feature = "compiler")]
5use super::trampoline::{libcall_trampoline_len, make_libcall_trampolines};
6
7use crate::{
8 ArtifactCreate, Features,
9 serialize::{
10 ArchivedSerializableCompilation, ArchivedSerializableModule, MetadataHeader,
11 SerializableModule,
12 },
13 types::{
14 function::{CompiledFunctionFrameInfo, FunctionBody, GOT, UnwindInfo},
15 module::CompileModuleInfo,
16 relocation::Relocation,
17 section::{CustomSection, SectionIndex},
18 },
19};
20#[cfg(feature = "compiler")]
21use crate::{
22 EngineInner, ModuleEnvironment, ModuleMiddlewareChain, serialize::SerializableCompilation,
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 CompilationProgressCallback, DeserializeError,
35 entity::{ArchivedPrimaryMap, PrimaryMap},
36 target::CpuFeature,
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 progress_callback: Option<&CompilationProgressCallback>,
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 module.hash = Some(ModuleHash::new(data));
82 let compile_info = CompileModuleInfo {
83 module: Arc::new(module),
84 features,
85 memory_styles,
86 table_styles,
87 };
88
89 let compilation = compiler.compile_module(
91 target,
92 &compile_info,
93 translation.module_translation_state.as_ref().unwrap(),
97 translation.function_body_inputs,
98 progress_callback,
99 )?;
100
101 let data_initializers = translation
102 .data_initializers
103 .iter()
104 .map(OwnedDataInitializer::new)
105 .collect::<Vec<_>>()
106 .into_boxed_slice();
107
108 let mut function_frame_info = PrimaryMap::with_capacity(compilation.functions.len());
110 let mut function_bodies = PrimaryMap::with_capacity(compilation.functions.len());
111 let mut function_relocations = PrimaryMap::with_capacity(compilation.functions.len());
112 for (_, func) in compilation.functions.into_iter() {
113 function_bodies.push(func.body);
114 function_relocations.push(func.relocations);
115 function_frame_info.push(func.frame_info);
116 }
117 let mut custom_sections = compilation.custom_sections.clone();
118 let mut custom_section_relocations = compilation
119 .custom_sections
120 .iter()
121 .map(|(_, section)| section.relocations.clone())
122 .collect::<PrimaryMap<SectionIndex, _>>();
123 let libcall_trampolines_section = make_libcall_trampolines(target);
124 custom_section_relocations.push(libcall_trampolines_section.relocations.clone());
125 let libcall_trampolines = custom_sections.push(libcall_trampolines_section);
126 let libcall_trampoline_len = libcall_trampoline_len(target) as u32;
127 let cpu_features = compiler.get_cpu_features_used(target.cpu_features());
128
129 let serializable_compilation = SerializableCompilation {
130 function_bodies,
131 function_relocations,
132 function_frame_info,
133 function_call_trampolines: compilation.function_call_trampolines,
134 dynamic_function_trampolines: compilation.dynamic_function_trampolines,
135 custom_sections,
136 custom_section_relocations,
137 unwind_info: compilation.unwind_info,
138 libcall_trampolines,
139 libcall_trampoline_len,
140 got: compilation.got,
141 };
142 let serializable = SerializableModule {
143 compilation: serializable_compilation,
144 compile_info,
145 data_initializers,
146 cpu_features: cpu_features.as_u64(),
147 };
148 Ok(Self { serializable })
149 }
150
151 pub fn from_serializable(serializable: SerializableModule) -> Self {
153 Self { serializable }
154 }
155
156 pub fn get_function_bodies_ref(&self) -> &PrimaryMap<LocalFunctionIndex, FunctionBody> {
158 &self.serializable.compilation.function_bodies
159 }
160
161 pub fn get_function_call_trampolines_ref(&self) -> &PrimaryMap<SignatureIndex, FunctionBody> {
163 &self.serializable.compilation.function_call_trampolines
164 }
165
166 pub fn get_dynamic_function_trampolines_ref(&self) -> &PrimaryMap<FunctionIndex, FunctionBody> {
168 &self.serializable.compilation.dynamic_function_trampolines
169 }
170
171 pub fn get_custom_sections_ref(&self) -> &PrimaryMap<SectionIndex, CustomSection> {
173 &self.serializable.compilation.custom_sections
174 }
175
176 pub fn get_function_relocations(&self) -> &PrimaryMap<LocalFunctionIndex, Vec<Relocation>> {
178 &self.serializable.compilation.function_relocations
179 }
180
181 pub fn get_custom_section_relocations_ref(&self) -> &PrimaryMap<SectionIndex, Vec<Relocation>> {
183 &self.serializable.compilation.custom_section_relocations
184 }
185
186 pub fn get_libcall_trampolines(&self) -> SectionIndex {
188 self.serializable.compilation.libcall_trampolines
189 }
190
191 pub fn get_libcall_trampoline_len(&self) -> usize {
193 self.serializable.compilation.libcall_trampoline_len as usize
194 }
195
196 pub fn get_unwind_info(&self) -> &UnwindInfo {
198 &self.serializable.compilation.unwind_info
199 }
200
201 pub fn get_got_ref(&self) -> &GOT {
203 &self.serializable.compilation.got
204 }
205
206 pub fn get_frame_info_ref(&self) -> &PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
208 &self.serializable.compilation.function_frame_info
209 }
210}
211
212impl<'a> ArtifactCreate<'a> for ArtifactBuild {
213 type OwnedDataInitializer = &'a OwnedDataInitializer;
214 type OwnedDataInitializerIterator = core::slice::Iter<'a, OwnedDataInitializer>;
215
216 fn create_module_info(&self) -> Arc<ModuleInfo> {
217 self.serializable.compile_info.module.clone()
218 }
219
220 fn set_module_info_name(&mut self, name: String) -> bool {
221 Arc::get_mut(&mut self.serializable.compile_info.module).is_some_and(|module_info| {
222 module_info.name = Some(name.to_string());
223 true
224 })
225 }
226
227 fn module_info(&self) -> &ModuleInfo {
228 &self.serializable.compile_info.module
229 }
230
231 fn features(&self) -> &Features {
232 &self.serializable.compile_info.features
233 }
234
235 fn cpu_features(&self) -> EnumSet<CpuFeature> {
236 EnumSet::from_u64(self.serializable.cpu_features)
237 }
238
239 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
240 self.serializable.data_initializers.iter()
241 }
242
243 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
244 &self.serializable.compile_info.memory_styles
245 }
246
247 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
248 &self.serializable.compile_info.table_styles
249 }
250
251 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
252 serialize_module(&self.serializable)
253 }
254}
255
256#[derive(Debug)]
259pub struct ModuleFromArchive<'a> {
260 pub compilation: &'a ArchivedSerializableCompilation,
262 pub data_initializers: &'a rkyv::Archived<Box<[OwnedDataInitializer]>>,
264 pub cpu_features: u64,
266
267 original_module: &'a ArchivedSerializableModule,
269}
270
271impl<'a> ModuleFromArchive<'a> {
272 pub fn from_serializable_module(
274 module: &'a ArchivedSerializableModule,
275 ) -> Result<Self, DeserializeError> {
276 Ok(Self {
277 compilation: &module.compilation,
278 data_initializers: &module.data_initializers,
279 cpu_features: module.cpu_features.to_native(),
280 original_module: module,
281 })
282 }
283}
284
285self_cell!(
286 struct ArtifactBuildFromArchiveCell {
287 owner: OwnedBuffer,
288
289 #[covariant]
290 dependent: ModuleFromArchive,
291 }
292
293 impl {Debug}
294);
295
296#[cfg(feature = "artifact-size")]
297impl loupe::MemoryUsage for ArtifactBuildFromArchiveCell {
298 fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
299 std::mem::size_of_val(self.borrow_owner()) + std::mem::size_of_val(self.borrow_dependent())
300 }
301}
302
303#[derive(Clone, Debug)]
305#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
306pub struct ArtifactBuildFromArchive {
307 cell: Arc<ArtifactBuildFromArchiveCell>,
308
309 compile_info: CompileModuleInfo,
311}
312
313impl ArtifactBuildFromArchive {
314 #[allow(unused)]
315 pub(crate) fn try_new(
316 buffer: OwnedBuffer,
317 module_builder: impl FnOnce(
318 &OwnedBuffer,
319 ) -> Result<&ArchivedSerializableModule, DeserializeError>,
320 ) -> Result<Self, DeserializeError> {
321 let mut compile_info = MaybeUninit::uninit();
322
323 let cell = ArtifactBuildFromArchiveCell::try_new(buffer, |buffer| {
324 let module = module_builder(buffer)?;
325 compile_info = MaybeUninit::new(
326 rkyv::deserialize::<_, RkyvError>(&module.compile_info)
327 .map_err(|e| DeserializeError::CorruptedBinary(format!("{e:?}")))?,
328 );
329 ModuleFromArchive::from_serializable_module(module)
330 })?;
331
332 let compile_info = unsafe { compile_info.assume_init() };
334 Ok(Self {
335 cell: Arc::new(cell),
336 compile_info,
337 })
338 }
339
340 pub fn owned_buffer(&self) -> &OwnedBuffer {
342 self.cell.borrow_owner()
343 }
344
345 pub fn get_function_bodies_ref(&self) -> &ArchivedPrimaryMap<LocalFunctionIndex, FunctionBody> {
347 &self.cell.borrow_dependent().compilation.function_bodies
348 }
349
350 pub fn get_function_call_trampolines_ref(
352 &self,
353 ) -> &ArchivedPrimaryMap<SignatureIndex, FunctionBody> {
354 &self
355 .cell
356 .borrow_dependent()
357 .compilation
358 .function_call_trampolines
359 }
360
361 pub fn get_dynamic_function_trampolines_ref(
363 &self,
364 ) -> &ArchivedPrimaryMap<FunctionIndex, FunctionBody> {
365 &self
366 .cell
367 .borrow_dependent()
368 .compilation
369 .dynamic_function_trampolines
370 }
371
372 pub fn get_custom_sections_ref(&self) -> &ArchivedPrimaryMap<SectionIndex, CustomSection> {
374 &self.cell.borrow_dependent().compilation.custom_sections
375 }
376
377 pub fn get_function_relocations(
379 &self,
380 ) -> &ArchivedPrimaryMap<LocalFunctionIndex, Vec<Relocation>> {
381 &self
382 .cell
383 .borrow_dependent()
384 .compilation
385 .function_relocations
386 }
387
388 pub fn get_custom_section_relocations_ref(
390 &self,
391 ) -> &ArchivedPrimaryMap<SectionIndex, Vec<Relocation>> {
392 &self
393 .cell
394 .borrow_dependent()
395 .compilation
396 .custom_section_relocations
397 }
398
399 pub fn get_libcall_trampolines(&self) -> SectionIndex {
401 rkyv::deserialize::<_, RkyvError>(
402 &self.cell.borrow_dependent().compilation.libcall_trampolines,
403 )
404 .unwrap()
405 }
406
407 pub fn get_libcall_trampoline_len(&self) -> usize {
409 self.cell
410 .borrow_dependent()
411 .compilation
412 .libcall_trampoline_len
413 .to_native() as usize
414 }
415
416 pub fn get_unwind_info(&self) -> UnwindInfo {
418 rkyv::deserialize::<_, rkyv::rancor::Error>(
419 &self.cell.borrow_dependent().compilation.unwind_info,
420 )
421 .unwrap()
422 }
423
424 pub fn get_got_ref(&self) -> GOT {
426 rkyv::deserialize::<_, rkyv::rancor::Error>(&self.cell.borrow_dependent().compilation.got)
427 .unwrap()
428 }
429
430 pub fn get_frame_info_ref(
432 &self,
433 ) -> &ArchivedPrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
434 &self.cell.borrow_dependent().compilation.function_frame_info
435 }
436
437 pub fn deserialize_frame_info_ref(
439 &self,
440 ) -> Result<PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo>, DeserializeError> {
441 rkyv::deserialize::<_, RkyvError>(
442 &self.cell.borrow_dependent().compilation.function_frame_info,
443 )
444 .map_err(|e| DeserializeError::CorruptedBinary(format!("{e:?}")))
445 }
446}
447
448impl<'a> ArtifactCreate<'a> for ArtifactBuildFromArchive {
449 type OwnedDataInitializer = &'a ArchivedOwnedDataInitializer;
450 type OwnedDataInitializerIterator = core::slice::Iter<'a, ArchivedOwnedDataInitializer>;
451
452 fn create_module_info(&self) -> Arc<ModuleInfo> {
453 self.compile_info.module.clone()
454 }
455
456 fn set_module_info_name(&mut self, name: String) -> bool {
457 Arc::get_mut(&mut self.compile_info.module).is_some_and(|module_info| {
458 module_info.name = Some(name.to_string());
459 true
460 })
461 }
462
463 fn module_info(&self) -> &ModuleInfo {
464 &self.compile_info.module
465 }
466
467 fn features(&self) -> &Features {
468 &self.compile_info.features
469 }
470
471 fn cpu_features(&self) -> EnumSet<CpuFeature> {
472 EnumSet::from_u64(self.cell.borrow_dependent().cpu_features)
473 }
474
475 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
476 self.cell.borrow_dependent().data_initializers.iter()
477 }
478
479 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
480 &self.compile_info.memory_styles
481 }
482
483 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
484 &self.compile_info.table_styles
485 }
486
487 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
488 let mut module: SerializableModule =
496 rkyv::deserialize::<_, RkyvError>(self.cell.borrow_dependent().original_module)
497 .map_err(|e| SerializeError::Generic(e.to_string()))?;
498 module.compile_info = self.compile_info.clone();
499 serialize_module(&module)
500 }
501}
502
503fn serialize_module(module: &SerializableModule) -> Result<Vec<u8>, SerializeError> {
504 let serialized_data = module.serialize()?;
505 assert!(std::mem::align_of::<SerializableModule>() <= MetadataHeader::ALIGN);
506
507 let mut metadata_binary = vec![];
508 metadata_binary.extend(ArtifactBuild::MAGIC_HEADER);
509 metadata_binary.extend(MetadataHeader::new(serialized_data.len()).into_bytes());
510 metadata_binary.extend(serialized_data);
511 Ok(metadata_binary)
512}