use luau_common::BString;
use crate::gc::GcObject;
use crate::handle::RawHandle;
use crate::value::TValueCursor;
mod dump;
mod heap;
mod validate;
pub(super) use dump::{DumpContext, dump_gco, dump_gco_visitor};
pub(super) use heap::{HeapEnumContext, enum_heap_gco_visitor};
pub(super) use validate::validate_gco_visitor;
pub(super) fn safe_json(byte: u8) -> bool {
(32..128).contains(&byte) && byte != b'\\' && byte != b'"'
}
pub(in crate::gc) fn append_decimal(output: &mut BString, value: impl ToString) {
output.extend_from_slice(value.to_string().as_bytes());
}
pub(in crate::gc) unsafe fn append_ref(output: &mut BString, object: GcObject) {
output.push(b'"');
output.extend_from_slice(format!("{:p}", object.as_ptr()).as_bytes());
output.push(b'"');
}
pub(super) unsafe fn append_dump_refs(output: &mut BString, data: TValueCursor, size: usize) {
let mut first = true;
for index in 0..size {
let value = unsafe { data.add(index) };
if unsafe { value.value_unchecked() }.is_collectable() {
if !first {
output.push(b',');
}
first = false;
unsafe { append_ref(output, value.value_unchecked().gc_value()) };
}
}
}
pub(super) fn append_dump_string_data(output: &mut BString, bytes: &[u8]) {
for &byte in bytes {
output.push(if safe_json(byte) { byte } else { b'?' });
}
}