1 use crate::ValRaw;
2 use std::mem::{self, MaybeUninit};
3 use std::slice;
4 
5 fn 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`.
12 pub 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.
22 pub 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.
32 pub 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 }
44