luaur_vm/functions/
lua_setmetatable.rs1use 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}