Skip to main content

luaur_vm/functions/
lua_c_barrierback.rs

1use crate::records::gc_object::GCObject;
2use crate::type_aliases::lua_state::lua_State;
3use luaur_common::macros::luau_assert::LUAU_ASSERT;
4
5#[allow(non_snake_case)]
6pub unsafe fn lua_c_barrierback(l: *mut lua_State, o: *mut GCObject, gclist: *mut *mut GCObject) {
7    let g = (*l).global;
8
9    // isblack(o) is ((*o).gch.marked & 4) != 0
10    // isdead(g, o) is ((*o).gch.marked & 11) == (((*g).currentwhite ^ 3) & 3)
11    let is_black = ((*o).gch.marked & 4) != 0;
12    let is_dead = ((*o).gch.marked & 11) == (((*g).currentwhite ^ 3) & 3);
13
14    LUAU_ASSERT!(is_black && !is_dead);
15    LUAU_ASSERT!((*g).gcstate as i32 != 0); // GCSpause is 0
16
17    // black2gray(o) clears the BLACKBIT (bit 2, mask 4)
18    (*o).gch.marked &= !4;
19
20    *gclist = (*g).grayagain;
21    (*g).grayagain = o;
22}
23
24#[export_name = "luaC_barrierback"]
25pub unsafe extern "C" fn lua_c_barrierback_export(
26    l: *mut lua_State,
27    o: *mut core::ffi::c_void,
28    gclist: *mut *mut core::ffi::c_void,
29) {
30    lua_c_barrierback(l, o as *mut GCObject, gclist as *mut *mut GCObject);
31}