Skip to main content

luaur_vm/functions/
lua_setmetatable.rs

1use core::ffi::c_int;
2
3use crate::enums::lua_type::lua_Type;
4use crate::functions::index_2_addr::index2addr;
5use crate::functions::lua_g_readonlyerror::lua_g_readonlyerror;
6use crate::macros::api_check::api_check;
7use crate::macros::api_checknelems::api_checknelems;
8use crate::macros::hvalue::hvalue;
9use crate::macros::lua_c_objbarrier::luaC_objbarrier;
10use crate::macros::lua_o_nilobject::luaO_nilobject;
11use crate::macros::ttisnil::ttisnil;
12use crate::macros::ttistable::ttistable;
13use crate::macros::ttype::ttype;
14use crate::macros::uvalue::uvalue;
15use crate::records::lua_state::lua_State;
16use crate::records::lua_table::LuaTable;
17use crate::records::udata::Udata;
18use crate::type_aliases::stk_id::StkId;
19
20#[allow(non_snake_case)]
21pub unsafe fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int {
22    api_checknelems!(L, 1);
23
24    let obj: StkId = index2addr(L, objindex);
25    api_check!(L, obj != luaO_nilobject as StkId);
26
27    let mut mt: *mut LuaTable = core::ptr::null_mut();
28    if !ttisnil!((*L).top.sub(1)) {
29        api_check!(L, ttistable!((*L).top.sub(1)));
30        mt = hvalue!((*L).top.sub(1));
31    }
32
33    match ttype!(obj) {
34        x if x == lua_Type::LUA_TTABLE as c_int => {
35            let h = hvalue!(obj);
36            if (*h).readonly != 0 {
37                lua_g_readonlyerror(L);
38            }
39            (*h).metatable = mt;
40            if !mt.is_null() {
41                luaC_objbarrier!(L, h, mt);
42            }
43        }
44        x if x == lua_Type::LUA_TUSERDATA as c_int => {
45            let u = uvalue!(obj) as *const _ as *mut Udata;
46            (*u).metatable = mt;
47            if !mt.is_null() {
48                luaC_objbarrier!(L, u, mt);
49            }
50        }
51        _ => {
52            (*(*L).global).mt[ttype!(obj) as usize] = mt;
53        }
54    }
55
56    (*L).top = (*L).top.sub(1);
57    1
58}