Skip to main content

luaur_vm/functions/
lua_setuserdatametatable.rs

1//! `lua_setuserdatametatable` — pop a table from the stack and register it as
2//! the metatable for userdata of type `tag`.
3//! C++ source: `VM/src/lapi.cpp:1616`
4
5use crate::enums::lua_type::lua_Type;
6use crate::macros::lua_utag_limit::LUA_UTAG_LIMIT;
7use crate::records::lua_state::lua_State;
8use crate::records::lua_table::LuaTable;
9
10#[no_mangle]
11#[allow(non_snake_case)]
12pub unsafe fn lua_setuserdatametatable(l: *mut lua_State, tag: core::ffi::c_int) {
13    crate::api_checknelems!(l, 1);
14    crate::api_check!(l, (tag as u32) < LUA_UTAG_LIMIT as u32);
15    // reassignment not supported
16    crate::api_check!(l, (*(*l).global).udatamt[tag as usize].is_null());
17
18    let t = (*l).top.offset(-1);
19    crate::api_check!(l, (*t).tt == lua_Type::LUA_TTABLE as core::ffi::c_int);
20
21    // hvalue(top-1): the gc pointer refers to a GcObject; its `h` union arm is a LuaTable.
22    let gco = (*t).value.gc;
23    let h: *mut LuaTable = core::ptr::addr_of_mut!((*gco).h) as *mut LuaTable;
24    (*(*l).global).udatamt[tag as usize] = h;
25
26    (*l).top = (*l).top.offset(-1);
27}