Skip to main content

luaur_vm/records/
t_key.rs

1#[allow(non_camel_case_types)]
2#[derive(Clone, Copy)]
3#[repr(C)]
4pub struct TKey {
5    pub(crate) value: crate::type_aliases::value::Value,
6    pub(crate) extra: [core::ffi::c_int; 1],
7    /// C++ bitfields `unsigned tt : 4; int next : 28;` packed into one 4-byte
8    /// word (low 4 bits = tt, high 28 bits = signed next). Keeping them as two
9    /// separate `c_int`s made TKey 24 bytes (LuaNode 40) instead of 16/32, which
10    /// broke the JIT ABI guard. Access via tt()/next()/set_tt()/set_next() only.
11    pub(crate) tt_next: core::ffi::c_uint,
12}
13
14#[allow(non_camel_case_types)]
15pub type t_key = TKey;
16
17impl TKey {
18    #[inline]
19    pub fn tt(&self) -> core::ffi::c_int {
20        (self.tt_next & 0xF) as core::ffi::c_int
21    }
22
23    #[inline]
24    pub fn set_tt(&mut self, tt: core::ffi::c_int) {
25        self.tt_next = (self.tt_next & !0xF) | ((tt as core::ffi::c_uint) & 0xF);
26    }
27
28    #[inline]
29    pub fn next(&self) -> i32 {
30        // `int next : 28` — sign-extend from the 28-bit field (bits 4..31).
31        (self.tt_next as i32) >> 4
32    }
33
34    #[inline]
35    pub fn set_next(&mut self, next: i32) {
36        self.tt_next = (self.tt_next & 0xF) | ((next as u32) << 4);
37    }
38}
39
40impl Default for TKey {
41    fn default() -> Self {
42        Self {
43            value: crate::type_aliases::value::Value::default(),
44            extra: [0; 1],
45            tt_next: 0,
46        }
47    }
48}
49
50impl core::fmt::Debug for TKey {
51    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52        f.debug_struct("TKey")
53            .field("extra", &self.extra)
54            .field("tt", &self.tt())
55            .field("next", &self.next())
56            .finish_non_exhaustive()
57    }
58}