Skip to main content

luaur_vm/functions/
validategraylist.rs

1//! `validategraylist` — validate every node in a GC gray list.
2//! C++ source: `VM/src/lgcdebug.cpp:218`
3//!
4//! Walks the singly-linked gray list starting at `o`; asserts each node is
5//! still gray and follows the per-type `gclist` pointer to the next node.
6//! Returns immediately if the GC invariant is not active (sweep phase etc.).
7
8use crate::enums::lua_type::lua_Type;
9use crate::macros::keepinvariant::keepinvariant;
10use crate::records::gc_object::GCObject;
11use crate::records::global_state::global_State;
12use luaur_common::macros::luau_assert::LUAU_ASSERT;
13
14#[allow(non_snake_case)]
15pub(crate) unsafe fn validategraylist(g: *mut global_State, mut o: *mut GCObject) {
16    if !keepinvariant(g) {
17        return;
18    }
19
20    while !o.is_null() {
21        LUAU_ASSERT!(crate::isgray!(o));
22
23        match (*o).gch.tt as i32 {
24            t if t == lua_Type::LUA_TTABLE as i32 => {
25                o = (*crate::gco2h!(o)).gclist;
26            }
27            t if t == lua_Type::LUA_TFUNCTION as i32 => {
28                o = (*crate::gco2cl!(o)).gclist;
29            }
30            t if t == lua_Type::LUA_TTHREAD as i32 => {
31                o = (*crate::gco2th!(o)).gclist;
32            }
33            t if t == lua_Type::LUA_TCLASS as i32 => {
34                o = (*crate::gco2class!(o)).gclist;
35            }
36            t if t == lua_Type::LUA_TOBJECT as i32 => {
37                o = (*crate::gco2object!(o)).gclist;
38            }
39            t if t == lua_Type::LUA_TPROTO as i32 => {
40                o = (*crate::gco2p!(o)).gclist;
41            }
42            _ => {
43                LUAU_ASSERT!(false);
44                return;
45            }
46        }
47    }
48}