199ecf728SChris Fallin use crate::Engine;
299ecf728SChris Fallin use crate::Module;
396e19700SNick Fitzgerald use crate::Result;
499ecf728SChris Fallin use crate::module::ModuleRegistry;
599ecf728SChris Fallin use crate::vm::ModuleMemoryImageSource;
6d4242001SAdam Bratschi-Kaye use crate::{code_memory::CodeMemory, type_registry::TypeCollection};
799ecf728SChris Fallin #[cfg(feature = "debug")]
899ecf728SChris Fallin use alloc::boxed::Box;
981a89169SAlex Crichton use alloc::sync::Arc;
1099ecf728SChris Fallin use core::ops::{Add, Range, Sub};
11*6e0ded7cSNick Fitzgerald use wasmtime_core::error::OutOfMemory;
1299ecf728SChris Fallin use wasmtime_environ::DefinedFuncIndex;
1390ac295eSAlex Crichton use wasmtime_environ::ModuleTypes;
14c07c94d2SChris Fallin use wasmtime_environ::StaticModuleIndex;
15d4242001SAdam Bratschi-Kaye #[cfg(feature = "component-model")]
16d4242001SAdam Bratschi-Kaye use wasmtime_environ::component::ComponentTypes;
17d4242001SAdam Bratschi-Kaye 
1899ecf728SChris Fallin macro_rules! define_pc_kind {
1999ecf728SChris Fallin     ($ty:ident) => {
2099ecf728SChris Fallin         #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
2199ecf728SChris Fallin         pub struct $ty(usize);
2299ecf728SChris Fallin 
2399ecf728SChris Fallin         impl Add<usize> for $ty {
2499ecf728SChris Fallin             type Output = $ty;
2599ecf728SChris Fallin             fn add(self, other: usize) -> $ty {
2699ecf728SChris Fallin                 $ty(self.0.wrapping_add(other))
2799ecf728SChris Fallin             }
2899ecf728SChris Fallin         }
2999ecf728SChris Fallin         impl Sub<usize> for $ty {
3099ecf728SChris Fallin             type Output = $ty;
3199ecf728SChris Fallin             fn sub(self, other: usize) -> $ty {
3299ecf728SChris Fallin                 $ty(self.0.wrapping_sub(other))
3399ecf728SChris Fallin             }
3499ecf728SChris Fallin         }
3599ecf728SChris Fallin 
3699ecf728SChris Fallin         impl $ty {
3799ecf728SChris Fallin             /// Is the given PC within this range? Give the relative
3899ecf728SChris Fallin             /// offset if so.
3999ecf728SChris Fallin             pub fn offset_of(range: Range<$ty>, pc: usize) -> Option<usize> {
4099ecf728SChris Fallin                 if pc >= range.start.0 && pc < range.end.0 {
4199ecf728SChris Fallin                     Some(pc.wrapping_sub(range.start.0))
4299ecf728SChris Fallin                 } else {
4399ecf728SChris Fallin                     None
4499ecf728SChris Fallin                 }
4599ecf728SChris Fallin             }
4699ecf728SChris Fallin 
4799ecf728SChris Fallin             /// Get the raw PC value.
4899ecf728SChris Fallin             pub fn raw(&self) -> usize {
4999ecf728SChris Fallin                 self.0
5099ecf728SChris Fallin             }
5199ecf728SChris Fallin         }
5299ecf728SChris Fallin     };
5399ecf728SChris Fallin }
5499ecf728SChris Fallin 
5599ecf728SChris Fallin // An address in "engine code": the original (canonical) copy of code
5699ecf728SChris Fallin // for a compiled module.
5799ecf728SChris Fallin //
5899ecf728SChris Fallin // See [`EngineCode`] for more details.
5999ecf728SChris Fallin define_pc_kind!(EngineCodePC);
6099ecf728SChris Fallin 
6199ecf728SChris Fallin // An address in "store code": the copy of code used when executing
6299ecf728SChris Fallin // instances of a module in a given store.
6399ecf728SChris Fallin //
6499ecf728SChris Fallin // May or may not be the same as the engine code address -- a store
6599ecf728SChris Fallin // is allowed to make a private copy of engine code as its store
6699ecf728SChris Fallin // code.
6799ecf728SChris Fallin //
6899ecf728SChris Fallin // See [`StoreCode`] for more details.
6999ecf728SChris Fallin define_pc_kind!(StoreCodePC);
7099ecf728SChris Fallin 
7199ecf728SChris Fallin impl StoreCodePC {
7299ecf728SChris Fallin     /// Construct a StoreCodePC for search purposes from a raw PC
7399ecf728SChris Fallin     /// observed during execution.
from_raw(pc: usize) -> StoreCodePC7499ecf728SChris Fallin     pub fn from_raw(pc: usize) -> StoreCodePC {
7599ecf728SChris Fallin         StoreCodePC(pc)
7699ecf728SChris Fallin     }
7799ecf728SChris Fallin }
7899ecf728SChris Fallin 
7999ecf728SChris Fallin /// Metadata about, and original machine code for, a loaded compiled
8099ecf728SChris Fallin /// artifact in memory which is ready for Wasmtime to execute.
81d4242001SAdam Bratschi-Kaye ///
82d4242001SAdam Bratschi-Kaye /// This structure is used in both `Module` and `Component`. For components it's
83d4242001SAdam Bratschi-Kaye /// notably shared amongst the core wasm modules within a component and the
84d4242001SAdam Bratschi-Kaye /// component itself. For core wasm modules this is uniquely owned within a
85d4242001SAdam Bratschi-Kaye /// `Module`.
8699ecf728SChris Fallin ///
8799ecf728SChris Fallin /// The `EngineCode` is "static", like a module: there is one copy per
8899ecf728SChris Fallin /// unit of code. Instantiation of a module containing an `EngineCode`
8999ecf728SChris Fallin /// into a `Store` produces a `StoreCode`. The latter is the owner of
9099ecf728SChris Fallin /// the actual machine code that runs. This machine code *may* be a
9199ecf728SChris Fallin /// read-only-shared copy of the original, or may be a private copy
9299ecf728SChris Fallin /// that we have patched. The latter is useful for some kinds of
9399ecf728SChris Fallin /// debugging/instrumentation, which is always scoped per-Store.
9499ecf728SChris Fallin ///
9599ecf728SChris Fallin /// The `EngineCode` does *not* expose its underlying `CodeMemory`, to
9699ecf728SChris Fallin /// guard against the original-copy being used in an inappropriate
9799ecf728SChris Fallin /// (store-specific) context. Instead, it has accessors that provide
9899ecf728SChris Fallin /// the instance-agnostic metadata from the `CodeMemory`, and
9999ecf728SChris Fallin /// instance-specific data and code pointers can be obtained from the
10099ecf728SChris Fallin /// `StoreCode`.
10199ecf728SChris Fallin pub struct EngineCode {
10299ecf728SChris Fallin     /// Actual underlying code which is executable and contains other
10399ecf728SChris Fallin     /// compiled information.
104d4242001SAdam Bratschi-Kaye     ///
105d4242001SAdam Bratschi-Kaye     /// Note the `Arc` here is used to share this with `CompiledModule` and the
106d4242001SAdam Bratschi-Kaye     /// global module registry of traps. While probably not strictly necessary
107d4242001SAdam Bratschi-Kaye     /// and could be avoided with some refactorings is a hopefully a relatively
108d4242001SAdam Bratschi-Kaye     /// minor `Arc` for now.
10999ecf728SChris Fallin     ///
11099ecf728SChris Fallin     /// As noted above, this is the *original* copy of the code, and
11199ecf728SChris Fallin     /// may be used directly, but may also be deep-cloned to a private
11299ecf728SChris Fallin     /// copy in a `StoreCode`.
11399ecf728SChris Fallin     original_code: Arc<CodeMemory>,
114d4242001SAdam Bratschi-Kaye 
115d4242001SAdam Bratschi-Kaye     /// Registered shared signature for the loaded object.
116d4242001SAdam Bratschi-Kaye     ///
117d4242001SAdam Bratschi-Kaye     /// Note that this type has a significant destructor which unregisters
118d4242001SAdam Bratschi-Kaye     /// signatures within the `Engine` it was originally tied to, and this ends
1190e9121daSFrankReh     /// up corresponding to the lifetime of a `Component` or `Module`.
120d4242001SAdam Bratschi-Kaye     signatures: TypeCollection,
121d4242001SAdam Bratschi-Kaye 
122d4242001SAdam Bratschi-Kaye     /// Type information for the loaded object.
123d4242001SAdam Bratschi-Kaye     ///
124d4242001SAdam Bratschi-Kaye     /// This is either a `ModuleTypes` or a `ComponentTypes` depending on the
125d4242001SAdam Bratschi-Kaye     /// top-level creator of this code.
126d4242001SAdam Bratschi-Kaye     types: Types,
127d4242001SAdam Bratschi-Kaye }
128d4242001SAdam Bratschi-Kaye 
12999ecf728SChris Fallin impl EngineCode {
new( mmap: Arc<CodeMemory>, signatures: TypeCollection, types: Types, ) -> Result<EngineCode, OutOfMemory>130*6e0ded7cSNick Fitzgerald     pub fn new(
131*6e0ded7cSNick Fitzgerald         mmap: Arc<CodeMemory>,
132*6e0ded7cSNick Fitzgerald         signatures: TypeCollection,
133*6e0ded7cSNick Fitzgerald         types: Types,
134*6e0ded7cSNick Fitzgerald     ) -> Result<EngineCode, OutOfMemory> {
1355393c2bfSBruce Mitchener         // The corresponding unregister for this is below in `Drop for
13699ecf728SChris Fallin         // EngineCode`.
137*6e0ded7cSNick Fitzgerald         crate::module::register_code(&mmap, mmap.raw_addr_range())?;
138d4242001SAdam Bratschi-Kaye 
139*6e0ded7cSNick Fitzgerald         Ok(EngineCode {
14099ecf728SChris Fallin             original_code: mmap,
141d4242001SAdam Bratschi-Kaye             signatures,
142d4242001SAdam Bratschi-Kaye             types,
143*6e0ded7cSNick Fitzgerald         })
144d4242001SAdam Bratschi-Kaye     }
145d4242001SAdam Bratschi-Kaye 
146d4242001SAdam Bratschi-Kaye     #[cfg(feature = "component-model")]
types(&self) -> &Types147d4242001SAdam Bratschi-Kaye     pub fn types(&self) -> &Types {
148d4242001SAdam Bratschi-Kaye         &self.types
149d4242001SAdam Bratschi-Kaye     }
150d4242001SAdam Bratschi-Kaye 
module_types(&self) -> &ModuleTypes151d4242001SAdam Bratschi-Kaye     pub fn module_types(&self) -> &ModuleTypes {
152d4242001SAdam Bratschi-Kaye         self.types.module_types()
153d4242001SAdam Bratschi-Kaye     }
154d4242001SAdam Bratschi-Kaye 
signatures(&self) -> &TypeCollection155d4242001SAdam Bratschi-Kaye     pub fn signatures(&self) -> &TypeCollection {
156d4242001SAdam Bratschi-Kaye         &self.signatures
157d4242001SAdam Bratschi-Kaye     }
15899ecf728SChris Fallin 
text_size(&self) -> usize15999ecf728SChris Fallin     pub fn text_size(&self) -> usize {
16099ecf728SChris Fallin         self.original_code.text().len()
161d4242001SAdam Bratschi-Kaye     }
162d4242001SAdam Bratschi-Kaye 
16399ecf728SChris Fallin     /// Give the range of engine-code PCs in this code.
text_range(&self) -> Range<EngineCodePC>16499ecf728SChris Fallin     pub fn text_range(&self) -> Range<EngineCodePC> {
16599ecf728SChris Fallin         let raw = self.original_code.raw_addr_range();
16699ecf728SChris Fallin         EngineCodePC(raw.start)..EngineCodePC(raw.end)
16799ecf728SChris Fallin     }
16899ecf728SChris Fallin 
16999ecf728SChris Fallin     // For all accessors to code object sections below: we can use the
17099ecf728SChris Fallin     // original (uncloned) code image for these: they are just slices
17199ecf728SChris Fallin     // of bytes that we interpret independent of location.
17299ecf728SChris Fallin     //
17399ecf728SChris Fallin     // We hide the raw `CodeMemory` in `original_code` (*not* a public
17499ecf728SChris Fallin     // field) because we do not want the EngineCode copy used
17599ecf728SChris Fallin     // inadvertently for execution of Wasm functions.
17699ecf728SChris Fallin     //
17799ecf728SChris Fallin     // We thus *cannot* add an accessor below for anything that
17899ecf728SChris Fallin     // actually interprets the location of the bytes as a code
17999ecf728SChris Fallin     // pointer to a Wasm function.
18099ecf728SChris Fallin     //
18199ecf728SChris Fallin     // Note that Wasm-to-array trampolines, in contrast, are fair game
18299ecf728SChris Fallin     // to execute directly from the EngineCode: these are not specific
18399ecf728SChris Fallin     // to Wasm functions, but instead call builtins, and we never
18499ecf728SChris Fallin     // patch trampolines in StoreCode, so we can freely mix in
18599ecf728SChris Fallin     // EngineCode variants.
18699ecf728SChris Fallin 
18799ecf728SChris Fallin     /// Get the Wasm-to-array trampoline for the given raw range in
18899ecf728SChris Fallin     /// the text segment.
raw_wasm_to_array_trampoline_data(&self, range: Range<usize>) -> &[u8]18999ecf728SChris Fallin     pub(crate) fn raw_wasm_to_array_trampoline_data(&self, range: Range<usize>) -> &[u8] {
19099ecf728SChris Fallin         &self.original_code.text()[range]
19199ecf728SChris Fallin     }
19299ecf728SChris Fallin 
19399ecf728SChris Fallin     /// Provide the address-map data for this EngineCode.
address_map_data(&self) -> &[u8]19499ecf728SChris Fallin     pub fn address_map_data(&self) -> &[u8] {
19599ecf728SChris Fallin         // We can use the original (uncloned) code image for this: it
19699ecf728SChris Fallin         // is just a slice of bytes that we interpret independent of
19799ecf728SChris Fallin         // location.
19899ecf728SChris Fallin         self.original_code.address_map_data()
19999ecf728SChris Fallin     }
20099ecf728SChris Fallin 
20199ecf728SChris Fallin     /// Provide the stack-map data for this EngineCode.
stack_map_data(&self) -> &[u8]20299ecf728SChris Fallin     pub fn stack_map_data(&self) -> &[u8] {
20399ecf728SChris Fallin         // We can use the original (uncloned) code image for this: it
20499ecf728SChris Fallin         // is just a slice of bytes that we interpret independent of
20599ecf728SChris Fallin         // location.
20699ecf728SChris Fallin         self.original_code.stack_map_data()
20799ecf728SChris Fallin     }
20899ecf728SChris Fallin 
20999ecf728SChris Fallin     /// Returns the encoded exception-tables section to pass to
21099ecf728SChris Fallin     /// `wasmtime_unwinder::ExceptionTable::parse`.
exception_tables(&self) -> &[u8]21199ecf728SChris Fallin     pub fn exception_tables(&self) -> &[u8] {
21299ecf728SChris Fallin         // We can use the original (uncloned) code image for this: it
21399ecf728SChris Fallin         // is just a slice of bytes that we interpret independent of
21499ecf728SChris Fallin         // location.
21599ecf728SChris Fallin         self.original_code.exception_tables()
21699ecf728SChris Fallin     }
21799ecf728SChris Fallin 
21899ecf728SChris Fallin     /// Returns the encoded frame-tables section to pass to
21999ecf728SChris Fallin     /// `wasmtime_environ::FrameTable::parse`.
frame_tables(&self) -> &[u8]22099ecf728SChris Fallin     pub fn frame_tables(&self) -> &[u8] {
22199ecf728SChris Fallin         self.original_code.frame_tables()
22299ecf728SChris Fallin     }
22399ecf728SChris Fallin 
22499ecf728SChris Fallin     /// Returns the data in the `ELF_NAME_DATA` section.
22599ecf728SChris Fallin     #[inline]
func_name_data(&self) -> &[u8]22699ecf728SChris Fallin     pub fn func_name_data(&self) -> &[u8] {
22799ecf728SChris Fallin         self.original_code.func_name_data()
22899ecf728SChris Fallin     }
22999ecf728SChris Fallin 
23099ecf728SChris Fallin     /// Returns the contents of the `ELF_WASMTIME_DWARF` section.
23199ecf728SChris Fallin     #[inline]
wasm_dwarf(&self) -> &[u8]23299ecf728SChris Fallin     pub fn wasm_dwarf(&self) -> &[u8] {
23399ecf728SChris Fallin         self.original_code.wasm_dwarf()
23499ecf728SChris Fallin     }
23599ecf728SChris Fallin 
236c07c94d2SChris Fallin     /// Returns the original Wasm bytecode section if preserved in the
237c07c94d2SChris Fallin     /// compiled artifact.
238c07c94d2SChris Fallin     #[inline]
wasm_bytecode_for_module(&self, module: StaticModuleIndex) -> Option<&[u8]>239c07c94d2SChris Fallin     pub fn wasm_bytecode_for_module(&self, module: StaticModuleIndex) -> Option<&[u8]> {
240c07c94d2SChris Fallin         self.original_code.wasm_bytecode_for_module(module)
241c07c94d2SChris Fallin     }
242c07c94d2SChris Fallin 
24399ecf728SChris Fallin     /// Returns the raw image as bytes (in our internal image format).
image(&self) -> &[u8]24499ecf728SChris Fallin     pub fn image(&self) -> &[u8] {
24599ecf728SChris Fallin         &self.original_code.mmap()[..]
24699ecf728SChris Fallin     }
24799ecf728SChris Fallin 
text(&self) -> &[u8]24899ecf728SChris Fallin     pub fn text(&self) -> &[u8] {
24999ecf728SChris Fallin         &self.original_code.text()
25099ecf728SChris Fallin     }
25199ecf728SChris Fallin 
25299ecf728SChris Fallin     /// Returns the concatenated list of all data associated with this wasm
25399ecf728SChris Fallin     /// module.
25499ecf728SChris Fallin     ///
25599ecf728SChris Fallin     /// This is used for initialization of memories and all data ranges stored
25699ecf728SChris Fallin     /// in a `Module` are relative to the slice returned here.
25799ecf728SChris Fallin     #[inline]
wasm_data(&self) -> &[u8]25899ecf728SChris Fallin     pub fn wasm_data(&self) -> &[u8] {
25999ecf728SChris Fallin         self.original_code.wasm_data()
26099ecf728SChris Fallin     }
26199ecf728SChris Fallin 
module_memory_image_source(&self) -> &Arc<impl ModuleMemoryImageSource>26299ecf728SChris Fallin     pub(crate) fn module_memory_image_source(&self) -> &Arc<impl ModuleMemoryImageSource> {
26399ecf728SChris Fallin         &self.original_code
26499ecf728SChris Fallin     }
26599ecf728SChris Fallin }
26699ecf728SChris Fallin 
26799ecf728SChris Fallin impl Drop for EngineCode {
drop(&mut self)268d4242001SAdam Bratschi-Kaye     fn drop(&mut self) {
26999ecf728SChris Fallin         crate::module::unregister_code(self.original_code.raw_addr_range());
270d4242001SAdam Bratschi-Kaye     }
271d4242001SAdam Bratschi-Kaye }
272d4242001SAdam Bratschi-Kaye 
273d4242001SAdam Bratschi-Kaye pub enum Types {
274d4242001SAdam Bratschi-Kaye     Module(ModuleTypes),
275d4242001SAdam Bratschi-Kaye     #[cfg(feature = "component-model")]
276d4242001SAdam Bratschi-Kaye     Component(Arc<ComponentTypes>),
277d4242001SAdam Bratschi-Kaye }
278d4242001SAdam Bratschi-Kaye 
279d4242001SAdam Bratschi-Kaye impl Types {
module_types(&self) -> &ModuleTypes280d4242001SAdam Bratschi-Kaye     fn module_types(&self) -> &ModuleTypes {
281d4242001SAdam Bratschi-Kaye         match self {
282d4242001SAdam Bratschi-Kaye             Types::Module(m) => m,
283d4242001SAdam Bratschi-Kaye             #[cfg(feature = "component-model")]
284d4242001SAdam Bratschi-Kaye             Types::Component(c) => c.module_types(),
285d4242001SAdam Bratschi-Kaye         }
286d4242001SAdam Bratschi-Kaye     }
287d4242001SAdam Bratschi-Kaye }
288d4242001SAdam Bratschi-Kaye 
289d4242001SAdam Bratschi-Kaye impl From<ModuleTypes> for Types {
from(types: ModuleTypes) -> Types290d4242001SAdam Bratschi-Kaye     fn from(types: ModuleTypes) -> Types {
291d4242001SAdam Bratschi-Kaye         Types::Module(types)
292d4242001SAdam Bratschi-Kaye     }
293d4242001SAdam Bratschi-Kaye }
294d4242001SAdam Bratschi-Kaye 
295d4242001SAdam Bratschi-Kaye #[cfg(feature = "component-model")]
296d4242001SAdam Bratschi-Kaye impl From<Arc<ComponentTypes>> for Types {
from(types: Arc<ComponentTypes>) -> Types297d4242001SAdam Bratschi-Kaye     fn from(types: Arc<ComponentTypes>) -> Types {
298d4242001SAdam Bratschi-Kaye         Types::Component(types)
299d4242001SAdam Bratschi-Kaye     }
300d4242001SAdam Bratschi-Kaye }
30199ecf728SChris Fallin 
30299ecf728SChris Fallin /// A `Store`-local instance of code.
30399ecf728SChris Fallin ///
30499ecf728SChris Fallin /// This type encapsulates executable code within the context of
30599ecf728SChris Fallin /// instantiation in a single store. It may be an unmodified pointer
30699ecf728SChris Fallin /// to the read-only original code, or it may be locally patched for
30799ecf728SChris Fallin /// this store due to debugging or instrumentation settings.
30899ecf728SChris Fallin ///
30999ecf728SChris Fallin /// Most things that the runtime will want to do with a module's image
31099ecf728SChris Fallin /// will require the `EngineCode` -- all metadata lives there. The
31199ecf728SChris Fallin /// `StoreCode` is solely responsible for the executable machine code.
31299ecf728SChris Fallin ///
31399ecf728SChris Fallin /// This type is designed to be uniquely owned, unlike `EngineCode`
31499ecf728SChris Fallin /// above. The runtime data structures will have scattered `Arc`s to
31599ecf728SChris Fallin /// the `EngineCode` but only one
31699ecf728SChris Fallin pub struct StoreCode(StoreCodeStorage);
31799ecf728SChris Fallin 
31899ecf728SChris Fallin enum StoreCodeStorage {
31999ecf728SChris Fallin     Shared(Arc<CodeMemory>),
32099ecf728SChris Fallin     /// Private copy of the given code memory.
32199ecf728SChris Fallin     ///
32299ecf728SChris Fallin     /// This is the only reference to this CodeMemory. The StoreCode
32399ecf728SChris Fallin     /// is owned directly by the Store's ModuleRegistry.
32499ecf728SChris Fallin     #[cfg(feature = "debug")]
32599ecf728SChris Fallin     Private(Box<CodeMemory>),
32699ecf728SChris Fallin }
32799ecf728SChris Fallin 
32899ecf728SChris Fallin impl StoreCode {
32999ecf728SChris Fallin     /// Create a new StoreCode for a given Store from a given
33099ecf728SChris Fallin     /// EngineCode, given the engine's settings (tunables).
new(engine: &Engine, engine_code: &Arc<EngineCode>) -> Result<Self>33199ecf728SChris Fallin     pub fn new(engine: &Engine, engine_code: &Arc<EngineCode>) -> Result<Self> {
33299ecf728SChris Fallin         // Enabled guest-debugging causes us to allocate private
33399ecf728SChris Fallin         // copies of code in every store, to allow individual enabling
33499ecf728SChris Fallin         // of breakpoints (by code patching) independently in each
33599ecf728SChris Fallin         // one.
33699ecf728SChris Fallin         #[cfg(feature = "debug")]
33799ecf728SChris Fallin         let code = if engine.tunables().debug_guest {
33899ecf728SChris Fallin             // TODO(#12104): we should be able to clone only `.text`;
33999ecf728SChris Fallin             // this clones the whole image.
34099ecf728SChris Fallin             let mut private_copy = engine_code.original_code.deep_clone(engine)?;
34199ecf728SChris Fallin             private_copy.publish()?;
342*6e0ded7cSNick Fitzgerald             crate::module::register_code(
343*6e0ded7cSNick Fitzgerald                 &engine_code.original_code,
344*6e0ded7cSNick Fitzgerald                 private_copy.raw_addr_range(),
345*6e0ded7cSNick Fitzgerald             )?;
34699ecf728SChris Fallin             StoreCodeStorage::Private(Box::new(private_copy))
34799ecf728SChris Fallin         } else {
34899ecf728SChris Fallin             StoreCodeStorage::Shared(engine_code.original_code.clone())
34999ecf728SChris Fallin         };
35099ecf728SChris Fallin 
35199ecf728SChris Fallin         #[cfg(not(feature = "debug"))]
35299ecf728SChris Fallin         let code = StoreCodeStorage::Shared(engine_code.original_code.clone());
35399ecf728SChris Fallin         // Avoid unused-variable warning in build without debugging
35499ecf728SChris Fallin         // support.
35599ecf728SChris Fallin         let _ = engine;
35699ecf728SChris Fallin 
35799ecf728SChris Fallin         Ok(StoreCode(code))
35899ecf728SChris Fallin     }
35999ecf728SChris Fallin 
36099ecf728SChris Fallin     /// Provide the underlying CodeMemory.
code_memory(&self) -> &CodeMemory36199ecf728SChris Fallin     pub fn code_memory(&self) -> &CodeMemory {
36299ecf728SChris Fallin         match &self.0 {
36399ecf728SChris Fallin             StoreCodeStorage::Shared(m) => m,
36499ecf728SChris Fallin             #[cfg(feature = "debug")]
36599ecf728SChris Fallin             StoreCodeStorage::Private(m) => m,
36699ecf728SChris Fallin         }
36799ecf728SChris Fallin     }
36899ecf728SChris Fallin 
36999ecf728SChris Fallin     /// Provide a mutable reference to a CodeMemory that is privately
37099ecf728SChris Fallin     /// owned only by this StoreCode.
37199ecf728SChris Fallin     #[cfg(feature = "debug")]
code_memory_mut(&mut self) -> Option<&mut CodeMemory>37299ecf728SChris Fallin     pub fn code_memory_mut(&mut self) -> Option<&mut CodeMemory> {
37399ecf728SChris Fallin         match &mut self.0 {
37499ecf728SChris Fallin             StoreCodeStorage::Shared(_) => None,
37599ecf728SChris Fallin             StoreCodeStorage::Private(m) => Some(m),
37699ecf728SChris Fallin         }
37799ecf728SChris Fallin     }
37899ecf728SChris Fallin 
37999ecf728SChris Fallin     /// Provide the address range for this StoreCode.
text_range(&self) -> Range<StoreCodePC>38099ecf728SChris Fallin     pub fn text_range(&self) -> Range<StoreCodePC> {
38199ecf728SChris Fallin         let raw = self.code_memory().raw_addr_range();
38299ecf728SChris Fallin         StoreCodePC(raw.start)..StoreCodePC(raw.end)
38399ecf728SChris Fallin     }
38499ecf728SChris Fallin 
38599ecf728SChris Fallin     /// Provide the actual text segment for this StoreCode.
text(&self) -> &[u8]38699ecf728SChris Fallin     pub fn text(&self) -> &[u8] {
38799ecf728SChris Fallin         self.code_memory().text()
38899ecf728SChris Fallin     }
38999ecf728SChris Fallin }
39099ecf728SChris Fallin 
39199ecf728SChris Fallin impl Drop for StoreCode {
drop(&mut self)39299ecf728SChris Fallin     fn drop(&mut self) {
39399ecf728SChris Fallin         match &self.0 {
39499ecf728SChris Fallin             StoreCodeStorage::Shared(_) => {
39599ecf728SChris Fallin                 // Drop impl for EngineCode will de-register (see
39699ecf728SChris Fallin                 // above).
39799ecf728SChris Fallin             }
39899ecf728SChris Fallin             #[cfg(feature = "debug")]
39999ecf728SChris Fallin             StoreCodeStorage::Private(mem) => {
40099ecf728SChris Fallin                 crate::module::unregister_code(mem.raw_addr_range());
40199ecf728SChris Fallin             }
40299ecf728SChris Fallin         }
40399ecf728SChris Fallin     }
40499ecf728SChris Fallin }
40599ecf728SChris Fallin 
40699ecf728SChris Fallin /// A wrapper for a Module together with a StoreCode. Allows fetching
40799ecf728SChris Fallin /// code pointers, ready to call.
40899ecf728SChris Fallin pub struct ModuleWithCode<'a> {
40999ecf728SChris Fallin     module: &'a Module,
41099ecf728SChris Fallin     store_code: &'a StoreCode,
41199ecf728SChris Fallin }
41299ecf728SChris Fallin 
41399ecf728SChris Fallin impl<'a> ModuleWithCode<'a> {
41499ecf728SChris Fallin     /// Find the StoreCode in a given store for a module and wrap it
41599ecf728SChris Fallin     /// up with that module, ready to compute code pointers.
in_store( registry: &'a ModuleRegistry, module: &'a Module, ) -> Option<ModuleWithCode<'a>>41699ecf728SChris Fallin     pub fn in_store(
41799ecf728SChris Fallin         registry: &'a ModuleRegistry,
41899ecf728SChris Fallin         module: &'a Module,
41999ecf728SChris Fallin     ) -> Option<ModuleWithCode<'a>> {
42099ecf728SChris Fallin         let store_code = registry.store_code(module.engine_code())?;
42199ecf728SChris Fallin         Some(ModuleWithCode { module, store_code })
42299ecf728SChris Fallin     }
42399ecf728SChris Fallin 
from_raw(module: &'a Module, store_code: &'a StoreCode) -> ModuleWithCode<'a>42499ecf728SChris Fallin     pub(crate) fn from_raw(module: &'a Module, store_code: &'a StoreCode) -> ModuleWithCode<'a> {
42599ecf728SChris Fallin         ModuleWithCode { module, store_code }
42699ecf728SChris Fallin     }
42799ecf728SChris Fallin 
42899ecf728SChris Fallin     /// Provide the Module wrapped in this tuple.
module(&self) -> &'a Module42999ecf728SChris Fallin     pub fn module(&self) -> &'a Module {
43099ecf728SChris Fallin         self.module
43199ecf728SChris Fallin     }
43299ecf728SChris Fallin 
43399ecf728SChris Fallin     /// Provide the StoreCode wrapped in this tuple.
store_code(&self) -> &'a StoreCode43499ecf728SChris Fallin     pub fn store_code(&self) -> &'a StoreCode {
43599ecf728SChris Fallin         self.store_code
43699ecf728SChris Fallin     }
43799ecf728SChris Fallin 
43899ecf728SChris Fallin     /// Returns an iterator over all functions defined within this module with
43999ecf728SChris Fallin     /// their index and their raw pointer.
44099ecf728SChris Fallin     #[inline]
finished_functions( &self, ) -> impl ExactSizeIterator<Item = (DefinedFuncIndex, &[u8])> + '_44199ecf728SChris Fallin     pub fn finished_functions(
44299ecf728SChris Fallin         &self,
44399ecf728SChris Fallin     ) -> impl ExactSizeIterator<Item = (DefinedFuncIndex, &[u8])> + '_ {
44499ecf728SChris Fallin         self.module
44599ecf728SChris Fallin             .env_module()
44699ecf728SChris Fallin             .defined_func_indices()
44799ecf728SChris Fallin             .map(|i| (i, self.finished_function(i)))
44899ecf728SChris Fallin     }
44999ecf728SChris Fallin 
45099ecf728SChris Fallin     /// Returns the slice in the text section of the function that
45199ecf728SChris Fallin     /// `index` points to.
45299ecf728SChris Fallin     #[inline]
finished_function(&self, def_func_index: DefinedFuncIndex) -> &[u8]45399ecf728SChris Fallin     pub fn finished_function(&self, def_func_index: DefinedFuncIndex) -> &[u8] {
45499ecf728SChris Fallin         let range = self
45599ecf728SChris Fallin             .module
45699ecf728SChris Fallin             .compiled_module()
45799ecf728SChris Fallin             .finished_function_range(def_func_index);
45899ecf728SChris Fallin         &self.store_code.text()[range]
45999ecf728SChris Fallin     }
46099ecf728SChris Fallin 
46199ecf728SChris Fallin     /// Get the array-to-Wasm trampoline for the function `index`
46299ecf728SChris Fallin     /// points to, as a slice of raw code that can be converted to a
46399ecf728SChris Fallin     /// callable function pointer.
46499ecf728SChris Fallin     ///
46599ecf728SChris Fallin     /// If the function `index` points to does not escape, then `None` is
46699ecf728SChris Fallin     /// returned.
46799ecf728SChris Fallin     ///
46899ecf728SChris Fallin     /// These trampolines are used for array callers (e.g. `Func::new`)
46999ecf728SChris Fallin     /// calling Wasm callees.
array_to_wasm_trampoline(&self, def_func_index: DefinedFuncIndex) -> Option<&[u8]>47099ecf728SChris Fallin     pub fn array_to_wasm_trampoline(&self, def_func_index: DefinedFuncIndex) -> Option<&[u8]> {
47199ecf728SChris Fallin         let range = self
47299ecf728SChris Fallin             .module
47399ecf728SChris Fallin             .compiled_module()
47499ecf728SChris Fallin             .array_to_wasm_trampoline_range(def_func_index)?;
47599ecf728SChris Fallin         Some(&self.store_code.text()[range])
47699ecf728SChris Fallin     }
47799ecf728SChris Fallin 
47899ecf728SChris Fallin     /// Get the text offset (relative PC) for a given absolute PC in
47999ecf728SChris Fallin     /// this module.
48017fbd3c6SChris Fallin     #[cfg(feature = "gc")]
text_offset(&self, pc: usize) -> Option<u32>48199ecf728SChris Fallin     pub(crate) fn text_offset(&self, pc: usize) -> Option<u32> {
48299ecf728SChris Fallin         StoreCodePC::offset_of(self.store_code.text_range(), pc)
48399ecf728SChris Fallin             .map(|offset| u32::try_from(offset).expect("Module larger than 4GiB"))
48499ecf728SChris Fallin     }
48599ecf728SChris Fallin 
48699ecf728SChris Fallin     /// Lookup the stack map at a program counter value.
48799ecf728SChris Fallin     #[cfg(feature = "gc")]
lookup_stack_map(&self, pc: usize) -> Option<wasmtime_environ::StackMap<'_>>48899ecf728SChris Fallin     pub(crate) fn lookup_stack_map(&self, pc: usize) -> Option<wasmtime_environ::StackMap<'_>> {
48999ecf728SChris Fallin         let text_offset = self.text_offset(pc)?;
49099ecf728SChris Fallin         let info = self.module.engine_code().stack_map_data();
49199ecf728SChris Fallin         wasmtime_environ::StackMap::lookup(text_offset, info)
49299ecf728SChris Fallin     }
49399ecf728SChris Fallin }
494