1 use crate::ValRaw; 2 use core::mem::{self, MaybeUninit}; 3 use core::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 MaybeUninit<T>) -> &mut [MaybeUninit<ValRaw>] { 23 assert_raw_slice_compat::<T>(); 24 25 slice::from_raw_parts_mut( 26 (storage as *mut MaybeUninit<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!( 41 mem::size_of_val(slice) >= mem::size_of::<T>(), 42 "needed {}; got {}", 43 mem::size_of::<T>(), 44 mem::size_of_val(slice) 45 ); 46 47 &mut *slice.as_mut_ptr().cast() 48 } 49 50 /// Same as `storage_as_slice`, but in reverse 51 #[cfg(feature = "component-model-async")] 52 pub unsafe fn slice_to_storage<T>(slice: &[ValRaw]) -> &T { 53 assert_raw_slice_compat::<T>(); 54 55 // See notes above in `slice_to_storage_mut` about how this is an actual 56 // runtime assertion. 57 assert!( 58 mem::size_of_val(slice) >= mem::size_of::<T>(), 59 "needed {}; got {}", 60 mem::size_of::<T>(), 61 mem::size_of_val(slice) 62 ); 63 64 &*slice.as_ptr().cast() 65 } 66