1 use crate::prelude::*;
2 #[cfg(feature = "std")]
3 use crate::runtime::vm::open_file_for_mmap;
4 use crate::runtime::vm::{CompiledModuleId, MmapVec, ModuleMemoryImages, VMWasmCallFunction};
5 use crate::sync::OnceLock;
6 use crate::{
7     Engine,
8     code::CodeObject,
9     code_memory::CodeMemory,
10     instantiate::CompiledModule,
11     resources::ResourcesRequired,
12     types::{ExportType, ExternType, ImportType},
13 };
14 use alloc::sync::Arc;
15 use core::fmt;
16 use core::ops::Range;
17 use core::ptr::NonNull;
18 #[cfg(feature = "std")]
19 use std::{fs::File, path::Path};
20 use wasmparser::{Parser, ValidPayload, Validator};
21 use wasmtime_environ::{
22     CompiledFunctionsTable, CompiledModuleInfo, EntityIndex, HostPtr, ModuleTypes, ObjectKind,
23     TypeTrace, VMOffsets, VMSharedTypeIndex,
24 };
25 #[cfg(feature = "gc")]
26 use wasmtime_unwinder::ExceptionTable;
27 mod registry;
28 
29 pub use registry::*;
30 
31 /// A compiled WebAssembly module, ready to be instantiated.
32 ///
33 /// A `Module` is a compiled in-memory representation of an input WebAssembly
34 /// binary. A `Module` is then used to create an [`Instance`](crate::Instance)
35 /// through an instantiation process. You cannot call functions or fetch
36 /// globals, for example, on a `Module` because it's purely a code
37 /// representation. Instead you'll need to create an
38 /// [`Instance`](crate::Instance) to interact with the wasm module.
39 ///
40 /// A `Module` can be created by compiling WebAssembly code through APIs such as
41 /// [`Module::new`]. This would be a JIT-style use case where code is compiled
42 /// just before it's used. Alternatively a `Module` can be compiled in one
43 /// process and [`Module::serialize`] can be used to save it to storage. A later
44 /// call to [`Module::deserialize`] will quickly load the module to execute and
45 /// does not need to compile any code, representing a more AOT-style use case.
46 ///
47 /// Currently a `Module` does not implement any form of tiering or dynamic
48 /// optimization of compiled code. Creation of a `Module` via [`Module::new`] or
49 /// related APIs will perform the entire compilation step synchronously. When
50 /// finished no further compilation will happen at runtime or later during
51 /// execution of WebAssembly instances for example.
52 ///
53 /// Compilation of WebAssembly by default goes through Cranelift and is
54 /// recommended to be done once-per-module. The same WebAssembly binary need not
55 /// be compiled multiple times and can instead used an embedder-cached result of
56 /// the first call.
57 ///
58 /// `Module` is thread-safe and safe to share across threads.
59 ///
60 /// ## Modules and `Clone`
61 ///
62 /// Using `clone` on a `Module` is a cheap operation. It will not create an
63 /// entirely new module, but rather just a new reference to the existing module.
64 /// In other words it's a shallow copy, not a deep copy.
65 ///
66 /// ## Examples
67 ///
68 /// There are a number of ways you can create a `Module`, for example pulling
69 /// the bytes from a number of locations. One example is loading a module from
70 /// the filesystem:
71 ///
72 /// ```no_run
73 /// # use wasmtime::*;
74 /// # fn main() -> anyhow::Result<()> {
75 /// let engine = Engine::default();
76 /// let module = Module::from_file(&engine, "path/to/foo.wasm")?;
77 /// # Ok(())
78 /// # }
79 /// ```
80 ///
81 /// You can also load the wasm text format if more convenient too:
82 ///
83 /// ```no_run
84 /// # use wasmtime::*;
85 /// # fn main() -> anyhow::Result<()> {
86 /// let engine = Engine::default();
87 /// // Now we're using the WebAssembly text extension: `.wat`!
88 /// let module = Module::from_file(&engine, "path/to/foo.wat")?;
89 /// # Ok(())
90 /// # }
91 /// ```
92 ///
93 /// And if you've already got the bytes in-memory you can use the
94 /// [`Module::new`] constructor:
95 ///
96 /// ```no_run
97 /// # use wasmtime::*;
98 /// # fn main() -> anyhow::Result<()> {
99 /// let engine = Engine::default();
100 /// # let wasm_bytes: Vec<u8> = Vec::new();
101 /// let module = Module::new(&engine, &wasm_bytes)?;
102 ///
103 /// // It also works with the text format!
104 /// let module = Module::new(&engine, "(module (func))")?;
105 /// # Ok(())
106 /// # }
107 /// ```
108 ///
109 /// Serializing and deserializing a module looks like:
110 ///
111 /// ```no_run
112 /// # use wasmtime::*;
113 /// # fn main() -> anyhow::Result<()> {
114 /// let engine = Engine::default();
115 /// # let wasm_bytes: Vec<u8> = Vec::new();
116 /// let module = Module::new(&engine, &wasm_bytes)?;
117 /// let module_bytes = module.serialize()?;
118 ///
119 /// // ... can save `module_bytes` to disk or other storage ...
120 ///
121 /// // recreate the module from the serialized bytes. For the `unsafe` bits
122 /// // see the documentation of `deserialize`.
123 /// let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
124 /// # Ok(())
125 /// # }
126 /// ```
127 ///
128 /// [`Config`]: crate::Config
129 #[derive(Clone)]
130 pub struct Module {
131     inner: Arc<ModuleInner>,
132 }
133 
134 struct ModuleInner {
135     engine: Engine,
136     /// The compiled artifacts for this module that will be instantiated and
137     /// executed.
138     module: CompiledModule,
139 
140     /// Runtime information such as the underlying mmap, type information, etc.
141     ///
142     /// Note that this `Arc` is used to share information between compiled
143     /// modules within a component. For bare core wasm modules created with
144     /// `Module::new`, for example, this is a uniquely owned `Arc`.
145     code: Arc<CodeObject>,
146 
147     /// A set of initialization images for memories, if any.
148     ///
149     /// Note that this is behind a `OnceCell` to lazily create this image. On
150     /// Linux where `memfd_create` may be used to create the backing memory
151     /// image this is a pretty expensive operation, so by deferring it this
152     /// improves memory usage for modules that are created but may not ever be
153     /// instantiated.
154     memory_images: OnceLock<Option<ModuleMemoryImages>>,
155 
156     /// Flag indicating whether this module can be serialized or not.
157     #[cfg(any(feature = "cranelift", feature = "winch"))]
158     serializable: bool,
159 
160     /// Runtime offset information for `VMContext`.
161     offsets: VMOffsets<HostPtr>,
162 }
163 
164 impl fmt::Debug for Module {
165     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166         f.debug_struct("Module")
167             .field("name", &self.name())
168             .finish_non_exhaustive()
169     }
170 }
171 
172 impl fmt::Debug for ModuleInner {
173     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174         f.debug_struct("ModuleInner")
175             .field("name", &self.module.module().name.as_ref())
176             .finish_non_exhaustive()
177     }
178 }
179 
180 impl Module {
181     /// Creates a new WebAssembly `Module` from the given in-memory `bytes`.
182     ///
183     /// The `bytes` provided must be in one of the following formats:
184     ///
185     /// * A [binary-encoded][binary] WebAssembly module. This is always supported.
186     /// * A [text-encoded][text] instance of the WebAssembly text format.
187     ///   This is only supported when the `wat` feature of this crate is enabled.
188     ///   If this is supplied then the text format will be parsed before validation.
189     ///   Note that the `wat` feature is enabled by default.
190     ///
191     /// The data for the wasm module must be loaded in-memory if it's present
192     /// elsewhere, for example on disk. This requires that the entire binary is
193     /// loaded into memory all at once, this API does not support streaming
194     /// compilation of a module.
195     ///
196     /// The WebAssembly binary will be decoded and validated. It will also be
197     /// compiled according to the configuration of the provided `engine`.
198     ///
199     /// # Errors
200     ///
201     /// This function may fail and return an error. Errors may include
202     /// situations such as:
203     ///
204     /// * The binary provided could not be decoded because it's not a valid
205     ///   WebAssembly binary
206     /// * The WebAssembly binary may not validate (e.g. contains type errors)
207     /// * Implementation-specific limits were exceeded with a valid binary (for
208     ///   example too many locals)
209     /// * The wasm binary may use features that are not enabled in the
210     ///   configuration of `engine`
211     /// * If the `wat` feature is enabled and the input is text, then it may be
212     ///   rejected if it fails to parse.
213     ///
214     /// The error returned should contain full information about why module
215     /// creation failed if one is returned.
216     ///
217     /// [binary]: https://webassembly.github.io/spec/core/binary/index.html
218     /// [text]: https://webassembly.github.io/spec/core/text/index.html
219     ///
220     /// # Examples
221     ///
222     /// The `new` function can be invoked with a in-memory array of bytes:
223     ///
224     /// ```no_run
225     /// # use wasmtime::*;
226     /// # fn main() -> anyhow::Result<()> {
227     /// # let engine = Engine::default();
228     /// # let wasm_bytes: Vec<u8> = Vec::new();
229     /// let module = Module::new(&engine, &wasm_bytes)?;
230     /// # Ok(())
231     /// # }
232     /// ```
233     ///
234     /// Or you can also pass in a string to be parsed as the wasm text
235     /// format:
236     ///
237     /// ```
238     /// # use wasmtime::*;
239     /// # fn main() -> anyhow::Result<()> {
240     /// # let engine = Engine::default();
241     /// let module = Module::new(&engine, "(module (func))")?;
242     /// # Ok(())
243     /// # }
244     /// ```
245     #[cfg(any(feature = "cranelift", feature = "winch"))]
246     pub fn new(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Module> {
247         crate::CodeBuilder::new(engine)
248             .wasm_binary_or_text(bytes.as_ref(), None)?
249             .compile_module()
250     }
251 
252     /// Creates a new WebAssembly `Module` from the contents of the given
253     /// `file` on disk.
254     ///
255     /// This is a convenience function that will read the `file` provided and
256     /// pass the bytes to the [`Module::new`] function. For more information
257     /// see [`Module::new`]
258     ///
259     /// # Examples
260     ///
261     /// ```no_run
262     /// # use wasmtime::*;
263     /// # fn main() -> anyhow::Result<()> {
264     /// let engine = Engine::default();
265     /// let module = Module::from_file(&engine, "./path/to/foo.wasm")?;
266     /// # Ok(())
267     /// # }
268     /// ```
269     ///
270     /// The `.wat` text format is also supported:
271     ///
272     /// ```no_run
273     /// # use wasmtime::*;
274     /// # fn main() -> anyhow::Result<()> {
275     /// # let engine = Engine::default();
276     /// let module = Module::from_file(&engine, "./path/to/foo.wat")?;
277     /// # Ok(())
278     /// # }
279     /// ```
280     #[cfg(all(feature = "std", any(feature = "cranelift", feature = "winch")))]
281     pub fn from_file(engine: &Engine, file: impl AsRef<Path>) -> Result<Module> {
282         crate::CodeBuilder::new(engine)
283             .wasm_binary_or_text_file(file.as_ref())?
284             .compile_module()
285     }
286 
287     /// Creates a new WebAssembly `Module` from the given in-memory `binary`
288     /// data.
289     ///
290     /// This is similar to [`Module::new`] except that it requires that the
291     /// `binary` input is a WebAssembly binary, the text format is not supported
292     /// by this function. It's generally recommended to use [`Module::new`], but
293     /// if it's required to not support the text format this function can be
294     /// used instead.
295     ///
296     /// # Examples
297     ///
298     /// ```
299     /// # use wasmtime::*;
300     /// # fn main() -> anyhow::Result<()> {
301     /// # let engine = Engine::default();
302     /// let wasm = b"\0asm\x01\0\0\0";
303     /// let module = Module::from_binary(&engine, wasm)?;
304     /// # Ok(())
305     /// # }
306     /// ```
307     ///
308     /// Note that the text format is **not** accepted by this function:
309     ///
310     /// ```
311     /// # use wasmtime::*;
312     /// # fn main() -> anyhow::Result<()> {
313     /// # let engine = Engine::default();
314     /// assert!(Module::from_binary(&engine, b"(module)").is_err());
315     /// # Ok(())
316     /// # }
317     /// ```
318     #[cfg(any(feature = "cranelift", feature = "winch"))]
319     pub fn from_binary(engine: &Engine, binary: &[u8]) -> Result<Module> {
320         crate::CodeBuilder::new(engine)
321             .wasm_binary(binary, None)?
322             .compile_module()
323     }
324 
325     /// Creates a new WebAssembly `Module` from the contents of the given `file`
326     /// on disk, but with assumptions that the file is from a trusted source.
327     /// The file should be a binary- or text-format WebAssembly module, or a
328     /// precompiled artifact generated by the same version of Wasmtime.
329     ///
330     /// # Unsafety
331     ///
332     /// All of the reasons that [`deserialize`] is `unsafe` apply to this
333     /// function as well. Arbitrary data loaded from a file may trick Wasmtime
334     /// into arbitrary code execution since the contents of the file are not
335     /// validated to be a valid precompiled module.
336     ///
337     /// [`deserialize`]: Module::deserialize
338     ///
339     /// Additionally though this function is also `unsafe` because the file
340     /// referenced must remain unchanged and a valid precompiled module for the
341     /// entire lifetime of the [`Module`] returned. Any changes to the file on
342     /// disk may change future instantiations of the module to be incorrect.
343     /// This is because the file is mapped into memory and lazily loaded pages
344     /// reflect the current state of the file, not necessarily the original
345     /// state of the file.
346     #[cfg(all(feature = "std", any(feature = "cranelift", feature = "winch")))]
347     pub unsafe fn from_trusted_file(engine: &Engine, file: impl AsRef<Path>) -> Result<Module> {
348         let open_file = open_file_for_mmap(file.as_ref())?;
349         let mmap = crate::runtime::vm::MmapVec::from_file(open_file)?;
350         if &mmap[0..4] == b"\x7fELF" {
351             let code = engine.load_code(mmap, ObjectKind::Module)?;
352             return Module::from_parts(engine, code, None);
353         }
354 
355         crate::CodeBuilder::new(engine)
356             .wasm_binary_or_text(&mmap[..], Some(file.as_ref()))?
357             .compile_module()
358     }
359 
360     /// Deserializes an in-memory compiled module previously created with
361     /// [`Module::serialize`] or [`Engine::precompile_module`].
362     ///
363     /// This function will deserialize the binary blobs emitted by
364     /// [`Module::serialize`] and [`Engine::precompile_module`] back into an
365     /// in-memory [`Module`] that's ready to be instantiated.
366     ///
367     /// Note that the [`Module::deserialize_file`] method is more optimized than
368     /// this function, so if the serialized module is already present in a file
369     /// it's recommended to use that method instead.
370     ///
371     /// # Unsafety
372     ///
373     /// This function is marked as `unsafe` because if fed invalid input or used
374     /// improperly this could lead to memory safety vulnerabilities. This method
375     /// should not, for example, be exposed to arbitrary user input.
376     ///
377     /// The structure of the binary blob read here is only lightly validated
378     /// internally in `wasmtime`. This is intended to be an efficient
379     /// "rehydration" for a [`Module`] which has very few runtime checks beyond
380     /// deserialization. Arbitrary input could, for example, replace valid
381     /// compiled code with any other valid compiled code, meaning that this can
382     /// trivially be used to execute arbitrary code otherwise.
383     ///
384     /// For these reasons this function is `unsafe`. This function is only
385     /// designed to receive the previous input from [`Module::serialize`] and
386     /// [`Engine::precompile_module`]. If the exact output of those functions
387     /// (unmodified) is passed to this function then calls to this function can
388     /// be considered safe. It is the caller's responsibility to provide the
389     /// guarantee that only previously-serialized bytes are being passed in
390     /// here.
391     ///
392     /// Note that this function is designed to be safe receiving output from
393     /// *any* compiled version of `wasmtime` itself. This means that it is safe
394     /// to feed output from older versions of Wasmtime into this function, in
395     /// addition to newer versions of wasmtime (from the future!). These inputs
396     /// will deterministically and safely produce an `Err`. This function only
397     /// successfully accepts inputs from the same version of `wasmtime`, but the
398     /// safety guarantee only applies to externally-defined blobs of bytes, not
399     /// those defined by any version of wasmtime. (this means that if you cache
400     /// blobs across versions of wasmtime you can be safely guaranteed that
401     /// future versions of wasmtime will reject old cache entries).
402     pub unsafe fn deserialize(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Module> {
403         let code = engine.load_code_bytes(bytes.as_ref(), ObjectKind::Module)?;
404         Module::from_parts(engine, code, None)
405     }
406 
407     /// In-place deserialization of an in-memory compiled module previously
408     /// created with [`Module::serialize`] or [`Engine::precompile_module`].
409     ///
410     /// See [`Self::deserialize`] for additional information; this method
411     /// works identically except that it will not create a copy of the provided
412     /// memory but will use it directly.
413     ///
414     /// # Unsafety
415     ///
416     /// All of the safety notes from [`Self::deserialize`] apply here as well
417     /// with the additional constraint that the code memory provide by `memory`
418     /// lives for as long as the module and is nevery externally modified for
419     /// the lifetime of the deserialized module.
420     pub unsafe fn deserialize_raw(engine: &Engine, memory: NonNull<[u8]>) -> Result<Module> {
421         // SAFETY: the contract required by `load_code_raw` is the same as this
422         // function.
423         let code = unsafe { engine.load_code_raw(memory, ObjectKind::Module)? };
424         Module::from_parts(engine, code, None)
425     }
426 
427     /// Same as [`deserialize`], except that the contents of `path` are read to
428     /// deserialize into a [`Module`].
429     ///
430     /// This method is provided because it can be faster than [`deserialize`]
431     /// since the data doesn't need to be copied around, but rather the module
432     /// can be used directly from an mmap'd view of the file provided.
433     ///
434     /// [`deserialize`]: Module::deserialize
435     ///
436     /// # Unsafety
437     ///
438     /// All of the reasons that [`deserialize`] is `unsafe` applies to this
439     /// function as well. Arbitrary data loaded from a file may trick Wasmtime
440     /// into arbitrary code execution since the contents of the file are not
441     /// validated to be a valid precompiled module.
442     ///
443     /// Additionally though this function is also `unsafe` because the file
444     /// referenced must remain unchanged and a valid precompiled module for the
445     /// entire lifetime of the [`Module`] returned. Any changes to the file on
446     /// disk may change future instantiations of the module to be incorrect.
447     /// This is because the file is mapped into memory and lazily loaded pages
448     /// reflect the current state of the file, not necessarily the original
449     /// state of the file.
450     #[cfg(feature = "std")]
451     pub unsafe fn deserialize_file(engine: &Engine, path: impl AsRef<Path>) -> Result<Module> {
452         let file = open_file_for_mmap(path.as_ref())?;
453         // SAFETY: the contract of `deserialize_open_file` is the samea s this
454         // function.
455         unsafe {
456             Self::deserialize_open_file(engine, file)
457                 .with_context(|| format!("failed deserialization for: {}", path.as_ref().display()))
458         }
459     }
460 
461     /// Same as [`deserialize_file`], except that it takes an open `File`
462     /// instead of a path.
463     ///
464     /// This method is provided because it can be used instead of
465     /// [`deserialize_file`] in situations where `wasmtime` is running with
466     /// limited file system permissions. In that case a process
467     /// with file system access can pass already opened files to `wasmtime`.
468     ///
469     /// [`deserialize_file`]: Module::deserialize_file
470     ///
471     /// Note that the corresponding will be mapped as private writeable
472     /// (copy-on-write) and executable. For `windows` this means the file needs
473     /// to be opened with at least `FILE_GENERIC_READ | FILE_GENERIC_EXECUTE`
474     /// [`access_mode`].
475     ///
476     /// [`access_mode`]: https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.access_mode
477     ///
478     /// # Unsafety
479     ///
480     /// All of the reasons that [`deserialize_file`] is `unsafe` applies to this
481     /// function as well.
482     #[cfg(feature = "std")]
483     pub unsafe fn deserialize_open_file(engine: &Engine, file: File) -> Result<Module> {
484         let code = engine.load_code_file(file, ObjectKind::Module)?;
485         Module::from_parts(engine, code, None)
486     }
487 
488     /// Entrypoint for creating a `Module` for all above functions, both
489     /// of the AOT and jit-compiled categories.
490     ///
491     /// In all cases the compilation artifact, `code_memory`, is provided here.
492     /// The `info_and_types` argument is `None` when a module is being
493     /// deserialized from a precompiled artifact or it's `Some` if it was just
494     /// compiled and the values are already available.
495     pub(crate) fn from_parts(
496         engine: &Engine,
497         code_memory: Arc<CodeMemory>,
498         info_and_types: Option<(CompiledModuleInfo, CompiledFunctionsTable, ModuleTypes)>,
499     ) -> Result<Self> {
500         // Acquire this module's metadata and type information, deserializing
501         // it from the provided artifact if it wasn't otherwise provided
502         // already.
503         let (mut info, index, mut types) = match info_and_types {
504             Some((info, index, types)) => (info, index, types),
505             None => postcard::from_bytes(code_memory.wasmtime_info())?,
506         };
507 
508         // Register function type signatures into the engine for the lifetime
509         // of the `Module` that will be returned. This notably also builds up
510         // maps for trampolines to be used for this module when inserted into
511         // stores.
512         //
513         // Note that the unsafety here should be ok since the `trampolines`
514         // field should only point to valid trampoline function pointers
515         // within the text section.
516         let signatures =
517             engine.register_and_canonicalize_types(&mut types, core::iter::once(&mut info.module));
518 
519         // Package up all our data into a `CodeObject` and delegate to the final
520         // step of module compilation.
521         let code = Arc::new(CodeObject::new(code_memory, signatures, types.into()));
522         let index = Arc::new(index);
523         Module::from_parts_raw(engine, code, info, index, true)
524     }
525 
526     pub(crate) fn from_parts_raw(
527         engine: &Engine,
528         code: Arc<CodeObject>,
529         info: CompiledModuleInfo,
530         index: Arc<CompiledFunctionsTable>,
531         serializable: bool,
532     ) -> Result<Self> {
533         let module = CompiledModule::from_artifacts(
534             code.code_memory().clone(),
535             info,
536             index,
537             engine.profiler(),
538         )?;
539 
540         // Validate the module can be used with the current instance allocator.
541         let offsets = VMOffsets::new(HostPtr, module.module());
542         engine
543             .allocator()
544             .validate_module(module.module(), &offsets)?;
545 
546         let _ = serializable;
547 
548         Ok(Self {
549             inner: Arc::new(ModuleInner {
550                 engine: engine.clone(),
551                 code,
552                 memory_images: OnceLock::new(),
553                 module,
554                 #[cfg(any(feature = "cranelift", feature = "winch"))]
555                 serializable,
556                 offsets,
557             }),
558         })
559     }
560 
561     /// Validates `binary` input data as a WebAssembly binary given the
562     /// configuration in `engine`.
563     ///
564     /// This function will perform a speedy validation of the `binary` input
565     /// WebAssembly module (which is in [binary form][binary], the text format
566     /// is not accepted by this function) and return either `Ok` or `Err`
567     /// depending on the results of validation. The `engine` argument indicates
568     /// configuration for WebAssembly features, for example, which are used to
569     /// indicate what should be valid and what shouldn't be.
570     ///
571     /// Validation automatically happens as part of [`Module::new`].
572     ///
573     /// # Errors
574     ///
575     /// If validation fails for any reason (type check error, usage of a feature
576     /// that wasn't enabled, etc) then an error with a description of the
577     /// validation issue will be returned.
578     ///
579     /// [binary]: https://webassembly.github.io/spec/core/binary/index.html
580     pub fn validate(engine: &Engine, binary: &[u8]) -> Result<()> {
581         let mut validator = Validator::new_with_features(engine.features());
582 
583         let mut functions = Vec::new();
584         for payload in Parser::new(0).parse_all(binary) {
585             let payload = payload?;
586             if let ValidPayload::Func(a, b) = validator.payload(&payload)? {
587                 functions.push((a, b));
588             }
589             if let wasmparser::Payload::Version { encoding, .. } = &payload {
590                 if let wasmparser::Encoding::Component = encoding {
591                     bail!("component passed to module validation");
592                 }
593             }
594         }
595 
596         engine.run_maybe_parallel(functions, |(validator, body)| {
597             // FIXME: it would be best here to use a rayon-specific parallel
598             // iterator that maintains state-per-thread to share the function
599             // validator allocations (`Default::default` here) across multiple
600             // functions.
601             validator.into_validator(Default::default()).validate(&body)
602         })?;
603         Ok(())
604     }
605 
606     /// Serializes this module to a vector of bytes.
607     ///
608     /// This function is similar to the [`Engine::precompile_module`] method
609     /// where it produces an artifact of Wasmtime which is suitable to later
610     /// pass into [`Module::deserialize`]. If a module is never instantiated
611     /// then it's recommended to use [`Engine::precompile_module`] instead of
612     /// this method, but if a module is both instantiated and serialized then
613     /// this method can be useful to get the serialized version without
614     /// compiling twice.
615     #[cfg(any(feature = "cranelift", feature = "winch"))]
616     pub fn serialize(&self) -> Result<Vec<u8>> {
617         // The current representation of compiled modules within a compiled
618         // component means that it cannot be serialized. The mmap returned here
619         // is the mmap for the entire component and while it contains all
620         // necessary data to deserialize this particular module it's all
621         // embedded within component-specific information.
622         //
623         // It's not the hardest thing in the world to support this but it's
624         // expected that there's not much of a use case at this time. In theory
625         // all that needs to be done is to edit the `.wasmtime.info` section
626         // to contains this module's metadata instead of the metadata for the
627         // whole component. The metadata itself is fairly trivially
628         // recreateable here it's more that there's no easy one-off API for
629         // editing the sections of an ELF object to use here.
630         //
631         // Overall for now this simply always returns an error in this
632         // situation. If you're reading this and feel that the situation should
633         // be different please feel free to open an issue.
634         if !self.inner.serializable {
635             bail!("cannot serialize a module exported from a component");
636         }
637         Ok(self.compiled_module().mmap().to_vec())
638     }
639 
640     pub(crate) fn compiled_module(&self) -> &CompiledModule {
641         &self.inner.module
642     }
643 
644     pub(crate) fn code_object(&self) -> &Arc<CodeObject> {
645         &self.inner.code
646     }
647 
648     pub(crate) fn env_module(&self) -> &Arc<wasmtime_environ::Module> {
649         self.compiled_module().module()
650     }
651 
652     pub(crate) fn types(&self) -> &ModuleTypes {
653         self.inner.code.module_types()
654     }
655 
656     #[cfg(any(feature = "component-model", feature = "gc-drc"))]
657     pub(crate) fn signatures(&self) -> &crate::type_registry::TypeCollection {
658         self.inner.code.signatures()
659     }
660 
661     /// Returns identifier/name that this [`Module`] has. This name
662     /// is used in traps/backtrace details.
663     ///
664     /// Note that most LLVM/clang/Rust-produced modules do not have a name
665     /// associated with them, but other wasm tooling can be used to inject or
666     /// add a name.
667     ///
668     /// # Examples
669     ///
670     /// ```
671     /// # use wasmtime::*;
672     /// # fn main() -> anyhow::Result<()> {
673     /// # let engine = Engine::default();
674     /// let module = Module::new(&engine, "(module $foo)")?;
675     /// assert_eq!(module.name(), Some("foo"));
676     ///
677     /// let module = Module::new(&engine, "(module)")?;
678     /// assert_eq!(module.name(), None);
679     ///
680     /// # Ok(())
681     /// # }
682     /// ```
683     pub fn name(&self) -> Option<&str> {
684         self.compiled_module().module().name.as_deref()
685     }
686 
687     /// Returns the list of imports that this [`Module`] has and must be
688     /// satisfied.
689     ///
690     /// This function returns the list of imports that the wasm module has, but
691     /// only the types of each import. The type of each import is used to
692     /// typecheck the [`Instance::new`](crate::Instance::new) method's `imports`
693     /// argument. The arguments to that function must match up 1-to-1 with the
694     /// entries in the array returned here.
695     ///
696     /// The imports returned reflect the order of the imports in the wasm module
697     /// itself, and note that no form of deduplication happens.
698     ///
699     /// # Examples
700     ///
701     /// Modules with no imports return an empty list here:
702     ///
703     /// ```
704     /// # use wasmtime::*;
705     /// # fn main() -> anyhow::Result<()> {
706     /// # let engine = Engine::default();
707     /// let module = Module::new(&engine, "(module)")?;
708     /// assert_eq!(module.imports().len(), 0);
709     /// # Ok(())
710     /// # }
711     /// ```
712     ///
713     /// and modules with imports will have a non-empty list:
714     ///
715     /// ```
716     /// # use wasmtime::*;
717     /// # fn main() -> anyhow::Result<()> {
718     /// # let engine = Engine::default();
719     /// let wat = r#"
720     ///     (module
721     ///         (import "host" "foo" (func))
722     ///     )
723     /// "#;
724     /// let module = Module::new(&engine, wat)?;
725     /// assert_eq!(module.imports().len(), 1);
726     /// let import = module.imports().next().unwrap();
727     /// assert_eq!(import.module(), "host");
728     /// assert_eq!(import.name(), "foo");
729     /// match import.ty() {
730     ///     ExternType::Func(_) => { /* ... */ }
731     ///     _ => panic!("unexpected import type!"),
732     /// }
733     /// # Ok(())
734     /// # }
735     /// ```
736     pub fn imports<'module>(
737         &'module self,
738     ) -> impl ExactSizeIterator<Item = ImportType<'module>> + 'module {
739         let module = self.compiled_module().module();
740         let types = self.types();
741         let engine = self.engine();
742         module
743             .imports()
744             .map(move |(imp_mod, imp_field, ty)| {
745                 debug_assert!(ty.is_canonicalized_for_runtime_usage());
746                 ImportType::new(imp_mod, imp_field, ty, types, engine)
747             })
748             .collect::<Vec<_>>()
749             .into_iter()
750     }
751 
752     /// Returns the list of exports that this [`Module`] has and will be
753     /// available after instantiation.
754     ///
755     /// This function will return the type of each item that will be returned
756     /// from [`Instance::exports`](crate::Instance::exports). Each entry in this
757     /// list corresponds 1-to-1 with that list, and the entries here will
758     /// indicate the name of the export along with the type of the export.
759     ///
760     /// # Examples
761     ///
762     /// Modules might not have any exports:
763     ///
764     /// ```
765     /// # use wasmtime::*;
766     /// # fn main() -> anyhow::Result<()> {
767     /// # let engine = Engine::default();
768     /// let module = Module::new(&engine, "(module)")?;
769     /// assert!(module.exports().next().is_none());
770     /// # Ok(())
771     /// # }
772     /// ```
773     ///
774     /// When the exports are not empty, you can inspect each export:
775     ///
776     /// ```
777     /// # use wasmtime::*;
778     /// # fn main() -> anyhow::Result<()> {
779     /// # let engine = Engine::default();
780     /// let wat = r#"
781     ///     (module
782     ///         (func (export "foo"))
783     ///         (memory (export "memory") 1)
784     ///     )
785     /// "#;
786     /// let module = Module::new(&engine, wat)?;
787     /// assert_eq!(module.exports().len(), 2);
788     ///
789     /// let mut exports = module.exports();
790     /// let foo = exports.next().unwrap();
791     /// assert_eq!(foo.name(), "foo");
792     /// match foo.ty() {
793     ///     ExternType::Func(_) => { /* ... */ }
794     ///     _ => panic!("unexpected export type!"),
795     /// }
796     ///
797     /// let memory = exports.next().unwrap();
798     /// assert_eq!(memory.name(), "memory");
799     /// match memory.ty() {
800     ///     ExternType::Memory(_) => { /* ... */ }
801     ///     _ => panic!("unexpected export type!"),
802     /// }
803     /// # Ok(())
804     /// # }
805     /// ```
806     pub fn exports<'module>(
807         &'module self,
808     ) -> impl ExactSizeIterator<Item = ExportType<'module>> + 'module {
809         let module = self.compiled_module().module();
810         let types = self.types();
811         let engine = self.engine();
812         module.exports.iter().map(move |(name, entity_index)| {
813             ExportType::new(name, module.type_of(*entity_index), types, engine)
814         })
815     }
816 
817     /// Looks up an export in this [`Module`] by name.
818     ///
819     /// This function will return the type of an export with the given name.
820     ///
821     /// # Examples
822     ///
823     /// There may be no export with that name:
824     ///
825     /// ```
826     /// # use wasmtime::*;
827     /// # fn main() -> anyhow::Result<()> {
828     /// # let engine = Engine::default();
829     /// let module = Module::new(&engine, "(module)")?;
830     /// assert!(module.get_export("foo").is_none());
831     /// # Ok(())
832     /// # }
833     /// ```
834     ///
835     /// When there is an export with that name, it is returned:
836     ///
837     /// ```
838     /// # use wasmtime::*;
839     /// # fn main() -> anyhow::Result<()> {
840     /// # let engine = Engine::default();
841     /// let wat = r#"
842     ///     (module
843     ///         (func (export "foo"))
844     ///         (memory (export "memory") 1)
845     ///     )
846     /// "#;
847     /// let module = Module::new(&engine, wat)?;
848     /// let foo = module.get_export("foo");
849     /// assert!(foo.is_some());
850     ///
851     /// let foo = foo.unwrap();
852     /// match foo {
853     ///     ExternType::Func(_) => { /* ... */ }
854     ///     _ => panic!("unexpected export type!"),
855     /// }
856     ///
857     /// # Ok(())
858     /// # }
859     /// ```
860     pub fn get_export(&self, name: &str) -> Option<ExternType> {
861         let module = self.compiled_module().module();
862         let entity_index = module.exports.get(name)?;
863         Some(ExternType::from_wasmtime(
864             self.engine(),
865             self.types(),
866             &module.type_of(*entity_index),
867         ))
868     }
869 
870     /// Looks up an export in this [`Module`] by name to get its index.
871     ///
872     /// This function will return the index of an export with the given name. This can be useful
873     /// to avoid the cost of looking up the export by name multiple times. Instead the
874     /// [`ModuleExport`] can be stored and used to look up the export on the
875     /// [`Instance`](crate::Instance) later.
876     pub fn get_export_index(&self, name: &str) -> Option<ModuleExport> {
877         let compiled_module = self.compiled_module();
878         let module = compiled_module.module();
879         let entity = *module.exports.get(name)?;
880         Some(ModuleExport {
881             module: self.id(),
882             entity,
883         })
884     }
885 
886     /// Returns the [`Engine`] that this [`Module`] was compiled by.
887     pub fn engine(&self) -> &Engine {
888         &self.inner.engine
889     }
890 
891     /// Returns a summary of the resources required to instantiate this
892     /// [`Module`].
893     ///
894     /// Potential uses of the returned information:
895     ///
896     /// * Determining whether your pooling allocator configuration supports
897     ///   instantiating this module.
898     ///
899     /// * Deciding how many of which `Module` you want to instantiate within a
900     ///   fixed amount of resources, e.g. determining whether to create 5
901     ///   instances of module X or 10 instances of module Y.
902     ///
903     /// # Example
904     ///
905     /// ```
906     /// # fn main() -> wasmtime::Result<()> {
907     /// use wasmtime::{Config, Engine, Module};
908     ///
909     /// let mut config = Config::new();
910     /// config.wasm_multi_memory(true);
911     /// let engine = Engine::new(&config)?;
912     ///
913     /// let module = Module::new(&engine, r#"
914     ///     (module
915     ///         ;; Import a memory. Doesn't count towards required resources.
916     ///         (import "a" "b" (memory 10))
917     ///         ;; Define two local memories. These count towards the required
918     ///         ;; resources.
919     ///         (memory 1)
920     ///         (memory 6)
921     ///     )
922     /// "#)?;
923     ///
924     /// let resources = module.resources_required();
925     ///
926     /// // Instantiating the module will require allocating two memories, and
927     /// // the maximum initial memory size is six Wasm pages.
928     /// assert_eq!(resources.num_memories, 2);
929     /// assert_eq!(resources.max_initial_memory_size, Some(6));
930     ///
931     /// // The module doesn't need any tables.
932     /// assert_eq!(resources.num_tables, 0);
933     /// assert_eq!(resources.max_initial_table_size, None);
934     /// # Ok(()) }
935     /// ```
936     pub fn resources_required(&self) -> ResourcesRequired {
937         let em = self.env_module();
938         let num_memories = u32::try_from(em.num_defined_memories()).unwrap();
939         let max_initial_memory_size = em
940             .memories
941             .values()
942             .skip(em.num_imported_memories)
943             .map(|memory| memory.limits.min)
944             .max();
945         let num_tables = u32::try_from(em.num_defined_tables()).unwrap();
946         let max_initial_table_size = em
947             .tables
948             .values()
949             .skip(em.num_imported_tables)
950             .map(|table| table.limits.min)
951             .max();
952         ResourcesRequired {
953             num_memories,
954             max_initial_memory_size,
955             num_tables,
956             max_initial_table_size,
957         }
958     }
959 
960     /// Returns the range of bytes in memory where this module's compilation
961     /// image resides.
962     ///
963     /// The compilation image for a module contains executable code, data, debug
964     /// information, etc. This is roughly the same as the `Module::serialize`
965     /// but not the exact same.
966     ///
967     /// The range of memory reported here is exposed to allow low-level
968     /// manipulation of the memory in platform-specific manners such as using
969     /// `mlock` to force the contents to be paged in immediately or keep them
970     /// paged in after they're loaded.
971     ///
972     /// It is not safe to modify the memory in this range, nor is it safe to
973     /// modify the protections of memory in this range.
974     pub fn image_range(&self) -> Range<*const u8> {
975         self.compiled_module().mmap().image_range()
976     }
977 
978     /// Force initialization of copy-on-write images to happen here-and-now
979     /// instead of when they're requested during first instantiation.
980     ///
981     /// When [copy-on-write memory
982     /// initialization](crate::Config::memory_init_cow) is enabled then Wasmtime
983     /// will lazily create the initialization image for a module. This method
984     /// can be used to explicitly dictate when this initialization happens.
985     ///
986     /// Note that this largely only matters on Linux when memfd is used.
987     /// Otherwise the copy-on-write image typically comes from disk and in that
988     /// situation the creation of the image is trivial as the image is always
989     /// sourced from disk. On Linux, though, when memfd is used a memfd is
990     /// created and the initialization image is written to it.
991     ///
992     /// Also note that this method is not required to be called, it's available
993     /// as a performance optimization if required but is otherwise handled
994     /// automatically.
995     pub fn initialize_copy_on_write_image(&self) -> Result<()> {
996         self.memory_images()?;
997         Ok(())
998     }
999 
1000     /// Get the map from `.text` section offsets to Wasm binary offsets for this
1001     /// module.
1002     ///
1003     /// Each entry is a (`.text` section offset, Wasm binary offset) pair.
1004     ///
1005     /// Entries are yielded in order of `.text` section offset.
1006     ///
1007     /// Some entries are missing a Wasm binary offset. This is for code that is
1008     /// not associated with any single location in the Wasm binary, or for when
1009     /// source information was optimized away.
1010     ///
1011     /// Not every module has an address map, since address map generation can be
1012     /// turned off on `Config`.
1013     ///
1014     /// There is not an entry for every `.text` section offset. Every offset
1015     /// after an entry's offset, but before the next entry's offset, is
1016     /// considered to map to the same Wasm binary offset as the original
1017     /// entry. For example, the address map will not contain the following
1018     /// sequence of entries:
1019     ///
1020     /// ```ignore
1021     /// [
1022     ///     // ...
1023     ///     (10, Some(42)),
1024     ///     (11, Some(42)),
1025     ///     (12, Some(42)),
1026     ///     (13, Some(43)),
1027     ///     // ...
1028     /// ]
1029     /// ```
1030     ///
1031     /// Instead, it will drop the entries for offsets `11` and `12` since they
1032     /// are the same as the entry for offset `10`:
1033     ///
1034     /// ```ignore
1035     /// [
1036     ///     // ...
1037     ///     (10, Some(42)),
1038     ///     (13, Some(43)),
1039     ///     // ...
1040     /// ]
1041     /// ```
1042     pub fn address_map<'a>(&'a self) -> Option<impl Iterator<Item = (usize, Option<u32>)> + 'a> {
1043         Some(
1044             wasmtime_environ::iterate_address_map(
1045                 self.code_object().code_memory().address_map_data(),
1046             )?
1047             .map(|(offset, file_pos)| (offset as usize, file_pos.file_offset())),
1048         )
1049     }
1050 
1051     /// Get this module's code object's `.text` section, containing its compiled
1052     /// executable code.
1053     pub fn text(&self) -> &[u8] {
1054         self.code_object().code_memory().text()
1055     }
1056 
1057     /// Get information about functions in this module's `.text` section: their
1058     /// index, name, and offset+length.
1059     ///
1060     /// Results are yielded in a ModuleFunction struct.
1061     pub fn functions<'a>(&'a self) -> impl ExactSizeIterator<Item = ModuleFunction> + 'a {
1062         let module = self.compiled_module();
1063         module.finished_functions().map(|(idx, _)| {
1064             let loc = module.func_loc(idx);
1065             let idx = module.module().func_index(idx);
1066             ModuleFunction {
1067                 index: idx,
1068                 name: module.func_name(idx).map(|n| n.to_string()),
1069                 offset: loc.start as usize,
1070                 len: loc.length as usize,
1071             }
1072         })
1073     }
1074 
1075     pub(crate) fn id(&self) -> CompiledModuleId {
1076         self.inner.module.unique_id()
1077     }
1078 
1079     pub(crate) fn offsets(&self) -> &VMOffsets<HostPtr> {
1080         &self.inner.offsets
1081     }
1082 
1083     /// Return the address, in memory, of the trampoline that allows Wasm to
1084     /// call a array function of the given signature.
1085     pub(crate) fn wasm_to_array_trampoline(
1086         &self,
1087         signature: VMSharedTypeIndex,
1088     ) -> Option<NonNull<VMWasmCallFunction>> {
1089         log::trace!("Looking up trampoline for {signature:?}");
1090         let trampoline_shared_ty = self.inner.engine.signatures().trampoline_type(signature);
1091         let trampoline_module_ty = self
1092             .inner
1093             .code
1094             .signatures()
1095             .trampoline_type(trampoline_shared_ty)?;
1096         debug_assert!(
1097             self.inner
1098                 .engine
1099                 .signatures()
1100                 .borrow(
1101                     self.inner
1102                         .code
1103                         .signatures()
1104                         .shared_type(trampoline_module_ty)
1105                         .unwrap()
1106                 )
1107                 .unwrap()
1108                 .unwrap_func()
1109                 .is_trampoline_type()
1110         );
1111 
1112         let ptr = self
1113             .compiled_module()
1114             .wasm_to_array_trampoline(trampoline_module_ty)
1115             .expect("always have a trampoline for the trampoline type")
1116             .as_ptr()
1117             .cast::<VMWasmCallFunction>()
1118             .cast_mut();
1119         Some(NonNull::new(ptr).unwrap())
1120     }
1121 
1122     pub(crate) fn memory_images(&self) -> Result<Option<&ModuleMemoryImages>> {
1123         let images = self
1124             .inner
1125             .memory_images
1126             .get_or_try_init(|| memory_images(&self.inner))?
1127             .as_ref();
1128         Ok(images)
1129     }
1130 
1131     /// Lookup the stack map at a program counter value.
1132     #[cfg(feature = "gc")]
1133     pub(crate) fn lookup_stack_map(&self, pc: usize) -> Option<wasmtime_environ::StackMap<'_>> {
1134         let text_offset = u32::try_from(pc - self.inner.module.text().as_ptr() as usize).unwrap();
1135         let info = self.inner.code.code_memory().stack_map_data();
1136         wasmtime_environ::StackMap::lookup(text_offset, info)
1137     }
1138 
1139     /// Obtain an exception-table parser on this module's exception metadata.
1140     #[cfg(feature = "gc")]
1141     pub(crate) fn exception_table<'a>(&'a self) -> ExceptionTable<'a> {
1142         ExceptionTable::parse(self.inner.code.code_memory().exception_tables())
1143             .expect("Exception tables were validated on module load")
1144     }
1145 }
1146 
1147 /// Describes a function for a given module.
1148 pub struct ModuleFunction {
1149     pub index: wasmtime_environ::FuncIndex,
1150     pub name: Option<String>,
1151     pub offset: usize,
1152     pub len: usize,
1153 }
1154 
1155 impl Drop for ModuleInner {
1156     fn drop(&mut self) {
1157         // When a `Module` is being dropped that means that it's no longer
1158         // present in any `Store` and it's additionally not longer held by any
1159         // embedder. Take this opportunity to purge any lingering instantiations
1160         // within a pooling instance allocator, if applicable.
1161         self.engine
1162             .allocator()
1163             .purge_module(self.module.unique_id());
1164     }
1165 }
1166 
1167 /// Describes the location of an export in a module.
1168 #[derive(Copy, Clone)]
1169 pub struct ModuleExport {
1170     /// The module that this export is defined in.
1171     pub(crate) module: CompiledModuleId,
1172     /// A raw index into the wasm module.
1173     pub(crate) entity: EntityIndex,
1174 }
1175 
1176 fn _assert_send_sync() {
1177     fn _assert<T: Send + Sync>() {}
1178     _assert::<Module>();
1179 }
1180 
1181 /// Helper method to construct a `ModuleMemoryImages` for an associated
1182 /// `CompiledModule`.
1183 fn memory_images(inner: &Arc<ModuleInner>) -> Result<Option<ModuleMemoryImages>> {
1184     // If initialization via copy-on-write is explicitly disabled in
1185     // configuration then this path is skipped entirely.
1186     if !inner.engine.tunables().memory_init_cow {
1187         return Ok(None);
1188     }
1189 
1190     // ... otherwise logic is delegated to the `ModuleMemoryImages::new`
1191     // constructor.
1192     ModuleMemoryImages::new(
1193         &inner.engine,
1194         inner.module.module(),
1195         inner.code.code_memory(),
1196     )
1197 }
1198 
1199 impl crate::vm::ModuleMemoryImageSource for CodeMemory {
1200     fn wasm_data(&self) -> &[u8] {
1201         <Self>::wasm_data(self)
1202     }
1203 
1204     fn mmap(&self) -> Option<&MmapVec> {
1205         Some(<Self>::mmap(self))
1206     }
1207 }
1208 
1209 #[cfg(test)]
1210 mod tests {
1211     use crate::{Engine, Module};
1212     use wasmtime_environ::MemoryInitialization;
1213 
1214     #[test]
1215     fn cow_on_by_default() {
1216         let engine = Engine::default();
1217         let module = Module::new(
1218             &engine,
1219             r#"
1220                 (module
1221                     (memory 1)
1222                     (data (i32.const 100) "abcd")
1223                 )
1224             "#,
1225         )
1226         .unwrap();
1227 
1228         let init = &module.env_module().memory_initialization;
1229         assert!(matches!(init, MemoryInitialization::Static { .. }));
1230     }
1231 }
1232