1use crate::engine::link::link_module;
5use crate::lib::std::vec::IntoIter;
6use crate::ArtifactBuild;
7use crate::ArtifactBuildFromArchive;
8use crate::ArtifactCreate;
9use crate::Features;
10use crate::FrameInfosVariant;
11use crate::ModuleEnvironment;
12use crate::{
13 register_frame_info, resolve_imports, FunctionExtent, GlobalFrameInfoRegistration,
14 InstantiationError, Tunables,
15};
16#[cfg(feature = "static-artifact-create")]
17use crate::{Compiler, FunctionBodyData, ModuleTranslationState};
18use crate::{Engine, EngineInner};
19use enumset::EnumSet;
20use shared_buffer::OwnedBuffer;
21#[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))]
22use std::mem;
23use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
24use std::sync::Arc;
25#[cfg(feature = "static-artifact-create")]
26use wasmer_object::{emit_compilation, emit_data, get_object_for_target, Object};
27#[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))]
28use wasmer_types::compilation::symbols::ModuleMetadata;
29use wasmer_types::entity::{BoxedSlice, PrimaryMap};
30use wasmer_types::ArchivedDataInitializerLocation;
31use wasmer_types::ArchivedOwnedDataInitializer;
32#[cfg(feature = "static-artifact-create")]
33use wasmer_types::CompileModuleInfo;
34use wasmer_types::DataInitializerLike;
35use wasmer_types::DataInitializerLocation;
36use wasmer_types::DataInitializerLocationLike;
37use wasmer_types::MetadataHeader;
38use wasmer_types::{
39 CompileError, CpuFeature, DataInitializer, DeserializeError, FunctionIndex, HashAlgorithm,
40 LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, SignatureIndex, TableIndex,
41 Target,
42};
43use wasmer_types::{SerializableModule, SerializeError};
44use wasmer_vm::{FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex, VMTrampoline};
45use wasmer_vm::{InstanceAllocator, StoreObjects, TrapHandlerFn, VMConfig, VMExtern, VMInstance};
46
47#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
48pub struct AllocatedArtifact {
49 frame_info_registered: bool,
54 frame_info_registration: Option<GlobalFrameInfoRegistration>,
58 finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
59
60 #[cfg_attr(feature = "artifact-size", loupe(skip))]
61 finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,
62 finished_dynamic_function_trampolines: BoxedSlice<FunctionIndex, FunctionBodyPtr>,
63 signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
64 finished_function_lengths: BoxedSlice<LocalFunctionIndex, usize>,
65}
66
67#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
68#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
69#[repr(transparent)]
70pub struct ArtifactId {
72 id: usize,
73}
74
75impl ArtifactId {
76 pub fn id(&self) -> String {
78 format!("{}", &self.id)
79 }
80}
81
82impl Clone for ArtifactId {
83 fn clone(&self) -> Self {
84 Self::default()
85 }
86}
87
88impl Default for ArtifactId {
89 fn default() -> Self {
90 static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
91 Self {
92 id: NEXT_ID.fetch_add(1, SeqCst),
93 }
94 }
95}
96
97#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
99pub struct Artifact {
100 id: ArtifactId,
101 artifact: ArtifactBuildVariant,
102 allocated: Option<AllocatedArtifact>,
105}
106
107#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
111pub enum ArtifactBuildVariant {
112 Plain(ArtifactBuild),
113 Archived(ArtifactBuildFromArchive),
114}
115
116impl Artifact {
117 #[cfg(feature = "compiler")]
119 pub fn new(
120 engine: &Engine,
121 data: &[u8],
122 tunables: &dyn Tunables,
123 hash_algorithm: Option<HashAlgorithm>,
124 ) -> Result<Self, CompileError> {
125 let mut inner_engine = engine.inner_mut();
126 let environ = ModuleEnvironment::new();
127 let translation = environ.translate(data).map_err(CompileError::Wasm)?;
128 let module = translation.module;
129 let memory_styles: PrimaryMap<MemoryIndex, MemoryStyle> = module
130 .memories
131 .values()
132 .map(|memory_type| tunables.memory_style(memory_type))
133 .collect();
134 let table_styles: PrimaryMap<TableIndex, TableStyle> = module
135 .tables
136 .values()
137 .map(|table_type| tunables.table_style(table_type))
138 .collect();
139
140 let artifact = ArtifactBuild::new(
141 &mut inner_engine,
142 data,
143 engine.target(),
144 memory_styles,
145 table_styles,
146 hash_algorithm,
147 )?;
148
149 Self::from_parts(
150 &mut inner_engine,
151 ArtifactBuildVariant::Plain(artifact),
152 engine.target(),
153 )
154 .map_err(|e| match e {
155 DeserializeError::Compiler(c) => c,
156
157 _ => unreachable!(),
166 })
167 }
168
169 pub fn allocated(&self) -> bool {
173 self.allocated.is_some()
174 }
175
176 pub fn id(&self) -> &ArtifactId {
182 &self.id
183 }
184
185 #[cfg(not(feature = "compiler"))]
187 pub fn new(_engine: &Engine, _data: &[u8]) -> Result<Self, CompileError> {
188 Err(CompileError::Codegen(
189 "Compilation is not enabled in the engine".to_string(),
190 ))
191 }
192
193 pub unsafe fn deserialize(
202 engine: &Engine,
203 bytes: OwnedBuffer,
204 ) -> Result<Self, DeserializeError> {
205 if !ArtifactBuild::is_deserializable(bytes.as_ref()) {
206 let static_artifact = Self::deserialize_object(engine, bytes);
207 match static_artifact {
208 Ok(v) => {
209 return Ok(v);
210 }
211 Err(_) => {
212 return Err(DeserializeError::Incompatible(
213 "The provided bytes are not wasmer-universal".to_string(),
214 ));
215 }
216 }
217 }
218
219 let artifact = ArtifactBuildFromArchive::try_new(bytes, |bytes| {
220 let bytes =
221 Self::get_byte_slice(bytes, ArtifactBuild::MAGIC_HEADER.len(), bytes.len())?;
222
223 let metadata_len = MetadataHeader::parse(bytes)?;
224 let metadata_slice = Self::get_byte_slice(bytes, MetadataHeader::LEN, bytes.len())?;
225 let metadata_slice = Self::get_byte_slice(metadata_slice, 0, metadata_len)?;
226
227 SerializableModule::archive_from_slice_checked(metadata_slice)
228 })?;
229
230 let mut inner_engine = engine.inner_mut();
231 Self::from_parts(
232 &mut inner_engine,
233 ArtifactBuildVariant::Archived(artifact),
234 engine.target(),
235 )
236 }
237
238 pub unsafe fn deserialize_unchecked(
247 engine: &Engine,
248 bytes: OwnedBuffer,
249 ) -> Result<Self, DeserializeError> {
250 if !ArtifactBuild::is_deserializable(bytes.as_ref()) {
251 let static_artifact = Self::deserialize_object(engine, bytes);
252 match static_artifact {
253 Ok(v) => {
254 return Ok(v);
255 }
256 Err(_) => {
257 return Err(DeserializeError::Incompatible(
258 "The provided bytes are not wasmer-universal".to_string(),
259 ));
260 }
261 }
262 }
263
264 let artifact = ArtifactBuildFromArchive::try_new(bytes, |bytes| {
265 let bytes =
266 Self::get_byte_slice(bytes, ArtifactBuild::MAGIC_HEADER.len(), bytes.len())?;
267
268 let metadata_len = MetadataHeader::parse(bytes)?;
269 let metadata_slice = Self::get_byte_slice(bytes, MetadataHeader::LEN, bytes.len())?;
270 let metadata_slice = Self::get_byte_slice(metadata_slice, 0, metadata_len)?;
271
272 SerializableModule::archive_from_slice(metadata_slice)
273 })?;
274
275 let mut inner_engine = engine.inner_mut();
276 Self::from_parts(
277 &mut inner_engine,
278 ArtifactBuildVariant::Archived(artifact),
279 engine.target(),
280 )
281 }
282
283 pub fn from_parts(
285 engine_inner: &mut EngineInner,
286 artifact: ArtifactBuildVariant,
287 target: &Target,
288 ) -> Result<Self, DeserializeError> {
289 if !target.is_native() {
290 return Ok(Self {
291 id: Default::default(),
292 artifact,
293 allocated: None,
294 });
295 } else {
296 let cpu_features = artifact.cpu_features();
298 if !target.cpu_features().is_superset(cpu_features) {
299 return Err(DeserializeError::Incompatible(format!(
300 "Some CPU Features needed for the artifact are missing: {:?}",
301 cpu_features.difference(*target.cpu_features())
302 )));
303 }
304 }
305 let module_info = artifact.module_info();
306 let (
307 finished_functions,
308 finished_function_call_trampolines,
309 finished_dynamic_function_trampolines,
310 custom_sections,
311 ) = match &artifact {
312 ArtifactBuildVariant::Plain(p) => engine_inner.allocate(
313 module_info,
314 p.get_function_bodies_ref().values(),
315 p.get_function_call_trampolines_ref().values(),
316 p.get_dynamic_function_trampolines_ref().values(),
317 p.get_custom_sections_ref().values(),
318 )?,
319 ArtifactBuildVariant::Archived(a) => engine_inner.allocate(
320 module_info,
321 a.get_function_bodies_ref().values(),
322 a.get_function_call_trampolines_ref().values(),
323 a.get_dynamic_function_trampolines_ref().values(),
324 a.get_custom_sections_ref().values(),
325 )?,
326 };
327
328 match &artifact {
329 ArtifactBuildVariant::Plain(p) => link_module(
330 module_info,
331 &finished_functions,
332 p.get_function_relocations()
333 .iter()
334 .map(|(k, v)| (k, v.iter())),
335 &custom_sections,
336 p.get_custom_section_relocations_ref()
337 .iter()
338 .map(|(k, v)| (k, v.iter())),
339 p.get_libcall_trampolines(),
340 p.get_libcall_trampoline_len(),
341 ),
342 ArtifactBuildVariant::Archived(a) => link_module(
343 module_info,
344 &finished_functions,
345 a.get_function_relocations()
346 .iter()
347 .map(|(k, v)| (k, v.iter())),
348 &custom_sections,
349 a.get_custom_section_relocations_ref()
350 .iter()
351 .map(|(k, v)| (k, v.iter())),
352 a.get_libcall_trampolines(),
353 a.get_libcall_trampoline_len(),
354 ),
355 };
356
357 let signatures = {
359 let signature_registry = engine_inner.signatures();
360 module_info
361 .signatures
362 .values()
363 .map(|sig| signature_registry.register(sig))
364 .collect::<PrimaryMap<_, _>>()
365 };
366
367 let debug_ref = match &artifact {
368 ArtifactBuildVariant::Plain(p) => p.get_debug_ref(),
369 ArtifactBuildVariant::Archived(a) => a.get_debug_ref(),
370 };
371 let eh_frame = match debug_ref {
372 Some(debug) => {
373 let eh_frame_section_size = match &artifact {
374 ArtifactBuildVariant::Plain(p) => {
375 p.get_custom_sections_ref()[debug.eh_frame].bytes.len()
376 }
377 ArtifactBuildVariant::Archived(a) => {
378 a.get_custom_sections_ref()[debug.eh_frame].bytes.len()
379 }
380 };
381 let eh_frame_section_pointer = custom_sections[debug.eh_frame];
382 Some(unsafe {
383 std::slice::from_raw_parts(*eh_frame_section_pointer, eh_frame_section_size)
384 })
385 }
386 None => None,
387 };
388
389 engine_inner.publish_compiled_code();
391
392 engine_inner.publish_eh_frame(eh_frame)?;
393
394 let finished_function_lengths = finished_functions
395 .values()
396 .map(|extent| extent.length)
397 .collect::<PrimaryMap<LocalFunctionIndex, usize>>()
398 .into_boxed_slice();
399 let finished_functions = finished_functions
400 .values()
401 .map(|extent| extent.ptr)
402 .collect::<PrimaryMap<LocalFunctionIndex, FunctionBodyPtr>>()
403 .into_boxed_slice();
404 let finished_function_call_trampolines =
405 finished_function_call_trampolines.into_boxed_slice();
406 let finished_dynamic_function_trampolines =
407 finished_dynamic_function_trampolines.into_boxed_slice();
408 let signatures = signatures.into_boxed_slice();
409
410 let mut artifact = Self {
411 id: Default::default(),
412 artifact,
413 allocated: Some(AllocatedArtifact {
414 frame_info_registered: false,
415 frame_info_registration: None,
416 finished_functions,
417 finished_function_call_trampolines,
418 finished_dynamic_function_trampolines,
419 signatures,
420 finished_function_lengths,
421 }),
422 };
423
424 artifact
425 .internal_register_frame_info()
426 .map_err(|e| DeserializeError::CorruptedBinary(format!("{:?}", e)))?;
427 if let Some(frame_info) = artifact.internal_take_frame_info_registration() {
428 engine_inner.register_frame_info(frame_info);
429 }
430
431 Ok(artifact)
432 }
433
434 pub fn is_deserializable(bytes: &[u8]) -> bool {
436 ArtifactBuild::is_deserializable(bytes)
437 }
438}
439
440impl PartialEq for Artifact {
441 fn eq(&self, other: &Self) -> bool {
442 self.id == other.id
443 }
444}
445impl Eq for Artifact {}
446
447impl std::fmt::Debug for Artifact {
448 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
449 f.debug_struct("Artifact")
450 .field("artifact_id", &self.id)
451 .field("module_info", &self.module_info())
452 .finish()
453 }
454}
455
456impl<'a> ArtifactCreate<'a> for Artifact {
457 type OwnedDataInitializer = <ArtifactBuildVariant as ArtifactCreate<'a>>::OwnedDataInitializer;
458 type OwnedDataInitializerIterator =
459 <ArtifactBuildVariant as ArtifactCreate<'a>>::OwnedDataInitializerIterator;
460
461 fn set_module_info_name(&mut self, name: String) -> bool {
462 self.artifact.set_module_info_name(name)
463 }
464
465 fn create_module_info(&self) -> Arc<ModuleInfo> {
466 self.artifact.create_module_info()
467 }
468
469 fn module_info(&self) -> &ModuleInfo {
470 self.artifact.module_info()
471 }
472
473 fn features(&self) -> &Features {
474 self.artifact.features()
475 }
476
477 fn cpu_features(&self) -> EnumSet<CpuFeature> {
478 self.artifact.cpu_features()
479 }
480
481 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
482 self.artifact.data_initializers()
483 }
484
485 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
486 self.artifact.memory_styles()
487 }
488
489 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
490 self.artifact.table_styles()
491 }
492
493 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
494 self.artifact.serialize()
495 }
496}
497
498impl<'a> ArtifactCreate<'a> for ArtifactBuildVariant {
499 type OwnedDataInitializer = OwnedDataInitializerVariant<'a>;
500 type OwnedDataInitializerIterator = IntoIter<Self::OwnedDataInitializer>;
501
502 fn create_module_info(&self) -> Arc<ModuleInfo> {
503 match self {
504 Self::Plain(artifact) => artifact.create_module_info(),
505 Self::Archived(artifact) => artifact.create_module_info(),
506 }
507 }
508
509 fn set_module_info_name(&mut self, name: String) -> bool {
510 match self {
511 Self::Plain(artifact) => artifact.set_module_info_name(name),
512 Self::Archived(artifact) => artifact.set_module_info_name(name),
513 }
514 }
515
516 fn module_info(&self) -> &ModuleInfo {
517 match self {
518 Self::Plain(artifact) => artifact.module_info(),
519 Self::Archived(artifact) => artifact.module_info(),
520 }
521 }
522
523 fn features(&self) -> &Features {
524 match self {
525 Self::Plain(artifact) => artifact.features(),
526 Self::Archived(artifact) => artifact.features(),
527 }
528 }
529
530 fn cpu_features(&self) -> EnumSet<CpuFeature> {
531 match self {
532 Self::Plain(artifact) => artifact.cpu_features(),
533 Self::Archived(artifact) => artifact.cpu_features(),
534 }
535 }
536
537 fn memory_styles(&self) -> &PrimaryMap<MemoryIndex, MemoryStyle> {
538 match self {
539 Self::Plain(artifact) => artifact.memory_styles(),
540 Self::Archived(artifact) => artifact.memory_styles(),
541 }
542 }
543
544 fn table_styles(&self) -> &PrimaryMap<TableIndex, TableStyle> {
545 match self {
546 Self::Plain(artifact) => artifact.table_styles(),
547 Self::Archived(artifact) => artifact.table_styles(),
548 }
549 }
550
551 fn data_initializers(&'a self) -> Self::OwnedDataInitializerIterator {
552 match self {
553 Self::Plain(artifact) => artifact
554 .data_initializers()
555 .map(OwnedDataInitializerVariant::Plain)
556 .collect::<Vec<_>>()
557 .into_iter(),
558 Self::Archived(artifact) => artifact
559 .data_initializers()
560 .map(OwnedDataInitializerVariant::Archived)
561 .collect::<Vec<_>>()
562 .into_iter(),
563 }
564 }
565
566 fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
567 match self {
568 Self::Plain(artifact) => artifact.serialize(),
569 Self::Archived(artifact) => artifact.serialize(),
570 }
571 }
572}
573
574#[derive(Clone, Copy)]
575pub enum OwnedDataInitializerVariant<'a> {
576 Plain(&'a OwnedDataInitializer),
577 Archived(&'a ArchivedOwnedDataInitializer),
578}
579
580impl<'a> DataInitializerLike<'a> for OwnedDataInitializerVariant<'a> {
581 type Location = DataInitializerLocationVariant<'a>;
582
583 fn location(&self) -> Self::Location {
584 match self {
585 Self::Plain(plain) => DataInitializerLocationVariant::Plain(plain.location()),
586 Self::Archived(archived) => {
587 DataInitializerLocationVariant::Archived(archived.location())
588 }
589 }
590 }
591
592 fn data(&self) -> &'a [u8] {
593 match self {
594 Self::Plain(plain) => plain.data(),
595 Self::Archived(archived) => archived.data(),
596 }
597 }
598}
599
600#[derive(Clone, Copy)]
601pub enum DataInitializerLocationVariant<'a> {
602 Plain(&'a DataInitializerLocation),
603 Archived(&'a ArchivedDataInitializerLocation),
604}
605
606impl<'a> DataInitializerLocationVariant<'a> {
607 pub fn clone_to_plain(&self) -> DataInitializerLocation {
608 match self {
609 Self::Plain(p) => (*p).clone(),
610 Self::Archived(a) => DataInitializerLocation {
611 memory_index: a.memory_index(),
612 base: a.base(),
613 offset: a.offset(),
614 },
615 }
616 }
617}
618
619impl<'a> DataInitializerLocationLike for DataInitializerLocationVariant<'a> {
620 fn memory_index(&self) -> MemoryIndex {
621 match self {
622 Self::Plain(plain) => plain.memory_index(),
623 Self::Archived(archived) => archived.memory_index(),
624 }
625 }
626
627 fn base(&self) -> Option<wasmer_types::GlobalIndex> {
628 match self {
629 Self::Plain(plain) => plain.base(),
630 Self::Archived(archived) => archived.base(),
631 }
632 }
633
634 fn offset(&self) -> usize {
635 match self {
636 Self::Plain(plain) => plain.offset(),
637 Self::Archived(archived) => archived.offset(),
638 }
639 }
640}
641
642impl Artifact {
643 #[deprecated(
647 since = "4.0.0",
648 note = "done automaticaly by Artifact::from_parts, use 'take_frame_info_registration' if you use this method"
649 )]
650 pub fn register_frame_info(&mut self) -> Result<(), DeserializeError> {
651 self.internal_register_frame_info()
652 }
653
654 fn internal_register_frame_info(&mut self) -> Result<(), DeserializeError> {
655 if self
656 .allocated
657 .as_ref()
658 .expect("It must be allocated")
659 .frame_info_registered
660 {
661 return Ok(()); }
663
664 let finished_function_extents = self
665 .allocated
666 .as_ref()
667 .expect("It must be allocated")
668 .finished_functions
669 .values()
670 .copied()
671 .zip(
672 self.allocated
673 .as_ref()
674 .expect("It must be allocated")
675 .finished_function_lengths
676 .values()
677 .copied(),
678 )
679 .map(|(ptr, length)| FunctionExtent { ptr, length })
680 .collect::<PrimaryMap<LocalFunctionIndex, _>>()
681 .into_boxed_slice();
682
683 let frame_info_registration = &mut self
684 .allocated
685 .as_mut()
686 .expect("It must be allocated")
687 .frame_info_registration;
688
689 *frame_info_registration = register_frame_info(
690 self.artifact.create_module_info(),
691 &finished_function_extents,
692 match &self.artifact {
693 ArtifactBuildVariant::Plain(p) => {
694 FrameInfosVariant::Owned(p.get_frame_info_ref().clone())
695 }
696 ArtifactBuildVariant::Archived(a) => FrameInfosVariant::Archived(a.clone()),
697 },
698 );
699
700 self.allocated
701 .as_mut()
702 .expect("It must be allocated")
703 .frame_info_registered = true;
704
705 Ok(())
706 }
707
708 #[deprecated(since = "4.0.0", note = "done automaticaly by Artifact::from_parts.")]
711 pub fn take_frame_info_registration(&mut self) -> Option<GlobalFrameInfoRegistration> {
712 self.internal_take_frame_info_registration()
713 }
714
715 fn internal_take_frame_info_registration(&mut self) -> Option<GlobalFrameInfoRegistration> {
716 let frame_info_registration = &mut self
717 .allocated
718 .as_mut()
719 .expect("It must be allocated")
720 .frame_info_registration;
721
722 frame_info_registration.take()
723 }
724
725 pub fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr> {
728 &self
729 .allocated
730 .as_ref()
731 .expect("It must be allocated")
732 .finished_functions
733 }
734
735 pub fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline> {
738 &self
739 .allocated
740 .as_ref()
741 .expect("It must be allocated")
742 .finished_function_call_trampolines
743 }
744
745 pub fn finished_dynamic_function_trampolines(
748 &self,
749 ) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr> {
750 &self
751 .allocated
752 .as_ref()
753 .expect("It must be allocated")
754 .finished_dynamic_function_trampolines
755 }
756
757 pub fn signatures(&self) -> &BoxedSlice<SignatureIndex, VMSharedSignatureIndex> {
759 &self
760 .allocated
761 .as_ref()
762 .expect("It must be allocated")
763 .signatures
764 }
765
766 #[allow(clippy::result_large_err)]
768 pub fn preinstantiate(&self) -> Result<(), InstantiationError> {
769 Ok(())
770 }
771
772 #[allow(clippy::result_large_err)]
778 pub unsafe fn instantiate(
779 &self,
780 tunables: &dyn Tunables,
781 imports: &[VMExtern],
782 context: &mut StoreObjects,
783 ) -> Result<VMInstance, InstantiationError> {
784 let host_cpu_features = CpuFeature::for_host();
787 if !host_cpu_features.is_superset(self.cpu_features()) {
788 return Err(InstantiationError::CpuFeature(format!(
789 "{:?}",
790 self.cpu_features().difference(host_cpu_features)
791 )));
792 }
793
794 self.preinstantiate()?;
795
796 let module = self.create_module_info();
797 let imports = resolve_imports(
798 &module,
799 imports,
800 context,
801 self.finished_dynamic_function_trampolines(),
802 self.memory_styles(),
803 self.table_styles(),
804 )
805 .map_err(InstantiationError::Link)?;
806
807 let (allocator, memory_definition_locations, table_definition_locations) =
811 InstanceAllocator::new(&module);
812 let finished_memories = tunables
813 .create_memories(
814 context,
815 &module,
816 self.memory_styles(),
817 &memory_definition_locations,
818 )
819 .map_err(InstantiationError::Link)?
820 .into_boxed_slice();
821 let finished_tables = tunables
822 .create_tables(
823 context,
824 &module,
825 self.table_styles(),
826 &table_definition_locations,
827 )
828 .map_err(InstantiationError::Link)?
829 .into_boxed_slice();
830 let finished_globals = tunables
831 .create_globals(context, &module)
832 .map_err(InstantiationError::Link)?
833 .into_boxed_slice();
834
835 let handle = VMInstance::new(
836 allocator,
837 module,
838 context,
839 self.finished_functions().clone(),
840 self.finished_function_call_trampolines().clone(),
841 finished_memories,
842 finished_tables,
843 finished_globals,
844 imports,
845 self.signatures().clone(),
846 )
847 .map_err(InstantiationError::Start)?;
848 Ok(handle)
849 }
850
851 #[allow(clippy::result_large_err)]
857 pub unsafe fn finish_instantiation(
858 &self,
859 config: &VMConfig,
860 trap_handler: Option<*const TrapHandlerFn<'static>>,
861 handle: &mut VMInstance,
862 ) -> Result<(), InstantiationError> {
863 let data_initializers = self
864 .data_initializers()
865 .map(|init| DataInitializer {
866 location: init.location().clone_to_plain(),
867 data: init.data(),
868 })
869 .collect::<Vec<_>>();
870 handle
871 .finish_instantiation(config, trap_handler, &data_initializers)
872 .map_err(InstantiationError::Start)
873 }
874
875 #[allow(clippy::type_complexity)]
876 #[cfg(feature = "static-artifact-create")]
877 pub fn generate_metadata<'data>(
879 data: &'data [u8],
880 compiler: &dyn Compiler,
881 tunables: &dyn Tunables,
882 features: &Features,
883 ) -> Result<
884 (
885 CompileModuleInfo,
886 PrimaryMap<LocalFunctionIndex, FunctionBodyData<'data>>,
887 Vec<DataInitializer<'data>>,
888 Option<ModuleTranslationState>,
889 ),
890 CompileError,
891 > {
892 let environ = ModuleEnvironment::new();
893 let translation = environ.translate(data).map_err(CompileError::Wasm)?;
894
895 use crate::translator::ModuleMiddlewareChain;
897 let mut module = translation.module;
898 let middlewares = compiler.get_middlewares();
899 middlewares
900 .apply_on_module_info(&mut module)
901 .map_err(|e| CompileError::MiddlewareError(e.to_string()))?;
902
903 let memory_styles: PrimaryMap<MemoryIndex, MemoryStyle> = module
904 .memories
905 .values()
906 .map(|memory_type| tunables.memory_style(memory_type))
907 .collect();
908 let table_styles: PrimaryMap<TableIndex, TableStyle> = module
909 .tables
910 .values()
911 .map(|table_type| tunables.table_style(table_type))
912 .collect();
913
914 let compile_info = CompileModuleInfo {
915 module: Arc::new(module),
916 features: features.clone(),
917 memory_styles,
918 table_styles,
919 };
920 Ok((
921 compile_info,
922 translation.function_body_inputs,
923 translation.data_initializers,
924 translation.module_translation_state,
925 ))
926 }
927
928 #[cfg(feature = "static-artifact-create")]
930 #[allow(clippy::type_complexity)]
931 pub fn metadata<'a>(
932 compiler: &dyn Compiler,
933 data: &'a [u8],
934 metadata_prefix: Option<&str>,
935 target: &Target,
936 tunables: &dyn Tunables,
937 features: &Features,
938 ) -> Result<
939 (
940 ModuleMetadata,
941 Option<ModuleTranslationState>,
942 PrimaryMap<LocalFunctionIndex, FunctionBodyData<'a>>,
943 ),
944 CompileError,
945 > {
946 #[allow(dead_code)]
947 let (compile_info, function_body_inputs, data_initializers, module_translation) =
948 Self::generate_metadata(data, compiler, tunables, features)?;
949
950 let data_initializers = data_initializers
951 .iter()
952 .map(OwnedDataInitializer::new)
953 .collect::<Vec<_>>()
954 .into_boxed_slice();
955
956 let function_body_lengths = function_body_inputs
960 .keys()
961 .map(|_function_body| 0u64)
962 .collect::<PrimaryMap<LocalFunctionIndex, u64>>();
963
964 let metadata = ModuleMetadata {
965 compile_info,
966 prefix: metadata_prefix.map(|s| s.to_string()).unwrap_or_default(),
967 data_initializers,
968 function_body_lengths,
969 cpu_features: target.cpu_features().as_u64(),
970 };
971
972 Ok((metadata, module_translation, function_body_inputs))
973 }
974
975 #[cfg(feature = "static-artifact-create")]
983 pub fn generate_object<'data>(
984 compiler: &dyn Compiler,
985 data: &[u8],
986 metadata_prefix: Option<&str>,
987 target: &'data Target,
988 tunables: &dyn Tunables,
989 features: &Features,
990 ) -> Result<
991 (
992 ModuleInfo,
993 Object<'data>,
994 usize,
995 Box<dyn wasmer_types::SymbolRegistry>,
996 ),
997 CompileError,
998 > {
999 use wasmer_types::{compilation::symbols::ModuleMetadataSymbolRegistry, SymbolRegistry};
1000
1001 fn to_compile_error(err: impl std::error::Error) -> CompileError {
1002 CompileError::Codegen(format!("{}", err))
1003 }
1004
1005 let target_triple = target.triple();
1006 let (mut metadata, module_translation, function_body_inputs) =
1007 Self::metadata(compiler, data, metadata_prefix, target, tunables, features)
1008 .map_err(to_compile_error)?;
1009
1010 let serialized_data = metadata.serialize().map_err(to_compile_error)?;
1028 let mut metadata_binary = vec![];
1029 metadata_binary.extend(MetadataHeader::new(serialized_data.len()).into_bytes());
1030 metadata_binary.extend(serialized_data);
1031
1032 let (_compile_info, symbol_registry) = metadata.split();
1033
1034 let compilation: wasmer_types::compilation::function::Compilation = compiler
1035 .compile_module(
1036 target,
1037 &metadata.compile_info,
1038 module_translation.as_ref().unwrap(),
1039 function_body_inputs,
1040 )?;
1041 let mut obj = get_object_for_target(target_triple).map_err(to_compile_error)?;
1042
1043 let object_name = ModuleMetadataSymbolRegistry {
1044 prefix: metadata_prefix.unwrap_or_default().to_string(),
1045 }
1046 .symbol_to_name(wasmer_types::Symbol::Metadata);
1047
1048 emit_data(&mut obj, object_name.as_bytes(), &metadata_binary, 1)
1049 .map_err(to_compile_error)?;
1050
1051 emit_compilation(&mut obj, compilation, &symbol_registry, target_triple)
1052 .map_err(to_compile_error)?;
1053 Ok((
1054 Arc::try_unwrap(metadata.compile_info.module).unwrap(),
1055 obj,
1056 metadata_binary.len(),
1057 Box::new(symbol_registry),
1058 ))
1059 }
1060
1061 #[cfg(not(feature = "static-artifact-load"))]
1066 pub unsafe fn deserialize_object(
1067 _engine: &Engine,
1068 _bytes: OwnedBuffer,
1069 ) -> Result<Self, DeserializeError> {
1070 Err(DeserializeError::Compiler(
1071 CompileError::UnsupportedFeature("static load is not compiled in".to_string()),
1072 ))
1073 }
1074
1075 fn get_byte_slice(input: &[u8], start: usize, end: usize) -> Result<&[u8], DeserializeError> {
1076 if (start == end && input.len() > start)
1077 || (start < end && input.len() > start && input.len() >= end)
1078 {
1079 Ok(&input[start..end])
1080 } else {
1081 Err(DeserializeError::InvalidByteLength {
1082 expected: end - start,
1083 got: input.len(),
1084 })
1085 }
1086 }
1087
1088 #[cfg(feature = "static-artifact-load")]
1093 pub unsafe fn deserialize_object(
1094 engine: &Engine,
1095 bytes: OwnedBuffer,
1096 ) -> Result<Self, DeserializeError> {
1097 use wasmer_types::SerializableCompilation;
1098
1099 let bytes = bytes.as_slice();
1100 let metadata_len = MetadataHeader::parse(bytes)?;
1101 let metadata_slice = Self::get_byte_slice(bytes, MetadataHeader::LEN, bytes.len())?;
1102 let metadata_slice = Self::get_byte_slice(metadata_slice, 0, metadata_len)?;
1103 let metadata: ModuleMetadata = ModuleMetadata::deserialize(metadata_slice)?;
1104
1105 const WORD_SIZE: usize = mem::size_of::<usize>();
1106 let mut byte_buffer = [0u8; WORD_SIZE];
1107
1108 let mut cur_offset = MetadataHeader::LEN + metadata_len;
1109
1110 let byte_buffer_slice = Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1111 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1112 cur_offset += WORD_SIZE;
1113
1114 let num_finished_functions = usize::from_ne_bytes(byte_buffer);
1115 let mut finished_functions: PrimaryMap<LocalFunctionIndex, FunctionBodyPtr> =
1116 PrimaryMap::new();
1117
1118 let engine_inner = engine.inner();
1119 let signature_registry = engine_inner.signatures();
1120
1121 for _i in 0..num_finished_functions {
1123 let byte_buffer_slice =
1124 Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1125 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1126 let fp = FunctionBodyPtr(usize::from_ne_bytes(byte_buffer) as _);
1127 cur_offset += WORD_SIZE;
1128
1129 finished_functions.push(fp);
1131 }
1132
1133 let signatures = {
1135 metadata
1136 .compile_info
1137 .module
1138 .signatures
1139 .values()
1140 .map(|sig| signature_registry.register(sig))
1141 .collect::<PrimaryMap<_, _>>()
1142 };
1143
1144 let mut finished_function_call_trampolines = PrimaryMap::new();
1146
1147 let byte_buffer_slice = Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1148 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1149 cur_offset += WORD_SIZE;
1150 let num_function_trampolines = usize::from_ne_bytes(byte_buffer);
1151 for _ in 0..num_function_trampolines {
1152 let byte_buffer_slice =
1153 Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1154 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1155 cur_offset += WORD_SIZE;
1156 let trampoline_ptr_bytes = usize::from_ne_bytes(byte_buffer);
1157 let trampoline = mem::transmute::<usize, VMTrampoline>(trampoline_ptr_bytes);
1158 finished_function_call_trampolines.push(trampoline);
1159 }
1161
1162 let mut finished_dynamic_function_trampolines = PrimaryMap::new();
1164 let byte_buffer_slice = Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1165 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1166 cur_offset += WORD_SIZE;
1167 let num_dynamic_trampoline_functions = usize::from_ne_bytes(byte_buffer);
1168 for _i in 0..num_dynamic_trampoline_functions {
1169 let byte_buffer_slice =
1170 Self::get_byte_slice(bytes, cur_offset, cur_offset + WORD_SIZE)?;
1171 byte_buffer[0..WORD_SIZE].clone_from_slice(byte_buffer_slice);
1172 let fp = FunctionBodyPtr(usize::from_ne_bytes(byte_buffer) as _);
1173 cur_offset += WORD_SIZE;
1174
1175 finished_dynamic_function_trampolines.push(fp);
1178 }
1179
1180 let artifact = ArtifactBuild::from_serializable(SerializableModule {
1181 compilation: SerializableCompilation::default(),
1182 compile_info: metadata.compile_info,
1183 data_initializers: metadata.data_initializers,
1184 cpu_features: metadata.cpu_features,
1185 });
1186
1187 let finished_function_lengths = finished_functions
1188 .values()
1189 .map(|_| 0)
1190 .collect::<PrimaryMap<LocalFunctionIndex, usize>>()
1191 .into_boxed_slice();
1192
1193 Ok(Self {
1194 id: Default::default(),
1195 artifact: ArtifactBuildVariant::Plain(artifact),
1196 allocated: Some(AllocatedArtifact {
1197 frame_info_registered: false,
1198 frame_info_registration: None,
1199 finished_functions: finished_functions.into_boxed_slice(),
1200 finished_function_call_trampolines: finished_function_call_trampolines
1201 .into_boxed_slice(),
1202 finished_dynamic_function_trampolines: finished_dynamic_function_trampolines
1203 .into_boxed_slice(),
1204 signatures: signatures.into_boxed_slice(),
1205 finished_function_lengths,
1206 }),
1207 })
1208 }
1209}