1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use std::rc::Rc;
use std::ptr::NonNull;
use crate::{HandleCollectorId, prelude::*};
use super::{EpsilonCollectorId, EpsilonContext, EpsilonSystem, State};
pub struct GcHandle<T: ?Sized + GcSafe<'static, EpsilonCollectorId>> {
state: Rc<State>,
ptr: *const T
}
impl<T: ?Sized + GcSafe<'static, EpsilonCollectorId>> Clone for GcHandle<T> {
fn clone(&self) -> Self {
GcHandle {
state: Rc::clone(&self.state),
ptr: self.ptr
}
}
}
unsafe impl<T: ?Sized + GcSafe<'static, EpsilonCollectorId>> zerogc::GcHandle<T> for GcHandle<T> {
type System = EpsilonSystem;
type Id = EpsilonCollectorId;
#[inline]
fn use_critical<R>(&self, func: impl FnOnce(&T) -> R) -> R {
func(unsafe { &*self.ptr })
}
fn bind_to<'new_gc>(
&self,
context: &'new_gc EpsilonContext
) -> Gc<'new_gc, T::Branded, Self::Id>
where T: GcRebrand<'new_gc, Self::Id> {
assert_eq!(context.state.as_ptr() as *const State, &*self.state as *const State);
unsafe {
Gc::from_raw(NonNull::new_unchecked(
std::mem::transmute_copy::<*const T, *const T::Branded>(&self.ptr) as *mut T::Branded
))
}
}
}
zerogc_derive::unsafe_gc_impl!(
target => GcHandle<T>,
params => [T: GcSafe<'static, EpsilonCollectorId>],
bounds => {
Trace => { where T: ?Sized },
TraceImmutable => { where T: ?Sized },
TrustedDrop => { where T: ?Sized },
GcSafe => { where T: ?Sized },
},
null_trace => { where T: ?Sized },
NEEDS_DROP => true,
NEEDS_TRACE => false,
branded_type => Self,
trace_template => |self, visitor| { Ok(()) }
);
unsafe impl HandleCollectorId for EpsilonCollectorId {
type Handle<T>
where T: GcSafe<'static, Self> + ?Sized = GcHandle<T>;
fn create_handle<'gc, T>(_gc: Gc<'gc, T, Self>) -> Self::Handle<T::Branded>
where T: GcSafe<'gc, Self> + GcRebrand<'static, Self> + ?Sized {
unimplemented!("epsilon collector can't convert Gc -> GcContext")
}
}