cell_gc/
gcref.rs

1use traits::IntoHeapAllocation;
2use heap::{Heap, HeapSessionId};
3use ptr::Pointer;
4use std::fmt;
5use std::marker::PhantomData;
6
7pub struct GcRef<'h, T: IntoHeapAllocation<'h>> {
8    ptr: Pointer<T::In>,
9    heap_id: HeapSessionId<'h>,
10}
11
12impl<'h, T: IntoHeapAllocation<'h>> GcRef<'h, T> {
13    /// Pin an object, returning a new `GcRef` that will unpin it when
14    /// dropped. Unsafe because if `p` is not a pointer to a live allocation of
15    /// type `T::In` --- and a complete allocation, not a sub-object of one ---
16    /// then later unsafe code will explode.
17    pub unsafe fn new(p: Pointer<T::In>) -> GcRef<'h, T> {
18        let heap: *const Heap = Heap::from_allocation::<T>(p);
19        (*heap).pin::<T>(p);
20        GcRef {
21            ptr: p,
22            heap_id: PhantomData,
23        }
24    }
25
26    pub fn ptr(&self) -> Pointer<T::In> {
27        self.ptr
28    }
29
30    pub fn as_ptr(&self) -> *const T::In {
31        self.ptr.as_raw()
32    }
33
34    pub fn as_mut_ptr(&self) -> *mut T::In {
35        self.ptr.as_raw() as *mut T::In
36    }
37}
38
39impl<'h, T: IntoHeapAllocation<'h>> Drop for GcRef<'h, T> {
40    fn drop(&mut self) {
41        unsafe {
42            let heap = Heap::from_allocation::<T>(self.ptr);
43            (*heap).unpin::<T>(self.ptr);
44        }
45    }
46}
47
48impl<'h, T: IntoHeapAllocation<'h>> Clone for GcRef<'h, T> {
49    fn clone(&self) -> GcRef<'h, T> {
50        let &GcRef { ptr, heap_id } = self;
51        unsafe {
52            let heap = Heap::from_allocation::<T>(ptr);
53            (*heap).pin::<T>(ptr);
54        }
55        GcRef {
56            ptr: ptr,
57            heap_id: heap_id,
58        }
59    }
60}
61
62impl<'h, T: IntoHeapAllocation<'h>> fmt::Debug for GcRef<'h, T> {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        write!(f, "GcRef {{ ptr: {:p} }}", self.ptr.as_raw())
65    }
66}
67
68impl<'h, T: IntoHeapAllocation<'h>> PartialEq for GcRef<'h, T> {
69    fn eq(&self, other: &GcRef<'h, T>) -> bool {
70        self.ptr == other.ptr
71    }
72}
73
74impl<'h, T: IntoHeapAllocation<'h>> Eq for GcRef<'h, T> {}