use crate::Janet;
#[derive(Debug, Default)]
pub struct JanetGc {
_phantom: core::marker::PhantomData<*const ()>,
}
impl JanetGc {
#[inline]
#[must_use = "function is a constructor associated function"]
pub fn obtain() -> Self {
Self {
_phantom: core::marker::PhantomData,
}
}
#[inline]
pub unsafe fn collect(&self) {
evil_janet::janet_collect()
}
#[inline]
#[must_use = "JanetGcLockGuard will be dropped if the result is not used"]
pub fn lock(&self) -> JanetGcLockGuard {
let handle = unsafe { evil_janet::janet_gclock() };
JanetGcLockGuard::new(handle)
}
#[inline]
pub fn unlock(guard: JanetGcLockGuard) {
drop(guard)
}
#[inline]
#[must_use = "JanetGcRootGuard will be dropped if the result is not used"]
pub fn root(&self, value: Janet) -> JanetGcRootGuard {
JanetGcRootGuard::new(value)
}
#[inline]
pub fn unroot(guard: JanetGcRootGuard) {
drop(guard)
}
}
#[derive(Debug)]
pub struct JanetGcLockGuard {
handle: i32,
_phantom: core::marker::PhantomData<*const ()>,
}
impl JanetGcLockGuard {
#[inline]
pub(crate) fn new(handle: i32) -> Self {
Self {
handle,
_phantom: core::marker::PhantomData,
}
}
}
impl Drop for JanetGcLockGuard {
#[inline]
fn drop(&mut self) {
unsafe { evil_janet::janet_gcunlock(self.handle) }
}
}
#[derive(Debug)]
pub struct JanetGcRootGuard {
value: Janet,
_phantom: core::marker::PhantomData<*const ()>,
}
impl JanetGcRootGuard {
#[inline]
fn new(value: Janet) -> Self {
unsafe { evil_janet::janet_gcroot(value.inner) };
Self {
value,
_phantom: core::marker::PhantomData,
}
}
}
impl Drop for JanetGcRootGuard {
#[inline]
fn drop(&mut self) {
let res = unsafe { evil_janet::janet_gcunroot(self.value.inner) };
debug_assert_eq!(res, 1)
}
}