comet/internal/
gc_info.rs

1use std::{any::TypeId, sync::atomic::AtomicU16};
2
3use crate::gc_info_table::{GCInfo, GC_TABLE};
4
5use super::{finalize_trait::FinalizeTrait, trace_trait::TraceTrait};
6
7/// Trait determines how the garbage collector treats objects wrt. to traversing,
8/// and finalization. It is automatically implemented for all types that implement [TraceTrait](crate::internal::trace_trait::TraceTrait) and 
9/// [FinalizeTrait](crate::internal::finalize_trait::FinalizeTrait).
10pub trait GCInfoTrait<T: TraceTrait + FinalizeTrait<T> + Sized + 'static> {
11    const REGISTERED_INDEX: AtomicU16;
12    /// Returns index of [GCInfo](crate::gc_info_table::GCInfo) in [GCInfoTable](crate::gc_info_table::GCInfoTable).
13    fn index() -> GCInfoIndex;
14}
15
16impl<T: TraceTrait + FinalizeTrait<T> + Sized + 'static> GCInfoTrait<T> for T {
17    const REGISTERED_INDEX: AtomicU16 = AtomicU16::new(0);
18    fn index() -> GCInfoIndex {
19        unsafe {
20            GC_TABLE.add_gc_info_type_id(
21                TypeId::of::<T>(),
22                GCInfo {
23                    finalize: <T as FinalizeTrait<T>>::CALLBACK,
24                    trace: <T as TraceTrait>::trace_,
25                    vtable: 0,
26                },
27            )
28        }
29    }
30}
31
32#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
33#[repr(transparent)]
34pub struct GCInfoIndex(pub(crate) u16);
35
36impl GCInfoIndex {
37    pub fn get(self) -> GCInfo {
38        unsafe { GC_TABLE.get_gc_info(self) }
39    }
40    /// Obtain mutable reference to GCInfo.
41    ///
42    /// # Safety
43    /// Unsafe since modifying GCInfo is unsafe and might break GC.
44    ///
45    pub unsafe fn get_mut(self) -> &'static mut GCInfo {
46        GC_TABLE.get_gc_info_mut(self)
47    }
48}