nanvm-lib 0.1.1

NaNVM library
Documentation
use super::{constructor::Constructor, object::Object};

#[repr(transparent)]
#[derive(Debug)]
pub struct Fixed<T>(pub T);

impl<T> Object for Fixed<T> {}

impl<T> Constructor for Fixed<T> {
    type Result = Fixed<T>;
    #[inline(always)]
    fn result_size(&self) -> usize {
        Self::Result::object_size(self)
    }
    #[inline(always)]
    unsafe fn construct(self, p: *mut Self::Result) {
        p.write(self);
    }
}

#[cfg(test)]
mod test {
    use core::{
        mem::forget,
        ptr::null,
        sync::atomic::{AtomicIsize, Ordering},
    };

    use wasm_bindgen_test::wasm_bindgen_test;

    use super::{Fixed, *};

    #[test]
    #[wasm_bindgen_test]
    fn test_object() {
        let a = Fixed(5);
        assert_eq!(a.object_size(), 4);
    }

    struct X<'a>(&'a AtomicIsize);

    impl Object for X<'_> {}

    impl Drop for X<'_> {
        fn drop(&mut self) {
            self.0.fetch_add(1, Ordering::Relaxed);
        }
    }

    #[test]
    #[wasm_bindgen_test]
    fn test_object_drop_in_place() {
        let a = AtomicIsize::new(5);
        {
            let mut x = X(&a);
            unsafe { x.object_drop() };
            assert_eq!(a.load(Ordering::Relaxed), 6);
            forget(x);
        }
        assert_eq!(a.load(Ordering::Relaxed), 6);
    }

    struct Y(*const AtomicIsize);

    impl Drop for Y {
        fn drop(&mut self) {
            unsafe { (*self.0).fetch_add(1, Ordering::Relaxed) };
        }
    }

    #[test]
    #[wasm_bindgen_test]
    fn test_fixed_object_drop_in_place() {
        let a = AtomicIsize::new(5);
        {
            let mut x = Fixed(Y(&a));
            unsafe { x.object_drop() };
            assert_eq!(a.load(Ordering::Relaxed), 6);
            forget(x);
        }
        assert_eq!(a.load(Ordering::Relaxed), 6);
    }

    #[test]
    #[wasm_bindgen_test]
    fn test_new_in_place() {
        let a = AtomicIsize::new(5);
        {
            let x = Fixed(Y(&a as *const AtomicIsize));
            {
                let mut y = Fixed(Y(null()));
                unsafe { x.construct(&mut y) };
                assert_eq!(a.load(Ordering::Relaxed), 5);
            }
            assert_eq!(a.load(Ordering::Relaxed), 6);
        }
        assert_eq!(a.load(Ordering::Relaxed), 6);
    }
}