use crate::*; const MASK_WHITE0: u8 = 0b1; const MASK_WHITE1: u8 = 0b10; const MASK_WHITE: u8 = MASK_WHITE0 | MASK_WHITE1; const MASK_BLACK: u8 = 0b100; const MASK_FIXED: u8 = 0b1000; /// Possible states of the Garbage Collector #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] enum GCState { Pause = 0, Propagate = 1, PropagateAgain = 2, Atomic = 3, Sweep = 4, } #[inline(always)] unsafe fn is_black(o: GCObjectPtr) -> bool { (&*o.0).gch.marked & MASK_BLACK != 0 } #[inline(always)] unsafe fn is_white(o: GCObjectPtr) -> bool { (&*o.0).gch.marked & MASK_WHITE != 0 } /*#[inline(always)] unsafe fn is_dead(g: *mut global_State, o: *mut GCObject) -> bool { (&*o).gch.marked & (MASK_WHITE | MASK_FIXED) == otherwhite(g) & MASK_WHITE } #[inline(always)] unsafe fn otherwhite(g: *mut global_State) -> u8 { (&*g).currentwhite ^ MASK_WHITE } #[inline(always)] fn black2gray(o: *mut GCObject) { (&mut *o).gch.marked &= !MASK_BLACK; } pub unsafe fn luaC_barrierback(L: *mut lua_State, o: *mut GCObject, gclist: *mut *mut GCObject) { let g = (&*L).global; debug_assert!(is_black(o) && !is_dead(g, o) != 0); debug_assert_ne!(g.gcstate, GCState::Pause); black2gray(o); // make object gray (again) *gclist = (&*g).grayagain; (&mut *g).grayagain = o; }*/ extern "C" { pub fn luaC_barrierback(L: *mut lua_State, o: GCObjectPtr, gclist: *mut *mut GCObject); pub fn luaC_barriertable(L: *mut lua_State, t: *mut Table, v: GCObjectPtr); } #[inline(always)] pub unsafe fn luaC_threadbarrier(L: *mut lua_State) { if is_black(L.into()) { luaC_barrierback(L, L.into(), &mut (&mut *L).gc_list as *mut _); } } #[inline(always)] pub unsafe fn luaC_barriert(L: *mut lua_State, t: *mut Table, v: *mut TValue) { if (*v).is_collectable() { debug_assert_eq!((*v).tt, (*(*v).value.gc).gch.tt.into(), "types do not match"); let v = (*v).value.gc.into(); if is_black(v) && is_white(v) { luaC_barriertable(L, t, v); } } }