Skip to main content

luaur_code_gen/functions/
forg_loop_node_iter.rs

1use luaur_vm::macros::lu_tag_iterator::LU_TAG_ITERATOR;
2use luaur_vm::macros::setobj::setobj;
3use luaur_vm::macros::setpvalue::setpvalue;
4use luaur_vm::macros::ttisnil::ttisnil;
5use luaur_vm::records::lua_node::LuaNode;
6use luaur_vm::records::lua_table::LuaTable;
7use luaur_vm::type_aliases::lua_state::lua_State;
8use luaur_vm::type_aliases::t_value::TValue;
9use luaur_vm::type_aliases::value::Value;
10
11#[repr(C)]
12struct LocalTKey {
13    value: Value,
14    extra: [core::ffi::c_int; 1],
15    tt_next: i32,
16}
17
18impl LocalTKey {
19    #[inline]
20    fn tt(&self) -> core::ffi::c_int {
21        self.tt_next & 0xF
22    }
23}
24
25#[repr(C)]
26struct LocalLuaNode {
27    val: TValue,
28    key: LocalTKey,
29}
30
31unsafe fn node_gval(n: *const LuaNode) -> *const TValue {
32    core::ptr::addr_of!((*(n as *const LocalLuaNode)).val)
33}
34
35unsafe fn get_node_key(L: *mut lua_State, obj: *mut TValue, node: *const LuaNode) {
36    let key = core::ptr::addr_of!((*(node as *const LocalLuaNode)).key);
37    (*obj).value = (*key).value;
38    core::ptr::copy_nonoverlapping(
39        (*key).extra.as_ptr(),
40        (*obj).extra.as_mut_ptr(),
41        (*obj).extra.len(),
42    );
43    (*obj).tt = (*key).tt();
44    luaur_vm::macros::checkliveness::checkliveness!((*L).global, obj);
45}
46
47#[allow(non_snake_case)]
48pub unsafe fn forg_loop_node_iter(
49    L: *mut lua_State,
50    h: *mut LuaTable,
51    mut index: i32,
52    ra: *mut TValue,
53) -> bool {
54    let sizearray = (*h).sizearray;
55    let sizenode = 1 << (*h).lsizenode;
56
57    // then we advance index through the hash portion
58    while (index as u32).wrapping_sub(sizearray as u32) < (sizenode as u32) {
59        let n = (*h).node.add((index - sizearray) as usize);
60
61        if !ttisnil!(node_gval(n)) {
62            setpvalue!(
63                ra.add(2),
64                (index + 1) as usize as *mut core::ffi::c_void,
65                LU_TAG_ITERATOR
66            );
67            get_node_key(L, ra.add(3), n);
68            setobj!(L, ra.add(4), node_gval(n));
69
70            return true;
71        }
72
73        index += 1;
74    }
75
76    false
77}
78
79#[no_mangle]
80pub unsafe extern "C" fn forgLoopNodeIter(
81    L: *mut lua_State,
82    h: *mut core::ffi::c_void,
83    index: i32,
84    ra: *mut TValue,
85) -> bool {
86    forg_loop_node_iter(L, h as *mut LuaTable, index, ra)
87}