1use super::{Object, WithLifetime};
2use crate::core::gc::{GcMoveable, Trace};
3use std::{cell::Cell, fmt};
4
5#[derive(PartialEq, Eq)]
14#[repr(transparent)]
15pub(crate) struct ObjCell(Cell<Object<'static>>);
16
17impl std::hash::Hash for ObjCell {
18 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
19 self.0.get().hash(state);
20 }
21}
22
23impl ObjCell {
24 pub(crate) fn get(&self) -> Object<'_> {
25 unsafe { self.0.get().with_lifetime() }
26 }
27
28 pub(in crate::core) unsafe fn new(obj: Object) -> Self {
29 Self(Cell::new(obj.with_lifetime()))
30 }
31
32 pub(in crate::core) unsafe fn as_mut(&self) -> &MutObjCell {
35 &*(self as *const Self).cast()
36 }
37}
38
39impl fmt::Display for ObjCell {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 fmt::Display::fmt(&self.0.get(), f)
42 }
43}
44
45impl fmt::Debug for ObjCell {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 write!(f, "{self}")
48 }
49}
50
51impl Trace for ObjCell {
52 fn trace(&self, state: &mut crate::core::gc::GcState) {
53 let cell = unsafe { self.as_mut() };
54 if let Some((new, moved)) = cell.get().move_value(&state.to_space) {
55 cell.set(new);
56 if moved {
57 state.push(new);
58 }
59 }
60 }
61}
62
63#[derive(PartialEq)]
68#[repr(transparent)]
69pub(crate) struct MutObjCell(ObjCell);
70
71impl std::ops::Deref for MutObjCell {
72 type Target = ObjCell;
73
74 fn deref(&self) -> &Self::Target {
75 &self.0
76 }
77}
78
79impl MutObjCell {
80 pub(crate) fn set(&self, value: Object) {
81 unsafe {
82 self.0.0.set(value.with_lifetime());
83 }
84 }
85}