Skip to main content

luaur_vm/functions/
lua_c_barriertable.rs

1//! Node: `cxx:Function:Luau.VM:VM/src/lgc.cpp:1296:lua_c_barriertable`
2//! Source: `VM/src/lgc.cpp` (lgc.cpp:1296-1314, hand-ported)
3
4use crate::functions::reallymarkobject::reallymarkobject;
5use crate::macros::black_2_gray::black2gray;
6use crate::macros::gc_spause::GCSpause;
7use crate::macros::gc_spropagateagain::GCSpropagateagain;
8use crate::macros::isblack::isblack;
9use crate::macros::isdead::isdead;
10use crate::macros::iswhite::iswhite;
11use crate::records::gc_object::GCObject;
12use crate::records::lua_table::LuaTable;
13use crate::type_aliases::lua_state::lua_State;
14use luaur_common::macros::luau_assert::LUAU_ASSERT;
15
16#[allow(non_snake_case)]
17pub unsafe fn luaC_barriertable(l: *mut lua_State, t: *mut LuaTable, v: *mut GCObject) {
18    let g = (*l).global;
19    let o = t as *mut GCObject;
20
21    // in the second propagation stage, table assignment barrier works as a forward barrier
22    if (*g).gcstate as i32 == GCSpropagateagain {
23        LUAU_ASSERT!(isblack!(o) && iswhite!(v) && !isdead!(g, v) && !isdead!(g, o));
24        reallymarkobject(g, v);
25        return;
26    }
27
28    LUAU_ASSERT!(isblack!(o) && !isdead!(g, o));
29    LUAU_ASSERT!((*g).gcstate as i32 != GCSpause);
30    black2gray!(o); // make table gray (again)
31    (*t).gclist = (*g).grayagain;
32    (*g).grayagain = o;
33}
34
35#[allow(unused_imports)]
36pub use luaC_barriertable as lua_c_barriertable;
37
38#[export_name = "luaur_luaC_barriertable"]
39pub unsafe extern "C" fn lua_c_barriertable_export(
40    l: *mut lua_State,
41    t: *mut core::ffi::c_void,
42    v: *mut core::ffi::c_void,
43) {
44    luaC_barriertable(l, t as *mut LuaTable, v as *mut GCObject);
45}