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

source

pub fn is_segmented(&self) -> bool

Returns whether this initialization is of the form MemoryInitialization::Segmented.

source

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 is u64. A None 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.

Trait Implementations§

source§

impl Debug for MemoryInitialization

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for MemoryInitialization

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<'de> Deserialize<'de> for MemoryInitialization

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Serialize for MemoryInitialization

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

const: unstable · source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

const: unstable · 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, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

impl<T> DeserializeOwned for Twhere T: for<'de> Deserialize<'de>,