Skip to main content

luaur_vm/functions/
lua_replace.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_checknelems::api_checknelems;
5use crate::macros::hvalue::hvalue;
6use crate::macros::lua_c_barrier::luaC_barrier;
7use crate::macros::lua_environindex::LUA_ENVIRONINDEX;
8use crate::macros::lua_globalsindex::LUA_GLOBALSINDEX;
9use crate::macros::lua_o_nilobject::luaO_nilobject;
10use crate::macros::setobj::setobj;
11use crate::macros::ttistable::ttistable;
12use crate::records::lua_state::lua_State;
13use crate::type_aliases::closure::Closure;
14use crate::type_aliases::stk_id::StkId;
15
16unsafe fn current_closure(L: *mut lua_State) -> *mut Closure {
17    let func = (*(*L).ci).func;
18    core::ptr::addr_of_mut!((*(*func).value.gc).cl) as *mut Closure
19}
20
21#[allow(non_snake_case)]
22pub unsafe fn lua_replace(L: *mut lua_State, idx: core::ffi::c_int) {
23    api_checknelems!(L, 1);
24    lua_c_threadbarrier_lapi(L);
25    let o: StkId = index2addr(L, idx);
26    api_check!(L, o != luaO_nilobject as StkId);
27    if idx == LUA_ENVIRONINDEX {
28        api_check!(L, (*L).ci != (*L).base_ci);
29        let func: *mut Closure = current_closure(L);
30        api_check!(L, ttistable!((*L).top.offset(-1)));
31        (*func).env = hvalue!((*L).top.offset(-1));
32        luaC_barrier!(L, func, (*L).top.offset(-1));
33    } else if idx == LUA_GLOBALSINDEX {
34        api_check!(L, ttistable!((*L).top.offset(-1)));
35        (*L).gt = hvalue!((*L).top.offset(-1));
36    } else {
37        setobj!(L, o, (*L).top.offset(-1));
38        if idx < LUA_GLOBALSINDEX {
39            luaC_barrier!(L, current_closure(L), (*L).top.offset(-1));
40        }
41    }
42    (*L).top = (*L).top.offset(-1);
43}