Skip to main content

LinearMemory

Trait LinearMemory 

Source
pub unsafe trait LinearMemory:
    Any
    + Send
    + Sync {
    // Required methods
    fn byte_size(&self) -> usize;
    fn byte_capacity(&self) -> usize;
    fn grow_to(&mut self, new_size: usize) -> Result<(), Error>;
    fn as_ptr(&self) -> *mut u8;

    // Provided method
    fn init_from_image(&mut self, image: &MemoryImage) -> Result<bool, Error> { ... }
}
Expand description

A linear memory. This trait provides an interface for raw memory buffers which are used by wasmtime, e.g. inside [‘Memory’]. Such buffers are in principle not thread safe. By implementing this trait together with MemoryCreator, one can supply wasmtime with custom allocated host managed memory.

Note that this is a relatively advanced feature and it is recommended to be familiar with wasmtime runtime code to use it.

In the following, minimum, reserved_size_in_bytes, and guard_size_in_bytes arguments are given to a MemoryCreator::new_memory implementation.

§Safety

Wasmtime’s compiled code and runtime rely on the following invariants for memory safety. Note that while we strive to be thorough in this documentation, we do not guarantee that the following points are exhaustive. When using a custom memory backend in a security-sensitive context auditing just the external implementation of this trait is not sufficient.

  • Valid region. From creation until the memory is dropped, the first byte_size bytes starting at the as_ptr memory location must be allocated, initialized, readable, and writeable. The pointer must be non-null. Nothing other than Wasmtime may read, write, unmap, or otherwise modify this region while the memory is in use by Wasmtime. If the memory moves (although see conditions on stability below), the previous region is no longer in use by Wasmtime. Moreover, be aware that Wasmtime currently has a soundness hole for shared memory, as multiple threads may access the same slice of memory mutably at the same time (aliasing) (see issue #4203).

  • Size. byte_size must be at least minimum after creation and at least new_size after a successful call to grow_to, and it must never decrease.

  • Base pointer stability. A call to as_ptr must return the same address until the next successful call to grow_to. Moreover, a successful grow_to(new_size) call where new_size is at most the byte_capacity reported before the call must not change the result of as_ptr. If static memory is forced (e.g. when using shared memory or when Config::memory_may_move is disabled), Wasmtime will never ask the memory to grow beyond its byte_capacity.

  • Base pointer alignment. The base pointer returned by as_ptr must always be 8-byte aligned. Moreover, if guard_size_in_bytes is non-zero, or reserved_size_in_bytes is Some and non-zero, then as_ptr must be aligned to the host page size at all times.

  • Inaccessible region. If: guard_size_in_bytes is non-zero, or reserved_size_in_bytes is Some and non-zero; then every byte from as_ptr() + byte_size(), rounded up to the next host page boundary, up to as_ptr() + max(reserved_size_in_bytes, byte_size()) + guard_size_in_bytes must be inaccessible, so that any access to it faults. This must hold at all times, including after growth.

Additionally, observe the safety requirements when the memory is accessed, as explained in Memory.

§Correctness

The following constraints do not cause memory safety issues, but break WebAssembly semantics, or expose potentially unwanted data to WebAssembly programs:

  • byte_size should be exactly minimum after creation and exactly new_size after a successful call to grow_to(new_size). Wasmtime only requests sizes that are multiples of the Wasm page size.

  • The memory’s contents must be zeroed at creation, and bytes made accessible by grow_to must be zeroed.

  • If init_from_image returns Ok(true), then the bytes at MemoryImage::linear_memory_offset must equal the image and all other bytes must be zero.

Required Methods§

Source

fn byte_size(&self) -> usize

Returns the number of allocated bytes which are accessible at this time.

Source

fn byte_capacity(&self) -> usize

Returns byte capacity of this linear memory’s current allocation.

Growth up to this value should not relocate the linear memory base pointer.

Source

fn grow_to(&mut self, new_size: usize) -> Result<(), Error>

Grows this memory to have the new_size, in bytes, specified.

Returns Err if memory can’t be grown by the specified amount of bytes. The error may be downcastable to std::io::Error. Returns Ok if memory was grown successfully.

Source

fn as_ptr(&self) -> *mut u8

Return the allocated memory as a mutable pointer to u8.

Provided Methods§

Source

fn init_from_image(&mut self, image: &MemoryImage) -> Result<bool, Error>

Optionally initializes this memory’s contents from a copy-on-write MemoryImage.

When copy-on-write memory initialization is enabled and a module’s data segments for this memory can be represented as an image, Wasmtime calls this method once, right after the memory is created and before anything else reads or writes it.

If the function succeeds with false, the runtime assumes the memory was not initialized. It then fully copies the module’s data segments into the memory region. This is always correct and is essentially equivalent to CoW being disabled.

If the function succeeds with true, the runtime assumes the memory’s contents match image exactly. The bytes of the image must start at MemoryImage::linear_memory_offset and all other bytes must be zero.

§Shortcut for memory maps

MemoryImage exposes a shortcut, MemoryImage::map_at, which allows an implementation backed by a memory map to replace a portion of its mapping with the pages of the image. Consult that function’s documentation for safety notes.

Returning an error causes instantiation to fail with that error.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§