Skip to main content

luaur_vm/functions/
lua_h_getnum.rs

1use crate::functions::hashnum::hashnum;
2use crate::functions::lua_a_toobject::luaO_nilobject;
3use crate::macros::cast_num::cast_num;
4use crate::macros::dummynode::luaH_dummynode;
5use crate::macros::gkey::{gkey, gval};
6use crate::macros::luai_numeq::luai_numeq;
7use crate::macros::nvalue::nvalue;
8use crate::macros::ttisnumber::ttisnumber;
9use crate::records::lua_table::LuaTable;
10use crate::type_aliases::t_value::TValue;
11
12#[allow(non_snake_case)]
13pub unsafe fn lua_h_getnum(t: *mut LuaTable, key: core::ffi::c_int) -> *const TValue {
14    // (1 <= key && key <= t->sizearray)
15    if (key as core::ffi::c_uint).wrapping_sub(1) < (*t).sizearray as core::ffi::c_uint {
16        return (*t).array.add((key - 1) as usize);
17    } else if (*t).node != &luaH_dummynode as *const _ as *mut _ {
18        let nk = cast_num!(key);
19        let mut n = hashnum(t, nk);
20
21        loop {
22            // check whether `key' is somewhere in the chain
23            if ttisnumber!(gkey!(n)) && luai_numeq(nvalue!(gkey!(n)), nk) {
24                return gval!(n); // that's it
25            }
26
27            // gnext(n) is defined as ((n)->key.next) in ltable.h
28            let next_offset = (*n).key.next();
29
30            if next_offset == 0 {
31                break;
32            }
33            n = n.offset(next_offset as isize);
34        }
35        return luaO_nilobject;
36    } else {
37        return luaO_nilobject;
38    }
39}