Skip to main content

luaur_vm/functions/
lua_h_next.rs

1use crate::functions::findindex::findindex;
2use crate::macros::cast_num::cast_num;
3use crate::macros::getnodekey::getnodekey;
4use crate::macros::gnext::gnext;
5use crate::macros::gnode::gnode;
6use crate::macros::setnvalue::setnvalue;
7use crate::macros::setobj_2_s::setobj_2_s;
8use crate::macros::sizenode::sizenode;
9use crate::macros::ttisnil::ttisnil;
10use crate::type_aliases::lua_state::lua_State;
11use crate::type_aliases::lua_table::LuaTable;
12use crate::type_aliases::stk_id::StkId;
13
14// Required by getnodekey macro expansion
15use crate::macros::checkliveness::checkliveness;
16use crate::records::lua_node::LuaNode;
17use crate::records::lua_t_value::lua_TValue;
18use crate::type_aliases::t_value::TValue;
19
20#[allow(non_snake_case)]
21pub unsafe fn lua_h_next(L: *mut lua_State, t: *mut LuaTable, key: StkId) -> i32 {
22    let mut i = findindex(L, t, key);
23
24    i += 1;
25
26    // try first array part
27    while i < (*t).sizearray {
28        let e = (*t).array.add(i as usize);
29        if !ttisnil!(e) {
30            setnvalue!(key, cast_num!(i + 1));
31            setobj_2_s!(L, key.add(1), e);
32            return 1;
33        }
34        i += 1;
35    }
36
37    // then hash part
38    let mut k = i - (*t).sizearray;
39    let size = sizenode!(t);
40    while k < size {
41        let n = gnode!(t, k);
42        // gval(n) in C++ is (&(n)->val). In our Rust macros, gval is not provided as a standalone macro
43        // but the logic is usually just the address of the val field.
44        let val = core::ptr::addr_of_mut!((*n).val);
45        if !ttisnil!(val) {
46            getnodekey!(L, key, n);
47            setobj_2_s!(L, key.add(1), val);
48            return 1;
49        }
50        k += 1;
51    }
52
53    0 // no more elements
54}