wasmtime/runtime/component/
storage.rs

1use crate::ValRaw;
2use core::mem::{self, MaybeUninit};
3use core::slice;
4
5fn assert_raw_slice_compat<T>() {
6    assert!(mem::size_of::<T>() % mem::size_of::<ValRaw>() == 0);
7    assert!(mem::align_of::<T>() == mem::align_of::<ValRaw>());
8}
9
10/// Converts a `<T as ComponentType>::Lower` representation to a slice of
11/// `ValRaw`.
12pub unsafe fn storage_as_slice<T>(storage: &T) -> &[ValRaw] {
13    assert_raw_slice_compat::<T>();
14
15    slice::from_raw_parts(
16        (storage as *const T).cast(),
17        mem::size_of_val(storage) / mem::size_of::<ValRaw>(),
18    )
19}
20
21/// Same as `storage_as_slice`, but mutable.
22pub unsafe fn storage_as_slice_mut<T>(storage: &mut T) -> &mut [ValRaw] {
23    assert_raw_slice_compat::<T>();
24
25    slice::from_raw_parts_mut(
26        (storage as *mut T).cast(),
27        mem::size_of_val(storage) / mem::size_of::<ValRaw>(),
28    )
29}
30
31/// Same as `storage_as_slice`, but in reverse and mutable.
32pub unsafe fn slice_to_storage_mut<T>(slice: &mut [MaybeUninit<ValRaw>]) -> &mut MaybeUninit<T> {
33    assert_raw_slice_compat::<T>();
34
35    // This is an actual runtime assertion which if performance calls for we may
36    // need to relax to a debug assertion. This notably tries to ensure that we
37    // stay within the bounds of the number of actual values given rather than
38    // reading past the end of an array. This shouldn't actually trip unless
39    // there's a bug in Wasmtime though.
40    assert!(mem::size_of_val(slice) >= mem::size_of::<T>());
41
42    &mut *slice.as_mut_ptr().cast()
43}