pub enum MemoryInitialization {
Segmented(Vec<MemoryInitializer>),
Static {
map: PrimaryMap<MemoryIndex, Option<StaticMemoryInitializer>>,
},
}
Expand description
The type of WebAssembly linear memory initialization to use for a module.
Variants§
Segmented(Vec<MemoryInitializer>)
Memory initialization is segmented.
Segmented initialization can be used for any module, but it is required if:
- A data segment referenced an imported memory.
- A data segment uses a global base.
Segmented initialization is performed by processing the complete set of data segments when the module is instantiated.
This is the default memory initialization type.
Static
Fields
map: PrimaryMap<MemoryIndex, Option<StaticMemoryInitializer>>
The initialization contents for each linear memory.
This array has, for each module’s own linear memory, the contents
necessary to initialize it. If the memory has a None
value then no
initialization is necessary (it’s zero-filled). Otherwise with
Some
the first element of the tuple is the offset in memory to
start the initialization and the Range
is the range within the
final data section of the compiled module of bytes to copy into the
memory.
The offset, range base, and range end are all guaranteed to be page
aligned to the page size passed in to try_static_init
.
Memory initialization is statically known and involves a single memcpy
or otherwise simply making the defined data visible.
To be statically initialized everything must reference a defined memory and all data segments have a statically known in-bounds base (no globals).
This form of memory initialization is a more optimized version of
Segmented
where memory can be initialized with one of a few methods:
- First it could be initialized with a single
memcpy
of data from the module to the linear memory. - Otherwise techniques like
mmap
are also possible to make this data, which might reside in a compiled module on disk, available immediately in a linear memory’s address space.
To facilitate the latter of these techniques the try_static_init
function below, which creates this variant, takes a host page size
argument which can page-align everything to make mmap-ing possible.
Implementations§
source§impl MemoryInitialization
impl MemoryInitialization
sourcepub fn is_segmented(&self) -> bool
pub fn is_segmented(&self) -> bool
Returns whether this initialization is of the form
MemoryInitialization::Segmented
.
sourcepub fn init_memory(
&self,
state: InitMemory<'_>,
write: &mut dyn FnMut(MemoryIndex, &StaticMemoryInitializer) -> bool
) -> bool
pub fn init_memory( &self, state: InitMemory<'_>, write: &mut dyn FnMut(MemoryIndex, &StaticMemoryInitializer) -> bool ) -> bool
Performs the memory initialization steps for this set of initializers.
This will perform wasm initialization in compliance with the wasm spec and how data segments are processed. This doesn’t need to necessarily only be called as part of initialization, however, as it’s structured to allow learning about memory ahead-of-time at compile time possibly.
The various callbacks provided here are used to drive the smaller bits of initialization, such as:
-
get_cur_size_in_pages
- gets the current size, in wasm pages, of the memory specified. For compile-time purposes this would be the memory type’s minimum size. -
get_global
- gets the value of the global specified. This is statically, via validation, a pointer to the global of the correct type (either u32 or u64 depending on the memory), but the value returned here isu64
. ANone
value can be returned to indicate that the global’s value isn’t known yet. -
write
- a callback used to actually write data. This indicates that the specified memory must receive the specified range of data at the specified offset. This can internally return an false error if it wants to fail.
This function will return true if all memory initializers are processed
successfully. If any initializer hits an error or, for example, a
global value is needed but None
is returned, then false will be
returned. At compile-time this typically means that the “error” in
question needs to be deferred to runtime, and at runtime this means
that an invalid initializer has been found and a trap should be
generated.