Skip to main content

luaur_code_gen/functions/
new_userdata.rs

1use core::ffi::c_int;
2
3use luaur_common::macros::luau_assert::LUAU_ASSERT;
4use luaur_vm::macros::isblack::isblack;
5use luaur_vm::records::gc_object::GCObject;
6use luaur_vm::records::lua_state::lua_State;
7use luaur_vm::records::udata::Udata;
8
9unsafe extern "C" {
10    #[link_name = "luaU_newudata"]
11    #[link_name = "luaur_luaU_newudata"]
12    fn luaU_newudata(L: *mut lua_State, s: usize, tag: c_int) -> *mut Udata;
13}
14
15#[allow(non_snake_case)]
16pub unsafe fn new_userdata(L: *mut lua_State, s: usize, tag: i32) -> *mut Udata {
17    let u = luaU_newudata(L, s, tag);
18
19    let h = (*(*L).global).udatamt[tag as usize];
20    if !h.is_null() {
21        // currently, we always allocate unmarked objects, so forward barrier can be skipped
22        LUAU_ASSERT!(!isblack!(u as *mut GCObject));
23
24        (*u).metatable = h;
25    }
26
27    u
28}
29
30#[export_name = "luaur_newUserdata"]
31pub unsafe extern "C" fn newUserdata(
32    L: *mut lua_State,
33    s: usize,
34    tag: c_int,
35) -> *mut core::ffi::c_void {
36    new_userdata(L, s, tag).cast()
37}