nanvm_lib/mem/
field_layout.rs1use core::{
2 alloc::Layout,
3 marker::PhantomData,
4 mem::{align_of, size_of},
5};
6
7use crate::common::usize::max;
8
9pub struct FieldLayout<T, A> {
10 pub align: usize,
11 pub size: usize,
12 _0: PhantomData<(T, A)>,
13}
14
15pub const fn align_to(i: usize, align: usize) -> usize {
16 let mask = align - 1;
17 (i + mask) & !mask
18}
19
20impl<T, A> FieldLayout<T, A> {
21 pub const fn align_to(adjacent_align: usize) -> FieldLayout<T, A> {
22 assert!(adjacent_align.is_power_of_two());
23 assert!(adjacent_align >= align_of::<A>());
24 FieldLayout {
25 align: max(align_of::<T>(), adjacent_align),
26 size: align_to(size_of::<T>(), adjacent_align),
27 _0: PhantomData,
28 }
29 }
30 #[inline(always)]
31 pub const unsafe fn to_adjacent(&self, r: &T) -> *const A {
32 unsafe { (r as *const T).byte_add(self.size) as *const _ }
33 }
34 #[inline(always)]
35 pub unsafe fn into_adjacent_mut(self, r: &mut T) -> *mut A {
36 unsafe { (r as *mut T).byte_add(self.size) as *mut _ }
37 }
38 #[allow(clippy::wrong_self_convention)]
39 #[inline(always)]
40 pub unsafe fn from_adjacent_mut(self, r: &mut A) -> *mut T {
41 unsafe { (r as *mut A).byte_sub(self.size) as *mut _ }
42 }
43 #[inline(always)]
44 pub const fn layout(&self, a_size: usize) -> Layout {
45 unsafe { Layout::from_size_align_unchecked(self.size + a_size, self.align) }
46 }
47}
48
49#[cfg(test)]
50mod test {
51 use wasm_bindgen_test::wasm_bindgen_test;
52
53 use super::FieldLayout;
54
55 const _A_4_1: FieldLayout<u32, u8> = FieldLayout::align_to(1);
56 const _: () = assert!(_A_4_1.align == 4 && _A_4_1.size == 4);
57
58 const _A_4_8: FieldLayout<u32, u8> = FieldLayout::align_to(8);
59 const _: () = assert!(_A_4_8.align == 8 && _A_4_8.size == 8);
60
61 const _A_1_4: FieldLayout<[u8; 3], u8> = FieldLayout::align_to(4);
62 const _: () = assert!(_A_1_4.align == 4 && _A_1_4.size == 4);
63
64 #[test]
65 #[should_panic]
66 #[wasm_bindgen_test]
67 fn test_invalid_align1() {
68 FieldLayout::<u32, u8>::align_to(3);
69 }
70
71 #[test]
72 #[should_panic]
73 #[wasm_bindgen_test]
74 fn test_invalid_align2() {
75 FieldLayout::<u32, u16>::align_to(1);
76 }
77}