pub struct ModuleTranslation<'data> {Show 23 fields
pub module: Module,
pub wasm: &'data [u8],
pub wasm_module_offset: u64,
pub function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
pub known_imported_functions: SecondaryMap<FuncIndex, Option<KnownFunc>>,
pub known_imported_globals: SecondaryMap<GlobalIndex, Option<KnownGlobal>>,
pub known_imported_memories: SecondaryMap<MemoryIndex, Option<KnownEntity<DefinedMemoryIndex>>>,
pub known_imported_tables: SecondaryMap<TableIndex, Option<KnownEntity<DefinedTableIndex>>>,
pub globals_known_to_importers: EntitySet<DefinedGlobalIndex>,
pub memories_known_to_importers: EntitySet<DefinedMemoryIndex>,
pub tables_known_to_importers: EntitySet<DefinedTableIndex>,
pub exported_signatures: Vec<ModuleInternedTypeIndex>,
pub debuginfo: DebugInfoData<'data>,
pub has_unparsed_debuginfo: bool,
pub data_align: Option<u64>,
pub runtime_data_map: SecondaryMap<DataIndex, Option<RuntimeDataIndex>>,
pub passive_elem_map: SecondaryMap<ElemIndex, Option<PassiveElemIndex>>,
pub runtime_data: PrimaryMap<RuntimeDataIndex, Cow<'data, [u8]>>,
pub start_func: Option<FuncIndex>,
pub global_initializers: Vec<(DefinedGlobalIndex, ConstExpr)>,
pub passive_elements: PrimaryMap<PassiveElemIndex, TableSegmentElements>,
pub table_initialization: TableInitialization,
pub memory_init: MemoryInit<'data>,
/* private fields */
}Expand description
The result of translating via ModuleEnvironment.
Function bodies are not yet translated, and data initializers have not yet been copied out of the original buffer.
Fields§
§module: ModuleModule information.
wasm: &'data [u8]The input wasm binary.
This can be useful, for example, when modules are parsed from a component and the embedder wants access to the raw wasm modules themselves.
wasm_module_offset: u64The byte offset of this module’s Wasm binary within the outer binary (e.g. a component). For standalone modules this is 0. This is used to convert component-relative source locations to module-relative source locations.
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>References to the function bodies.
known_imported_functions: SecondaryMap<FuncIndex, Option<KnownFunc>>For each imported function, the single statically-known function that always satisfies that import, if any.
This is used to turn what would otherwise be indirect calls through the imports table into direct calls, when possible.
When filled in, this only ever contains
FuncKey::DefinedWasmFunction(..)s, FuncKey::Intrinsic(..)s, and
FuncKey::FactInlineIntrinsics.
known_imported_globals: SecondaryMap<GlobalIndex, Option<KnownGlobal>>For each imported global, memory, or table, the single statically-known defined entity that always satisfies that import, if any.
This is used to access the entity via the defining module’s precise
AliasRegionKey::Defined{Global,Memory,Table} region instead of the
conservative AliasRegionKey::Public{Global,Memory,Table} region that is
shared by every entity of that kind which crosses a module boundary.
XXX: Being “known” requires more here than it does for functions: it is not enough that this module’s import is always the same entity, every module that may import that entity must also always import that same entity. Otherwise a function from one of those other modules, which accesses the entity via the conservative region, could be inlined next to one of our accesses via the precise region, and accessing the same memory through two different alias regions is invalid.
This extra condition is an artifact of this implementation, and how we consume this data to choose the alias region for loads and stores to a global/memory/table, not something inherent to knowing exactly which entity satisfies a particular import. Really, there are two independent axes here:
-
Is this import always satisfied by the same defined entity?
-
Is that entity’s identity additionally known to every other module that may import it?
Only alias regions need (2), but other theoretical optimizations could
be perfectly happy with just (1). For example, if we know that an import
of an immutable global is always a particular defined global, then we
could inline that global’s value at each global.get of the import,
regardless what any other module does or does not know about that
global.
TODO(#14164): Actually record (1) and (2) in separate maps, enabling optimizations that rely on just (1) but not (2), instead of folding them into this same map.
known_imported_memories: SecondaryMap<MemoryIndex, Option<KnownEntity<DefinedMemoryIndex>>>Same as known_imported_globals, but for memories.
known_imported_tables: SecondaryMap<TableIndex, Option<KnownEntity<DefinedTableIndex>>>Same as known_imported_globals, but for tables.
globals_known_to_importers: EntitySet<DefinedGlobalIndex>For each global defined by this module, whether every module that may import this global always imports exactly this global.
When this holds, accesses of the global may use its precise
AliasRegionKey::DefinedGlobal region even when the global is exported,
because every module that can reach it agrees on that same region. This
is vacuously true of globals that nothing in the component imports.
This can only be determined by looking at the whole component, so it is
always false for standalone modules.
memories_known_to_importers: EntitySet<DefinedMemoryIndex>Same as Self::globals_known_to_importers, but for memories.
tables_known_to_importers: EntitySet<DefinedTableIndex>Same as Self::globals_known_to_importers, but for tables.
exported_signatures: Vec<ModuleInternedTypeIndex>A list of type signatures which are considered exported from this module, or those that can possibly be called. This list is sorted, and trampolines for each of these signatures are required.
debuginfo: DebugInfoData<'data>DWARF debug information, if enabled, parsed from the module.
has_unparsed_debuginfo: boolSet if debuginfo was found but it was not parsed due to Tunables
configuration.
data_align: Option<u64>The desired alignment of data in the final data section of the object
file that we’ll emit.
Note that this is 1 by default but MemoryInitialization::Static might
switch this to a higher alignment to facilitate mmap-ing data from
an object file into a linear memory.
runtime_data_map: SecondaryMap<DataIndex, Option<RuntimeDataIndex>>Map from a data segment to whether it’s a passive data segment or not.
passive_elem_map: SecondaryMap<ElemIndex, Option<PassiveElemIndex>>Map from an elem segment to whether it’s a passive elem segment or not.
runtime_data: PrimaryMap<RuntimeDataIndex, Cow<'data, [u8]>>List of passive element segments found in this module which will get concatenated for the final artifact.
start_func: Option<FuncIndex>The WebAssembly start function, if defined.
global_initializers: Vec<(DefinedGlobalIndex, ConstExpr)>Initializers for global values which aren’t considered “simple”.
These initializers are later compiled into a “module startup” function.
passive_elements: PrimaryMap<PassiveElemIndex, TableSegmentElements>Definitions of all passive elements found within a module.
This maps passive element segments to their definition, either functions or expressions-basd.
table_initialization: TableInitializationWebAssembly table initialization data, per table.
This keeps track of all per-table initialization (e.g. initial value for
non-null tables) as well as active element segments. This is processed
and refined by ModuleTranslation::finalize_table_init after
translation.
memory_init: MemoryInit<'data>WebAssembly memory initialization.
This is held here in an Unprocessed form during translation, and then
this is later finished with ModuleTranslation::finalize_memory_init.
Implementations§
Source§impl<'data> ModuleTranslation<'data>
impl<'data> ModuleTranslation<'data>
Sourcepub fn new(module_index: StaticModuleIndex) -> Self
pub fn new(module_index: StaticModuleIndex) -> Self
Create a new translation for the module with the given index.
Sourcepub fn branch_hints(&self, func: FuncIndex) -> Option<BranchHintReader<'data>>
pub fn branch_hints(&self, func: FuncIndex) -> Option<BranchHintReader<'data>>
Returns the BranchHintReader for func, if the section attached any.
Sourcepub fn get_types(&self) -> &Types
pub fn get_types(&self) -> &Types
Returns a reference to the type information of the current module.
Sourcepub fn module_index(&self) -> StaticModuleIndex
pub fn module_index(&self) -> StaticModuleIndex
Get this translation’s module’s index.
Source§impl ModuleTranslation<'_>
impl ModuleTranslation<'_>
Sourcepub fn finalize_memory_init(
&mut self,
tunables: &Tunables,
page_size: u64,
max_image_size_always_allowed: u64,
types: &mut ModuleTypesBuilder,
)
pub fn finalize_memory_init( &mut self, tunables: &Tunables, page_size: u64, max_image_size_always_allowed: u64, types: &mut ModuleTypesBuilder, )
Called after translation is complete this will finalize the memory initialization strategy for this module.
This will notably use Self::try_static_init to attempt to massage
data segments to being CoW-init-friendly. Afterwards the
self.memory_init field is transitioned from Unprocessed to
Processed.
Sourcepub fn finalize_table_init(
&mut self,
tunables: &Tunables,
types: &mut ModuleTypesBuilder,
)
pub fn finalize_table_init( &mut self, tunables: &Tunables, types: &mut ModuleTypesBuilder, )
Finalizes the initialization of tables.
This is invoked after translation and notably uses
Self::try_func_table_init to attempt to optimize initialization of
tables into static precomputed images.