pub enum MemoryInitialization {
    Segmented(Vec<MemoryInitializer>),
    Paged {
        map: PrimaryMap<MemoryIndex, Vec<StaticMemoryInitializer>>,
    },
    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.

Paged

Fields

map: PrimaryMap<MemoryIndex, Vec<StaticMemoryInitializer>>

The map of defined memory index to a list of initialization pages.

The list of page data is sparse, with each element starting with the offset in memory where it will be placed (specified here, as a page index, with a u64). Each page of initialization data is WebAssembly page-sized (64 KiB). Pages whose offset are not specified in this array start with 0s in memory. The Range indices, like those in MemoryInitializer, point within a data segment that will come as an auxiliary descriptor with other data such as the compiled code for the wasm module.

Memory initialization is paged.

To be paged, the following requirements must be met:

  • All data segments must reference defined memories.
  • All data segments must not use a global base.

Paged initialization is performed by copying (or mapping) entire WebAssembly pages to each linear memory.

The uffd feature makes use of this type of memory initialization because it can instruct the kernel to back an entire WebAssembly page from an existing set of in-memory pages.

By processing the data segments at module compilation time, the uffd fault handler doesn’t have to do any work to point the kernel at the right linear memory page to use.

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 the same requirements as Paged must be met, namely that everything references a dfeined memory and all data segments have a staitcally 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 fo 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

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

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

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

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

Deserialize this value from the given Serde deserializer. Read more

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.