mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Prepare for custom (Luau) userdata destructors.
We need to add logic later to prevent calling any Lua functions when UserData destructor is running.
This commit is contained in:
@@ -97,7 +97,7 @@ impl<T> UserDataRegistry<T> {
|
||||
meta_methods: Vec::new(),
|
||||
#[cfg(feature = "async")]
|
||||
async_meta_methods: Vec::new(),
|
||||
destructor: super::util::userdata_destructor::<T>,
|
||||
destructor: super::util::destroy_userdata_storage::<T>,
|
||||
type_id: r#type.type_id(),
|
||||
type_name: short_type_name::<T>(),
|
||||
};
|
||||
|
||||
+24
-1
@@ -2,6 +2,7 @@ use std::any::TypeId;
|
||||
use std::cell::Cell;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_int;
|
||||
use std::ptr;
|
||||
|
||||
use super::UserDataStorage;
|
||||
use crate::error::{Error, Result};
|
||||
@@ -423,7 +424,29 @@ unsafe fn init_userdata_metatable_newindex(state: *mut ffi::lua_State) -> Result
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) unsafe extern "C-unwind" fn userdata_destructor<T>(state: *mut ffi::lua_State) -> c_int {
|
||||
// This method is called by Lua GC when it's time to collect the userdata.
|
||||
//
|
||||
// This method is usually used to collect internal userdata.
|
||||
#[cfg(not(feature = "luau"))]
|
||||
pub(crate) unsafe extern "C-unwind" fn collect_userdata<T>(state: *mut ffi::lua_State) -> c_int {
|
||||
let ud = get_userdata::<T>(state, -1);
|
||||
ptr::drop_in_place(ud);
|
||||
0
|
||||
}
|
||||
|
||||
// This method is called by Luau GC when it's time to collect the userdata.
|
||||
#[cfg(feature = "luau")]
|
||||
pub(crate) unsafe extern "C-unwind" fn collect_userdata<T>(
|
||||
_state: *mut ffi::lua_State,
|
||||
ud: *mut std::os::raw::c_void,
|
||||
) {
|
||||
ptr::drop_in_place(ud as *mut T);
|
||||
}
|
||||
|
||||
// This method can be called by user or Lua GC to destroy the userdata.
|
||||
// It checks if the userdata is safe to destroy and sets the "destroyed" metatable
|
||||
// to prevent further GC collection.
|
||||
pub(super) unsafe extern "C-unwind" fn destroy_userdata_storage<T>(state: *mut ffi::lua_State) -> c_int {
|
||||
let ud = get_userdata::<UserDataStorage<T>>(state, -1);
|
||||
if (*ud).is_safe_to_destroy() {
|
||||
take_userdata::<UserDataStorage<T>>(state);
|
||||
|
||||
Reference in New Issue
Block a user