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