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<()>;
fn as_ptr(&self) -> *mut u8;
// Provided method
fn init_from_image(&mut self, image: &MemoryImage) -> Result<bool> { ... }
}runtime only.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_sizebytes starting at theas_ptrmemory 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_sizemust be at leastminimumafter creation and at leastnew_sizeafter a successful call togrow_to, and it must never decrease. -
Base pointer stability. A call to
as_ptrmust return the same address until the next successful call togrow_to. Moreover, a successfulgrow_to(new_size)call wherenew_sizeis at most thebyte_capacityreported before the call must not change the result ofas_ptr. If static memory is forced (e.g. when using shared memory or whenConfig::memory_may_moveis disabled), Wasmtime will never ask the memory to grow beyond itsbyte_capacity. -
Base pointer alignment. The base pointer returned by
as_ptrmust always be 8-byte aligned. Moreover, ifguard_size_in_bytesis non-zero, orreserved_size_in_bytesisSomeand non-zero, thenas_ptrmust be aligned to the host page size at all times. -
Inaccessible region. If:
guard_size_in_bytesis non-zero, orreserved_size_in_bytesisSomeand non-zero; then every byte fromas_ptr() + byte_size(), rounded up to the next host page boundary, up toas_ptr() + max(reserved_size_in_bytes, byte_size()) + guard_size_in_bytesmust 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_sizeshould be exactlyminimumafter creation and exactlynew_sizeafter a successful call togrow_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_tomust be zeroed. -
If
init_from_imagereturnsOk(true), then the bytes atMemoryImage::linear_memory_offsetmust equal the image and all other bytes must be zero.
Required Methods§
Sourcefn byte_size(&self) -> usize
fn byte_size(&self) -> usize
Returns the number of allocated bytes which are accessible at this time.
Sourcefn byte_capacity(&self) -> usize
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.
Provided Methods§
Sourcefn init_from_image(&mut self, image: &MemoryImage) -> Result<bool>
fn init_from_image(&mut self, image: &MemoryImage) -> Result<bool>
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".