Skip to main content

ModuleTranslation

Struct ModuleTranslation 

Source
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: Module

Module 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: u64

The 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:

  1. Is this import always satisfied by the same defined entity?

  2. 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: bool

Set 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: TableInitialization

WebAssembly 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>

Source

pub fn new(module_index: StaticModuleIndex) -> Self

Create a new translation for the module with the given index.

Source

pub fn branch_hints(&self, func: FuncIndex) -> Option<BranchHintReader<'data>>

Returns the BranchHintReader for func, if the section attached any.

Source

pub fn get_types(&self) -> &Types

Returns a reference to the type information of the current module.

Source

pub fn module_index(&self) -> StaticModuleIndex

Get this translation’s module’s index.

Source§

impl ModuleTranslation<'_>

Source

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.

Source

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.

Auto Trait Implementations§

§

impl<'data> Freeze for ModuleTranslation<'data>

§

impl<'data> RefUnwindSafe for ModuleTranslation<'data>

§

impl<'data> Send for ModuleTranslation<'data>

§

impl<'data> Sync for ModuleTranslation<'data>

§

impl<'data> Unpin for ModuleTranslation<'data>

§

impl<'data> UnsafeUnpin for ModuleTranslation<'data>

§

impl<'data> UnwindSafe for ModuleTranslation<'data>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.