use lua_gc::{Marker, Trace};
use crate::state::{LuaState, GlobalState};
use crate::string::{LuaStringImpl, LuaUserDataImpl};
use lua_types::{LuaClosure, LuaValue};
impl Trace for LuaStringImpl {
fn trace(&self, _m: &mut Marker) {}
}
impl Trace for LuaUserDataImpl {
fn trace(&self, _m: &mut Marker) {}
}
impl Trace for LuaState {
fn trace(&self, m: &mut Marker) {
let trace_debug_locals = self.cached_thread_id == self.global.borrow().current_thread_id;
let mut ci_idx = Some(self.ci);
while let Some(idx) = ci_idx {
let ci = &self.call_info[idx.as_usize()];
let start = ci.func.0 as usize;
let end_idx = if idx == self.ci {
self.top.0 as usize
} else if let Some(next) = ci.next {
self.call_info[next.as_usize()].func.0 as usize
} else {
self.top.0 as usize
};
let end = end_idx.min(self.stack.len());
if start < end {
for slot in &self.stack[start..end] {
slot.val.trace(m);
}
}
if trace_debug_locals && ci.is_lua() {
if let Some(slot) = self.stack.get(ci.func.0 as usize) {
if let LuaValue::Function(LuaClosure::Lua(cl)) = &slot.val {
let pc = ci.saved_pc().saturating_sub(1) as i32;
let base = ci.func.0 as usize + 1;
let mut n = 1i32;
while crate::func::get_local_name(&cl.proto, n, pc).is_some() {
let idx = base + (n as usize - 1);
if let Some(local_slot) = self.stack.get(idx) {
local_slot.val.trace(m);
}
n += 1;
}
}
}
}
ci_idx = ci.previous;
}
for uv in self.openupval.iter() {
uv.trace(m);
}
}
}
impl Trace for GlobalState {
fn trace(&self, m: &mut Marker) {
self.l_registry.trace(m);
for value in self.external_roots.iter_values() {
value.trace(m);
}
self.globals.trace(m);
self.loaded.trace(m);
if let Some(t) = &self.mainthread {
t.trace(m);
}
self.main_thread_value.trace(m);
if self.current_thread_id != self.main_thread_id {
if let Some(entry) = self.threads.get(&self.current_thread_id) {
entry.value.trace(m);
}
}
for slot in self.mt.iter() {
if let Some(t) = slot {
t.trace(m);
}
}
for s in self.tmname.iter() {
s.trace(m);
}
self.memerrmsg.trace(m);
for th in self.twups.iter() {
th.trace(m);
}
for s in self.interned_lt.values() {
s.trace(m);
}
for row in self.strcache.iter() {
for s in row.iter() {
s.trace(m);
}
}
for t in self.to_be_finalized.iter() {
t.trace(m);
}
for stack_snapshot in self.suspended_parent_stacks.iter() {
for v in stack_snapshot.iter() {
v.trace(m);
}
}
for upval_snapshot in self.suspended_parent_open_upvals.iter() {
for uv in upval_snapshot.iter() {
uv.trace(m);
}
}
}
}