Skip to main content

luaur_vm/functions/
lua_rawiter.rs

1use crate::functions::index_2_addr::index2addr;
2use crate::functions::lua_concat::lua_c_threadbarrier_lapi;
3use crate::macros::api_check::api_check;
4use crate::macros::api_update_top::api_update_top;
5use crate::macros::getnodekey::getnodekey;
6use crate::macros::hvalue::hvalue;
7use crate::macros::setnvalue::setnvalue;
8use crate::macros::setobj_2_s::setobj2s;
9use crate::macros::ttisnil::ttisnil;
10use crate::macros::ttistable::ttistable;
11use crate::records::lua_node::LuaNode;
12use crate::records::lua_state::lua_State;
13use crate::records::lua_table::LuaTable;
14use crate::type_aliases::stk_id::StkId;
15use crate::type_aliases::t_value::TValue;
16
17#[allow(non_snake_case)]
18pub unsafe fn lua_rawiter(
19    L: *mut lua_State,
20    idx: core::ffi::c_int,
21    iter: core::ffi::c_int,
22) -> core::ffi::c_int {
23    lua_c_threadbarrier_lapi(L);
24
25    let t: StkId = index2addr(L, idx);
26    api_check!(L, ttistable!(t));
27    api_check!(L, iter >= 0);
28
29    let h: *mut LuaTable = hvalue!(t);
30    let sizearray = (*h).sizearray;
31
32    // first we advance iter through the array portion
33    let mut iter = iter;
34    while (iter as u32) < (sizearray as u32) {
35        let e: *mut TValue = (*h).array.add(iter as usize);
36        if !ttisnil!(e) {
37            let top: StkId = (*L).top;
38            setnvalue!(top.add(0), (iter + 1) as f64);
39            setobj2s!(L, top.add(1), e);
40            api_update_top!(L, top.add(2));
41            return iter + 1;
42        }
43        iter += 1;
44    }
45
46    let sizenode = 1 << (*h).lsizenode;
47
48    // then we advance iter through the hash portion
49    while ((iter - sizearray) as u32) < (sizenode as u32) {
50        let n: *mut LuaNode = (*h).node.add((iter - sizearray) as usize);
51        let val = core::ptr::addr_of_mut!((*n).val);
52        if !ttisnil!(val) {
53            let top: StkId = (*L).top;
54            getnodekey!(L, top.add(0), n);
55            setobj2s!(L, top.add(1), val);
56            api_update_top!(L, top.add(2));
57            return iter + 1;
58        }
59        iter += 1;
60    }
61
62    // traversal finished
63    -1
64}