luaur_repl_cli/functions/
safe_get_table.rs1use core::ffi::c_char;
2
3use luaur_vm::functions::lua_l_getmetafield::lua_l_getmetafield;
4use luaur_vm::functions::lua_pushnil::lua_pushnil;
5use luaur_vm::functions::lua_pushvalue::lua_pushvalue;
6use luaur_vm::functions::lua_rawget::lua_rawget;
7use luaur_vm::functions::lua_remove::lua_remove;
8use luaur_vm::functions::lua_replace::lua_replace;
9use luaur_vm::macros::lua_isnil::lua_isnil;
10use luaur_vm::macros::lua_istable::lua_istable;
11use luaur_vm::macros::lua_pop::lua_pop;
12use luaur_vm::type_aliases::lua_state::lua_State;
13
14const MAX_TRAVERSAL_LIMIT: i32 = 50;
16
17pub unsafe fn safe_get_table(l: *mut lua_State, table_index: i32) {
20 lua_pushvalue(l, table_index); let mut loop_count = 0;
25 loop {
26 lua_pushvalue(l, -2); lua_rawget(l, -2); if !lua_isnil!(l, -1) || loop_count >= MAX_TRAVERSAL_LIMIT {
29 break;
31 } else {
32 lua_pop(l, 1); if lua_l_getmetafield(l, -1, c"__index".as_ptr() as *const c_char) == 0 {
34 lua_pushnil(l);
35 break;
36 } else if lua_istable!(l, -1) {
37 lua_replace(l, -2);
39 } else {
40 lua_pop(l, 1); lua_pushnil(l);
42 break;
43 }
44 }
45
46 loop_count += 1;
47 }
48
49 lua_remove(l, -2); lua_remove(l, -2); }